UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_data.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 2002-2020 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "../cl_shared.h"
26 #include "../cl_language.h"
27 #include "ui_main.h"
28 #include "ui_internal.h"
29 #include "ui_nodes.h"
30 #include "node/ui_node_option.h"
31 
32 #include "../cl_language.h"
33 
37 static const char* const ui_sharedDataIDNames[] = {
38  "",
83 
95 };
97 
102 int UI_GetDataIDByName (const char* name)
103 {
104  for (int num = 0; num < UI_MAX_DATAID; num++)
105  if (Q_streq(name, ui_sharedDataIDNames[num]))
106  return num;
107 
108  return -1;
109 }
110 
115 void UI_RegisterText (int dataId, const char* text)
116 {
117  UI_ResetData(dataId);
118 
119  if (!text)
120  return;
121 
123  ui_global.sharedData[dataId].data.text = text;
124  ui_global.sharedData[dataId].versionId++;
125 }
126 
132 {
135  ui_global.sharedData[dataId].versionId++;
136  return;
137  }
138  UI_ResetData(dataId);
141  ui_global.sharedData[dataId].versionId++;
142 }
143 
144 const char* UI_GetText (int textId)
145 {
146  if (ui_global.sharedData[textId].type != UI_SHARED_TEXT)
147  return nullptr;
148  return CL_Translate(ui_global.sharedData[textId].data.text);
149 }
150 
151 const char* UI_GetTextFromList (int textId, int line)
152 {
154  return nullptr;
156  return static_cast<const char*>(LIST_GetByIdx(list, line));
157 }
158 
159 int UI_GetDataVersion (int textId)
160 {
161  return ui_global.sharedData[textId].versionId;
162 }
163 
172 uiNode_t* UI_AddOption (uiNode_t** tree, const char* name, const char* label, const char* value)
173 {
174  uiNode_t* last;
175  uiNode_t* option;
176  assert(tree != nullptr);
177 
178  option = UI_AllocOptionNode(name, label, value);
179 
180  /* append the option */
181  last = *tree;
182  if (last != nullptr) {
183  while (last->next)
184  last = last->next;
185  }
186 
187  if (last)
188  last->next = option;
189  else
190  *tree = option;
191 
192  return option;
193 }
194 
200 static void UI_DeleteOption (uiNode_t* tree)
201 {
202  while (tree) {
203  uiNode_t* del = tree;
204  tree = tree->next;
205  UI_DeleteNode(del);
206  }
207 }
208 
212 void UI_ResetData (int dataId)
213 {
214  assert(dataId < UI_MAX_DATAID);
215  assert(dataId >= 0);
216 
217  switch (ui_global.sharedData[dataId].type) {
220  break;
221  case UI_SHARED_OPTION:
224  }
225  break;
226  default:
227  break;
228  }
229 
231  ui_global.sharedData[dataId].data.text = nullptr;
232  ui_global.sharedData[dataId].versionId++;
233 }
234 
241 {
242  uiNode_t* prev = *option;
243  uiNode_t* prevfind = nullptr;
244  uiNode_t* search = (*option)->next;
245  const char* label = CL_Translate(OPTIONEXTRADATA(*option).label);
246 
247  /* search the smaller element */
248  while (search) {
249  const char* searchlabel = CL_Translate(OPTIONEXTRADATA(search).label);
250  if (strcmp(label, searchlabel) < 0) {
251  prevfind = prev;
252  label = searchlabel;
253  }
254  prev = search;
255  search = search->next;
256  }
257 
258  /* remove the first element */
259  if (prevfind == nullptr) {
260  uiNode_t* tmp = *option;
261  *option = (*option)->next;
262  return tmp;
263  } else {
264  uiNode_t* tmp = prevfind->next;
265  prevfind->next = tmp->next;
266  return tmp;
267  }
268 }
269 
273 void UI_SortOptions (uiNode_t** first)
274 {
275  uiNode_t* option;
276 
277  /* unlink the unsorted list */
278  option = *first;
279  if (option == nullptr)
280  return;
281  *first = nullptr;
282 
283  /* construct a sorted list */
284  while (option) {
285  uiNode_t* element;
286  element = UI_OptionNodeRemoveHigherOption(&option);
287  element->next = *first;
288  *first = element;
289  }
290 }
291 
297 void UI_UpdateInvisOptions (uiNode_t* option, const linkedList_t* stringList)
298 {
299  if (option == nullptr || stringList == nullptr)
300  return;
301 
302  while (option) {
303  if (LIST_ContainsString(stringList, option->name))
304  option->invis = false;
305  else
306  option->invis = true;
307  option = option->next;
308  }
309 }
310 
311 void UI_RegisterOption (int dataId, uiNode_t* option)
312 {
314  if (ui_global.sharedData[dataId].type == UI_SHARED_OPTION && ui_global.sharedData[dataId].data.option == option) {
315  ui_global.sharedData[dataId].versionId++;
316  return;
317  }
318  UI_ResetData(dataId);
320  ui_global.sharedData[dataId].data.option = option;
321  ui_global.sharedData[dataId].versionId++;
322 }
323 
324 uiNode_t* UI_GetOption (int dataId)
325 {
326  if (ui_global.sharedData[dataId].type == UI_SHARED_OPTION) {
327  return ui_global.sharedData[dataId].data.option;
328  }
329  return nullptr;
330 }
331 
339 {
340  while (option) {
341  assert(option->behaviour == ui_optionBehaviour);
342  if (option->invis) {
343  option = option->next;
344  continue;
345  }
346 
347  /* we are on the right element */
348  if (index == 0) {
349  iterator->option = option;
350  return option;
351  }
352 
353  /* not the parent */
354  index--;
355 
356  if (OPTIONEXTRADATA(option).collapsed) {
357  option = option->next;
358  continue;
359  }
360 
361  /* its a child */
362  if (index < OPTIONEXTRADATA(option).childCount) {
363  if (iterator->depthPos >= MAX_DEPTH_OPTIONITERATORCACHE)
364  assert(false);
365  iterator->depthCache[iterator->depthPos] = option;
366  iterator->depthPos++;
367  return UI_FindOptionAtIndex(index, option->firstChild, iterator);
368  }
369  index -= OPTIONEXTRADATA(option).childCount;
370  option = option->next;
371  }
372 
373  iterator->option = nullptr;
374  return nullptr;
375 }
376 
395  return UI_InitOptionIteratorAtIndex(index, option, iterator, true, true);
396 }
397 
417 uiNode_t* UI_InitOptionIteratorAtIndex (int index, uiNode_t* option, uiOptionIterator_t* iterator, bool skipCollapsed, bool skipInvisible)
418 {
419  assert(option == nullptr || option->behaviour == ui_optionBehaviour);
420  OBJZERO(*iterator);
421  iterator->skipCollapsed = skipCollapsed;
422  iterator->skipInvisible = skipInvisible;
423  return UI_FindOptionAtIndex(index, option, iterator);
424 }
425 
431 {
432  uiNode_t* option;
433 
434  option = iterator->option;
435  assert(iterator->depthPos < MAX_DEPTH_OPTIONITERATORCACHE);
436  iterator->depthCache[iterator->depthPos] = option;
437  iterator->depthPos++;
438 
439  if (OPTIONEXTRADATA(option).collapsed && iterator->skipCollapsed)
440  option = nullptr;
441  else
442  option = option->firstChild;
443 
444  while (true) {
445  while (option) {
446  if (!option->invis || !iterator->skipInvisible) {
447  iterator->option = option;
448  return option;
449  }
450  option = option->next;
451  }
452  if (iterator->depthPos == 0)
453  break;
454  iterator->depthPos--;
455  option = iterator->depthCache[iterator->depthPos]->next;
456  }
457 
458  iterator->option = nullptr;
459  return nullptr;
460 }
461 
468 uiNode_t* UI_FindOptionByValue (uiOptionIterator_t* iterator, const char* value)
469 {
470  while (iterator->option) {
471  assert(iterator->option->behaviour == ui_optionBehaviour);
472  if (Q_streq(OPTIONEXTRADATA(iterator->option).value, value))
473  return iterator->option;
474  UI_OptionIteratorNextOption(iterator);
475  }
476  return nullptr;
477 }
478 
485 int UI_FindOptionPosition (uiOptionIterator_t* iterator, const uiNode_t* option)
486 {
487  int i = 0;
488  while (iterator->option) {
489  if (iterator->option == option)
490  return i;
491  i++;
492  UI_OptionIteratorNextOption(iterator);
493  }
494  return -1;
495 }
496 
502 static void UI_ResetData_f (void)
503 {
504  if (Cmd_Argc() == 2) {
505  const char* dataId = Cmd_Argv(1);
506  const int id = UI_GetDataIDByName(dataId);
507  if (id == -1)
508  Com_Printf("%s: invalid data ID: %s\n", Cmd_Argv(0), dataId);
509  else
510  UI_ResetData(id);
511  } else {
512  for (int i = 0; i < UI_MAX_DATAID; i++)
513  UI_ResetData(i);
514  }
515 }
516 
521 void UI_InitData (void)
522 {
523  Cmd_AddCommand("ui_resetdata", UI_ResetData_f, "Resets memory and data used by a UI data id");
524 }
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition: cmd.cpp:516
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition: cmd.cpp:744
bool skipCollapsed
Definition: ui_data.h:64
#define STRINGIFY(x)
Definition: shared.h:89
void UI_RegisterLinkedListText(int dataId, linkedList_t *text)
share a linked list of text with a data id
Definition: ui_data.cpp:131
uiNode_t * next
Definition: ui_nodes.h:91
void UI_RegisterText(int dataId, const char *text)
share a text with a data id
Definition: ui_data.cpp:115
void UI_SortOptions(uiNode_t **first)
Sort options by alphabet.
Definition: ui_data.cpp:273
uiGlobal_t ui_global
Definition: ui_main.cpp:38
void * LIST_GetByIdx(linkedList_t *list, int index)
Get an entry of a linked list by its index in the list.
Definition: list.cpp:362
uiSharedData_t sharedData[UI_MAX_DATAID]
Holds shared data.
Definition: ui_internal.h:59
uiNode_t * UI_FindOptionByValue(uiOptionIterator_t *iterator, const char *value)
Find an option (and all his parents) by is value.
Definition: ui_data.cpp:468
bool skipInvisible
Definition: ui_data.h:63
static uiNode_t * UI_FindOptionAtIndex(int index, uiNode_t *option, uiOptionIterator_t *iterator)
find an option why index (0 is the first option)
Definition: ui_data.cpp:338
char name[MAX_VAR]
Definition: ui_nodes.h:82
static void UI_ResetData_f(void)
Resets the ui_global.sharedData pointers from a func node.
Definition: ui_data.cpp:502
uiBehaviour_t * behaviour
Definition: ui_nodes.h:83
void UI_UpdateInvisOptions(uiNode_t *option, const linkedList_t *stringList)
Unhide those options that are stored in the linked list and hide the others.
Definition: ui_data.cpp:297
#define MAX_DEPTH_OPTIONITERATORCACHE
Definition: ui_data.h:57
uiNode_t * option
Holds a linked list for option (label, action, icon...)
Definition: ui_data.h:52
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
uiNode_t * UI_GetOption(int dataId)
Definition: ui_data.cpp:324
int num
Definition: ui_nodes.h:111
void UI_DeleteNode(uiNode_t *node)
Definition: ui_nodes.cpp:618
void LIST_Delete(linkedList_t **list)
Definition: list.cpp:195
int UI_GetDataVersion(int textId)
Definition: ui_data.cpp:159
int UI_GetDataIDByName(const char *name)
Return a dataId by name.
Definition: ui_data.cpp:102
static const char *const ui_sharedDataIDNames[]
Definition: ui_data.cpp:37
static void UI_DeleteOption(uiNode_t *tree)
Definition: ui_data.cpp:200
Internal data use by the UI package.
uiNode_t * depthCache[MAX_DEPTH_OPTIONITERATORCACHE]
Definition: ui_data.h:61
uiNode_t * UI_OptionIteratorNextOption(uiOptionIterator_t *iterator)
Find the next element from the iterator Iterator skipCollapsed and skipInvisible attribute can contro...
Definition: ui_data.cpp:430
bool invis
Definition: ui_nodes.h:101
const char * UI_GetText(int textId)
Definition: ui_data.cpp:144
bool _Mem_AllocatedInPool(memPool_t *pool, const void *pointer)
Definition: mem.cpp:482
uiNode_t * UI_AllocOptionNode(const char *name, const char *label, const char *value)
Initializes an option with a very little set of values.
void UI_InitData(void)
Initialize console command about UI shared data.
Definition: ui_data.cpp:521
#define OPTIONEXTRADATA(node)
void UI_ResetData(int dataId)
Reset a shared data. Type became NONE and value became nullptr.
Definition: ui_data.cpp:212
uiSharedType_t type
Definition: ui_data.h:45
linkedList_t * linkedListText
Holds a linked list for displaying in the UI.
Definition: ui_data.h:50
#define OBJZERO(obj)
Definition: shared.h:178
const char * UI_GetTextFromList(int textId, int line)
Definition: ui_data.cpp:151
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
memPool_t * com_genericPool
Definition: common.cpp:73
int UI_FindOptionPosition(uiOptionIterator_t *iterator, const uiNode_t *option)
Find an option position from an option iterator.
Definition: ui_data.cpp:485
const linkedList_t * LIST_ContainsString(const linkedList_t *list, const char *string)
Searches for the first occurrence of a given string.
Definition: list.cpp:73
Atomic structure used to define most of the UI.
Definition: ui_nodes.h:80
uiNode_t * UI_InitOptionIteratorAtIndex(int index, uiNode_t *option, uiOptionIterator_t *iterator)
Init an option iterator at an index.
Definition: ui_data.cpp:394
QGL_EXTERN GLuint index
Definition: r_gl.h:110
CASSERT(lengthof(ui_sharedDataIDNames)==UI_MAX_DATAID)
int versionId
Definition: ui_data.h:54
union uiSharedData_s::@18 data
QGL_EXTERN GLint i
Definition: r_gl.h:113
const char * CL_Translate(const char *t)
static uiNode_t * UI_OptionNodeRemoveHigherOption(uiNode_t **option)
Remove the higher element (in alphabet) from a list.
Definition: ui_data.cpp:240
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
void UI_RegisterOption(int dataId, uiNode_t *option)
Definition: ui_data.cpp:311
uiNode_t * UI_AddOption(uiNode_t **tree, const char *name, const char *label, const char *value)
Append an option to an option list.
Definition: ui_data.cpp:172
#define lengthof(x)
Definition: shared.h:105
uiNode_t * firstChild
Definition: ui_nodes.h:89
#define Q_streq(a, b)
Definition: shared.h:136
uiNode_t * option
Definition: ui_data.h:60
const uiBehaviour_t * ui_optionBehaviour
const char * text
Holds static array of characters to display.
Definition: ui_data.h:48
char * text
Definition: ui_nodes.h:121