UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_node_abstractvalue.cpp
Go to the documentation of this file.
1 
7 /*
8 Copyright (C) 2002-2020 UFO: Alien Invasion.
9 
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 
19 See the GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25 */
26 
27 #include "../ui_nodes.h"
28 #include "../ui_parse.h"
29 #include "../ui_internal.h"
30 #include "../ui_lua.h"
31 
32 #include "ui_node_abstractvalue.h"
33 
34 #include "../../input/cl_input.h"
35 #include "../../input/cl_keys.h"
36 
37 #include "../../../common/scripts_lua.h"
38 
39 #define EXTRADATA_TYPE abstractValueExtraData_t
40 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
41 #define EXTRADATACONST(node) UI_EXTRADATACONST(node, EXTRADATA_TYPE)
42 
46 static inline void UI_InitCvarOrFloat (float** adress, float defaultValue)
47 {
48  if (*adress == nullptr) {
49  *adress = UI_AllocStaticFloat(1);
50  **adress = defaultValue;
51  }
52 }
53 
54 static void UI_CloneCvarOrFloat (const uiNode_t* source, uiNode_t* clone, const float*const* sourceData, float** cloneData)
55 {
56  /* dont update cvar */
57  if (Q_strstart(*(const char*const*)sourceData, "*cvar:")) {
58  /* thats anyway a const string */
59  if (clone->dynamic)
60  Mem_Free(*(char**)cloneData);
61  *(const char**)cloneData = *(const char*const*)sourceData;
62  } else {
63  /* clone float */
64  if (!clone->dynamic)
65  *cloneData = UI_AllocStaticFloat(1);
66  **cloneData = **sourceData;
67  }
68 }
69 
70 static void UI_FreeCvarOrFloat (const uiNode_t* node, void** data) {
71  /* if this is a string starting with "*cvar", then it points to a cvar variable and the
72  allocated string should be released */
73  if ((*data != nullptr) && Q_strstart((char*)(*data), "*cvar:")) {
74  Mem_Free(*data);
75  }
76  /* else this is a reference float */
77  else {
78  /* static floats do not have to be released */
79  }
80  *data = nullptr;
81 }
82 
83 
85 {
87  EXTRADATA(node).shiftIncreaseFactor = 2.0F;
88 }
89 
91 {
93  UI_InitCvarOrFloat((float**)&EXTRADATA(node).value, 0);
94  UI_InitCvarOrFloat((float**)&EXTRADATA(node).delta, 1);
95  UI_InitCvarOrFloat((float**)&EXTRADATA(node).max, 0);
96  UI_InitCvarOrFloat((float**)&EXTRADATA(node).min, 0);
97 }
98 
101 }
102 
104 {
106 }
107 
109 {
110  uiNode::deleteNode(node);
111  UI_FreeCvarOrFloat(node, &EXTRADATA(node).min);
112  UI_FreeCvarOrFloat(node, &EXTRADATA(node).max);
113  UI_FreeCvarOrFloat(node, &EXTRADATA(node).value);
114  UI_FreeCvarOrFloat(node, &EXTRADATA(node).delta);
115 }
116 
120 void uiAbstractValueNode::clone (const uiNode_t* source, uiNode_t* clone)
121 {
122  uiLocatedNode::clone(source, clone);
123  /* upon cloning a memcpy is done of the internal data so we need to replace the allocated floats with
124  new allocs or else a mismatch will occur between the number of allocated floats and the number of
125  deleted floats if nodes go out of scope */
126  EXTRADATA(clone).value = Mem_PoolAllocType(float, ui_dynPool);
127  EXTRADATA(clone).delta = Mem_PoolAllocType(float, ui_dynPool);
128  EXTRADATA(clone).max = Mem_PoolAllocType(float, ui_dynPool);
129  EXTRADATA(clone).min = Mem_PoolAllocType(float, ui_dynPool);
130  /* now clone the values */
131  UI_CloneCvarOrFloat(source, clone, (const float*const*)&EXTRADATACONST(source).value, (float**)&EXTRADATA(clone).value);
132  UI_CloneCvarOrFloat(source, clone, (const float*const*)&EXTRADATACONST(source).delta, (float**)&EXTRADATA(clone).delta);
133  UI_CloneCvarOrFloat(source, clone, (const float*const*)&EXTRADATACONST(source).max, (float**)&EXTRADATA(clone).max);
134  UI_CloneCvarOrFloat(source, clone, (const float*const*)&EXTRADATACONST(source).min, (float**)&EXTRADATA(clone).min);
135 }
136 
138 {
139  if (!Key_IsDown(K_SHIFT))
140  return 1.0F;
141 
142  return EXTRADATACONST(node).shiftIncreaseFactor;
143 }
144 
146  return EXTRADATACONST(node).lastdiff;
147 }
148 
150  return EXTRADATA(node).shiftIncreaseFactor;
151 }
152 
153 void uiAbstractValueNode::setRange(uiNode_t* node, float min, float max)
154 {
155  if (EXTRADATA(node).min == nullptr) {
156  UI_InitCvarOrFloat((float**)&EXTRADATA(node).min, min);
157  }
158  else {
159  setMin(node, min);
160  }
161  if (EXTRADATA(node).max == nullptr) {
162  UI_InitCvarOrFloat((float**)&EXTRADATA(node).max, max);
163  }
164  else {
165  setMax(node, max);
166  }
167 }
168 
169 bool uiAbstractValueNode::setValue(uiNode_t* node, float value)
170 {
171  const float last = UI_GetReferenceFloat(node, EXTRADATA(node).value);
172  const float max = UI_GetReferenceFloat(node, EXTRADATA(node).max);
173  const float min = UI_GetReferenceFloat(node, EXTRADATA(node).min);
174 
175  /* ensure sane values */
176  if (value < min)
177  value = min;
178  else if (value > max)
179  value = max;
180 
181  /* nothing change? */
182  if (last == value) {
183  return false;
184  }
185 
186  /* save result */
187  EXTRADATA(node).lastdiff = value - last;
188  const char* cvar = Q_strstart((char*)EXTRADATA(node).value, "*cvar:");
189  if (cvar)
190  Cvar_SetValue(cvar, value);
191  else
192  *(float*) EXTRADATA(node).value = value;
193 
194  /* fire change event */
195  if (node->onChange) {
196  UI_ExecuteEventActions(node, node->onChange);
197  }
198  if (node->lua_onChange != LUA_NOREF) {
200  }
201 
202  return true;
203 }
204 
205 bool uiAbstractValueNode::setDelta(uiNode_t* node, float delta) {
206  const float last = UI_GetReferenceFloat(node, EXTRADATA(node).delta);
207 
208  /* nothing change? */
209  if (last == delta) {
210  return false;
211  }
212 
213  /* save result */
214  const char* cvar = Q_strstart((char*)EXTRADATA(node).delta, "*cvar:");
215  if (cvar)
216  Cvar_SetValue(cvar, delta);
217  else
218  *(float*) EXTRADATA(node).delta = delta;
219 
220  return true;
221 }
222 bool uiAbstractValueNode::setMax(uiNode_t* node, float max) {
223  const float last = UI_GetReferenceFloat(node, EXTRADATA(node).max);
224 
225  /* nothing change? */
226  if (last == max) {
227  return false;
228  }
229 
230  /* save result */
231  const char* cvar = Q_strstart((char*)EXTRADATA(node).max, "*cvar:");
232  if (cvar)
233  Cvar_SetValue(cvar, max);
234  else
235  *(float*) EXTRADATA(node).max = max;
236 
237  return true;
238 }
239 
240 bool uiAbstractValueNode::setMin(uiNode_t* node, float min) {
241  const float last = UI_GetReferenceFloat(node, EXTRADATA(node).min);
242 
243  /* nothing change? */
244  if (last == min) {
245  return false;
246  }
247 
248  /* save result */
249  const char* cvar = Q_strstart((char*)EXTRADATA(node).min, "*cvar:");
250  if (cvar)
251  Cvar_SetValue(cvar, min);
252  else
253  *(float*) EXTRADATA(node).min = min;
254 
255  return true;
256 }
257 
259 {
260  float value = UI_GetReferenceFloat(node, EXTRADATA(node).value);
261  const float delta = getFactorFloat(node) * UI_GetReferenceFloat(node, EXTRADATA(node).delta);
262  return setValue(node, value + delta);
263 }
264 
266 {
267  float value = UI_GetReferenceFloat(node, EXTRADATA(node).value);
268  const float delta = getFactorFloat(node) * UI_GetReferenceFloat(node, EXTRADATA(node).delta);
269  return setValue(node, value - delta);
270 }
271 
273 {
274  return UI_GetReferenceFloat(node, EXTRADATACONST(node).min);
275 }
276 
278 {
279  return UI_GetReferenceFloat(node, EXTRADATACONST(node).max);
280 }
281 
283 {
284  return UI_GetReferenceFloat(node, EXTRADATACONST(node).delta);
285 }
286 
288 {
289  return UI_GetReferenceFloat(node, EXTRADATACONST(node).value);
290 }
291 
293  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
294  return b->getMin(node);
295 }
296 
298  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
299  return b->getMax(node);
300 }
301 
303  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
304  return b->getValue(node);
305 }
306 
308  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
309  return b->getDelta(node);
310 }
311 
313  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
314  return b->getLastDiff(node);
315 }
316 
318  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
319  return b->getShiftIncreaseFactor(node);
320 }
321 
323  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
324  b->incValue(node);
325 }
326 
328  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
329  b->decValue(node);
330 }
331 
332 void UI_AbstractValue_SetRange (uiNode_t* node, float min, float max) {
333  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
334  b->setRange(node, min, max);
335 }
336 
337 void UI_AbstractValue_SetMin (uiNode_t* node, float min) {
338  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
339  b->setRange(node, min, b->getMax(node));
340 }
341 
342 void UI_AbstractValue_SetMax (uiNode_t* node, float max) {
343  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
344  b->setRange(node, b->getMin(node), max);
345 }
346 
347 void UI_AbstractValue_SetValue (uiNode_t* node, float value) {
348  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
349  b->setValue(node, value);
350 }
351 
352 void UI_AbstractValue_SetDelta (uiNode_t* node, float delta) {
353  uiAbstractValueNode* b=static_cast<uiAbstractValueNode*>(node->behaviour->manager.get());
354  b->setDelta(node, delta);
355 }
356 
357 void UI_AbstractValue_SetRangeCvar (uiNode_t* node, const char* min, const char* max) {
358  /* This is a special case: we have a situation where the node already has a (min,max) value
359  (either being floats or cvars). We now want to replace this value by a new cvar. So we first
360  need to free the existing references, then create new cvar references and store them. */
361  UI_FreeCvarOrFloat(node, &EXTRADATA(node).min);
362  EXTRADATA(node).min = Mem_StrDup(min);
363  UI_FreeCvarOrFloat(node, &EXTRADATA(node).max);
364  EXTRADATA(node).max = Mem_StrDup(max);
365 }
366 
367 void UI_AbstractValue_SetMinCvar (uiNode_t* node, const char* min) {
368  /* This is a special case: we have a situation where the node already has a (min,max) value
369  (either being floats or cvars). We now want to replace this value by a new cvar. So we first
370  need to free the existing references, then create new cvar references and store them. */
371  UI_FreeCvarOrFloat(node, &EXTRADATA(node).min);
372  EXTRADATA(node).min = Mem_StrDup(min);
373 }
374 
375 void UI_AbstractValue_SetMaxCvar (uiNode_t* node, const char* max) {
376  /* This is a special case: we have a situation where the node already has a (min,max) value
377  (either being floats or cvars). We now want to replace this value by a new cvar. So we first
378  need to free the existing references, then create new cvar references and store them. */
379  UI_FreeCvarOrFloat(node, &EXTRADATA(node).max);
380  EXTRADATA(node).max = Mem_StrDup(max);
381 }
382 
383 void UI_AbstractValue_SetValueCvar (uiNode_t* node, const char* value) {
384  /* This is a special case: we have a situation where the node already has a value reference
385  (either being float or cvar). We now want to replace this value reference by a new cvar. So we first
386  need to free the existing reference, then create new cvar reference (just a string starting with
387  '*cvar' and store it. */
388  UI_FreeCvarOrFloat(node, &EXTRADATA(node).value);
389  EXTRADATA(node).value= Mem_StrDup(value);
390 
391  /* fire change event */
392  if (node->onChange) {
393  UI_ExecuteEventActions(node, node->onChange);
394  }
395  if (node->lua_onChange != LUA_NOREF) {
397  }
398 }
399 
401  EXTRADATA(node).shiftIncreaseFactor = factor;
402 }
403 
405 {
406  behaviour->name = "abstractvalue";
407  behaviour->manager = UINodePtr(new uiAbstractValueNode());
408  behaviour->isAbstract = true;
409  behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
410  behaviour->lua_SWIG_typeinfo = UI_SWIG_TypeQuery("uiAbstractValueNode_t *");
411 
412  /* Current value of the node. It should be a cvar */
414  /* Value of a positive step. Must be bigger than 1. */
416  /* Maximum value we can set to the node. It can be a cvar. Default value is 0. */
418  /* Minimum value we can set to the node. It can be a cvar. Default value is 1. */
420  /* Defines a factor that is applied to the delta value when the shift key is held down. */
421  UI_RegisterExtradataNodeProperty(behaviour, "shiftincreasefactor", V_FLOAT, abstractValueExtraData_t, shiftIncreaseFactor);
422 
423  /* Callback value set when before calling onChange. It is used to know the change apply by the user
424  * @Deprecated
425  */
426  UI_RegisterExtradataNodeProperty(behaviour, "lastdiff", V_FLOAT, abstractValueExtraData_t, lastdiff);
427 
428 }
bool setMax(uiNode_t *node, float max)
float UI_AbstractValue_GetMax(uiNode_t *node)
float getDelta(uiNode_t const *node)
float getShiftIncreaseFactor(uiNode_t *const node)
#define EXTRADATA(node)
float UI_AbstractValue_GetLastDiff(uiNode_t *node)
LUA_EVENT lua_onChange
Definition: ui_nodes.h:162
float getMin(uiNode_t const *node)
virtual void initNodeDynamic(uiNode_t *node)
void clone(uiNode_t const *source, uiNode_t *clone) override
Call to update a cloned node.
bool incValue(uiNode_t *node)
const char * name
Definition: ui_behaviour.h:41
struct uiAction_s * onChange
Definition: ui_nodes.h:143
static void UI_InitCvarOrFloat(float **adress, float defaultValue)
Allocates a float and initializes it if the pointer value is not set, else does nothing.
virtual void onLoaded(uiNode_t *node)
float * UI_AllocStaticFloat(int count)
Allocate a float into the UI static memory.
Definition: ui_parse.cpp:171
uiBehaviour_t * behaviour
Definition: ui_nodes.h:83
UINodePtr manager
Definition: ui_behaviour.h:43
bool UI_ExecuteLuaEventScript(uiNode_t *node, LUA_EVENT event)
Executes a lua event handler.
Definition: ui_lua.cpp:71
Define common thing for GUI controls which allow to edit a value (scroolbar, spinner, and more)
bool dynamic
Definition: ui_nodes.h:85
virtual void onLoading(uiNode_t *node)
#define Mem_StrDup(in)
Definition: mem.h:48
virtual void clone(uiNode_t const *source, uiNode_t *clone)
float UI_AbstractValue_GetValue(uiNode_t *node)
extradata for common GUI widget which allow to edit a value (scrollbar, spinner, and more) ...
void deleteNode(uiNode_t *node) override
static void UI_CloneCvarOrFloat(const uiNode_t *source, uiNode_t *clone, const float *const *sourceData, float **cloneData)
#define UI_RegisterExtradataNodeProperty(BEHAVIOUR, NAME, TYPE, EXTRADATATYPE, ATTRIBUTE)
Initialize a property from extradata of node.
Definition: ui_behaviour.h:109
float getFactorFloat(uiNode_t const *node)
float getMax(uiNode_t const *node)
void UI_AbstractValue_IncValue(uiNode_t *node)
float UI_AbstractValue_GetDelta(uiNode_t *node)
void UI_AbstractValue_SetDelta(uiNode_t *node, float delta)
#define EXTRADATA_TYPE
float getLastDiff(uiNode_t const *node)
float UI_AbstractValue_GetShiftIncreaseFactor(uiNode_t *node)
void UI_AbstractValue_DecValue(uiNode_t *node)
SharedPtr< uiNode > UINodePtr
bool setDelta(uiNode_t *node, float delta)
void * lua_SWIG_typeinfo
Definition: ui_behaviour.h:57
char const * Q_strstart(char const *str, char const *start)
Matches the start of a string.
Definition: shared.cpp:587
void UI_ExecuteEventActions(uiNode_t *source, const uiAction_t *firstAction)
Definition: ui_actions.cpp:726
PointerType get() const
Definition: sharedptr.h:197
float UI_AbstractValue_GetMin(uiNode_t *node)
memPool_t * ui_dynPool
Definition: ui_main.cpp:41
Atomic structure used to define most of the UI.
Definition: ui_nodes.h:80
void * UI_SWIG_TypeQuery(const char *name)
This function queries the SWIG type table for a type information structure. It is used in combination...
void UI_AbstractValue_SetValue(uiNode_t *node, float value)
#define EXTRADATACONST(node)
float UI_GetReferenceFloat(const uiNode_t *const node, const void *ref)
Returns the value of the reference variable.
Definition: ui_parse.cpp:1434
void UI_AbstractValue_SetMin(uiNode_t *node, float min)
void UI_AbstractValue_SetRange(uiNode_t *node, float min, float max)
bool Key_IsDown(unsigned int key)
Checks whether a given key is currently pressed.
Definition: cl_keys.cpp:214
void UI_AbstractValue_SetRangeCvar(uiNode_t *node, const char *min, const char *max)
void onLoaded(uiNode_t *node) override
virtual void initNode(uiNode_t *node)
bool setMin(uiNode_t *node, float min)
intptr_t extraDataSize
Definition: ui_behaviour.h:54
node behaviour, how a node work
Definition: ui_behaviour.h:39
static void UI_FreeCvarOrFloat(const uiNode_t *node, void **data)
void UI_RegisterAbstractValueNode(uiBehaviour_t *behaviour)
#define Mem_Free(ptr)
Definition: mem.h:35
void UI_AbstractValue_SetMax(uiNode_t *node, float max)
virtual void deleteNode(uiNode_t *node)
bool setValue(uiNode_t *node, float value)
#define V_CVAR_OR_FLOAT
Definition: ui_parse.h:68
void UI_AbstractValue_SetMinCvar(uiNode_t *node, const char *min)
void onLoading(uiNode_t *node) override
GLsizei const GLvoid * data
Definition: r_gl.h:152
#define Mem_PoolAllocType(type, pool)
Definition: mem.h:43
void initNode(uiNode_t *node) override
float getValue(uiNode_t const *node)
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition: cvar.cpp:671
void UI_AbstractValue_SetShiftIncreaseFactor(uiNode_t *node, float factor)
void setRange(uiNode_t *node, float min, float max)
bool decValue(uiNode_t *node)
void UI_AbstractValue_SetValueCvar(uiNode_t *node, const char *value)
void initNodeDynamic(uiNode_t *node) override
void UI_AbstractValue_SetMaxCvar(uiNode_t *node, const char *max)