File: widget.h

package info (click to toggle)
warzone2100 4.6.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 660,320 kB
  • sloc: cpp: 676,209; ansic: 391,201; javascript: 78,238; python: 16,632; php: 4,294; sh: 4,094; makefile: 2,629; lisp: 1,492; cs: 489; xml: 404; perl: 224; ruby: 156; java: 89
file content (399 lines) | stat: -rw-r--r-- 15,394 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
/*
	This file is part of Warzone 2100.
	Copyright (C) 1999-2004  Eidos Interactive
	Copyright (C) 2005-2020  Warzone 2100 Project

	Warzone 2100 is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	Warzone 2100 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Warzone 2100; if not, write to the Free Software
	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
 *	@file lib/widget/widget.h
 *	Definitions for the Widget library
 *	@defgroup Widget Widget system
 *	Warzone uses a pixel layout, callback based widget code. While it has several
 *	fallbacks for drawing standard widgets, usually you want to specify your
 *	own drawing callbacks.
 *	@{
 */

#ifndef __INCLUDED_LIB_WIDGET_WIDGET_H__
#define __INCLUDED_LIB_WIDGET_WIDGET_H__

#include "lib/framework/frame.h"
#include "lib/ivis_opengl/piepalette.h"
#include "widgbase.h"
#include <string>
#include <chrono>

/***********************************************************************************
 *
 * Widget style definitions - these control how the basic widget appears on screen
 */

/************ Form styles ****************/

#define WFORM_PLAIN		0	///< Plain form

/** Invisible (i.e. see through) form - can be used in conjunction with WFORM_PLAIN. */
#define WFORM_INVISIBLE		2

#define WFORM_CLICKABLE		4	///< Clickable form - return form id when the form is clicked
#define	WFORM_NOCLICKMOVE	8	///< Disable movement on a clickable form

/**
 * Control whether the primary or secondary buttons work on a clickable form.
 * Primary works by default - this turns it off.
 */
#define WFORM_NOPRIMARY		0x10
#define WFORM_SECONDARY		0x20	///< Enable secondary buttons

/************ Label styles ***************/

#define WLAB_PLAIN		0	///< Plain text only label
enum WzTextAlignment
{
	WLAB_ALIGNLEFT        = 0,      ///< Align the text at the left of the box
	WLAB_ALIGNCENTRE      = 1,      ///< Centre the text
	WLAB_ALIGNRIGHT       = 2,      ///< Align the text at the right of the box
	WLAB_ALIGNTOPLEFT     = 4,      ///< Align the text at the top left of the box
	WLAB_ALIGNTOP         = 4 + 1,  ///< Align the text at the top of the box
	WLAB_ALIGNTOPRIGHT    = 4 + 2,  ///< Align the text at the top right of the box
	WLAB_ALIGNBOTTOMLEFT  = 8,      ///< Align the text at the bottom left of the box
	WLAB_ALIGNBOTTOM      = 8 + 1,  ///< Align the text at the bottom of the box
	WLAB_ALIGNBOTTOMRIGHT = 8 + 2,  ///< Align the text at the bottom rightof the box
};

/************ Button styles **************/

#define WBUT_PLAIN		0	///< Plain button (text with a box around it)


/**
 * Control whether the primary or secondary buttons work on a button. Primary works by default -
 * this turns it off.
 */
#define WBUT_NOPRIMARY		0x10
#define WBUT_SECONDARY		0x20	///< Enable secondary buttons.
#define WBUT_TXTCENTRE		0x40	///< Text only buttons. centre the text?

/*********** Edit Box styles *************/

#define WEDB_PLAIN		0	///< Plain edit box (text with a box around it)

/*********** Bar Graph styles ************/

#define WBAR_PLAIN		0	////< Plain bar graph
#define WBAR_TROUGH		1	///< Bar graph with a trough showing empty percentage
#define WBAR_DOUBLE		2	///< Double bar graph, one on top of other

