00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef WINDOW_GUI_H
00013 #define WINDOW_GUI_H
00014
00015 #include "vehicle_type.h"
00016 #include "viewport_type.h"
00017 #include "company_type.h"
00018 #include "tile_type.h"
00019 #include "widget_type.h"
00020 #include "core/smallvec_type.hpp"
00021 #include "core/smallmap_type.hpp"
00022
00024 enum EventState {
00025 ES_HANDLED,
00026 ES_NOT_HANDLED,
00027 };
00028
00032 enum FrameFlags {
00033 FR_NONE = 0,
00034 FR_TRANSPARENT = 1 << 0,
00035 FR_BORDERONLY = 1 << 4,
00036 FR_LOWERED = 1 << 5,
00037 FR_DARKENED = 1 << 6,
00038 };
00039
00040 DECLARE_ENUM_AS_BIT_SET(FrameFlags)
00041
00042
00043 enum WidgetDrawDistances {
00044
00045 WD_IMGBTN_LEFT = 1,
00046 WD_IMGBTN_RIGHT = 2,
00047 WD_IMGBTN_TOP = 1,
00048 WD_IMGBTN_BOTTOM = 2,
00049
00050
00051 WD_INSET_LEFT = 2,
00052 WD_INSET_RIGHT = 2,
00053 WD_INSET_TOP = 1,
00054
00055 WD_SCROLLBAR_LEFT = 2,
00056 WD_SCROLLBAR_RIGHT = 2,
00057 WD_SCROLLBAR_TOP = 2,
00058 WD_SCROLLBAR_BOTTOM = 2,
00059
00060
00061 WD_BEVEL_LEFT = 1,
00062 WD_BEVEL_RIGHT = 1,
00063 WD_BEVEL_TOP = 1,
00064 WD_BEVEL_BOTTOM = 1,
00065
00066
00067 WD_FRAMERECT_LEFT = 2,
00068 WD_FRAMERECT_RIGHT = 2,
00069 WD_FRAMERECT_TOP = 1,
00070 WD_FRAMERECT_BOTTOM = 1,
00071
00072
00073 WD_TEXTPANEL_TOP = 6,
00074 WD_TEXTPANEL_BOTTOM = 6,
00075
00076
00077 WD_FRAMETEXT_LEFT = 6,
00078 WD_FRAMETEXT_RIGHT = 6,
00079 WD_FRAMETEXT_TOP = 6,
00080 WD_FRAMETEXT_BOTTOM = 6,
00081
00082
00083 WD_MATRIX_LEFT = 2,
00084 WD_MATRIX_RIGHT = 2,
00085 WD_MATRIX_TOP = 3,
00086 WD_MATRIX_BOTTOM = 1,
00087
00088
00089 WD_SHADEBOX_WIDTH = 12,
00090 WD_SHADEBOX_LEFT = 2,
00091 WD_SHADEBOX_RIGHT = 2,
00092 WD_SHADEBOX_TOP = 3,
00093 WD_SHADEBOX_BOTTOM = 3,
00094
00095
00096 WD_STICKYBOX_WIDTH = 12,
00097 WD_STICKYBOX_LEFT = 2,
00098 WD_STICKYBOX_RIGHT = 2,
00099 WD_STICKYBOX_TOP = 3,
00100 WD_STICKYBOX_BOTTOM = 3,
00101
00102
00103 WD_DEBUGBOX_WIDTH = 12,
00104 WD_DEBUGBOX_LEFT = 2,
00105 WD_DEBUGBOX_RIGHT = 2,
00106 WD_DEBUGBOX_TOP = 3,
00107 WD_DEBUGBOX_BOTTOM = 3,
00108
00109
00110 WD_DEFSIZEBOX_WIDTH = 12,
00111 WD_DEFSIZEBOX_LEFT = 2,
00112 WD_DEFSIZEBOX_RIGHT = 2,
00113 WD_DEFSIZEBOX_TOP = 3,
00114 WD_DEFSIZEBOX_BOTTOM = 3,
00115
00116
00117 WD_RESIZEBOX_WIDTH = 12,
00118 WD_RESIZEBOX_LEFT = 3,
00119 WD_RESIZEBOX_RIGHT = 2,
00120 WD_RESIZEBOX_TOP = 3,
00121 WD_RESIZEBOX_BOTTOM = 2,
00122
00123
00124 WD_CLOSEBOX_WIDTH = 11,
00125 WD_CLOSEBOX_LEFT = 2,
00126 WD_CLOSEBOX_RIGHT = 1,
00127 WD_CLOSEBOX_TOP = 2,
00128 WD_CLOSEBOX_BOTTOM = 2,
00129
00130
00131 WD_CAPTION_HEIGHT = 14,
00132 WD_CAPTIONTEXT_LEFT = 2,
00133 WD_CAPTIONTEXT_RIGHT = 2,
00134 WD_CAPTIONTEXT_TOP = 2,
00135 WD_CAPTIONTEXT_BOTTOM = 2,
00136
00137
00138 WD_DROPDOWN_HEIGHT = 12,
00139 WD_DROPDOWNTEXT_LEFT = 2,
00140 WD_DROPDOWNTEXT_RIGHT = 14,
00141 WD_DROPDOWNTEXT_TOP = 1,
00142 WD_DROPDOWNTEXT_BOTTOM = 1,
00143
00144 WD_SORTBUTTON_ARROW_WIDTH = 11,
00145
00146 WD_PAR_VSEP_NORMAL = 2,
00147 WD_PAR_VSEP_WIDE = 8,
00148 };
00149
00150
00151 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
00152 void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str);
00153
00154
00155 extern Window *_z_front_window;
00156 extern Window *_z_back_window;
00157 extern Window *_focused_window;
00158
00159
00161 enum WindowPosition {
00162 WDP_MANUAL,
00163 WDP_AUTO,
00164 WDP_CENTER,
00165 WDP_ALIGN_TOOLBAR,
00166 };
00167
00168 Point GetToolbarAlignedWindowPosition(int window_width);
00169
00173 struct WindowDesc : ZeroedMemoryAllocator {
00174
00175 WindowDesc(WindowPosition default_pos, const char *ini_key, int16 def_width, int16 def_height,
00176 WindowClass window_class, WindowClass parent_class, uint32 flags,
00177 const NWidgetPart *nwid_parts, int16 nwid_length);
00178
00179 ~WindowDesc();
00180
00181 WindowPosition default_pos;
00182 int16 default_width;
00183 int16 default_height;
00184 WindowClass cls;
00185 WindowClass parent_cls;
00186 const char *ini_key;
00187 uint32 flags;
00188 const NWidgetPart *nwid_parts;
00189 int16 nwid_length;
00190
00191 bool pref_sticky;
00192 int16 pref_width;
00193 int16 pref_height;
00194
00195 int16 GetDefaultWidth() const { return this->pref_width != 0 ? this->pref_width : this->default_width; }
00196 int16 GetDefaultHeight() const { return this->pref_height != 0 ? this->pref_height : this->default_height; }
00197
00198 static void LoadFromConfig();
00199 static void SaveToConfig();
00200 };
00201
00205 enum WindowDefaultFlag {
00206 WDF_CONSTRUCTION = 1 << 0,
00207 WDF_MODAL = 1 << 1,
00208 WDF_NO_FOCUS = 1 << 2,
00209 };
00210
00214 struct ResizeInfo {
00215 uint step_width;
00216 uint step_height;
00217 };
00218
00220 enum SortButtonState {
00221 SBS_OFF,
00222 SBS_DOWN,
00223 SBS_UP,
00224 };
00225
00229 enum WindowFlags {
00230 WF_TIMEOUT = 1 << 0,
00231
00232 WF_DRAGGING = 1 << 3,
00233 WF_SIZING_RIGHT = 1 << 4,
00234 WF_SIZING_LEFT = 1 << 5,
00235 WF_SIZING = WF_SIZING_RIGHT | WF_SIZING_LEFT,
00236 WF_STICKY = 1 << 6,
00237 WF_DISABLE_VP_SCROLL = 1 << 7,
00238 WF_WHITE_BORDER = 1 << 8,
00239 WF_HIGHLIGHTED = 1 << 9,
00240 WF_CENTERED = 1 << 10,
00241 };
00242 DECLARE_ENUM_AS_BIT_SET(WindowFlags)
00243
00244 static const int TIMEOUT_DURATION = 7;
00245 static const int WHITE_BORDER_DURATION = 3;
00246
00254 struct ViewportData : ViewPort {
00255 VehicleID follow_vehicle;
00256 int32 scrollpos_x;
00257 int32 scrollpos_y;
00258 int32 dest_scrollpos_x;
00259 int32 dest_scrollpos_y;
00260 };
00261
00262 struct QueryString;
00263
00267 struct Window : ZeroedMemoryAllocator {
00268 protected:
00269 void InitializeData(WindowNumber window_number);
00270 void InitializePositionSize(int x, int y, int min_width, int min_height);
00271 void FindWindowPlacementAndResize(int def_width, int def_height);
00272
00273 SmallVector<int, 4> scheduled_invalidation_data;
00274
00275 public:
00276 Window(WindowDesc *desc);
00277
00278 virtual ~Window();
00279
00286 inline void *operator new[](size_t size)
00287 {
00288 NOT_REACHED();
00289 }
00290
00296 inline void operator delete(void *ptr)
00297 {
00298 }
00299
00300 WindowDesc *window_desc;
00301 WindowFlags flags;
00302 WindowClass window_class;
00303 WindowNumber window_number;
00304
00305 uint8 timeout_timer;
00306 uint8 white_border_timer;
00307
00308 int left;
00309 int top;
00310 int width;
00311 int height;
00312
00313 ResizeInfo resize;
00314
00315 Owner owner;
00316
00317 ViewportData *viewport;
00318 const NWidgetCore *nested_focus;
00319 SmallMap<int, QueryString*> querystrings;
00320 NWidgetBase *nested_root;
00321 NWidgetBase **nested_array;
00322 uint nested_array_size;
00323 NWidgetStacked *shade_select;
00324 Dimension unshaded_size;
00325
00326 int scrolling_scrollbar;
00327
00328 Window *parent;
00329 Window *z_front;
00330 Window *z_back;
00331
00332 template <class NWID>
00333 inline const NWID *GetWidget(uint widnum) const;
00334 template <class NWID>
00335 inline NWID *GetWidget(uint widnum);
00336
00337 const Scrollbar *GetScrollbar(uint widnum) const;
00338 Scrollbar *GetScrollbar(uint widnum);
00339
00340 const QueryString *GetQueryString(uint widnum) const;
00341 QueryString *GetQueryString(uint widnum);
00342
00343 void InitNested(WindowNumber number = 0);
00344 void CreateNestedTree(bool fill_nested = true);
00345 void FinishInitNested(WindowNumber window_number = 0);
00346
00350 inline void SetTimeout()
00351 {
00352 this->flags |= WF_TIMEOUT;
00353 this->timeout_timer = TIMEOUT_DURATION;
00354 }
00355
00359 inline void SetWhiteBorder()
00360 {
00361 this->flags |= WF_WHITE_BORDER;
00362 this->white_border_timer = WHITE_BORDER_DURATION;
00363 }
00364
00365 void DisableAllWidgetHighlight();
00366 void SetWidgetHighlight(byte widget_index, TextColour highlighted_colour);
00367 bool IsWidgetHighlighted(byte widget_index) const;
00368
00376 inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00377 {
00378 assert(widget_index < this->nested_array_size);
00379 if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
00380 }
00381
00386 inline void DisableWidget(byte widget_index)
00387 {
00388 SetWidgetDisabledState(widget_index, true);
00389 }
00390
00395 inline void EnableWidget(byte widget_index)
00396 {
00397 SetWidgetDisabledState(widget_index, false);
00398 }
00399
00405 inline bool IsWidgetDisabled(byte widget_index) const
00406 {
00407 assert(widget_index < this->nested_array_size);
00408 return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
00409 }
00410
00416 inline bool IsWidgetFocused(byte widget_index) const
00417 {
00418 return this->nested_focus != NULL && this->nested_focus->index == widget_index;
00419 }
00420
00427 inline bool IsWidgetGloballyFocused(byte widget_index) const
00428 {
00429 return _focused_window == this && IsWidgetFocused(widget_index);
00430 }
00431
00437 inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00438 {
00439 assert(widget_index < this->nested_array_size);
00440 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
00441 }
00442
00447 inline void ToggleWidgetLoweredState(byte widget_index)
00448 {
00449 assert(widget_index < this->nested_array_size);
00450 bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00451 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
00452 }
00453
00458 inline void LowerWidget(byte widget_index)
00459 {
00460 SetWidgetLoweredState(widget_index, true);
00461 }
00462
00467 inline void RaiseWidget(byte widget_index)
00468 {
00469 SetWidgetLoweredState(widget_index, false);
00470 }
00471
00477 inline bool IsWidgetLowered(byte widget_index) const
00478 {
00479 assert(widget_index < this->nested_array_size);
00480 return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00481 }
00482
00483 void UnfocusFocusedWidget();
00484 bool SetFocusedWidget(int widget_index);
00485
00486 EventState HandleEditBoxKey(int wid, uint16 key, uint16 keycode);
00487
00488 void HandleButtonClick(byte widget);
00489 int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;
00490
00491 void RaiseButtons(bool autoraise = false);
00492 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00493 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00494 void SetWidgetDirty(byte widget_index) const;
00495
00496 void DrawWidgets() const;
00497 void DrawViewport() const;
00498 void DrawSortButtonState(int widget, SortButtonState state) const;
00499
00500 void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00501
00502 void SetDirty() const;
00503 void ReInit(int rx = 0, int ry = 0);
00504
00506 inline bool IsShaded() const
00507 {
00508 return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL;
00509 }
00510
00511 void SetShaded(bool make_shaded);
00512
00513 void InvalidateData(int data = 0, bool gui_scope = true);
00514 void ProcessScheduledInvalidations();
00515 void ProcessHighlightedInvalidations();
00516
00517
00518
00523 virtual void OnInit() { }
00524
00525 virtual void ApplyDefaults();
00526
00534 virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number);
00535
00540 virtual void OnPaint()
00541 {
00542 this->DrawWidgets();
00543 }
00544
00551 virtual void DrawWidget(const Rect &r, int widget) const {}
00552
00565 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {}
00566
00573 virtual void SetStringParameters(int widget) const {}
00574
00578 virtual void OnFocus() {}
00579
00583 virtual void OnFocusLost() {}
00584
00592 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00593
00599 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00600
00601
00608 virtual void OnClick(Point pt, int widget, int click_count) {}
00609
00617 virtual bool OnRightClick(Point pt, int widget) { return false; }
00618
00624 virtual void OnHover(Point pt, int widget) {}
00625
00631 virtual void OnMouseDrag(Point pt, int widget) {}
00632
00638 virtual void OnDragDrop(Point pt, int widget) {}
00639
00644 virtual void OnScroll(Point delta) {}
00645
00652 virtual void OnMouseOver(Point pt, int widget) {}
00653
00658 virtual void OnMouseWheel(int wheel) {}
00659
00660
00664 virtual void OnMouseLoop() {}
00665
00669 virtual void OnTick() {}
00670
00674 virtual void OnHundredthTick() {}
00675
00679 virtual void OnTimeout() {}
00680
00681
00686 virtual void OnResize() {}
00687
00693 virtual void OnDropdownSelect(int widget, int index) {}
00694
00695 virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close);
00696
00701 virtual void OnEditboxChanged(int widget) {}
00702
00709 virtual void OnQueryTextFinished(char *str) {}
00710
00716 virtual void OnInvalidateData(int data = 0, bool gui_scope = true) {}
00717
00724 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00725
00731 virtual bool OnVehicleSelect(const struct Vehicle *v) { return false; }
00732
00736 virtual void OnPlaceObjectAbort() {}
00737
00738
00746 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00747
00757 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00758
00766 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00767
00768
00769
00774 virtual bool IsNewGRFInspectable() const { return false; }
00775
00782 virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); }
00783 };
00784
00791 template <class NWID>
00792 inline NWID *Window::GetWidget(uint widnum)
00793 {
00794 if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL;
00795 NWID *nwid = dynamic_cast<NWID *>(this->nested_array[widnum]);
00796 assert(nwid != NULL);
00797 return nwid;
00798 }
00799
00801 template <>
00802 inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
00803 {
00804 if (widnum >= this->nested_array_size) return NULL;
00805 return this->nested_array[widnum];
00806 }
00807
00814 template <class NWID>
00815 inline const NWID *Window::GetWidget(uint widnum) const
00816 {
00817 return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
00818 }
00819
00820
00824 class PickerWindowBase : public Window {
00825
00826 public:
00827 PickerWindowBase(WindowDesc *desc, Window *parent) : Window(desc)
00828 {
00829 this->parent = parent;
00830 }
00831
00832 virtual ~PickerWindowBase();
00833 };
00834
00835 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00836 Window *FindWindowFromPt(int x, int y);
00837
00844 template <typename Wcls>
00845 Wcls *AllocateWindowDescFront(WindowDesc *desc, int window_number)
00846 {
00847 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00848 return new Wcls(desc, window_number);
00849 }
00850
00851 void RelocateAllWindows(int neww, int newh);
00852
00853
00854 enum TooltipCloseCondition {
00855 TCC_RIGHT_CLICK,
00856 TCC_LEFT_CLICK,
00857 TCC_HOVER,
00858 };
00859
00860 void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = NULL, TooltipCloseCondition close_tooltip = TCC_HOVER);
00861
00862
00863 int GetWidgetFromPos(const Window *w, int x, int y);
00864
00866 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00867 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00868 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00869 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00870
00871 extern Point _cursorpos_drag_start;
00872
00873 extern int _scrollbar_start_pos;
00874 extern int _scrollbar_size;
00875 extern byte _scroller_click_timeout;
00876
00877 extern bool _scrolling_viewport;
00878 extern bool _mouse_hovering;
00879
00881 enum SpecialMouseMode {
00882 WSM_NONE,
00883 WSM_DRAGDROP,
00884 WSM_SIZING,
00885 WSM_PRESIZE,
00886 };
00887 extern SpecialMouseMode _special_mouse_mode;
00888
00889 void SetFocusedWindow(Window *w);
00890
00891 void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y);
00892
00893 #endif