UFO: Alien Invasion
Loading...
Searching...
No Matches
ui_node_vscrollbar.cpp
Go to the documentation of this file.
1
6
7/*
8Copyright (C) 2002-2025 UFO: Alien Invasion.
9
10This program is free software; you can redistribute it and/or
11modify it under the terms of the GNU General Public License
12as published by the Free Software Foundation; either version 2
13of the License, or (at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19See the GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
22along with this program; if not, write to the Free Software
23Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25*/
26
27#include "../ui_nodes.h"
28#include "../ui_behaviour.h"
29#include "../ui_parse.h"
30#include "../ui_timer.h"
31#include "../ui_actions.h"
32#include "../ui_input.h"
33#include "../ui_render.h"
34#include "../ui_lua.h"
35
38#include "ui_node_vscrollbar.h"
39
41#include "../../input/cl_keys.h"
42
44
45static const int TILE_WIDTH = 32;
46static const int TILE_HEIGHT = 18;
47static const int ELEMENT_WIDTH = 19;
48static const int ELEMENT_HEIGHT = 16;
49
50static int oldPos;
51static int oldMouseY;
53static int capturedElement;
54
55#define EXTRADATA(node) UI_EXTRADATA(node, abstractScrollbarExtraData_t)
56
60static void UI_VScrollbarNodeGetElementSize (uiNode_t* node, int description[5])
61{
62 const int cuttableSize = node->box.size[1] - (ELEMENT_HEIGHT * 4);
63 const int low = cuttableSize * ((float)(EXTRADATA(node).pos + 0) / (float)EXTRADATA(node).fullsize);
64 const int middle = cuttableSize * ((float)(EXTRADATA(node).viewsize) / (float)EXTRADATA(node).fullsize);
65 const int hight = cuttableSize - low - middle;
66 description[0] = ELEMENT_HEIGHT;
67 description[1] = low;
68 description[2] = middle + 2 * ELEMENT_HEIGHT;
69 description[3] = hight;
70 description[4] = ELEMENT_HEIGHT;
71 assert(description[0] + description[1] + description[2] + description[3] + description[4] == node->box.size[1]);
72}
73
80static int UI_VScrollbarNodeGetElement (uiNode_t* node, int description[5], int x, int y)
81{
82 UI_NodeAbsoluteToRelativePos(node, &x, &y);
83 for (int i = 0; i < 5; i++) {
84 if (y < description[i])
85 return i;
86 y -= description[i];
87 }
88 return -1;
89}
90
91
95static inline void UI_VScrollbarNodeDiff (uiNode_t* node, int value)
96{
97 UI_AbstractScrollbarNodeSet(node, EXTRADATA(node).pos + value);
98}
99
100static inline void UI_VScrollbarNodeAction(uiNode_t* node, int hoveredElement, bool allowCapture);
101
103{
105 if (timer->calledTime == 1) {
106 timer->delay = 50;
107 }
108}
109
115static inline void UI_VScrollbarNodeAction (uiNode_t* node, int hoveredElement, bool allowCapture)
116{
117 switch (hoveredElement) {
118 case 0:
119 UI_VScrollbarNodeDiff(node, -1);
120 if (allowCapture) {
121 UI_SetMouseCapture(node);
122 capturedElement = hoveredElement;
125 }
126 break;
127 case 1:
128 UI_VScrollbarNodeDiff(node, -10);
129 if (allowCapture) {
130 UI_SetMouseCapture(node);
131 capturedElement = hoveredElement;
134 }
135 break;
136 case 2:
137 if (allowCapture) {
138 UI_SetMouseCapture(node);
139 /* save start value */
141 oldPos = EXTRADATA(node).pos;
142 capturedElement = hoveredElement;
143 }
144 break;
145 case 3:
146 UI_VScrollbarNodeDiff(node, 10);
147 if (allowCapture) {
148 UI_SetMouseCapture(node);
149 capturedElement = hoveredElement;
152 }
153 break;
154 case 4:
155 UI_VScrollbarNodeDiff(node, 1);
156 if (allowCapture) {
157 UI_SetMouseCapture(node);
158 capturedElement = hoveredElement;
161 }
162 break;
163 default:
164 assert(false);
165 break;
166 }
167}
168
169void uiVScrollbarNode::onMouseDown (uiNode_t* node, int x, int y, int button)
170{
171 if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize < EXTRADATA(node).viewsize)
172 return;
173 if (button != K_MOUSE1)
174 return;
175
176 int description[5];
177 UI_VScrollbarNodeGetElementSize(node, description);
178 const int hoveredElement = UI_VScrollbarNodeGetElement(node, description, x, y);
179 UI_VScrollbarNodeAction(node, hoveredElement, true);
180}
181
182void uiVScrollbarNode::onMouseUp (uiNode_t* node, int x, int y, int button)
183{
184 if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize < EXTRADATA(node).viewsize)
185 return;
186 if (button != K_MOUSE1)
187 return;
188
189 if (UI_GetMouseCapture() == node) {
191 }
192}
193
205
209bool uiVScrollbarNode::onScroll (uiNode_t* node, int deltaX, int deltaY)
210{
211 if (deltaY == 0)
212 return false;
213 if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize < EXTRADATA(node).viewsize)
214 return false;
215 UI_AbstractScrollbarNodeSet(node, EXTRADATA(node).pos + deltaY);
216 return true;
217}
218
223{
224 if (capturedElement != 2)
225 return;
226
227 const int posSize = EXTRADATA(node).fullsize;
228 const int graphicSize = node->box.size[1] - (4 * ELEMENT_HEIGHT);
229
230 /* compute mouse mouse */
231 y -= oldMouseY;
232
233 /* compute pos projection */
234 const int pos = oldPos + (((float)y * (float)posSize) / (float)graphicSize);
235
237}
238
243{
244 vec2_t pos;
245 int texX = 0;
246 int texY = 0;
247
248 UI_GetNodeAbsPos(node, pos);
249 int y = pos[1];
250
251 const char* texture = UI_GetReferenceString(node, node->image);
252 if (!texture)
253 return;
254
255 const image_t* image = UI_LoadImage(texture);
256
257 if (EXTRADATA(node).fullsize == 0 || EXTRADATA(node).fullsize <= EXTRADATA(node).viewsize) {
258 /* hide the scrollbar */
259 if (EXTRADATA(node).hideWhenUnused)
260 return;
261
262 texX = TILE_WIDTH * 3;
263
264 /* top */
266 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
267 image);
268 texY += TILE_HEIGHT;
269 y += ELEMENT_HEIGHT;
270
271 /* top to bottom */
272 UI_DrawNormImage(false, pos[0], y, ELEMENT_WIDTH, node->box.size[1] - (ELEMENT_HEIGHT * 2),
273 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
274 image);
275 texY += TILE_HEIGHT * 5;
276 y += node->box.size[1] - (ELEMENT_HEIGHT * 2);
277 assert(y == pos[1] + node->box.size[1] - ELEMENT_HEIGHT);
278
279 /* bottom */
281 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
282 image);
283
284 } else {
285 int hoveredElement = -1;
286 int description[5];
287 UI_VScrollbarNodeGetElementSize(node, description);
288 if (UI_GetMouseCapture() == node)
289 hoveredElement = capturedElement;
290 else if (node->state)
291 hoveredElement = UI_VScrollbarNodeGetElement(node, description,
293
294 /* top */
295 texX = (hoveredElement == 0) ? TILE_WIDTH : 0;
297 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image);
298 texY += TILE_HEIGHT;
299 y += ELEMENT_HEIGHT;
300
301 /* top to slider */
302 if (description[1]) {
303 texX = (hoveredElement == 1) ? TILE_WIDTH : 0;
304 UI_DrawNormImage(false, pos[0], y, ELEMENT_WIDTH, description[1],
305 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
306 image);
307 y += description[1];
308 }
309 texY += TILE_HEIGHT;
310
311 /* slider */
312 texX = (hoveredElement == 2) ? TILE_WIDTH : 0;
313
314 /* top slider */
316 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image);
317 texY += TILE_HEIGHT;
318 y += ELEMENT_HEIGHT;
319
320 /* middle slider */
321 if (description[2]) {
322 UI_DrawNormImage(false, pos[0], y, ELEMENT_WIDTH,
323 description[2] - ELEMENT_HEIGHT - ELEMENT_HEIGHT,
324 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
325 image);
326 y += description[2] - ELEMENT_HEIGHT - ELEMENT_HEIGHT;
327 }
328 texY += TILE_HEIGHT;
329
330 /* bottom slider */
332 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image);
333 texY += TILE_HEIGHT;
334 y += ELEMENT_HEIGHT;
335
336 /* slider to bottom */
337 if (description[3]) {
338 texX = (hoveredElement == 3) ? TILE_WIDTH : 0;
339 UI_DrawNormImage(false, pos[0], y, ELEMENT_WIDTH, description[3],
340 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY,
341 image);
342 y += description[3];
343 }
344 texY += TILE_HEIGHT;
345 assert(y == pos[1] + node->box.size[1] - ELEMENT_HEIGHT);
346
347 /* bottom */
348 texX = (hoveredElement == 4) ? TILE_WIDTH : 0;
350 texX + ELEMENT_WIDTH, texY + ELEMENT_HEIGHT, texX, texY, image);
351 }
352}
353
355{
356 node->box.size[0] = 19;
357}
358
360{
361#ifdef DEBUG
362 if (node->box.size[1] - (ELEMENT_HEIGHT * 4) < 0)
363 Com_DPrintf(DEBUG_CLIENT, "Node '%s' too small. It can create graphical glitches\n", UI_GetPath(node));
364#endif
365}
366
368{
369 behaviour->name = "vscrollbar";
370 behaviour->extends = "abstractscrollbar";
371 behaviour->manager = UINodePtr(new uiVScrollbarNode());
372 behaviour->lua_SWIG_typeinfo = UI_SWIG_TypeQuery("uiVScrollBarNode_t *");
373
374 /* Image to use. Each behaviour use it like they want.
375 * @todo use V_REF_OR_STRING when its possible ('image' is never a cvar)
376 */
377 UI_RegisterNodeProperty(behaviour, "image", V_CVAR_OR_STRING, uiNode_t, image);
378}
int mousePosY
Definition cl_input.cpp:76
int mousePosX
Definition cl_input.cpp:76
External (non-keyboard) input devices.
Header file for keyboard handler.
@ K_MOUSE1
Definition cl_keys.h:46
void onCapturedMouseLost(uiNode_t *node) override
Called when the node have lost the captured node We clean cached data.
void draw(uiNode_t *node) override
Call to draw the node.
void onLoaded(uiNode_t *node) override
void onMouseUp(uiNode_t *node, int x, int y, int button) override
void onMouseDown(uiNode_t *node, int x, int y, int button) override
void onCapturedMouseMove(uiNode_t *node, int x, int y) override
Called when the node is captured by the mouse.
void onLoading(uiNode_t *node) override
bool onScroll(uiNode_t *node, int deltaX, int deltaY) override
Called when the user wheel the mouse over the node.
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition common.cpp:440
#define DEBUG_CLIENT
Definition defines.h:59
QGL_EXTERN GLint i
Definition r_gl.h:113
Header for lua script functions.
node behaviour, how a node work
const char * name
void * lua_SWIG_typeinfo
UINodePtr manager
const char * extends
vec2_t size
Definition ui_nodes.h:52
Atomic structure used to define most of the UI.
Definition ui_nodes.h:80
uiBox_t box
Definition ui_nodes.h:96
char * image
Definition ui_nodes.h:123
bool state
Definition ui_nodes.h:106
vec_t vec2_t[2]
Definition ufotypes.h:38
#define UI_RegisterNodeProperty(BEHAVIOUR, NAME, TYPE, OBJECTTYPE, ATTRIBUTE)
Initialize a property.
void UI_SetMouseCapture(uiNode_t *node)
Captured the mouse into a node.
Definition ui_input.cpp:516
uiNode_t * UI_GetMouseCapture(void)
Return the captured node.
Definition ui_input.cpp:508
void UI_MouseRelease(void)
Release the captured node.
Definition ui_input.cpp:526
Basic lua initialization for the ui.
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_NodeAbsoluteToRelativePos(const uiNode_t *node, int *x, int *y)
Update an absolute position to a relative one.
Definition ui_node.cpp:604
void UI_GetNodeAbsPos(const uiNode_t *node, vec2_t pos)
Returns the absolute position of a node.
Definition ui_node.cpp:526
SharedPtr< uiNode > UINodePtr
#define EXTRADATA(node)
void UI_AbstractScrollbarNodeSet(uiNode_t *node, int value)
Set the position of the scrollbar to a value.
static int oldMouseY
static uiTimer_t * capturedTimer
static const int TILE_HEIGHT
static const int TILE_WIDTH
static int UI_VScrollbarNodeGetElement(uiNode_t *node, int description[5], int x, int y)
Get an element of the scrollbar at a position.
void UI_RegisterVScrollbarNode(uiBehaviour_t *behaviour)
static int capturedElement
static void UI_VScrollbarNodeGetElementSize(uiNode_t *node, int description[5])
Return size of all elements of the scrollbar.
static void UI_VScrollbarNodeDiff(uiNode_t *node, int value)
Translate the position to a value.
#define EXTRADATA(node)
static int oldPos
static void UI_VScrollbarNodeAction(uiNode_t *node, int hoveredElement, bool allowCapture)
static const int ELEMENT_WIDTH
static const int ELEMENT_HEIGHT
static void UI_VScrollbarNodeRepeat(uiNode_t *node, uiTimer_t *timer)
const char * UI_GetPath(const uiNode_t *node)
Return a path from a window to a node.
Definition ui_nodes.cpp:174
const char * UI_GetReferenceString(const uiNode_t *const node, const char *ref)
#define V_CVAR_OR_STRING
Definition ui_parse.h:69
const struct image_s * UI_LoadImage(const char *name)
Searches for an image in the image array.
Definition ui_render.cpp:91
void UI_DrawNormImage(bool flip, float x, float y, float w, float h, float sh, float th, float sl, float tl, const image_t *image)
Draw a normalized (to the screen) image.
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_TimerStart(uiTimer_t *timer)
Restart a timer.
Definition ui_timer.cpp:150
void UI_TimerRelease(uiTimer_t *timer)
Release the timer. It no more exists.
Definition ui_timer.cpp:176