/*********** Slider styles ***************/

#define WSLD_PLAIN		0	///< Plain slider

/***********************************************************************************/

/* An optional function that is used to initialize the pUserData pointer per widget instance */
/* (Useful if re-using a W_*INIT structure for multiple widget instances) */
typedef std::function<void* ()> WIDGET_INITIALIZE_PUSERDATA_FUNC;

struct Padding
{
	uint32_t top = 0;
	uint32_t right = 0;
	uint32_t bottom = 0;
	uint32_t left = 0;
};

/** The basic initialisation structure */
struct W_INIT
{
	W_INIT();

	UDWORD                  formID;                 ///< ID number of form to put widget on. ID == 0 specifies the default form for the screen
	UWORD                   majorID;                ///< Which tab to put the widget on for a tabbed form
	UDWORD                  id;                     ///< Unique id number (chosen by user)
	UDWORD                  style;                  ///< widget style
	SWORD                   x, y;                   ///< screen location
	UWORD                   width, height;          ///< widget size
	WIDGET_DISPLAY          pDisplay;               ///< Optional display function
	WIDGET_CALLBACK         pCallback;              ///< Optional callback function
	void                   *pUserData;              ///< Optional user data pointer
	UDWORD                  UserData;               ///< User data (if any)
	WIDGET_CALCLAYOUT_FUNC  calcLayout;				///< Optional calculate layout callback function
	WIDGET_ONDELETE_FUNC	onDelete;				///< Optional callback called when the Widget is about to be deleted
	WIDGET_HITTEST_FUNC		customHitTest;			///< Optional custom hit-testing function
	WIDGET_INITIALIZE_PUSERDATA_FUNC initPUserDataFunc;	///< (Optional) Used to initialize the pUserData pointer per widget instance
};

/** Form initialisation structure */
struct W_FORMINIT : public W_INIT
{
	W_FORMINIT();

	bool                    disableChildren;
	std::string	            pTip;			///< Tool tip for the form itself
};

/** Label initialisation structure */
struct W_LABINIT : public W_INIT
{
	W_LABINIT();

	WzString	            pText;			///< label text
	std::string	            pTip;			///< Tool tip for the label.
	enum iV_fonts           FontID;			///< ID of the IVIS font to use for this widget.
};

/** Button initialisation structure */
struct W_BUTINIT : public W_INIT
{
	W_BUTINIT();

	const char *pText;	///< Button text
	std::string pTip;	///< Tool tip text
	enum iV_fonts FontID;	//< ID of the IVIS font to use for this widget.
};

/** Edit box initialisation structure */
struct W_EDBINIT : public W_INIT
{
	W_EDBINIT();

	const char *pText;		///< initial contents of the edit box
	enum iV_fonts FontID;		///< ID of the IVIS font to use for this widget.
	WIDGET_DISPLAY pBoxDisplay;	///< Optional callback to display the form.
};

/* Orientation flags for the bar graph */
enum WBAR_ORIENTATION
{
	WBAR_LEFT = 1,                  ///< Bar graph fills from left to right
	WBAR_RIGHT,                     ///< Bar graph fills from right to left
	WBAR_TOP,                       ///< Bar graph fills from top to bottom
	WBAR_BOTTOM,                    ///< Bar graph fills from bottom to top
};

/** Bar Graph initialisation structure */
struct W_BARINIT : public W_INIT
{
	W_BARINIT();

	WBAR_ORIENTATION orientation;           ///< Orientation of the bar on the widget
	UWORD		size;			///< Initial percentage of the graph that is filled
	UWORD		minorSize;		///< Percentage of second bar graph if there is one
	UWORD		iRange;			///< Maximum range
	int             denominator;            ///< Denominator, 1 by default.
	int             precision;              ///< Number of places after the decimal point to display, 0 by default.
	PIELIGHT	sCol;			///< Bar colour
	PIELIGHT	sMinorCol;		///< Minor bar colour
	std::string      pTip;			///< Tool tip text
};


