ui_node_special.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "../../client.h"
00026 #include "../ui_nodes.h"
00027 #include "../ui_parse.h"
00028 #include "../ui_actions.h"
00029 #include "ui_node_window.h"
00030 #include "ui_node_special.h"
00031 #include "ui_node_abstractnode.h"
00032 
00037 static void UI_FuncNodeLoaded (uiNode_t *node)
00038 {
00040     const value_t *prop = UI_GetPropertyFromBehaviour(node->parent->behaviour, node->name);
00041     if (prop && prop->type == V_UI_ACTION) {
00042         void **value = (void**) ((uintptr_t)node->parent + prop->ofs);
00043         if (*value == NULL)
00044             *value = (void*) node->onClick;
00045         else
00046             Com_Printf("UI_FuncNodeLoaded: '%s' already defined. Second function ignored (\"%s\")\n", prop->string, UI_GetPath(node));
00047     }
00048 }
00049 
00050 void UI_RegisterSpecialNode (uiBehaviour_t *behaviour)
00051 {
00052     behaviour->name = "special";
00053     behaviour->isVirtual = qtrue;
00054 }
00055 
00056 void UI_RegisterFuncNode (uiBehaviour_t *behaviour)
00057 {
00058     behaviour->name = "func";
00059     behaviour->extends = "special";
00060     behaviour->isVirtual = qtrue;
00061     behaviour->isFunction = qtrue;
00062     behaviour->loaded = UI_FuncNodeLoaded;
00063 }
00064 
00065 void UI_RegisterNullNode (uiBehaviour_t *behaviour)
00066 {
00067     behaviour->name = "";
00068     behaviour->extends = "special";
00069     behaviour->isVirtual = qtrue;
00070 }
00071 
00075 static void UI_ConfuncCommand_f (void)
00076 {
00077     uiNode_t *node = (uiNode_t *) Cmd_Userdata();
00078     assert(node);
00079     assert(UI_NodeInstanceOf(node, "confunc"));
00080     UI_ExecuteConFuncActions(node, node->onClick);
00081 }
00082 
00088 static qboolean UI_ConFuncIsVirtual (const uiNode_t *const node)
00089 {
00090     /* magic way to know if it is a dummy node (used for inherited confunc) */
00091     const uiNode_t *dummy = (const uiNode_t*) Cmd_GetUserdata(node->name);
00092     assert(node);
00093     assert(UI_NodeInstanceOf(node, "confunc"));
00094     return (dummy != NULL && dummy->parent == NULL);
00095 }
00096 
00100 static void UI_ConFuncNodeLoaded (uiNode_t *node)
00101 {
00102     /* register confunc non inherited */
00103     if (node->super == NULL) {
00104         /* don't add a callback twice */
00105         if (!Cmd_Exists(node->name)) {
00106             Cmd_AddCommand(node->name, UI_ConfuncCommand_f, "Confunc callback");
00107             Cmd_AddUserdata(node->name, node);
00108         } else {
00109             Com_Printf("UI_ParseNodeBody: Command name for confunc '%s' already registered\n", UI_GetPath(node));
00110         }
00111     } else {
00112         uiNode_t *dummy;
00113 
00114         /* convert a confunc to an "inherited" confunc if it is possible */
00115         if (Cmd_Exists(node->name)) {
00116             if (UI_ConFuncIsVirtual(node))
00117                 return;
00118         }
00119 
00120         dummy = UI_AllocNode(node->name, "confunc", qfalse);
00121         Cmd_AddCommand(node->name, UI_ConfuncCommand_f, "Inherited confunc callback");
00122         Cmd_AddUserdata(dummy->name, dummy);
00123     }
00124 }
00125 
00126 static void UI_ConFuncNodeClone (const uiNode_t *source, uiNode_t *clone)
00127 {
00128     UI_ConFuncNodeLoaded(clone);
00129 }
00130 
00134 static void UI_ConFuncNodeInit (uiNode_t *node)
00135 {
00136     if (UI_ConFuncIsVirtual(node)) {
00137         const value_t *property = UI_GetPropertyFromBehaviour(node->behaviour, "onClick");
00138         uiNode_t *userData = (uiNode_t*) Cmd_GetUserdata(node->name);
00139         UI_AddListener(userData, property, node);
00140     }
00141 }
00142 
00146 static void UI_ConFuncNodeClose (uiNode_t *node)
00147 {
00148     if (UI_ConFuncIsVirtual(node)) {
00149         const value_t *property = UI_GetPropertyFromBehaviour(node->behaviour, "onClick");
00150         uiNode_t *userData = (uiNode_t*) Cmd_GetUserdata(node->name);
00151         UI_RemoveListener(userData, property, node);
00152     }
00153 }
00154 
00155 void UI_RegisterConFuncNode (uiBehaviour_t *behaviour)
00156 {
00157     behaviour->name = "confunc";
00158     behaviour->extends = "special";
00159     behaviour->isVirtual = qtrue;
00160     behaviour->isFunction = qtrue;
00161     behaviour->loaded = UI_ConFuncNodeLoaded;
00162     behaviour->init = UI_ConFuncNodeInit;
00163     behaviour->close = UI_ConFuncNodeClose;
00164     behaviour->clone = UI_ConFuncNodeClone;
00165 }
00166 
00167 void UI_RegisterCvarFuncNode (uiBehaviour_t *behaviour)
00168 {
00169     behaviour->name = "cvarfunc";
00170     behaviour->extends = "special";
00171     behaviour->isVirtual = qtrue;
00172     behaviour->isFunction = qtrue;
00173 }

Generated by  doxygen 1.6.2