ui_node_abstractnode.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     /* if we request the position of a non drawable node, there is a problem */
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     /* if we request the position of an undrawable node, there is a problem */
00161     assert(node->behaviour->isVirtual == qfalse);
00162     assert(x != NULL);
00163     assert(y != NULL);
00164 
00165     /* if we request the position of an undrawable node, there is a problem */
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     /* insert only a single element */
00244     assert(!newNode->next);
00245     /* everything come from the same window (force the dev to update himself this links) */
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:  /* common type */
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: /* 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: /* common type */
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     /* check string value */
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     /* check float value */
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     /* Top-left position of the node */
00751     {"pos", V_POS, offsetof(uiNode_t, pos), MEMBER_SIZEOF(uiNode_t, pos)},
00752     /* Size of the node */
00753     {"size", V_POS, offsetof(uiNode_t, size), MEMBER_SIZEOF(uiNode_t, size)},
00754     /* Width of the node (see also <code>size</code>) */
00755     {"width", V_FLOAT, offsetof(uiNode_t, size[0]), MEMBER_SIZEOF(uiNode_t, size[0])},
00756     /* Height of the node (see also <code>size</code>) */
00757     {"height", V_FLOAT, offsetof(uiNode_t, size[1]), MEMBER_SIZEOF(uiNode_t, size[1])},
00758     /* Left position of the node (see also <code>pos</code>) */
00759     {"left", V_FLOAT, offsetof(uiNode_t, pos[0]), MEMBER_SIZEOF(uiNode_t, pos[0])},
00760     /* Top position of the node (see also <code>pos</code>) */
00761     {"top", V_FLOAT, offsetof(uiNode_t, pos[1]), MEMBER_SIZEOF(uiNode_t, pos[1])},
00762 
00763     /* If true, the node name is indexed into the window. We can access to the node with
00764      * the path "windowName#nodeName"
00765      */
00766     {"indexed", V_BOOL, offsetof(uiNode_t, indexed), MEMBER_SIZEOF(uiNode_t, indexed)},
00767     /* If true, the node is not displayed nor or activatable. */
00768     {"invis", V_BOOL, offsetof(uiNode_t, invis), MEMBER_SIZEOF(uiNode_t, invis)},
00769     /* If true, the node is disabled. Few nodes support it, fell free to request an update. */
00770     {"disabled", V_BOOL, offsetof(uiNode_t, disabled), MEMBER_SIZEOF(uiNode_t, disabled)},
00771     /* If true, the node is not ''tangible''. We click through it, then it will not receive mouse event. */
00772     {"ghost", V_BOOL, offsetof(uiNode_t, ghost), MEMBER_SIZEOF(uiNode_t, ghost)},
00773     /* Border size we want to display. */
00774     {"border", V_INT, offsetof(uiNode_t, border), MEMBER_SIZEOF(uiNode_t, border)},
00775     /* Padding size we want to use. Few node support it. */
00776     {"padding", V_INT, offsetof(uiNode_t, padding), MEMBER_SIZEOF(uiNode_t, padding)},
00777     /* Background color we want to display. */
00778     {"bgcolor", V_COLOR, offsetof(uiNode_t, bgcolor), MEMBER_SIZEOF(uiNode_t, bgcolor)},
00779     /* Border color we want to display. */
00780     {"bordercolor", V_COLOR, offsetof(uiNode_t, bordercolor), MEMBER_SIZEOF(uiNode_t, bordercolor)},
00781 
00782     /*
00783      * Used to set the position of the node when the parent use a layout manager.
00784      * Else it do nothing.
00785      * Available values are: LAYOUTALIGN_TOPLEFT, LAYOUTALIGN_TOP, LAYOUTALIGN_TOPRIGHT,
00786      * LAYOUTALIGN_LEFT, LAYOUTALIGN_MIDDLE, LAYOUTALIGN_RIGHT, LAYOUTALIGN_BOTTOMLEFT,
00787      * LAYOUTALIGN_BOTTOM, LAYOUTALIGN_BOTTOMRIGHT, LAYOUTALIGN_FILL.
00788      * Allowed value depend the layout manager used. The update to date list is into
00789      * ui_node_panel.c
00790      * @image html http://ufoai.ninex.info/wiki/images/Layout.png
00791      */
00792     {"align", V_INT, offsetof(uiNode_t, align), MEMBER_SIZEOF(uiNode_t, align)},
00793 
00794     /*
00795      * Used share an int, only used by 1 behavour
00796      * @todo move it to the right behaviour, delete it
00797      */
00798     {"num", V_INT, offsetof(uiNode_t, num), MEMBER_SIZEOF(uiNode_t, num)},
00799 
00800     /* Tooltip we want to use. */
00801     {"tooltip", V_CVAR_OR_LONGSTRING, offsetof(uiNode_t, tooltip), 0},  /* translated in UI_Tooltip */
00802     /* Image to use. Each behaviour use it like they want.
00803      * @todo Move it into behaviour need it.
00804      * @todo use V_REF_OF_STRING when its possible ('image' is never a cvar)
00805      */
00806     {"image", V_CVAR_OR_STRING, offsetof(uiNode_t, image), 0},
00807     /* Text the node will display. */
00808     {"string", V_CVAR_OR_LONGSTRING, offsetof(uiNode_t, text), 0},  /* no gettext here - this can be a cvar, too */
00809     /* Text font the node will use.
00810      * @todo use V_REF_OF_STRING when its possible ('font' is never a cvar).
00811      */
00812     {"font", V_CVAR_OR_STRING, offsetof(uiNode_t, font), 0},
00813 
00814     /* Text color the node will use. */
00815     {"color", V_COLOR, offsetof(uiNode_t, color), MEMBER_SIZEOF(uiNode_t, color)},
00816     /* Text color the node will use when something is selected. */
00817     {"selectcolor", V_COLOR, offsetof(uiNode_t, selectedColor), MEMBER_SIZEOF(uiNode_t, selectedColor)},
00818     /* Alignement of the text into the node, or elements into blocks. */
00819     {"textalign", V_UI_ALIGN, offsetof(uiNode_t, textalign), MEMBER_SIZEOF(uiNode_t, textalign)},
00820     /* When <code>invis</code> property is false (default value), this condition say if the node is visible or not. It use a script expression. */
00821     {"visiblewhen", V_UI_IF, offsetof(uiNode_t, visibilityCondition), 0},
00822 
00823     /* Called when the user click with left button into the node. */
00824     {"onclick", V_UI_ACTION, offsetof(uiNode_t, onClick), MEMBER_SIZEOF(uiNode_t, onClick)},
00825     /* Called when the user click with right button into the node. */
00826     {"onrclick", V_UI_ACTION, offsetof(uiNode_t, onRightClick), MEMBER_SIZEOF(uiNode_t, onRightClick)},
00827     /* Called when the user click with middle button into the node. */
00828     {"onmclick", V_UI_ACTION, offsetof(uiNode_t, onMiddleClick), MEMBER_SIZEOF(uiNode_t, onMiddleClick)},
00829     /* Called when the user use the mouse wheel over the node. */
00830     {"onwheel", V_UI_ACTION, offsetof(uiNode_t, onWheel), MEMBER_SIZEOF(uiNode_t, onWheel)},
00831     /* Called when the user use the mouse wheel up over the node. */
00832     {"onwheelup", V_UI_ACTION, offsetof(uiNode_t, onWheelUp), MEMBER_SIZEOF(uiNode_t, onWheelUp)},
00833     /* Called when the user use the mouse wheel down over the node. */
00834     {"onwheeldown", V_UI_ACTION, offsetof(uiNode_t, onWheelDown), MEMBER_SIZEOF(uiNode_t, onWheelDown)},
00835     /* Called when the mouse enter over the node. */
00836     {"onmouseenter", V_UI_ACTION, offsetof(uiNode_t, onMouseEnter), MEMBER_SIZEOF(uiNode_t, onMouseEnter)},
00837     /* Called when the mouse go out of the node. */
00838     {"onmouseleave", V_UI_ACTION, offsetof(uiNode_t, onMouseLeave), MEMBER_SIZEOF(uiNode_t, onMouseLeave)},
00839     /* Called when the internal content of the nde change. Each behaviour use it how they need it.
00840      * @todo Move it where it is need.
00841      */
00842     {"onchange", V_UI_ACTION, offsetof(uiNode_t, onChange), MEMBER_SIZEOF(uiNode_t, onChange)},
00843 
00844     /* Special attribute only use into the node description to exclude part of the node (see also <code>ghost</code>). Rectangle position is relative to the node. */
00845     {"excluderect", V_UI_EXCLUDERECT, 0, 0},
00846 
00847     /* Remove all child from the node (only dynamic allocated nodes). */
00848     {"removeallchild", V_UI_NODEMETHOD, ((size_t) UI_AbstractNodeCallRemovaAllChild), 0},
00849 
00850     /* Create a new child with name and type. */
00851     {"createchild", V_UI_NODEMETHOD, ((size_t) UI_AbstractNodeCallCreateChild), 0},
00852 
00853     /* Delete the node and remove it from his parent. */
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     /* callbacks */
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     /* some commands */
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 }

Generated by  doxygen 1.6.2