1 /**
2 * @file
3 * @todo manage disabled option
4 */
5
6 /*
7 Copyright (C) 2002-2013 UFO: Alien Invasion.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18 See the GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 */
25
26 #include "../ui_main.h"
27 #include "../ui_internal.h"
28 #include "../ui_parse.h"
29 #include "../ui_draw.h"
30 #include "../ui_data.h"
31 #include "ui_node_abstractoption.h"
32 #include "ui_node_abstractnode.h"
33
34 #define EXTRADATA_TYPE abstractOptionExtraData_t
35 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
36
37 /**
38 * @brief Sort options by alphabet
39 */
UI_OptionNodeSortOptions(uiNode_t * node)40 void UI_OptionNodeSortOptions (uiNode_t* node)
41 {
42 uiNode_t* option;
43 assert(UI_Node_IsOptionContainer(node));
44 UI_SortOptions(&node->firstChild);
45
46 /** update lastChild */
47 /** @todo the sort option should do it itself */
48 option = node->firstChild;
49 while (option->next)
50 option = option->next;
51 node->lastChild = option;
52 }
53
UI_AbstractOptionGetCurrentValue(uiNode_t * node)54 const char* UI_AbstractOptionGetCurrentValue (uiNode_t* node)
55 {
56 /* no cvar given? */
57 if (!EXTRADATA(node).cvar || !*EXTRADATA(node).cvar) {
58 Com_Printf("UI_AbstractOptionGetCurrentValue: node '%s' doesn't have a valid cvar assigned\n", UI_GetPath(node));
59 return nullptr;
60 }
61
62 /* not a cvar? */
63 if (!Q_strstart(EXTRADATA(node).cvar, "*cvar:"))
64 return nullptr;
65
66 return UI_GetReferenceString(node, EXTRADATA(node).cvar);
67 }
68
UI_AbstractOptionSetCurrentValue(uiNode_t * node,const char * value)69 void UI_AbstractOptionSetCurrentValue(uiNode_t* node, const char* value)
70 {
71 const char* cvarName = &EXTRADATA(node).cvar[6];
72 Cvar_Set(cvarName, "%s", value);
73 if (node->onChange)
74 UI_ExecuteEventActions(node, node->onChange);
75 }
76
doLayout(uiNode_t * node)77 void uiAbstractOptionNode::doLayout (uiNode_t* node)
78 {
79 uiNode_t* option = node->firstChild;
80
81 if (EXTRADATA(node).dataId == 0) {
82 int count = 0;
83 while (option && option->behaviour == ui_optionBehaviour) {
84 UI_Validate(option);
85 if (!option->invis)
86 count++;
87 option = option->next;
88 }
89
90 EXTRADATA(node).count = count;
91 }
92
93 node->invalidated = false;
94 }
95
96 /**
97 * @brief Return the first option of the node
98 * @todo check versionId and update cached data, and fire events
99 */
UI_AbstractOptionGetFirstOption(uiNode_t * node)100 uiNode_t* UI_AbstractOptionGetFirstOption (uiNode_t* node)
101 {
102 if (node->firstChild && node->firstChild->behaviour == ui_optionBehaviour) {
103 return node->firstChild;
104 } else {
105 const int v = UI_GetDataVersion(EXTRADATA(node).dataId);
106 if (v != EXTRADATA(node).versionId) {
107 int count = 0;
108 uiNode_t* option = UI_GetOption(EXTRADATA(node).dataId);
109 while (option) {
110 if (!option->invis)
111 count++;
112 option = option->next;
113 }
114 EXTRADATA(node).count = count;
115 EXTRADATA(node).versionId = v;
116 }
117 return UI_GetOption(EXTRADATA(node).dataId);
118 }
119 }
120
121 /**
122 * @brief Return size of the cell, which is the size (in virtual "pixel") which represents 1 in the scroll values.
123 * Here expect the widget can scroll pixel per pixel.
124 * @return Size in pixel.
125 */
getCellWidth(uiNode_t * node)126 int uiAbstractOptionNode::getCellWidth (uiNode_t* node)
127 {
128 return 1;
129 }
130
131 /**
132 * @brief Return size of the cell, which is the size (in virtual "pixel") which represents 1 in the scroll values.
133 * Here we guess the widget can scroll pixel per pixel.
134 * @return Size in pixel.
135 */
getCellHeight(uiNode_t * node)136 int uiAbstractOptionNode::getCellHeight (uiNode_t* node)
137 {
138 return 1;
139 }
140
UI_RegisterAbstractOptionNode(uiBehaviour_t * behaviour)141 void UI_RegisterAbstractOptionNode (uiBehaviour_t* behaviour)
142 {
143 behaviour->name = "abstractoption";
144 behaviour->isAbstract = true;
145 behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
146 behaviour->drawItselfChild = true;
147 behaviour->manager = UINodePtr(new uiAbstractOptionNode());
148
149 /** Optional. Data ID we want to use. It must be an option list. It substitute to the inline options */
150 UI_RegisterExtradataNodeProperty(behaviour, "dataid", V_UI_DATAID, EXTRADATA_TYPE, dataId);
151 /** Optional. We can define the height of the block containing an option. */
152 UI_RegisterExtradataNodeProperty(behaviour, "lineheight", V_INT, EXTRADATA_TYPE, lineHeight);
153
154 /* position of the vertical view (into the full number of elements the node contain) */
155 UI_RegisterExtradataNodeProperty(behaviour, "viewpos", V_INT, EXTRADATA_TYPE, scrollY.viewPos);
156 /* size of the vertical view (proportional to the number of elements the node can display without moving) */
157 UI_RegisterExtradataNodeProperty(behaviour, "viewsize", V_INT, EXTRADATA_TYPE, scrollY.viewSize);
158 /* full vertical size (proportional to the number of elements the node contain) */
159 UI_RegisterExtradataNodeProperty(behaviour, "fullsize", V_INT, EXTRADATA_TYPE, scrollY.fullSize);
160
161 /* number of elements contain the node */
162 UI_RegisterExtradataNodeProperty(behaviour, "count", V_INT, EXTRADATA_TYPE, count);
163
164 /* Define the cvar containing the value of the current selected option */
165 UI_RegisterExtradataNodeProperty(behaviour, "cvar", V_UI_CVAR, EXTRADATA_TYPE, cvar);
166
167 /* Called when one of the properties viewpos/viewsize/fullsize change */
168 UI_RegisterExtradataNodeProperty(behaviour, "onviewchange", V_UI_ACTION, EXTRADATA_TYPE, onViewChange);
169 }
170