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_RESIZEBOX_WIDTH = 12,
00111 WD_RESIZEBOX_LEFT = 3,
00112 WD_RESIZEBOX_RIGHT = 2,
00113 WD_RESIZEBOX_TOP = 3,
00114 WD_RESIZEBOX_BOTTOM = 2,
00115
00116
00117 WD_CLOSEBOX_WIDTH = 11,
00118 WD_CLOSEBOX_LEFT = 2,
00119 WD_CLOSEBOX_RIGHT = 1,
00120 WD_CLOSEBOX_TOP = 2,
00121 WD_CLOSEBOX_BOTTOM = 2,
00122
00123
00124 WD_CAPTION_HEIGHT = 14,
00125 WD_CAPTIONTEXT_LEFT = 2,
00126 WD_CAPTIONTEXT_RIGHT = 2,
00127 WD_CAPTIONTEXT_TOP = 2,
00128 WD_CAPTIONTEXT_BOTTOM = 2,
00129
00130
00131 WD_DROPDOWN_HEIGHT = 12,
00132 WD_DROPDOWNTEXT_LEFT = 2,
00133 WD_DROPDOWNTEXT_RIGHT = 14,
00134 WD_DROPDOWNTEXT_TOP = 1,
00135 WD_DROPDOWNTEXT_BOTTOM = 1,
00136
00137 WD_SORTBUTTON_ARROW_WIDTH = 11,
00138
00139 WD_PAR_VSEP_NORMAL = 2,
00140 WD_PAR_VSEP_WIDE = 8,
00141 };
00142
00143
00144 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
00145 void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str);
00146
00147
00148 extern Window *_z_front_window;
00149 extern Window *_z_back_window;
00150 extern Window *_focused_window;
00151
00152
00154 enum WindowPosition {
00155 WDP_MANUAL,
00156 WDP_AUTO,
00157 WDP_CENTER,
00158 WDP_ALIGN_TOOLBAR,
00159 };
00160
00161 Point GetToolbarAlignedWindowPosition(int window_width);
00162
00166 struct WindowDesc : ZeroedMemoryAllocator {
00167
00168 WindowDesc(WindowPosition default_pos, int16 def_width, int16 def_height,
00169 WindowClass window_class, WindowClass parent_class, uint32 flags,
00170 const NWidgetPart *nwid_parts, int16 nwid_length);
00171
00172 ~WindowDesc();
00173
00174 WindowPosition default_pos;
00175 int16 default_width;
00176 int16 default_height;
00177 WindowClass cls;
00178 WindowClass parent_cls;
00179 uint32 flags;
00180 const NWidgetPart *nwid_parts;
00181 int16 nwid_length;
00182 };
00183
00187 enum WindowDefaultFlag {
00188 WDF_CONSTRUCTION = 1 << 0,
00189 WDF_MODAL = 1 << 1,
00190 WDF_NO_FOCUS = 1 << 2,
00191 };
00192
00196 struct ResizeInfo {
00197 uint step_width;
00198 uint step_height;
00199 };
00200
00202 enum SortButtonState {
00203 SBS_OFF,
00204 SBS_DOWN,
00205 SBS_UP,
00206 };
00207
00211 enum WindowFlags {
00212 WF_TIMEOUT = 1 << 0,
00213
00214 WF_DRAGGING = 1 << 3,
00215 WF_SIZING_RIGHT = 1 << 4,
00216 WF_SIZING_LEFT = 1 << 5,
00217 WF_SIZING = WF_SIZING_RIGHT | WF_SIZING_LEFT,
00218 WF_STICKY = 1 << 6,
00219 WF_DISABLE_VP_SCROLL = 1 << 7,
00220 WF_WHITE_BORDER = 1 << 8,
00221 WF_HIGHLIGHTED = 1 << 9,
00222 WF_CENTERED = 1 << 10,
00223 };
00224 DECLARE_ENUM_AS_BIT_SET(WindowFlags)
00225
00226 static const int TIMEOUT_DURATION = 7;
00227 static const int WHITE_BORDER_DURATION = 3;
00228
00236 struct ViewportData : ViewPort {
00237 VehicleID follow_vehicle;
00238 int32 scrollpos_x;
00239 int32 scrollpos_y;
00240 int32 dest_scrollpos_x;
00241 int32 dest_scrollpos_y;
00242 };
00243
00244 struct QueryString;
00245
00249 struct Window : ZeroedMemoryAllocator {
00250 protected:
00251 void InitializeData(const WindowDesc *desc, WindowNumber window_number);
00252 void InitializePositionSize(int x, int y, int min_width, int min_height);
00253 void FindWindowPlacementAndResize(int def_width, int def_height);
00254
00255 SmallVector<int, 4> scheduled_invalidation_data;
00256
00257 public:
00258 Window();
00259
00260 virtual ~Window();
00261
00268 inline void *operator new[](size_t size)
00269 {
00270 NOT_REACHED();
00271 }
00272
00278 inline void operator delete(void *ptr)
00279 {
00280 }
00281
00282 WindowFlags flags;
00283 WindowClass window_class;
00284 WindowNumber window_number;
00285
00286 uint8 timeout_timer;
00287 uint8 white_border_timer;
00288
00289 int left;
00290 int top;
00291 int width;
00292 int height;
00293
00294 ResizeInfo resize;
00295
00296 Owner owner;
00297
00298 ViewportData *viewport;
00299 uint32 desc_flags;
00300 const NWidgetCore *nested_focus;
00301 SmallMap<int, QueryString*> querystrings;
00302 NWidgetBase *nested_root;
00303 NWidgetBase **nested_array;
00304 uint nested_array_size;
00305 NWidgetStacked *shade_select;
00306 Dimension unshaded_size;
00307
00308 int scrolling_scrollbar;
00309
00310 Window *parent;
00311 Window *z_front;
00312 Window *z_back;
00313
00314 template <class NWID>
00315 inline const NWID *GetWidget(uint widnum) const;
00316 template <class NWID>
00317 inline NWID *GetWidget(uint widnum);
00318
00319 const Scrollbar *GetScrollbar(uint widnum) const;
00320 Scrollbar *GetScrollbar(uint widnum);
00321
00322 const QueryString *GetQueryString(uint widnum) const;
00323 QueryString *GetQueryString(uint widnum);
00324
00325 void InitNested(const WindowDesc *desc, WindowNumber number = 0);
00326 void CreateNestedTree(const WindowDesc *desc, bool fill_nested = true);
00327 void FinishInitNested(const WindowDesc *desc, WindowNumber window_number = 0);
00328
00332 inline void SetTimeout()
00333 {
00334 this->flags |= WF_TIMEOUT;
00335 this->timeout_timer = TIMEOUT_DURATION;
00336 }
00337
00341 inline void SetWhiteBorder()
00342 {
00343 this->flags |= WF_WHITE_BORDER;
00344 this->white_border_timer = WHITE_BORDER_DURATION;
00345 }
00346
00347 void DisableAllWidgetHighlight();
00348 void SetWidgetHighlight(byte widget_index, TextColour highlighted_colour);
00349 bool IsWidgetHighlighted(byte widget_index) const;
00350
00358 inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00359 {
00360 assert(widget_index < this->nested_array_size);
00361 if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
00362 }
00363
00368 inline void DisableWidget(byte widget_index)
00369 {
00370 SetWidgetDisabledState(widget_index, true);
00371 }
00372
00377 inline void EnableWidget(byte widget_index)
00378 {
00379 SetWidgetDisabledState(widget_index, false);
00380 }
00381
00387 inline bool IsWidgetDisabled(byte widget_index) const
00388 {
00389 assert(widget_index < this->nested_array_size);
00390 return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
00391 }
00392
00398 inline bool IsWidgetFocused(byte widget_index) const
00399 {
00400 return this->nested_focus != NULL && this->nested_focus->index == widget_index;
00401 }
00402
00409 inline bool IsWidgetGloballyFocused(byte widget_index) const
00410 {
00411 return _focused_window == this && IsWidgetFocused(widget_index);
00412 }
00413
00419 inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00420 {
00421 assert(widget_index < this->nested_array_size);
00422 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
00423 }
00424
00429 inline void ToggleWidgetLoweredState(byte widget_index)
00430 {
00431 assert(widget_index < this->nested_array_size);
00432 bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00433 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
00434 }
00435
00440 inline void LowerWidget(byte widget_index)
00441 {
00442 SetWidgetLoweredState(widget_index, true);
00443 }
00444
00449 inline void RaiseWidget(byte widget_index)
00450 {
00451 SetWidgetLoweredState(widget_index, false);
00452 }
00453
00459 inline bool IsWidgetLowered(byte widget_index) const
00460 {
00461 assert(widget_index < this->nested_array_size);
00462 return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00463 }
00464
00465 void UnfocusFocusedWidget();
00466 bool SetFocusedWidget(byte widget_index);
00467
00468 EventState HandleEditBoxKey(int wid, uint16 key, uint16 keycode);
00469
00470 void HandleButtonClick(byte widget);
00471 int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;
00472
00473 void RaiseButtons(bool autoraise = false);
00474 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00475 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00476 void SetWidgetDirty(byte widget_index) const;
00477
00478 void DrawWidgets() const;
00479 void DrawViewport() const;
00480 void DrawSortButtonState(int widget, SortButtonState state) const;
00481
00482 void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00483
00484 void SetDirty() const;
00485 void ReInit(int rx = 0, int ry = 0);
00486
00488 inline bool IsShaded() const
00489 {
00490 return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL;
00491 }
00492
00493 void SetShaded(bool make_shaded);
00494
00495 void InvalidateData(int data = 0, bool gui_scope = true);
00496 void ProcessScheduledInvalidations();
00497 void ProcessHighlightedInvalidations();
00498
00499
00500
00505 virtual void OnInit() { }
00506
00515 virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number);
00516
00521 virtual void OnPaint()
00522 {
00523 this->DrawWidgets();
00524 }
00525
00532 virtual void DrawWidget(const Rect &r, int widget) const {}
00533
00546 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {}
00547
00554 virtual void SetStringParameters(int widget) const {}
00555
00559 virtual void OnFocus() {}
00560
00564 virtual void OnFocusLost() {}
00565
00573 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00574
00580 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00581
00582
00589 virtual void OnClick(Point pt, int widget, int click_count) {}
00590
00598 virtual bool OnRightClick(Point pt, int widget) { return false; }
00599
00605 virtual void OnHover(Point pt, int widget) {}
00606
00612 virtual void OnMouseDrag(Point pt, int widget) {}
00613
00619 virtual void OnDragDrop(Point pt, int widget) {}
00620
00625 virtual void OnScroll(Point delta) {}
00626
00633 virtual void OnMouseOver(Point pt, int widget) {}
00634
00639 virtual void OnMouseWheel(int wheel) {}
00640
00641
00645 virtual void OnMouseLoop() {}
00646
00650 virtual void OnTick() {}
00651
00655 virtual void OnHundredthTick() {}
00656
00660 virtual void OnTimeout() {}
00661
00662
00667 virtual void OnResize() {}
00668
00674 virtual void OnDropdownSelect(int widget, int index) {}
00675
00676 virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close);
00677
00682 virtual void OnEditboxChanged(int widget) {}
00683
00690 virtual void OnQueryTextFinished(char *str) {}
00691
00697 virtual void OnInvalidateData(int data = 0, bool gui_scope = true) {}
00698
00705 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00706
00712 virtual bool OnVehicleSelect(const struct Vehicle *v) { return false; }
00713
00717 virtual void OnPlaceObjectAbort() {}
00718
00719
00727 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00728
00738 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00739
00747 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00748
00749
00750
00755 virtual bool IsNewGRFInspectable() const { return false; }
00756
00763 virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); }
00764 };
00765
00772 template <class NWID>
00773 inline NWID *Window::GetWidget(uint widnum)
00774 {
00775 if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL;
00776 NWID *nwid = dynamic_cast<NWID *>(this->nested_array[widnum]);
00777 assert(nwid != NULL);
00778 return nwid;
00779 }
00780
00782 template <>
00783 inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
00784 {
00785 if (widnum >= this->nested_array_size) return NULL;
00786 return this->nested_array[widnum];
00787 }
00788
00795 template <class NWID>
00796 inline const NWID *Window::GetWidget(uint widnum) const
00797 {
00798 return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
00799 }
00800
00801
00805 class PickerWindowBase : public Window {
00806
00807 public:
00808 PickerWindowBase(Window *parent) : Window()
00809 {
00810 this->parent = parent;
00811 }
00812
00813 virtual ~PickerWindowBase();
00814 };
00815
00816 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00817 Window *FindWindowFromPt(int x, int y);
00818
00825 template <typename Wcls>
00826 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00827 {
00828 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00829 return new Wcls(desc, window_number);
00830 }
00831
00832 void RelocateAllWindows(int neww, int newh);
00833
00834
00835 enum TooltipCloseCondition {
00836 TCC_RIGHT_CLICK,
00837 TCC_LEFT_CLICK,
00838 TCC_HOVER,
00839 };
00840
00841 void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = NULL, TooltipCloseCondition close_tooltip = TCC_HOVER);
00842
00843
00844 int GetWidgetFromPos(const Window *w, int x, int y);
00845
00847 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00848 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00849 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00850 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00851
00852 extern Point _cursorpos_drag_start;
00853
00854 extern int _scrollbar_start_pos;
00855 extern int _scrollbar_size;
00856 extern byte _scroller_click_timeout;
00857
00858 extern bool _scrolling_viewport;
00859 extern bool _mouse_hovering;
00860
00862 enum SpecialMouseMode {
00863 WSM_NONE,
00864 WSM_DRAGDROP,
00865 WSM_SIZING,
00866 WSM_PRESIZE,
00867 };
00868 extern SpecialMouseMode _special_mouse_mode;
00869
00870 void SetFocusedWindow(Window *w);
00871
00872 void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y);
00873
00874 #endif