00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ui_node_abstractnode.h"
00027 #include "ui_node_panel.h"
00028 #include "../ui_parse.h"
00029 #include "../ui_main.h"
00030 #include "../ui_components.h"
00031 #include "../ui_internal.h"
00032
00039 qboolean UI_NodeInstanceOf (const uiNode_t *node, const char* behaviourName)
00040 {
00041 const uiBehaviour_t *behaviour;
00042 for (behaviour = node->behaviour; behaviour; behaviour = behaviour->super) {
00043 if (strcmp(behaviour->name, behaviourName) == 0)
00044 return qtrue;
00045 }
00046 return qfalse;
00047 }
00048
00055 qboolean UI_NodeInstanceOfPointer (const uiNode_t *node, const uiBehaviour_t* behaviour)
00056 {
00057 const uiBehaviour_t *b;
00058 for (b = node->behaviour; b; b = b->super) {
00059 if (b == behaviour)
00060 return qtrue;
00061 }
00062 return qfalse;
00063 }
00064
00072 void UI_NodeGetPoint (const uiNode_t* node, vec2_t pos, int direction)
00073 {
00074 switch (UI_GET_HORIZONTAL_ALIGN(direction)) {
00075 case LAYOUTALIGN_H_LEFT:
00076 pos[0] = 0;
00077 break;
00078 case LAYOUTALIGN_H_MIDDLE:
00079 pos[0] = (int)(node->size[0] / 2);
00080 break;
00081 case LAYOUTALIGN_H_RIGHT:
00082 pos[0] = node->size[0];
00083 break;
00084 default:
00085 Com_Printf("UI_NodeGetPoint: Align '%d' (0x%X) is not a common alignment", direction, direction);
00086 pos[0] = 0;
00087 pos[1] = 0;
00088 return;
00089 }
00090
00091 switch (UI_GET_VERTICAL_ALIGN(direction)) {
00092 case LAYOUTALIGN_V_TOP:
00093 pos[1] = 0;
00094 break;
00095 case LAYOUTALIGN_V_MIDDLE:
00096 pos[1] = (int)(node->size[1] / 2);
00097 break;
00098 case LAYOUTALIGN_V_BOTTOM:
00099 pos[1] = node->size[1];
00100 break;
00101 default:
00102 Com_Printf("UI_NodeGetPoint: Align '%d' (0x%X) is not a common alignment", direction, direction);
00103 pos[0] = 0;
00104 pos[1] = 0;
00105 return;
00106 }
00107 }
00108
00114 void UI_GetNodeAbsPos (const uiNode_t* node, vec2_t pos)
00115 {
00116 assert(node);
00117 assert(pos);
00118
00119
00120 if (node->behaviour->isVirtual)
00121 Com_Error(ERR_FATAL, "UI_GetNodeAbsPos: Node '%s' doesn't have a position", node->name);
00122
00123 Vector2Set(pos, 0, 0);
00124 while (node) {
00125 #ifdef DEBUG
00126 if (node->pos[0] != (int)node->pos[0] || node->pos[1] != (int)node->pos[1])
00127 Com_Error(ERR_FATAL, "UI_GetNodeAbsPos: Node '%s' position %f,%f is not integer", UI_GetPath(node), node->pos[0], node->pos[1]);
00128 #endif
00129 pos[0] += node->pos[0];
00130 pos[1] += node->pos[1];
00131 node = node->parent;
00132 }
00133 }
00134
00140 void UI_NodeRelativeToAbsolutePoint (const uiNode_t* node, vec2_t pos)
00141 {
00142 assert(node);
00143 assert(pos);
00144 while (node) {
00145 pos[0] += node->pos[0];
00146 pos[1] += node->pos[1];
00147 node = node->parent;
00148 }
00149 }
00150
00157 void UI_NodeAbsoluteToRelativePos (const uiNode_t* node, int *x, int *y)
00158 {
00159 assert(node != NULL);
00160
00161 assert(node->behaviour->isVirtual == qfalse);
00162 assert(x != NULL);
00163 assert(y != NULL);
00164
00165
00166 if (node->behaviour->isVirtual)
00167 Com_Error(ERR_DROP, "UI_NodeAbsoluteToRelativePos: Node '%s' doesn't have a position", node->name);
00168
00169 while (node) {
00170 *x -= node->pos[0];
00171 *y -= node->pos[1];
00172 node = node->parent;
00173 }
00174 }
00175
00180 void UI_HideNode (uiNode_t* node)
00181 {
00182 if (node)
00183 node->invis = qtrue;
00184 else
00185 Com_Printf("UI_HideNode: No node given\n");
00186 }
00187
00192 void UI_UnHideNode (uiNode_t* node)
00193 {
00194 if (node)
00195 node->invis = qfalse;
00196 else
00197 Com_Printf("UI_UnHideNode: No node given\n");
00198 }
00199
00203 void UI_NodeSetSize (uiNode_t* node, vec2_t size)
00204 {
00205 if (node->size[0] == size[0] && node->size[1] == size[1])
00206 return;
00207 node->size[0] = size[0];
00208 node->size[1] = size[1];
00209 node->behaviour->sizeChanged(node);
00210 }
00211
00216 uiNode_t *UI_GetNode (const uiNode_t* const node, const char *name)
00217 {
00218 uiNode_t *current = NULL;
00219
00220 if (!node)
00221 return NULL;
00222
00223 for (current = node->firstChild; current; current = current->next)
00224 if (!strcmp(name, current->name))
00225 break;
00226
00227 return current;
00228 }
00229
00236 void UI_InsertNode (uiNode_t* const node, uiNode_t *prevNode, uiNode_t *newNode)
00237 {
00238 if (newNode->root == NULL)
00239 newNode->root = node->root;
00240
00241 assert(node);
00242 assert(newNode);
00243
00244 assert(!newNode->next);
00245
00246 assert(!prevNode || (prevNode->root == newNode->root));
00247 if (prevNode == NULL) {
00248 newNode->next = node->firstChild;
00249 node->firstChild = newNode;
00250 if (node->lastChild == NULL) {
00251 node->lastChild = newNode;
00252 }
00253 newNode->parent = node;
00254 } else {
00255 newNode->next = prevNode->next;
00256 prevNode->next = newNode;
00257 if (prevNode == node->lastChild) {
00258 node->lastChild = newNode;
00259 }
00260 newNode->parent = node;
00261 }
00262
00263 if (newNode->root && newNode->indexed)
00264 UI_WindowNodeAddIndexedNode(newNode->root, newNode);
00265
00266 UI_Invalidate(node);
00267 }
00268
00275 uiNode_t* UI_RemoveNode (uiNode_t* const node, uiNode_t *child)
00276 {
00277 assert(node);
00278 assert(child);
00279 assert(child->parent == node);
00280 assert(node->firstChild);
00281
00283 if (child == node->firstChild) {
00284 node->firstChild = child->next;
00285 } else {
00287 uiNode_t *previous = node->firstChild;
00288 while (previous != NULL) {
00289 if (previous->next == child)
00290 break;
00291 previous = previous->next;
00292 }
00293 previous->next = child->next;
00294 if (previous == NULL)
00295 return NULL;
00296 }
00297 UI_Invalidate(node);
00298
00300 if (node->lastChild == child) {
00301 node->lastChild = node->firstChild;
00302 while (node->lastChild && node->lastChild->next)
00303 node->lastChild = node->lastChild->next;
00304 }
00305 if (child->root && child->indexed)
00306 UI_WindowNodeRemoveIndexedNode(child->root, child);
00307
00308 child->next = NULL;
00309 return child;
00310 }
00311
00312 void UI_UpdateRoot (uiNode_t *node, uiNode_t *newRoot)
00313 {
00314 node->root = newRoot;
00315 node = node->firstChild;
00316 while (node) {
00317 UI_UpdateRoot(node, newRoot);
00318 node = node->next;
00319 }
00320 }
00321
00325 void UI_AppendNode (uiNode_t* const node, uiNode_t *newNode)
00326 {
00327 UI_InsertNode(node, node->lastChild, newNode);
00328 }
00329
00330 void UI_NodeSetPropertyFromRAW (uiNode_t* node, const value_t *property, void* rawValue, int rawType)
00331 {
00332 void *mem = ((byte *) node + property->ofs);
00333
00334 if (property->type != rawType) {
00335 Com_Printf("UI_NodeSetPropertyFromRAW: type %i expected, but @%s type %i found. Property setter to '%s@%s' skipped\n", rawType, property->string, property->type, UI_GetPath(node), property->string);
00336 return;
00337 }
00338
00339 if ((property->type & V_UI_MASK) == V_NOT_UI)
00340 Com_SetValue(node, rawValue, property->type, property->ofs, property->size);
00341 else if ((property->type & V_UI_MASK) == V_UI_CVAR) {
00342 UI_FreeStringProperty(*(void**)mem);
00343 switch (property->type & V_BASETYPEMASK) {
00344 case V_FLOAT:
00345 **(float **) mem = *(float*) rawValue;
00346 break;
00347 case V_INT:
00348 **(int **) mem = *(int*) rawValue;
00349 break;
00350 default:
00351 *(byte **) mem = (byte*) rawValue;
00352 }
00353 } else if (property->type == V_UI_ACTION) {
00354 *(uiAction_t**) mem = (uiAction_t*) rawValue;
00355 } else if (property->type == V_UI_ICONREF) {
00356 *(uiIcon_t**) mem = (uiIcon_t*) rawValue;
00357 } else {
00358 Com_Error(ERR_FATAL, "UI_NodeSetPropertyFromRAW: Property type '%d' unsupported", property->type);
00359 }
00360 node->behaviour->propertyChanged(node, property);
00361 }
00362
00366 qboolean UI_NodeSetProperty (uiNode_t* node, const value_t *property, const char* value)
00367 {
00368 byte* b = (byte*)node + property->ofs;
00369 const int specialType = property->type & V_UI_MASK;
00370 int result;
00371 size_t bytes;
00372
00373 switch (specialType) {
00374 case V_NOT_UI:
00375 result = Com_ParseValue(node, value, property->type, property->ofs, property->size, &bytes);
00376 if (result != RESULT_OK) {
00377 Com_Printf("UI_NodeSetProperty: Invalid value for property '%s': %s\n", property->string, Com_GetLastParseError());
00378 return qfalse;
00379 }
00380 node->behaviour->propertyChanged(node, property);
00381 return qtrue;
00382
00383 case V_UI_CVAR:
00384 switch (property->type) {
00385 case V_CVAR_OR_FLOAT:
00386 {
00387 float f;
00388
00389 if (!strncmp(value, "*cvar", 5)) {
00390 UI_FreeStringProperty(*(void**)b);
00391 *(char**) b = Mem_PoolStrDup(value, ui_dynStringPool, 0);
00392 node->behaviour->propertyChanged(node, property);
00393 return qtrue;
00394 }
00395
00396 result = Com_ParseValue(&f, value, V_FLOAT, 0, sizeof(f), &bytes);
00397 if (result != RESULT_OK) {
00398 Com_Printf("UI_NodeSetProperty: Invalid value for property '%s': %s\n", property->string, Com_GetLastParseError());
00399 return qfalse;
00400 }
00401
00402 b = (byte*) (*(void**)b);
00403 if (!strncmp((const char*)b, "*cvar", 5))
00404 UI_SetCvar(&((char*)b)[6], NULL, f);
00405 else
00406 *(float*) b = f;
00407 node->behaviour->propertyChanged(node, property);
00408 return qtrue;
00409 }
00410 case V_CVAR_OR_LONGSTRING:
00411 case V_CVAR_OR_STRING:
00412 {
00413 UI_FreeStringProperty(*(void**)b);
00414 *(char**) b = Mem_PoolStrDup(value, ui_dynStringPool, 0);
00415 node->behaviour->propertyChanged(node, property);
00416 return qtrue;
00417 }
00418 }
00419 }
00420
00421 Com_Printf("UI_NodeSetProperty: Unimplemented type for property '%s@%s'\n", UI_GetPath(node), property->string);
00422 return qfalse;
00423 }
00424
00431 const char* UI_GetStringFromNodeProperty (const uiNode_t* node, const value_t* property)
00432 {
00433 const int baseType = property->type & V_UI_MASK;
00434 const byte* b = (const byte*)node + property->ofs;
00435 assert(node);
00436 assert(property);
00437
00438 switch (baseType) {
00439 case V_NOT_UI:
00440 return Com_ValueToStr(node, property->type, property->ofs);
00441 case V_UI_CVAR:
00442 switch (property->type) {
00443 case V_CVAR_OR_FLOAT:
00444 {
00445 const float f = UI_GetReferenceFloat(node, *(const void*const*)b);
00446 const int i = f;
00447 if (f == i)
00448 return va("%i", i);
00449 else
00450 return va("%f", f);
00451 }
00452 case V_CVAR_OR_LONGSTRING:
00453 case V_CVAR_OR_STRING:
00454 return UI_GetReferenceString(node, *(const char*const*)b);
00455 }
00456 break;
00457 default:
00458 break;
00459 }
00460
00461 Com_Printf("UI_GetStringFromNodeProperty: Unsupported string getter for property type 0x%X (%s@%s)\n", property->type, UI_GetPath(node), property->string);
00462 return NULL;
00463 }
00464
00472 float UI_GetFloatFromNodeProperty (const uiNode_t* node, const value_t* property)
00473 {
00474 const byte* b = (const byte*)node + property->ofs;
00475 assert(node);
00476
00477 if (property->type == V_FLOAT) {
00478 return *(const float*) b;
00479 } else if (property->type == V_CVAR_OR_FLOAT) {
00480 b = *(const byte* const*) b;
00481 if (!strncmp((const char*)b, "*cvar", 5)) {
00482 const char* cvarName = (const char*)b + 6;
00483 const cvar_t *cvar = Cvar_Get(cvarName, "", 0, "UI script cvar property");
00484 return cvar->value;
00485 } else {
00486 return *(const float*) b;
00487 }
00488 } else if (property->type == V_INT) {
00489 return *(const int*) b;
00490 } else if (property->type == V_BOOL) {
00491 return *(const qboolean *) b;
00492 } else {
00493 #ifdef DEBUG
00494 Com_Printf("UI_GetFloatFromNodeProperty: Unimplemented float getter for property '%s@%s'. If it should return a float, request it.\n", UI_GetPath(node), property->string);
00495 #else
00496 Com_Printf("UI_GetFloatFromNodeProperty: Property '%s@%s' can't return a float\n", UI_GetPath(node), property->string);
00497 #endif
00498 }
00499
00500 return 0;
00501 }
00502
00503 #ifdef DEBUG
00504
00507 static void UI_NodeGetProperty_f (void)
00508 {
00509 uiNode_t *node;
00510 const value_t *property;
00511 const char *sValue;
00512 float fValue;
00513
00514 if (Cmd_Argc() != 2) {
00515 Com_Printf("Usage: %s <nodepath@prop>\n", Cmd_Argv(0));
00516 return;
00517 }
00518
00519 UI_ReadNodePath(Cmd_Argv(1), NULL, &node, &property);
00520
00521 if (node == NULL) {
00522 Com_Printf("UI_NodeGetProperty_f: Node from path '%s' doesn't exist\n", Cmd_Argv(1));
00523 return;
00524 }
00525
00526 if (property == NULL) {
00527 Com_Printf("UI_NodeGetProperty_f: Property from path '%s' doesn't exist\n", Cmd_Argv(1));
00528 return;
00529 }
00530
00531
00532 sValue = UI_GetStringFromNodeProperty(node, property);
00533 if (sValue) {
00534 Com_Printf("\"%s\" is \"%s\"\n", Cmd_Argv(1), sValue);
00535 return;
00536 }
00537
00538
00539 fValue = UI_GetFloatFromNodeProperty(node, property);
00540 Com_Printf("\"%s\" is \"%f\"\n", Cmd_Argv(1), fValue);
00541 }
00542
00547 static void UI_NodeSetProperty_f (void)
00548 {
00549 uiNode_t *node;
00550 const value_t *property;
00551
00552 if (Cmd_Argc() != 4) {
00553 Com_Printf("Usage: %s <nodepath> <prop> <value>\n", Cmd_Argv(0));
00554 return;
00555 }
00556
00557 node = UI_GetNodeByPath(Cmd_Argv(1));
00558 if (!node) {
00559 Com_Printf("UI_NodeSetProperty_f: Node '%s' not found\n", Cmd_Argv(1));
00560 return;
00561 }
00562
00563 property = UI_GetPropertyFromBehaviour(node->behaviour, Cmd_Argv(2));
00564 if (!property) {
00565 Com_Printf("Property '%s@%s' doesn't exist\n", UI_GetPath(node), Cmd_Argv(2));
00566 return;
00567 }
00568
00569 UI_NodeSetProperty(node, property, Cmd_Argv(3));
00570 }
00571 #endif
00572
00576 void UI_Invalidate (uiNode_t *node)
00577 {
00578 while (node) {
00579 if (node->invalidated)
00580 return;
00581 node->invalidated = qtrue;
00582 node = node->parent;
00583 }
00584 }
00585
00589 void UI_Validate (uiNode_t *node)
00590 {
00591 if (node->invalidated)
00592 node->behaviour->doLayout(node);
00593 }
00594
00595 static qboolean UI_AbstractNodeDNDEnter (uiNode_t *node)
00596 {
00597 return qfalse;
00598 }
00599
00600 static qboolean UI_AbstractNodeDNDMove (uiNode_t *node, int x, int y)
00601 {
00602 return qtrue;
00603 }
00604
00605 static void UI_AbstractNodeDNDLeave (uiNode_t *node)
00606 {
00607 }
00608
00609 static qboolean UI_AbstractNodeDNDDrop (uiNode_t *node, int x, int y)
00610 {
00611 return qtrue;
00612 }
00613
00614 static qboolean UI_AbstractNodeDNDFinished (uiNode_t *node, qboolean isDroped)
00615 {
00616 return isDroped;
00617 }
00618
00622 static void UI_AbstractNodeClone (const uiNode_t *source, uiNode_t *clone)
00623 {
00624 }
00625
00629 static void UI_AbstractNodeActivate (uiNode_t *node)
00630 {
00631 if (node->onClick)
00632 UI_ExecuteEventActions(node, node->onClick);
00633 }
00634
00638 static void UI_AbstractNodeDoLayout (uiNode_t *node)
00639 {
00640 uiNode_t *child;
00641 if (!node->invalidated)
00642 return;
00643
00644 for (child = node->firstChild; child; child = child->next) {
00645 child->behaviour->doLayout(child);
00646 }
00647
00648 node->invalidated = qfalse;
00649 }
00650
00651 static void UI_AbstractNodeInit (uiNode_t *node)
00652 {
00653 uiNode_t* child;
00654 for (child = node->firstChild; child; child = child->next) {
00655 if (child->behaviour->init) {
00656 child->behaviour->init(child);
00657 }
00658 }
00659 }
00660
00661 static void UI_AbstractNodeClose (uiNode_t *node)
00662 {
00663 uiNode_t* child;
00664 for (child = node->firstChild; child; child = child->next) {
00665 if (child->behaviour->close) {
00666 child->behaviour->close(child);
00667 }
00668 }
00669 }
00670
00674 static void UI_AbstractNodeSizeChanged (uiNode_t *node)
00675 {
00676 if (node->firstChild != NULL)
00677 UI_Invalidate(node);
00678 }
00679
00680 static void UI_AbstractNodeVisibilityChange (uiNode_t *node)
00681 {
00682 if (node->parent != NULL)
00683 UI_Invalidate(node->parent);
00684 }
00685
00686 static const value_t *propertyWidth;
00687 static const value_t *propertyHeight;
00688 static const value_t *propertySize;
00689 static const value_t *propertyInvis;
00690
00691 static void UI_AbstractNodePropertyChanged (uiNode_t *node, const value_t *property)
00692 {
00693 if (property == propertyWidth || property == propertyHeight || property == propertySize) {
00694 node->behaviour->sizeChanged(node);
00695 } else if (property == propertyInvis) {
00696 UI_AbstractNodeVisibilityChange(node);
00697 }
00698 }
00699
00700 static void UI_AbstractNodeCallRemovaAllChild (uiNode_t *node, const uiCallContext_t *context)
00701 {
00702 if (UI_GetParamNumber(context) != 0) {
00703 Com_Printf("UI_AbstractNodeCallRemovaAllChild: Invalide number of param\n");
00704 return;
00705 }
00706 UI_DeleteAllChild(node);
00707 }
00708
00709 static void UI_AbstractNodeCallCreateChild (uiNode_t *node, const uiCallContext_t *context)
00710 {
00711 uiNode_t *child;
00712 uiNode_t *component;
00713 const char *name;
00714 const char *type;
00715
00716 if (UI_GetParamNumber(context) != 2) {
00717 Com_Printf("UI_AbstractNodeCallCreateChild: Invalide number of param\n");
00718 return;
00719 }
00720
00721 name = UI_GetParam(context, 1);
00722 type = UI_GetParam(context, 2);
00723
00724 component = UI_GetComponent(type);
00725 if (component) {
00726 child = UI_CloneNode(component, node->root, qtrue, name, qtrue);
00727 } else {
00728 child = UI_AllocNode(name, type, qtrue);
00729 }
00730
00731 if (child == NULL) {
00732 Com_Printf("UI_AbstractNodeCallCreateChild: Impossible de create the node\n");
00733 return;
00734 }
00735
00736 UI_AppendNode(node, child);
00737 }
00738
00739 static void UI_AbstractNodeCallDelete (uiNode_t *node, const uiCallContext_t *context)
00740 {
00741 if (UI_GetParamNumber(context) != 0) {
00742 Com_Printf("UI_AbstractNodeCallDelete: Invalide number of param\n");
00743 return;
00744 }
00745 UI_DeleteNode(node);
00746 }
00747
00749 static const value_t properties[] = {
00750
00751 {"pos", V_POS, offsetof(uiNode_t, pos), MEMBER_SIZEOF(uiNode_t, pos)},
00752
00753 {"size", V_POS, offsetof(uiNode_t, size), MEMBER_SIZEOF(uiNode_t, size)},
00754
00755 {"width", V_FLOAT, offsetof(uiNode_t, size[0]), MEMBER_SIZEOF(uiNode_t, size[0])},
00756
00757 {"height", V_FLOAT, offsetof(uiNode_t, size[1]), MEMBER_SIZEOF(uiNode_t, size[1])},
00758
00759 {"left", V_FLOAT, offsetof(uiNode_t, pos[0]), MEMBER_SIZEOF(uiNode_t, pos[0])},
00760
00761 {"top", V_FLOAT, offsetof(uiNode_t, pos[1]), MEMBER_SIZEOF(uiNode_t, pos[1])},
00762
00763
00764
00765
00766 {"indexed", V_BOOL, offsetof(uiNode_t, indexed), MEMBER_SIZEOF(uiNode_t, indexed)},
00767
00768 {"invis", V_BOOL, offsetof(uiNode_t, invis), MEMBER_SIZEOF(uiNode_t, invis)},
00769
00770 {"disabled", V_BOOL, offsetof(uiNode_t, disabled), MEMBER_SIZEOF(uiNode_t, disabled)},
00771
00772 {"ghost", V_BOOL, offsetof(uiNode_t, ghost), MEMBER_SIZEOF(uiNode_t, ghost)},
00773
00774 {"border", V_INT, offsetof(uiNode_t, border), MEMBER_SIZEOF(uiNode_t, border)},
00775
00776 {"padding", V_INT, offsetof(uiNode_t, padding), MEMBER_SIZEOF(uiNode_t, padding)},
00777
00778 {"bgcolor", V_COLOR, offsetof(uiNode_t, bgcolor), MEMBER_SIZEOF(uiNode_t, bgcolor)},
00779
00780 {"bordercolor", V_COLOR, offsetof(uiNode_t, bordercolor), MEMBER_SIZEOF(uiNode_t, bordercolor)},
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 {"align", V_INT, offsetof(uiNode_t, align), MEMBER_SIZEOF(uiNode_t, align)},
00793
00794
00795
00796
00797
00798 {"num", V_INT, offsetof(uiNode_t, num), MEMBER_SIZEOF(uiNode_t, num)},
00799
00800
00801 {"tooltip", V_CVAR_OR_LONGSTRING, offsetof(uiNode_t, tooltip), 0},
00802
00803
00804
00805
00806 {"image", V_CVAR_OR_STRING, offsetof(uiNode_t, image), 0},
00807
00808 {"string", V_CVAR_OR_LONGSTRING, offsetof(uiNode_t, text), 0},
00809
00810
00811
00812 {"font", V_CVAR_OR_STRING, offsetof(uiNode_t, font), 0},
00813
00814
00815 {"color", V_COLOR, offsetof(uiNode_t, color), MEMBER_SIZEOF(uiNode_t, color)},
00816
00817 {"selectcolor", V_COLOR, offsetof(uiNode_t, selectedColor), MEMBER_SIZEOF(uiNode_t, selectedColor)},
00818
00819 {"textalign", V_UI_ALIGN, offsetof(uiNode_t, textalign), MEMBER_SIZEOF(uiNode_t, textalign)},
00820
00821 {"visiblewhen", V_UI_IF, offsetof(uiNode_t, visibilityCondition), 0},
00822
00823
00824 {"onclick", V_UI_ACTION, offsetof(uiNode_t, onClick), MEMBER_SIZEOF(uiNode_t, onClick)},
00825
00826 {"onrclick", V_UI_ACTION, offsetof(uiNode_t, onRightClick), MEMBER_SIZEOF(uiNode_t, onRightClick)},
00827
00828 {"onmclick", V_UI_ACTION, offsetof(uiNode_t, onMiddleClick), MEMBER_SIZEOF(uiNode_t, onMiddleClick)},
00829
00830 {"onwheel", V_UI_ACTION, offsetof(uiNode_t, onWheel), MEMBER_SIZEOF(uiNode_t, onWheel)},
00831
00832 {"onwheelup", V_UI_ACTION, offsetof(uiNode_t, onWheelUp), MEMBER_SIZEOF(uiNode_t, onWheelUp)},
00833
00834 {"onwheeldown", V_UI_ACTION, offsetof(uiNode_t, onWheelDown), MEMBER_SIZEOF(uiNode_t, onWheelDown)},
00835
00836 {"onmouseenter", V_UI_ACTION, offsetof(uiNode_t, onMouseEnter), MEMBER_SIZEOF(uiNode_t, onMouseEnter)},
00837
00838 {"onmouseleave", V_UI_ACTION, offsetof(uiNode_t, onMouseLeave), MEMBER_SIZEOF(uiNode_t, onMouseLeave)},
00839
00840
00841
00842 {"onchange", V_UI_ACTION, offsetof(uiNode_t, onChange), MEMBER_SIZEOF(uiNode_t, onChange)},
00843
00844
00845 {"excluderect", V_UI_EXCLUDERECT, 0, 0},
00846
00847
00848 {"removeallchild", V_UI_NODEMETHOD, ((size_t) UI_AbstractNodeCallRemovaAllChild), 0},
00849
00850
00851 {"createchild", V_UI_NODEMETHOD, ((size_t) UI_AbstractNodeCallCreateChild), 0},
00852
00853
00854 {"delete", V_UI_NODEMETHOD, ((size_t) UI_AbstractNodeCallDelete), 0},
00855
00856 {NULL, V_NULL, 0, 0}
00857 };
00858
00859 void UI_RegisterAbstractNode (uiBehaviour_t *behaviour)
00860 {
00861 behaviour->name = "abstractnode";
00862 behaviour->isAbstract = qtrue;
00863 behaviour->properties = properties;
00864
00865 propertyWidth = UI_GetPropertyFromBehaviour(behaviour, "width");
00866 propertyHeight = UI_GetPropertyFromBehaviour(behaviour, "height");
00867 propertySize = UI_GetPropertyFromBehaviour(behaviour, "size");
00868 propertyInvis = UI_GetPropertyFromBehaviour(behaviour, "invis");
00869
00870
00871 behaviour->dndEnter = UI_AbstractNodeDNDEnter;
00872 behaviour->dndMove = UI_AbstractNodeDNDMove;
00873 behaviour->dndLeave = UI_AbstractNodeDNDLeave;
00874 behaviour->dndDrop = UI_AbstractNodeDNDDrop;
00875 behaviour->dndFinished = UI_AbstractNodeDNDFinished;
00876 behaviour->doLayout = UI_AbstractNodeDoLayout;
00877 behaviour->clone = UI_AbstractNodeClone;
00878 behaviour->activate = UI_AbstractNodeActivate;
00879 behaviour->propertyChanged = UI_AbstractNodePropertyChanged;
00880 behaviour->sizeChanged = UI_AbstractNodeSizeChanged;
00881 behaviour->init = UI_AbstractNodeInit;
00882 behaviour->close = UI_AbstractNodeClose;
00883
00885 Com_RegisterConstInt("ALIGN_UL", ALIGN_UL);
00886 Com_RegisterConstInt("ALIGN_UC", ALIGN_UC);
00887 Com_RegisterConstInt("ALIGN_UR", ALIGN_UR);
00888 Com_RegisterConstInt("ALIGN_CL", ALIGN_CL);
00889 Com_RegisterConstInt("ALIGN_CC", ALIGN_CC);
00890 Com_RegisterConstInt("ALIGN_CR", ALIGN_CR);
00891 Com_RegisterConstInt("ALIGN_LL", ALIGN_LL);
00892 Com_RegisterConstInt("ALIGN_LC", ALIGN_LC);
00893 Com_RegisterConstInt("ALIGN_LR", ALIGN_LR);
00894
00895
00896 #ifdef DEBUG
00897 Cmd_AddCommand("debug_mnsetnodeproperty", UI_NodeSetProperty_f, "Set a node property");
00898 Cmd_AddCommand("debug_mngetnodeproperty", UI_NodeGetProperty_f, "Get a node property");
00899 #endif
00900 }