1
/* $Id: window_gui.h 12167 2008-02-17 17:00:43Z smatz $ */
1
/* $Id: window_gui.h 15723 2009-03-15 15:12:06Z rubidium $ */
3
3
/** @file window_gui.h Functions, definitions and such used only by the GUI. */
8
#include "core/bitmath_func.hpp"
8
#include "core/geometry_type.hpp"
9
9
#include "vehicle_type.h"
10
10
#include "viewport_type.h"
11
#include "player_type.h"
12
#include "strings_type.h"
11
#include "company_type.h"
12
#include "core/alloc_type.hpp"
13
#include "window_type.h"
14
#include "tile_type.h"
15
#include "widget_type.h"
15
* The maximum number of windows that can be opened.
18
* Flags to describe the look of the frame
17
static const int MAX_NUMBER_OF_WINDOWS = 25;
19
typedef void WindowProc(Window *w, WindowEvent *e);
21
/* How the resize system works:
22
First, you need to add a WWT_RESIZEBOX to the widgets, and you need
23
to add the flag WDF_RESIZABLE to the window. Now the window is ready
25
As you may have noticed, all widgets have a RESIZE_XXX in their line.
26
This lines controls how the widgets behave on resize. RESIZE_NONE means
27
it doesn't do anything. Any other option let's one of the borders
28
move with the changed width/height. So if a widget has
29
RESIZE_RIGHT, and the window is made 5 pixels wider by the user,
30
the right of the window will also be made 5 pixels wider.
31
Now, what if you want to clamp a widget to the bottom? Give it the flag
32
RESIZE_TB. This is RESIZE_TOP + RESIZE_BOTTOM. Now if the window gets
33
5 pixels bigger, both the top and bottom gets 5 bigger, so the whole
34
widgets moves downwards without resizing, and appears to be clamped
35
to the bottom. Nice aint it?
36
You should know one more thing about this system. Most windows can't
37
handle an increase of 1 pixel. So there is a step function, which
38
let the windowsize only be changed by X pixels. You configure this
39
after making the window, like this:
40
w->resize.step_height = 10;
41
Now the window will only change in height in steps of 10.
42
You can also give a minimum width and height. The default value is
43
the default height/width of the window itself. You can change this
44
AFTER window-creation, with:
45
w->resize.width or w->resize.height.
46
That was all.. good luck, and enjoy :) -- TrueLight */
49
RESIZE_NONE = 0, ///< no resize required
51
RESIZE_LEFT = 1, ///< left resize flag
52
RESIZE_RIGHT = 2, ///< rigth resize flag
53
RESIZE_TOP = 4, ///< top resize flag
54
RESIZE_BOTTOM = 8, ///< bottom resize flag
56
RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT, ///< combination of left and right resize flags
57
RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of right and bottom resize flags
58
RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM, ///< combination of top and bottom resize flags
59
RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM, ///< combination of left, right and bottom resize flags
60
RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, ///< combination of all resize flags
61
RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM, ///< combination of right, top and bottom resize flag
63
/* The following flags are used by the system to specify what is disabled, hidden, or clicked
64
* They are used in the same place as the above RESIZE_x flags, Widget visual_flags.
65
* These states are used in exceptions. If nothing is specified, they will indicate
66
* Enabled, visible or unclicked widgets*/
67
WIDG_DISABLED = 4, ///< widget is greyed out, not available
68
WIDG_HIDDEN = 5, ///< widget is made invisible
69
WIDG_LOWERED = 6, ///< widget is paint lowered, a pressed button in fact
73
WIDGET_LIST_END = -1, ///< indicate the end of widgets' list for vararg functions
77
byte type; ///< Widget type, see WindowWidgetTypes
78
byte display_flags; ///< Resize direction, alignment, etc. during resizing, see ResizeFlags
79
byte color; ///< Widget colour, see docs/ottd-colourtext-palette.png
80
int16 left, right, top, bottom; ///< The position offsets inside the window
81
uint16 data; ///< The String/Image or special code (list-matrixes) of a widget
82
StringID tooltips; ///< Tooltips that are shown when rightclicking on a widget
87
22
FR_TRANSPARENT = 1 << 0, ///< Makes the background transparent if set
88
23
FR_BORDERONLY = 1 << 4, ///< Draw border only, no background
89
FR_LOWERED = 1 << 5, ///< If set the frame is lowered and the background color brighter (ie. buttons when pressed)
90
FR_DARKENED = 1 << 6, ///< If set the background is darker, allows for lowered frames with normal background color when used with FR_LOWERED (ie. dropdown boxes)
24
FR_LOWERED = 1 << 5, ///< If set the frame is lowered and the background colour brighter (ie. buttons when pressed)
25
FR_DARKENED = 1 << 6, ///< If set the background is darker, allows for lowered frames with normal background colour when used with FR_LOWERED (ie. dropdown boxes)
93
28
DECLARE_ENUM_AS_BIT_SET(FrameFlags);
95
void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags);
97
enum WindowEventCodes {
114
WE_ON_EDIT_TEXT_CANCEL,
145
ViewportPlaceMethod select_method;
178
bool cont; ///< continue the search? (default true)
179
uint16 key; ///< 16-bit Unicode value of the key
180
uint16 keycode; ///< untranslated key (including shift-state)
184
int msg; ///< message to be sent
185
int wparam; ///< additional message-specific information
186
int lparam; ///< additional message-specific information
190
Point delta; ///< delta position against position of last call
194
int wheel; ///< how much was 'wheel'd'
198
bool cont; ///< continue the search? (default true)
204
int16 left, top, minimum_width, minimum_height, default_width, default_height;
206
WindowClass parent_cls;
208
const Widget *widgets;
31
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
34
extern Window *_z_front_window;
35
extern Window *_z_back_window;
36
extern Window *_focused_window;
39
* High level window description
41
struct WindowDesc : ZeroedMemoryAllocator {
43
WindowDesc(int16 left, int16 top, int16 min_width, int16 min_height, int16 def_width, int16 def_height,
44
WindowClass window_class, WindowClass parent_class, uint32 flags, const Widget *widgets);
46
int16 left; ///< Prefered x position of left edge of the window, @see WindowDefaultPosition()
47
int16 top; ///< Prefered y position of the top of the window, @see WindowDefaultPosition()
48
int16 minimum_width; ///< Minimal width of the window
49
int16 minimum_height; ///< Minimal height of the window
50
int16 default_width; ///< Prefered initial width of the window
51
int16 default_height; ///< Prefered initial height of the window
52
WindowClass cls; ///< Class of the window, @see WindowClass
53
WindowClass parent_cls; ///< Class of the parent window, @see WindowClass
54
uint32 flags; ///< Flags, @see WindowDefaultFlags
55
const Widget *widgets; ///< List of widgets with their position and size for the window
59
* Window default widget/window handling flags
212
61
enum WindowDefaultFlag {
213
62
WDF_STD_TOOLTIPS = 1 << 0, ///< use standard routine when displaying tooltips
214
WDF_DEF_WIDGET = 1 << 1, ///< default widget control for some widgets in the on click event
215
WDF_STD_BTN = 1 << 2, ///< default handling for close and drag widgets (widget no 0 and 1)
63
WDF_DEF_WIDGET = 1 << 1, ///< Default widget control for some widgets in the on click event, @see DispatchLeftClickEvent()
64
WDF_STD_BTN = 1 << 2, ///< Default handling for close and titlebar widgets (widget no 0 and 1)
65
WDF_CONSTRUCTION = 1 << 3, ///< This window is used for construction; close it whenever changing company.
217
WDF_UNCLICK_BUTTONS = 1 << 4, ///< Unclick buttons when the window event times out */
67
WDF_UNCLICK_BUTTONS = 1 << 4, ///< Unclick buttons when the window event times out
218
68
WDF_STICKY_BUTTON = 1 << 5, ///< Set window to sticky mode; they are not closed unless closed with 'X' (widget 2)
219
WDF_RESIZABLE = 1 << 6, ///< A window can be resized
69
WDF_RESIZABLE = 1 << 6, ///< Window can be resized
220
70
WDF_MODAL = 1 << 7, ///< The window is a modal child of some other window, meaning the parent is 'inactive'
72
WDF_NO_FOCUS = 1 << 8, ///< This window won't get focus/make any other window lose focus when click
223
/* can be used as x or y coordinates to cause a specific placement */
76
* Special values for 'left' and 'top' to cause a specific placement
224
78
enum WindowDefaultPosition {
225
79
WDP_AUTO = -1, ///< Find a place automatically
226
80
WDP_CENTER = -2, ///< Center the window (left/right or top/bottom)
228
82
WDP_ALIGN_TBL = -4, ///< Align the left side of the window with the left side of the main toolbar
231
#define WP(ptr, str) (*(str*)(ptr)->custom)
86
* Scrollbar data structure
233
88
struct Scrollbar {
234
uint16 count, cap, pos;
89
uint16 count; ///< Number of elements in the list
90
uint16 cap; ///< Number of visible elements of the scroll bar
91
uint16 pos; ///< Index of first visible item of the list
95
* Data structure for resizing a window
237
97
struct ResizeInfo {
238
uint width; ///< Minimum width and height
240
uint step_width; ///< In how big steps the width and height go
244
struct WindowMessage {
252
WindowClass window_class;
253
WindowNumber window_number;
258
Scrollbar hscroll, vscroll, vscroll2;
265
const Widget *original_widget;
270
WindowMessage message;
272
byte custom[WINDOW_CUSTOM_SIZE];
98
uint width; ///< Minimum allowed width of the window
99
uint height; ///< Minimum allowed height of the window
100
uint step_width; ///< Step-size of width resize changes
101
uint step_height; ///< Step-size of height resize changes
104
enum SortButtonState {
111
* Data structure for a window viewport
113
struct ViewportData : ViewPort {
114
VehicleID follow_vehicle;
117
int32 dest_scrollpos_x;
118
int32 dest_scrollpos_y;
122
* Data structure for an opened window
124
struct Window : ZeroedMemoryAllocator {
125
/** State whether an event is handled or not */
127
ES_HANDLED, ///< The passed event is handled
128
ES_NOT_HANDLED, ///< The passed event is not handled
132
void Initialize(int x, int y, int min_width, int min_height,
133
WindowClass cls, const Widget *widget, int window_number);
134
void FindWindowPlacementAndResize(int def_width, int def_height);
135
void FindWindowPlacementAndResize(const WindowDesc *desc);
138
Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
139
Window(const WindowDesc *desc, WindowNumber number = 0);
142
/* Don't allow arrays; arrays of Windows are pointless as you need
143
* to destruct them all at the same time too, which is kinda hard. */
144
FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
145
/* Don't free the window directly; it corrupts the linked list when iterating */
146
FORCEINLINE void operator delete(void *ptr, size_t size) {}
148
uint16 flags4; ///< Window flags, @see WindowFlags
149
WindowClass window_class; ///< Window class
150
WindowNumber window_number; ///< Window number within the window class
152
int left; ///< x position of left edge of the window
153
int top; ///< y position of top edge of the window
154
int width; ///< width of the window (number of pixels to the right in x direction)
155
int height; ///< Height of the window (number of pixels down in y direction)
157
Scrollbar hscroll; ///< Horizontal scroll bar
158
Scrollbar vscroll; ///< First vertical scroll bar
159
Scrollbar vscroll2; ///< Second vertical scroll bar
160
ResizeInfo resize; ///< Resize information
162
Owner owner; ///< The owner of the content shown in this window. Company colour is acquired from this variable.
164
ViewportData *viewport;///< Pointer to viewport data, if present
165
Widget *widget; ///< Widgets of the window
166
uint widget_count; ///< Number of widgets of the window
167
uint32 desc_flags; ///< Window/widgets default flags setting, @see WindowDefaultFlag
168
const Widget *focused_widget; ///< Currently focused widget or NULL, if no widget has focus
170
Window *parent; ///< Parent window
171
Window *z_front; ///< The window in front of us in z-order
172
Window *z_back; ///< The window behind us in z-order
175
* Sets the enabled/disabled status of a widget.
176
* By default, widgets are enabled.
177
* On certain conditions, they have to be disabled.
178
* @param widget_index index of this widget in the window
179
* @param disab_stat status to use ie: disabled = true, enabled = false
181
inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
183
assert(widget_index < this->widget_count);
184
SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
188
* Sets a widget to disabled.
189
* @param widget_index index of this widget in the window
191
inline void DisableWidget(byte widget_index)
193
SetWidgetDisabledState(widget_index, true);
197
* Sets a widget to Enabled.
198
* @param widget_index index of this widget in the window
200
inline void EnableWidget(byte widget_index)
202
SetWidgetDisabledState(widget_index, false);
206
* Gets the enabled/disabled status of a widget.
207
* @param widget_index index of this widget in the window
208
* @return status of the widget ie: disabled = true, enabled = false
210
inline bool IsWidgetDisabled(byte widget_index) const
212
assert(widget_index < this->widget_count);
213
return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
217
* Sets the hidden/shown status of a widget.
218
* By default, widgets are visible.
219
* On certain conditions, they have to be hidden.
220
* @param widget_index index of this widget in the window
221
* @param hidden_stat status to use ie. hidden = true, visible = false
223
inline void SetWidgetHiddenState(byte widget_index, bool hidden_stat)
225
assert(widget_index < this->widget_count);
226
SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
230
* Sets a widget hidden.
231
* @param widget_index index of this widget in the window
233
inline void HideWidget(byte widget_index)
235
SetWidgetHiddenState(widget_index, true);
239
* Sets a widget visible.
240
* @param widget_index index of this widget in the window
242
inline void ShowWidget(byte widget_index)
244
SetWidgetHiddenState(widget_index, false);
248
* Gets the visibility of a widget.
249
* @param widget_index index of this widget in the window
250
* @return status of the widget ie: hidden = true, visible = false
252
inline bool IsWidgetHidden(byte widget_index) const
254
assert(widget_index < this->widget_count);
255
return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
259
* Set focus within this window to given widget. The function however don't
260
* change which window that has focus.
261
* @param widget_index : index of the widget in the window to set focus to
263
inline void SetFocusedWidget(byte widget_index)
265
if (widget_index < this->widget_count) {
266
/* Repaint the widget that loss focus. A focused edit box may else leave the caret left on the screen */
267
if (this->focused_widget && this->focused_widget - this->widget != widget_index) {
268
this->InvalidateWidget(this->focused_widget - this->widget);
270
this->focused_widget = &this->widget[widget_index];
275
* Check if given widget is focused within this window
276
* @param widget_index : index of the widget in the window to check
277
* @return true if given widget is the focused window in this window
279
inline bool IsWidgetFocused(byte widget_index) const
281
return this->focused_widget == &this->widget[widget_index];
285
* Check if given widget has user input focus. This means that both the window
286
* has focus and that the given widget has focus within the window.
287
* @param widget_index : index of the widget in the window to check
288
* @return true if given widget is the focused window in this window and this window has focus
290
inline bool IsWidgetGloballyFocused(byte widget_index) const
292
return _focused_window == this && IsWidgetFocused(widget_index);
296
* Sets the lowered/raised status of a widget.
297
* @param widget_index index of this widget in the window
298
* @param lowered_stat status to use ie: lowered = true, raised = false
300
inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
302
assert(widget_index < this->widget_count);
303
SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
307
* Invert the lowered/raised status of a widget.
308
* @param widget_index index of this widget in the window
310
inline void ToggleWidgetLoweredState(byte widget_index)
312
assert(widget_index < this->widget_count);
313
ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
317
* Marks a widget as lowered.
318
* @param widget_index index of this widget in the window
320
inline void LowerWidget(byte widget_index)
322
SetWidgetLoweredState(widget_index, true);
326
* Marks a widget as raised.
327
* @param widget_index index of this widget in the window
329
inline void RaiseWidget(byte widget_index)
331
SetWidgetLoweredState(widget_index, false);
335
* Gets the lowered state of a widget.
336
* @param widget_index index of this widget in the window
337
* @return status of the widget ie: lowered = true, raised= false
339
inline bool IsWidgetLowered(byte widget_index) const
341
assert(widget_index < this->widget_count);
342
return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
346
* Align widgets a and b next to each other.
347
* @param widget_index_a the left widget
348
* @param widget_index_b the right widget (fixed)
350
inline void AlignWidgetRight(byte widget_index_a, byte widget_index_b)
352
assert(widget_index_a < this->widget_count);
353
assert(widget_index_b < this->widget_count);
354
int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
355
this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
356
this->widget[widget_index_a].left = this->widget[widget_index_a].right - w;
360
* Get the width of a widget.
361
* @param widget_index the widget
362
* @return width of the widget
364
inline int GetWidgetWidth(byte widget_index) const
366
assert(widget_index < this->widget_count);
367
return this->widget[widget_index].right - this->widget[widget_index].left + 1;
274
370
void HandleButtonClick(byte widget);
276
void SetWidgetDisabledState(byte widget_index, bool disab_stat);
277
void DisableWidget(byte widget_index);
278
void EnableWidget(byte widget_index);
279
bool IsWidgetDisabled(byte widget_index) const;
280
void SetWidgetHiddenState(byte widget_index, bool hidden_stat);
281
void HideWidget(byte widget_index);
282
void ShowWidget(byte widget_index);
283
bool IsWidgetHidden(byte widget_index) const;
284
void SetWidgetLoweredState(byte widget_index, bool lowered_stat);
285
void ToggleWidgetLoweredState(byte widget_index);
286
void LowerWidget(byte widget_index);
287
void RaiseWidget(byte widget_index);
288
bool IsWidgetLowered(byte widget_index) const;
371
bool HasWidgetOfType(WidgetType widget_type) const;
290
373
void RaiseButtons();
291
374
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
292
375
void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
293
376
void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
294
377
void InvalidateWidget(byte widget_index) const;
298
byte item_count; ///< follow_vehicle
299
byte sel_index; ///< scrollpos_x
300
byte main_button; ///< scrollpos_y
302
StringID string_id; ///< unk30
303
uint16 checked_items; ///< unk32
306
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(menu_d));
309
int16 data_1, data_2, data_3;
310
int16 data_4, data_5;
314
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(def_d));
319
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(void_d));
325
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tree_d));
332
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(tooltips_d));
334
struct replaceveh_d {
336
EngineID sel_engine[2];
338
bool wagon_btnstate; ///< true means engine is selected
345
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(replaceveh_d));
351
uint16 engine_list_length;
352
uint16 wagon_list_length;
355
Vehicle **vehicle_list;
356
Vehicle **wagon_list;
358
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(depot_d));
363
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(order_d));
365
struct vehicledetails_d {
368
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehicledetails_d));
375
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d));
379
struct RefitOption *cargo;
380
struct RefitList *list;
382
VehicleOrderID order;
384
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(refit_d));
387
VehicleID follow_vehicle;
390
int32 dest_scrollpos_x;
391
int32 dest_scrollpos_y;
393
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d));
396
uint16 follow_vehicle;
399
int32 dest_scrollpos_x;
400
int32 dest_scrollpos_y;
403
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d));
406
uint32 background_img;
409
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(highscore_d));
415
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(scroller_d));
418
VL_NONE = 0, ///< no sort
419
VL_DESC = 1 << 0, ///< sort descending or ascending
420
VL_RESORT = 1 << 1, ///< instruct the code to resort the list in the next loop
421
VL_REBUILD = 1 << 2, ///< create sort-listing to use for qsort and friends
425
DECLARE_ENUM_AS_BIT_SET(SortListFlags);
428
bool order; ///< Ascending/descending
429
byte criteria; ///< Sorting criteria
433
uint16 list_length; ///< length of the list being sorted
434
byte sort_type; ///< what criteria to sort on
435
SortListFlags flags; ///< used to control sorting/resorting/etc.
436
uint16 resort_timer; ///< resort list after a given amount of ticks if set
438
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(list_d));
445
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(message_d));
447
struct vehiclelist_d {
448
const Vehicle** sort_list; // List of vehicles (sorted)
449
Listing *_sorting; // pointer to the appropiate subcategory of _sorting
450
uint16 length_of_sort_list; // Keeps track of how many vehicle pointers sort list got space for
451
VehicleType vehicle_type; // The vehicle type that is sorted
452
list_d l; // General list struct
454
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d));
457
const Group **sort_list;
458
list_d l; // General list struct
460
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(grouplist_d));
462
struct groupveh_d : vehiclelist_d {
464
VehicleID vehicle_sel;
468
assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(groupveh_d));
470
/****************** THESE ARE NOT WIDGET TYPES!!!!! *******************/
471
enum WindowWidgetBehaviours {
472
WWB_PUSHBUTTON = 1 << 5,
478
enum WindowWidgetTypes {
481
WWT_PANEL, ///< simple depressed panel
482
WWT_INSET, ///< pressed (inset) panel, most commonly used as combo box _text_ area
483
WWT_IMGBTN, ///< button with image
484
WWT_IMGBTN_2, ///< button with diff image when clicked
486
WWT_TEXTBTN, ///< button with text
487
WWT_TEXTBTN_2, ///< button with diff text when clicked
488
WWT_LABEL, ///< centered label
489
WWT_TEXT, ///< pure simple text
492
WWT_FRAME, ///< frame
497
WWT_SCROLL2BAR, ///< 2nd vertical scrollbar
500
WWT_DROPDOWN, ///< Raised drop down list (regular)
501
WWT_DROPDOWNIN, ///< Inset drop down list (used on game options only)
502
WWT_LAST, ///< Last Item. use WIDGETS_END to fill up padding!!
506
WWT_PUSHBTN = WWT_PANEL | WWB_PUSHBUTTON,
507
WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON,
508
WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON,
511
#define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL
379
void DrawWidgets() const;
380
void DrawViewport() const;
381
void DrawSortButtonState(int widget, SortButtonState state) const;
383
void DeleteChildWindows() const;
385
void SetDirty() const;
387
/*** Event handling ***/
390
* This window is currently being repainted.
392
virtual void OnPaint() {}
395
* Called when window gains focus
397
virtual void OnFocus() {}
400
* Called when window looses focus
402
virtual void OnFocusLost() {}
405
* A key has been pressed.
406
* @param key the Unicode value of the key.
407
* @param keycode the untranslated key code including shift state.
408
* @return ES_HANDLED if the key press has been handled and no other
409
* window should receive the event.
411
virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
414
* The state of the control key has changed
415
* @return ES_HANDLED if the change has been handled and no other
416
* window should receive the event.
418
virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
422
* A click with the left mouse button has been made on the window.
423
* @param pt the point inside the window that has been clicked.
424
* @param widget the clicked widget.
426
virtual void OnClick(Point pt, int widget) {}
429
* A double click with the left mouse button has been made on the window.
430
* @param pt the point inside the window that has been clicked.
431
* @param widget the clicked widget.
433
virtual void OnDoubleClick(Point pt, int widget) {}
436
* A click with the right mouse button has been made on the window.
437
* @param pt the point inside the window that has been clicked.
438
* @param widget the clicked widget.
440
virtual void OnRightClick(Point pt, int widget) {}
443
* A dragged 'object' has been released.
444
* @param pt the point inside the window where the release took place.
445
* @param widget the widget where the release took place.
447
virtual void OnDragDrop(Point pt, int widget) {}
450
* Handle the request for (viewport) scrolling.
451
* @param delta the amount the viewport must be scrolled.
453
virtual void OnScroll(Point delta) {}
456
* The mouse is currently moving over the window or has just moved outside
457
* of the window. In the latter case pt is (-1, -1).
458
* @param pt the point inside the window that the mouse hovers over.
459
* @param widget the widget the mouse hovers over.
461
virtual void OnMouseOver(Point pt, int widget) {}
464
* The mouse wheel has been turned.
465
* @param wheel the amount of movement of the mouse wheel.
467
virtual void OnMouseWheel(int wheel) {}
471
* Called for every mouse loop run, which is at least once per (game) tick.
473
virtual void OnMouseLoop() {}
476
* Called once per (game) tick.
478
virtual void OnTick() {}
481
* Called once every 100 (game) ticks.
483
virtual void OnHundredthTick() {}
486
* Called when this window's timeout has been reached.
488
virtual void OnTimeout() {}
492
* Called when the window got resized.
493
* @param new_size the new size of the window.
494
* @param delta the amount of which the window size changed.
496
virtual void OnResize(Point new_size, Point delta) {}
499
* A dropdown option associated to this window has been selected.
500
* @param widget the widget (button) that the dropdown is associated with.
501
* @param index the element in the dropdown that is selected.
503
virtual void OnDropdownSelect(int widget, int index) {}
506
* The query window opened from this window has closed.
507
* @param str the new value of the string or NULL if the window
510
virtual void OnQueryTextFinished(char *str) {}
513
* Some data on this window has become invalid.
514
* @param data information about the changed data.
516
virtual void OnInvalidateData(int data = 0) {}
520
* The user clicked some place on the map when a tile highlight mode
522
* @param pt the exact point on the map that has been clicked.
523
* @param tile the tile on the map that has been clicked.
525
virtual void OnPlaceObject(Point pt, TileIndex tile) {}
528
* The user cancelled a tile highlight mode that has been set.
530
virtual void OnPlaceObjectAbort() {}
534
* The user is dragging over the map when the tile highlight mode
536
* @param select_method the method of selection (allowed directions)
537
* @param select_proc what will be created when the drag is over.
538
* @param pt the exact point on the map where the mouse is.
540
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
543
* The user has dragged over the map when the tile highlight mode
545
* @param select_method the method of selection (allowed directions)
546
* @param select_proc what should be created.
547
* @param pt the exact point on the map where the mouse was released.
548
* @param start_tile the begin tile of the drag.
549
* @param end_tile the end tile of the drag.
551
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
554
* The user moves over the map when a tile highlight mode has been set
555
* when the special mouse mode has been set to 'PRESIZE' mode. An
556
* example of this is the tile highlight for dock building.
557
* @param pt the exact point on the map where the mouse is.
558
* @param tile the tile on the map where the mouse is.
560
virtual void OnPlacePresize(Point pt, TileIndex tile) {}
562
/*** End of the event handling ***/
566
* Data structure for a window opened from a toolbar
568
class PickerWindowBase : public Window {
571
PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
573
this->parent = parent;
576
virtual ~PickerWindowBase();
513
582
enum WindowFlags {
516
WF_DRAGGING = 1 << 3,
517
WF_SCROLL_UP = 1 << 4,
518
WF_SCROLL_DOWN = 1 << 5,
519
WF_SCROLL_MIDDLE = 1 << 6,
583
WF_TIMEOUT_TRIGGER = 1, ///< When the timeout should start triggering
584
WF_TIMEOUT_BEGIN = 7, ///< The initial value for the timeout
585
WF_TIMEOUT_MASK = 7, ///< Window timeout counter bit mask (3 bits)
586
WF_DRAGGING = 1 << 3, ///< Window is being dragged
587
WF_SCROLL_UP = 1 << 4, ///< Upper scroll button has been pressed, @see ScrollbarClickHandler()
588
WF_SCROLL_DOWN = 1 << 5, ///< Lower scroll button has been pressed, @see ScrollbarClickHandler()
589
WF_SCROLL_MIDDLE = 1 << 6, ///< Scrollbar scrolling, @see ScrollbarClickHandler()
520
590
WF_HSCROLL = 1 << 7,
591
WF_SIZING = 1 << 8, ///< Window is being resized.
592
WF_STICKY = 1 << 9, ///< Window is made sticky by user
524
WF_DISABLE_VP_SCROLL = 1 << 10,
594
WF_DISABLE_VP_SCROLL = 1 << 10, ///< Window does not do autoscroll, @see HandleAutoscroll()
526
596
WF_WHITE_BORDER_ONE = 1 << 11,
527
597
WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
528
598
WF_SCROLL2 = 1 << 13,
532
void CallWindowEventNP(Window *w, int event);
533
void CallWindowTickEvent();
536
* Marks the window as dirty for repaint.
540
void SetWindowDirty(const Window *w);
541
void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam);
542
void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam);
544
Window *FindWindowById(WindowClass cls, WindowNumber number);
545
void DeleteWindow(Window *w);
546
void DeletePlayerWindows(PlayerID pi);
547
void ChangeWindowOwner(PlayerID old_player, PlayerID new_player);
548
601
Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
549
602
Window *FindWindowFromPt(int x, int y);
551
bool IsWindowOfPrototype(const Window *w, const Widget *widget);
552
void AssignWidgetToWindow(Window *w, const Widget *widget);
553
Window *AllocateWindow(
560
const Widget *widget,
563
Window *AllocateWindowDesc(const WindowDesc *desc, void *data = NULL);
564
Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number, void *data = NULL);
566
void DrawWindowViewport(const Window *w);
567
void ResizeWindow(Window *w, int x, int y);
569
void InitWindowSystem();
570
void UnInitWindowSystem();
571
void ResetWindowSystem();
572
int GetMenuItemIndex(const Window *w, int x, int y);
574
void InvalidateThisWindowData(Window *w);
575
void InvalidateWindowData(WindowClass cls, WindowNumber number);
606
* @param desc The pointer to the WindowDesc to be created
607
* @param window_number the window number of the new window
608
* @return see Window pointer of the newly created window
610
template <typename Wcls>
611
Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
613
if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
614
return new Wcls(desc, window_number);
576
617
void RelocateAllWindows(int neww, int newh);
578
619
/* misc_gui.cpp */
579
void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint64 params[]);
580
static inline void GuiShowTooltips(StringID str)
582
GuiShowTooltipsWithArgs(str, 0, NULL);
620
void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
586
623
int GetWidgetFromPos(const Window *w, int x, int y);
587
void DrawWindowWidgets(const Window *w);
589
enum SortButtonState {
595
void DrawSortButtonState(const Window *w, int widget, SortButtonState state);
598
Window *GetCallbackWnd();
599
void DeleteNonVitalWindows();
600
void DeleteAllNonVitalWindows();
601
void HideVitalWindows();
602
void ShowVitalWindows();
603
Window **FindWindowZPosition(const Window *w);
606
extern Window *_z_windows[];
607
extern Window **_last_z_window;
608
#define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
625
/** Iterate over all windows */
626
#define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
627
#define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
628
#define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
629
#define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
610
631
extern Point _cursorpos_drag_start;
648
Window *GetCallbackWnd();
650
void SetFocusedWindow(Window *w);
651
const Widget *GetGloballyFocusedWidget();
652
bool EditBoxInGlobalFocus();
628
654
void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
630
/** Evenly distribute some widgets when resizing horizontally (often a button row)
631
* The widgets are presumed to be in a line and numberef from left to right (without gaps)
632
* @param w widow to modify
633
* @param left The leftmost widget to resize
634
* @param right The rightmost widget to resize. Since right side of it is used, remember to set it to RESIZE_RIGHT
636
656
void ResizeButtons(Window *w, byte left, byte right);
638
/** Resize a widget an shuffle other widgets around to fit.
640
void ResizeWindowForWidget(Window *w, int widget, int delta_x, int delta_y);
644
* Sets the enabled/disabled status of a widget.
645
* By default, widgets are enabled.
646
* On certain conditions, they have to be disabled.
647
* @param widget_index : index of this widget in the window
648
* @param disab_stat : status to use ie: disabled = true, enabled = false
650
inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat)
652
assert(widget_index < this->widget_count);
653
SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
657
* Sets a widget to disabled.
658
* @param widget_index : index of this widget in the window
660
inline void Window::DisableWidget(byte widget_index)
662
SetWidgetDisabledState(widget_index, true);
666
* Sets a widget to Enabled.
667
* @param widget_index : index of this widget in the window
669
inline void Window::EnableWidget(byte widget_index)
671
SetWidgetDisabledState(widget_index, false);
675
* Gets the enabled/disabled status of a widget.
676
* @param widget_index : index of this widget in the window
677
* @return status of the widget ie: disabled = true, enabled = false
679
inline bool Window::IsWidgetDisabled(byte widget_index) const
681
assert(widget_index < this->widget_count);
682
return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
686
* Sets the hidden/shown status of a widget.
687
* By default, widgets are visible.
688
* On certain conditions, they have to be hidden.
689
* @param widget_index index of this widget in the window
690
* @param hidden_stat status to use ie. hidden = true, visible = false
692
inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat)
694
assert(widget_index < this->widget_count);
695
SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
699
* Sets a widget hidden.
700
* @param widget_index : index of this widget in the window
702
inline void Window::HideWidget(byte widget_index)
704
SetWidgetHiddenState(widget_index, true);
708
* Sets a widget visible.
709
* @param widget_index : index of this widget in the window
711
inline void Window::ShowWidget(byte widget_index)
713
SetWidgetHiddenState(widget_index, false);
717
* Gets the visibility of a widget.
718
* @param widget_index : index of this widget in the window
719
* @return status of the widget ie: hidden = true, visible = false
721
inline bool Window::IsWidgetHidden(byte widget_index) const
723
assert(widget_index < this->widget_count);
724
return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
728
* Sets the lowered/raised status of a widget.
729
* @param widget_index : index of this widget in the window
730
* @param lowered_stat : status to use ie: lowered = true, raised = false
732
inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat)
734
assert(widget_index < this->widget_count);
735
SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
739
* Invert the lowered/raised status of a widget.
740
* @param widget_index : index of this widget in the window
742
inline void Window::ToggleWidgetLoweredState(byte widget_index)
744
assert(widget_index < this->widget_count);
745
ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
749
* Marks a widget as lowered.
750
* @param widget_index : index of this widget in the window
752
inline void Window::LowerWidget(byte widget_index)
754
SetWidgetLoweredState(widget_index, true);
758
* Marks a widget as raised.
759
* @param widget_index : index of this widget in the window
761
inline void Window::RaiseWidget(byte widget_index)
763
SetWidgetLoweredState(widget_index, false);
767
* Gets the lowered state of a widget.
768
* @param widget_index : index of this widget in the window
769
* @return status of the widget ie: lowered = true, raised= false
771
inline bool Window::IsWidgetLowered(byte widget_index) const
773
assert(widget_index < this->widget_count);
774
return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
658
void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
660
void SetVScrollCount(Window *w, int num);
661
void SetVScroll2Count(Window *w, int num);
662
void SetHScrollCount(Window *w, int num);
777
664
#endif /* WINDOW_GUI_H */