/* Orientation of the slider */
enum WSLD_ORIENTATION
{
	WSLD_LEFT = 1,                  ///< Slider is horizontal and starts at left
	WSLD_RIGHT,                     ///< Slider is horizontal and starts at the right
	WSLD_TOP,                       ///< Slider is vertical and starts at the top
	WSLD_BOTTOM,                    ///< Slider is vertical and starts at the bottom
};

/** Slider initialisation structure */
struct W_SLDINIT : public W_INIT
{
	W_SLDINIT();

	WSLD_ORIENTATION orientation;           ///< Orientation of the slider
	UWORD		numStops;		///< Number of stops on the slider
	UWORD		barSize;		///< Size of the bar
	UWORD		pos;			///< Initial position of the slider bar
	std::string pTip;			///< Tip string
};

/***********************************************************************************/

/** The maximum value for bar graph size */
#define WBAR_SCALE		100

/** Initialise the widget module */
bool widgInitialise();

/** Reset the widget module */
void widgReset();

/** Shut down the widget module */
void widgShutDown();

/** Used by the notifications system to register forms that are "over the top", and may consume click / mouse-over events */
bool isRegisteredOverlayScreen(const std::shared_ptr<W_SCREEN> &psScreen);
void widgRegisterOverlayScreen(const std::shared_ptr<W_SCREEN> &psScreen, uint16_t zOrder);
void widgRegisterOverlayScreenOnTopOfScreen(const std::shared_ptr<W_SCREEN> &psScreen, const std::shared_ptr<W_SCREEN> &priorScreen);
void widgRemoveOverlayScreen(const std::shared_ptr<W_SCREEN> &psScreen);
void widgForEachOverlayScreen(const std::function<bool (const std::shared_ptr<W_SCREEN>& psScreen, uint16_t zOrder)>& func);
bool isMouseOverScreen(const std::shared_ptr<W_SCREEN>& psScreen);
bool isMouseOverScreenOverlayChild(int mx, int my); // global mouse coordinates - i.e. those returned from mouseX()/mouseY()
bool isMouseClickDownOnScreenOverlayChild();
bool isMouseOverSomeWidget(const std::shared_ptr<W_SCREEN> &psScreen);
void widgScheduleTask(std::function<void ()> f);

void widgOverlaysScreenSizeDidChange(int oldWidth, int oldHeight, int newWidth, int newHeight);

/** Add a form to the widget screen */
WZ_DECL_NONNULL(2) W_FORM *widgAddForm(const std::shared_ptr<W_SCREEN> &psScreen, const W_FORMINIT *psInit);

/** Add a label to the widget screen */
WZ_DECL_NONNULL(2) W_LABEL *widgAddLabel(const std::shared_ptr<W_SCREEN> &psScreen, const W_LABINIT *psInit);

/** Add a button to a form */
WZ_DECL_NONNULL(2) W_BUTTON *widgAddButton(const std::shared_ptr<W_SCREEN> &psScreen, const W_BUTINIT *psInit);

/** Add an edit box to a form */
WZ_DECL_NONNULL(2) W_EDITBOX *widgAddEditBox(const std::shared_ptr<W_SCREEN> &psScreen, const W_EDBINIT *psInit);

/** Add a bar graph to a form */
WZ_DECL_NONNULL(2) W_BARGRAPH *widgAddBarGraph(const std::shared_ptr<W_SCREEN> &psScreen, const W_BARINIT *psInit);

/** Add a slider to a form */
WZ_DECL_NONNULL(2) W_SLIDER *widgAddSlider(const std::shared_ptr<W_SCREEN> &psScreen, const W_SLDINIT *psInit);

