UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ui_node_spinner.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 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_nodes.h"
27 #include "../ui_parse.h"
28 #include "../ui_behaviour.h"
29 #include "../ui_main.h"
30 #include "../ui_input.h"
31 #include "../ui_timer.h"
32 #include "../ui_actions.h"
33 #include "../ui_render.h"
34 #include "../ui_sprite.h"
35 #include "ui_node_spinner.h"
36 #include "ui_node_abstractnode.h"
37 
38 #include "../../input/cl_input.h"
39 #include "../../input/cl_keys.h"
40 
41 #include "../../../common/scripts_lua.h"
42 
43 #define EXTRADATA_TYPE spinnerExtraData_t
44 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
45 #define EXTRADATACONST(node) UI_EXTRADATACONST(node, EXTRADATA_TYPE)
46 
47 static bool capturedDownButton;
48 static uiTimer_t* capturedTimer = nullptr;
49 
55 bool uiSpinnerNode::step (uiNode_t* node, bool down)
56 {
57  if (!down)
58  return incValue(node);
59  return decValue(node);
60 }
61 
63 {
64  step(node, capturedDownButton);
65  switch (timer->calledTime) {
66  case 1:
67  timer->delay = 50;
68  break;
69  }
70 }
71 
73 {
74  uiSpinnerNode* b = dynamic_cast<uiSpinnerNode*>(node->behaviour->manager.get());
75  b->repeat(node, timer);
76 }
77 
86 {
87  switch ((spinnerMode_t)EXTRADATA(node).mode) {
89  return true;
91  return false;
92  case SPINNER_NORMAL:
93  if (EXTRADATA(node).horizontal)
94  return x > node->box.size[0] * 0.5;
95  return y < node->box.size[1] * 0.5;
96  default:
97  return false;
98  }
99 }
100 
101 void uiSpinnerNode::onMouseDown (uiNode_t* node, int x, int y, int button)
102 {
103  const bool disabled = node->disabled || node->parent->disabled;
104  if (disabled)
105  return;
106 
107  if (button == K_MOUSE1) {
108  UI_SetMouseCapture(node);
109  UI_NodeAbsoluteToRelativePos(node, &x, &y);
110  capturedDownButton = !isPositionIncrease(node, x, y);
111  if (EXTRADATA(node).inverted)
113  step(node, capturedDownButton);
114  capturedTimer = UI_AllocTimer(node, 500, UI_SpinnerNodeRepeat);
115  UI_TimerStart(capturedTimer);
116  }
117 }
118 
119 void uiSpinnerNode::onMouseUp (uiNode_t* node, int x, int y, int button)
120 {
121  if (button == K_MOUSE1 && UI_GetMouseCapture() == node) {
122  UI_MouseRelease();
123  }
124 }
125 
131 {
132  if (capturedTimer) {
133  UI_TimerRelease(capturedTimer);
134  capturedTimer = nullptr;
135  }
136 }
137 
141 bool uiSpinnerNode::onScroll (uiNode_t* node, int deltaX, int deltaY)
142 {
143  bool down = deltaY > 0;
144  const bool disabled = node->disabled || node->parent->disabled;
145  if (deltaY == 0)
146  return false;
147  if (disabled)
148  return false;
149  return step(node, down);
150 }
151 
153 {
154  vec2_t pos;
155  const float delta = getDelta(node);
156  const bool disabled = node->disabled || node->parent->disabled;
157 
158  UI_GetNodeAbsPos(node, pos);
159 
160  uiSpriteStatus_t status;
161  uiSpriteStatus_t topStatus;
162  uiSpriteStatus_t bottomStatus;
163 
164  if (disabled || delta == 0) {
165  status = SPRITE_STATUS_DISABLED;
166  topStatus = SPRITE_STATUS_DISABLED;
167  bottomStatus = SPRITE_STATUS_DISABLED;
168  } else {
169  const float value = getValue(node);
170  const float min = getMin(node);
171  const float max = getMax(node);
172 
173  status = SPRITE_STATUS_NORMAL;
174 
175  bool increaseLocation = isPositionIncrease(node, mousePosX - pos[0], mousePosY - pos[1]);
176 
177  /* top button status */
178  if (node->state && increaseLocation) {
179  topStatus = SPRITE_STATUS_HOVER;
180  } else {
181  topStatus = SPRITE_STATUS_NORMAL;
182  }
183  /* bottom button status */
184  if (node->state && !increaseLocation) {
185  bottomStatus = SPRITE_STATUS_HOVER;
186  } else {
187  bottomStatus = SPRITE_STATUS_NORMAL;
188  }
189 
190  if (value >= max) {
191  if (EXTRADATA(node).inverted)
192  bottomStatus = SPRITE_STATUS_DISABLED;
193  else
194  topStatus = SPRITE_STATUS_DISABLED;
195  }
196  if (value <= min) {
197  if (EXTRADATA(node).inverted)
198  topStatus = SPRITE_STATUS_DISABLED;
199  else
200  bottomStatus = SPRITE_STATUS_DISABLED;
201  }
202  }
203 
204  if (EXTRADATA(node).background)
205  UI_DrawSpriteInBox(false, EXTRADATA(node).background, status, pos[0], pos[1], node->box.size[0], node->box.size[1]);
206  if (!EXTRADATA(node).horizontal) {
207  if (EXTRADATA(node).topIcon)
208  UI_DrawSpriteInBox(false, EXTRADATA(node).topIcon, topStatus, pos[0], pos[1], node->box.size[0], node->box.size[1]);
209  if (EXTRADATA(node).bottomIcon)
210  UI_DrawSpriteInBox(false, EXTRADATA(node).bottomIcon, bottomStatus, pos[0], pos[1], node->box.size[0], node->box.size[1]);
211  } else {
212  if (EXTRADATA(node).topIcon) /* Top becomes right */
213  UI_DrawSpriteInBox(false, EXTRADATA(node).topIcon, topStatus, pos[0] + node->box.size[0] / 2, pos[1], node->box.size[0] / 2, node->box.size[1]);
214  if (EXTRADATA(node).bottomIcon) /* Bottom becomes left */
215  UI_DrawSpriteInBox(false, EXTRADATA(node).bottomIcon, bottomStatus, pos[0], pos[1], node->box.size[0] / 2, node->box.size[1]);
216  }
217 }
218 
220 {
222 }
223 
224 void UI_Spinner_SetBackgroundByName(uiNode_t* node, const char* name) {
225  uiSprite_t* sprite = UI_GetSpriteByName(name);
226  UI_EXTRADATA(node, spinnerExtraData_t).background = sprite;
227 }
228 
229 void UI_Spinner_SetBottomIconByName(uiNode_t* node, const char* name) {
230  uiSprite_t* sprite = UI_GetSpriteByName(name);
231  UI_EXTRADATA(node, spinnerExtraData_t).bottomIcon = sprite;
232 }
233 
234 void UI_Spinner_SetTopIconByName(uiNode_t* node, const char* name) {
235  uiSprite_t* sprite = UI_GetSpriteByName(name);
236  UI_EXTRADATA(node, spinnerExtraData_t).topIcon = sprite;
237 }
238 
239 
241 {
242  behaviour->name = "spinner";
243  behaviour->extends = "abstractvalue";
244  behaviour->manager = UINodePtr(new uiSpinnerNode());
245  behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
246  behaviour->lua_SWIG_typeinfo = UI_SWIG_TypeQuery("uiSpinnerNode_t *");
247 
251  UI_RegisterExtradataNodeProperty(behaviour, "background", V_UI_SPRITEREF, EXTRADATA_TYPE, background);
252 
256  UI_RegisterExtradataNodeProperty(behaviour, "topIcon", V_UI_SPRITEREF, EXTRADATA_TYPE, topIcon);
257 
261  UI_RegisterExtradataNodeProperty(behaviour, "bottomIcon", V_UI_SPRITEREF, EXTRADATA_TYPE, bottomIcon);
262 
270 
274  UI_RegisterExtradataNodeProperty(behaviour, "horizontal", V_BOOL, EXTRADATA_TYPE, horizontal);
275 
279  UI_RegisterExtradataNodeProperty(behaviour, "inverted", V_BOOL, EXTRADATA_TYPE, inverted);
280 
281  Com_RegisterConstInt("SPINNER_NORMAL", SPINNER_NORMAL);
282  Com_RegisterConstInt("SPINNER_ONLY_INC", SPINNER_ONLY_INCREASE);
283  Com_RegisterConstInt("SPINNER_ONLY_DEC", SPINNER_ONLY_DECREASE);
284 }
#define EXTRADATA_TYPE
float getDelta(uiNode_t const *node)
vec2_t size
Definition: ui_nodes.h:52
uiNode_t * parent
Definition: ui_nodes.h:92
float getMin(uiNode_t const *node)
bool incValue(uiNode_t *node)
const char * name
Definition: ui_behaviour.h:41
uiBehaviour_t * behaviour
Definition: ui_nodes.h:83
UINodePtr manager
Definition: ui_behaviour.h:43
#define V_UI_SPRITEREF
Definition: ui_parse.h:56
void UI_DrawSpriteInBox(bool flip, const uiSprite_t *sprite, uiSpriteStatus_t status, int posX, int posY, int sizeX, int sizeY)
Definition: ui_sprite.cpp:187
uiTimer_t * UI_AllocTimer(uiNode_t *node, int firstDelay, timerCallback_t callback)
Allocate a new time for a node.
Definition: ui_timer.cpp:123
void UI_RegisterSpinnerNode(uiBehaviour_t *behaviour)
Definition: common.cpp:82
static void UI_SpinnerNodeRepeat(uiNode_t *node, uiTimer_t *timer)
void UI_MouseRelease(void)
Release the captured node.
Definition: ui_input.cpp:526
#define UI_RegisterExtradataNodeProperty(BEHAVIOUR, NAME, TYPE, EXTRADATATYPE, ATTRIBUTE)
Initialize a property from extradata of node.
Definition: ui_behaviour.h:109
int delay
Definition: ui_timer.h:45
float getMax(uiNode_t const *node)
#define EXTRADATA(node)
bool step(uiNode_t *node, bool down)
change the value of the spinner of one step
void UI_Spinner_SetBottomIconByName(uiNode_t *node, const char *name)
bool state
Definition: ui_nodes.h:106
int mousePosY
Definition: cl_input.cpp:80
void draw(uiNode_t *node) override
SharedPtr< uiNode > UINodePtr
void onMouseDown(uiNode_t *node, int x, int y, int button) override
static bool capturedDownButton
void UI_TimerRelease(uiTimer_t *timer)
Release the timer. It no more exists.
Definition: ui_timer.cpp:176
void onCapturedMouseLost(uiNode_t *node) override
Called when the node have lost the captured node We clean cached data.
void * lua_SWIG_typeinfo
Definition: ui_behaviour.h:57
void UI_Spinner_SetTopIconByName(uiNode_t *node, const char *name)
void UI_SetMouseCapture(uiNode_t *node)
Captured the mouse into a node.
Definition: ui_input.cpp:516
#define UI_EXTRADATA(NODE, TYPE)
Definition: ui_nodes.h:185
uiNode_t * UI_GetMouseCapture(void)
Return the captured node.
Definition: ui_input.cpp:508
PointerType get() const
Definition: sharedptr.h:197
void onLoading(uiNode_t *node) override
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 Com_RegisterConstInt(const char *name, int value)
Register mappings between script strings and enum values for values of the type V_INT.
Definition: scripts.cpp:198
bool disabled
Definition: ui_nodes.h:102
void UI_GetNodeAbsPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node.
Definition: ui_node.cpp:514
void repeat(uiNode_t *node, struct uiTimer_s *timer)
intptr_t extraDataSize
Definition: ui_behaviour.h:54
Definition: scripts.h:50
void onMouseUp(uiNode_t *node, int x, int y, int button) override
void UI_NodeAbsoluteToRelativePos(const uiNode_t *node, int *x, int *y)
Update an absolute position to a relative one.
Definition: ui_node.cpp:592
node behaviour, how a node work
Definition: ui_behaviour.h:39
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
const char * extends
Definition: ui_behaviour.h:42
uiSpriteStatus_t
Definition: ui_sprite.h:32
const char int mode
Definition: ioapi.h:41
bool isPositionIncrease(uiNode_t *node, int x, int y)
Check a position relative to the node to check action is can produce.
vec_t vec2_t[2]
Definition: ufotypes.h:38
Definition: scripts.h:52
static uiTimer_t * capturedTimer
void onLoading(uiNode_t *node) override
spinnerMode_t
uiBox_t box
Definition: ui_nodes.h:96
int mousePosX
Definition: cl_input.cpp:80
uiSprite_t * UI_GetSpriteByName(const char *name)
Return an sprite by is name.
Definition: ui_sprite.cpp:115
float getValue(uiNode_t const *node)
int calledTime
Definition: ui_timer.h:43
void UI_TimerStart(uiTimer_t *timer)
Restart a timer.
Definition: ui_timer.cpp:150
bool onScroll(uiNode_t *node, int deltaX, int deltaY) override
int down
Definition: cl_input.cpp:70
bool decValue(uiNode_t *node)
void UI_Spinner_SetBackgroundByName(uiNode_t *node, const char *name)