/** Delete a widget from the screen */
void widgDelete(WIDGET *widget);
void widgDelete(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);
void widgDeleteLater(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Hide a widget */
void widgHide(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Reveal a widget */
void widgReveal(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Return a pointer to a buffer containing the current string of a widget if any.
 * This will always return a valid string pointer.
 * NOTE: The string must be copied out of the buffer
 */
const char *widgGetString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Return the current string of a widget, if any.
 * This will always return a string. If the widget doesn't have a string, it will return an empty WzString.
 */
const WzString& widgGetWzString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Set the text in a widget */
void widgSetString(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, const char *pText);

/** Get the current position of a slider bar */
UDWORD widgGetSliderPos(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Set the current size of a bar graph */
void widgSetBarSize(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD size);

/** Set the current size of a minor bar on a double graph */
void widgSetMinorBarSize(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD size);

/** Set the range on a double graph */
void widgSetBarRange(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD iValue);

/** Return the ID of the widget the mouse was over this frame */
UDWORD widgGetMouseOver(const std::shared_ptr<W_SCREEN> &psScreen);

/** Return the user data for a widget */
void *widgGetUserData(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Set the user data for a widget */
void widgSetUserData(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, void *UserData);

/** Return the user data for a widget */
UDWORD widgGetUserData2(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Set the user data for a widget */
void widgSetUserData2(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD UserData);

/** Get widget structure */
WIDGET *widgGetFromID(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/* Find a widget on a form from its id number */
std::shared_ptr<WIDGET> widgFormGetFromID(const std::shared_ptr<WIDGET>& widget, UDWORD id);

/** Set tip string for a widget */
void widgSetTip(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, std::string pTip);

/** Colour numbers */
enum _w_colour
{
	WCOL_BKGRND,	///< Background colours
	WCOL_TEXT,	///< Text colour
	WCOL_LIGHT,	///< Light colour for 3D effects
	WCOL_DARK,	///< Dark colour for 3D effects
	WCOL_HILITE,	///< Hilite colour
	WCOL_CURSOR,	///< Edit Box cursor colour
	WCOL_TIPBKGRND,	///< Background for the tool tip window
	WCOL_DISABLE,	///< Text colour on a disabled button

	WCOL_MAX,	///< All colour numbers are less than this
};

/** Set the global toop tip text colour. */
void widgSetTipColour(PIELIGHT colour);

void widgSetButtonFlash(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);
void widgClearButtonFlash(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Get a button or clickable form's state */
UDWORD widgGetButtonState(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id);

/** Set a button or clickable form's state */
void widgSetButtonState(const std::shared_ptr<W_SCREEN> &psScreen, UDWORD id, UDWORD state);


/** Return which key was used to press the last returned widget */
UDWORD widgGetButtonKey_DEPRECATED(const std::shared_ptr<W_SCREEN> &psScreen);

/** Execute a set of widgets for one cycle.
 * Return the id of the widget that was activated, or 0 for none.
 */
WidgetTriggers const &widgRunScreen(const std::shared_ptr<W_SCREEN> &psScreen);

/** Display the screen's widgets in their current state
 * (Call after calling widgRunScreen, this allows the input
 *  processing to be separated from the display of the widgets).
 */
void widgDisplayScreen(const std::shared_ptr<W_SCREEN> &psScreen);


/** Set the current audio callback function and audio id's. */
void WidgSetAudio(WIDGET_AUDIOCALLBACK Callback, SWORD HilightID, SWORD ClickedID, SWORD ErrorID);

/** Get pointer to current audio callback function. */
WIDGET_AUDIOCALLBACK WidgGetAudioCallback();

/** Get current audio ID for hilight. */
SWORD WidgGetHilightAudioID();

/** Get current audio ID for clicked. */
SWORD WidgGetClickedAudioID();

// error ID
SWORD WidgGetErrorAudioID();

void setWidgetsStatus(bool var);
bool getWidgetsStatus();

std::weak_ptr<WIDGET> getMouseOverWidget();

std::chrono::milliseconds widgGetClickHoldMS();

/** @} */

#endif // __INCLUDED_LIB_WIDGET_WIDGET_H__