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 #include "string_type.h"
00023
00027 enum FrameFlags {
00028 FR_NONE = 0,
00029 FR_TRANSPARENT = 1 << 0,
00030 FR_BORDERONLY = 1 << 4,
00031 FR_LOWERED = 1 << 5,
00032 FR_DARKENED = 1 << 6,
00033 };
00034
00035 DECLARE_ENUM_AS_BIT_SET(FrameFlags)
00036
00037
00038 enum WidgetDrawDistances {
00039
00040 WD_IMGBTN_LEFT = 1,
00041 WD_IMGBTN_RIGHT = 2,
00042 WD_IMGBTN_TOP = 1,
00043 WD_IMGBTN_BOTTOM = 2,
00044
00045
00046 WD_INSET_LEFT = 2,
00047 WD_INSET_RIGHT = 2,
00048 WD_INSET_TOP = 1,
00049
00050 WD_SCROLLBAR_LEFT = 2,
00051 WD_SCROLLBAR_RIGHT = 2,
00052 WD_SCROLLBAR_TOP = 2,
00053 WD_SCROLLBAR_BOTTOM = 2,
00054
00055
00056 WD_BEVEL_LEFT = 1,
00057 WD_BEVEL_RIGHT = 1,
00058 WD_BEVEL_TOP = 1,
00059 WD_BEVEL_BOTTOM = 1,
00060
00061
00062 WD_FRAMERECT_LEFT = 2,
00063 WD_FRAMERECT_RIGHT = 2,
00064 WD_FRAMERECT_TOP = 1,
00065 WD_FRAMERECT_BOTTOM = 1,
00066
00067
00068 WD_TEXTPANEL_TOP = 6,
00069 WD_TEXTPANEL_BOTTOM = 6,
00070
00071
00072 WD_FRAMETEXT_LEFT = 6,
00073 WD_FRAMETEXT_RIGHT = 6,
00074 WD_FRAMETEXT_TOP = 6,
00075 WD_FRAMETEXT_BOTTOM = 6,
00076
00077
00078 WD_MATRIX_LEFT = 2,
00079 WD_MATRIX_RIGHT = 2,
00080 WD_MATRIX_TOP = 3,
00081 WD_MATRIX_BOTTOM = 1,
00082
00083
00084 WD_SHADEBOX_WIDTH = 12,
00085 WD_SHADEBOX_LEFT = 2,
00086 WD_SHADEBOX_RIGHT = 2,
00087 WD_SHADEBOX_TOP = 3,
00088 WD_SHADEBOX_BOTTOM = 3,
00089
00090
00091 WD_STICKYBOX_WIDTH = 12,
00092 WD_STICKYBOX_LEFT = 2,
00093 WD_STICKYBOX_RIGHT = 2,
00094 WD_STICKYBOX_TOP = 3,
00095 WD_STICKYBOX_BOTTOM = 3,
00096
00097
00098 WD_DEBUGBOX_WIDTH = 12,
00099 WD_DEBUGBOX_LEFT = 2,
00100 WD_DEBUGBOX_RIGHT = 2,
00101 WD_DEBUGBOX_TOP = 3,
00102 WD_DEBUGBOX_BOTTOM = 3,
00103
00104
00105 WD_DEFSIZEBOX_WIDTH = 12,
00106 WD_DEFSIZEBOX_LEFT = 2,
00107 WD_DEFSIZEBOX_RIGHT = 2,
00108 WD_DEFSIZEBOX_TOP = 3,
00109 WD_DEFSIZEBOX_BOTTOM = 3,
00110
00111
00112 WD_RESIZEBOX_WIDTH = 12,
00113 WD_RESIZEBOX_LEFT = 3,
00114 WD_RESIZEBOX_RIGHT = 2,
00115 WD_RESIZEBOX_TOP = 3,
00116 WD_RESIZEBOX_BOTTOM = 2,
00117
00118
00119 WD_CLOSEBOX_WIDTH = 11,
00120 WD_CLOSEBOX_LEFT = 2,
00121 WD_CLOSEBOX_RIGHT = 1,
00122 WD_CLOSEBOX_TOP = 2,
00123 WD_CLOSEBOX_BOTTOM = 2,
00124
00125
00126 WD_CAPTION_HEIGHT = 14,
00127 WD_CAPTIONTEXT_LEFT = 2,
00128 WD_CAPTIONTEXT_RIGHT = 2,
00129 WD_CAPTIONTEXT_TOP = 2,
00130 WD_CAPTIONTEXT_BOTTOM = 2,
00131
00132
00133 WD_DROPDOWN_HEIGHT = 12,
00134 WD_DROPDOWNTEXT_LEFT = 2,
00135 WD_DROPDOWNTEXT_RIGHT = 2,
00136 WD_DROPDOWNTEXT_TOP = 1,
00137 WD_DROPDOWNTEXT_BOTTOM = 1,
00138
00139 WD_SORTBUTTON_ARROW_WIDTH = 11,
00140
00141 WD_PAR_VSEP_NORMAL = 2,
00142 WD_PAR_VSEP_WIDE = 8,
00143 };
00144
00145
00146 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
00147 void DrawCaption(const Rect &r, Colours colour, Owner owner, StringID str);
00148
00149
00150 extern Window *_z_front_window;
00151 extern Window *_z_back_window;
00152 extern Window *_focused_window;
00153
00154
00156 enum WindowPosition {
00157 WDP_MANUAL,
00158 WDP_AUTO,
00159 WDP_CENTER,
00160 WDP_ALIGN_TOOLBAR,
00161 };
00162
00163 Point GetToolbarAlignedWindowPosition(int window_width);
00164
00165 struct HotkeyList;
00166
00170 struct WindowDesc : ZeroedMemoryAllocator {
00171
00172 WindowDesc(WindowPosition default_pos, const char *ini_key, int16 def_width, int16 def_height,
00173 WindowClass window_class, WindowClass parent_class, uint32 flags,
00174 const NWidgetPart *nwid_parts, int16 nwid_length, HotkeyList *hotkeys = NULL);
00175
00176 ~WindowDesc();
00177
00178 WindowPosition default_pos;
00179 int16 default_width;
00180 int16 default_height;
00181 WindowClass cls;
00182 WindowClass parent_cls;
00183 const char *ini_key;
00184 uint32 flags;
00185 const NWidgetPart *nwid_parts;
00186 int16 nwid_length;
00187 HotkeyList *hotkeys;
00188
00189 bool pref_sticky;
00190 int16 pref_width;
00191 int16 pref_height;
00192
00193 int16 GetDefaultWidth() const { return this->pref_width != 0 ? this->pref_width : this->default_width; }
00194 int16 GetDefaultHeight() const { return this->pref_height != 0 ? this->pref_height : this->default_height; }
00195
00196 static void LoadFromConfig();
00197 static void SaveToConfig();
00198
00199 private:
00204 WindowDesc(const WindowDesc &other);
00205 };
00206
00210 enum WindowDefaultFlag {
00211 WDF_CONSTRUCTION = 1 << 0,
00212 WDF_MODAL = 1 << 1,
00213 WDF_NO_FOCUS = 1 << 2,
00214 };
00215
00219 struct ResizeInfo {
00220 uint step_width;
00221 uint step_height;
00222 };
00223
00225 enum SortButtonState {
00226 SBS_OFF,
00227 SBS_DOWN,
00228 SBS_UP,
00229 };
00230
00234 enum WindowFlags {
00235 WF_TIMEOUT = 1 << 0,
00236
00237 WF_DRAGGING = 1 << 3,
00238 WF_SIZING_RIGHT = 1 << 4,
00239 WF_SIZING_LEFT = 1 << 5,
00240 WF_SIZING = WF_SIZING_RIGHT | WF_SIZING_LEFT,
00241 WF_STICKY = 1 << 6,
00242 WF_DISABLE_VP_SCROLL = 1 << 7,
00243 WF_WHITE_BORDER = 1 << 8,
00244 WF_HIGHLIGHTED = 1 << 9,
00245 WF_CENTERED = 1 << 10,
00246 };
00247 DECLARE_ENUM_AS_BIT_SET(WindowFlags)
00248
00249 static const int TIMEOUT_DURATION = 7;
00250 static const int WHITE_BORDER_DURATION = 3;
00251
00259 struct ViewportData : ViewPort {
00260 VehicleID follow_vehicle;
00261 int32 scrollpos_x;
00262 int32 scrollpos_y;
00263 int32 dest_scrollpos_x;
00264 int32 dest_scrollpos_y;
00265 };
00266
00267 struct QueryString;
00268
00272 struct Window : ZeroedMemoryAllocator {
00273 protected:
00274 void InitializeData(WindowNumber window_number);
00275 void InitializePositionSize(int x, int y, int min_width, int min_height);
00276 void FindWindowPlacementAndResize(int def_width, int def_height);
00277
00278 SmallVector<int, 4> scheduled_invalidation_data;
00279
00280 public:
00281 Window(WindowDesc *desc);
00282
00283 virtual ~Window();
00284
00291 inline void *operator new[](size_t size)
00292 {
00293 NOT_REACHED();
00294 }
00295
00301 inline void operator delete(void *ptr)
00302 {
00303 }
00304
00305 WindowDesc *window_desc;
00306 WindowFlags flags;
00307 WindowClass window_class;
00308 WindowNumber window_number;
00309
00310 uint8 timeout_timer;
00311 uint8 white_border_timer;
00312
00313 int left;
00314 int top;
00315 int width;
00316 int height;
00317
00318 ResizeInfo resize;
00319
00320 Owner owner;
00321
00322 ViewportData *viewport;
00323 const NWidgetCore *nested_focus;
00324 SmallMap<int, QueryString*> querystrings;
00325 NWidgetBase *nested_root;
00326 NWidgetBase **nested_array;
00327 uint nested_array_size;
00328 NWidgetStacked *shade_select;
00329 Dimension unshaded_size;
00330
00331 int scrolling_scrollbar;
00332
00333 Window *parent;
00334 Window *z_front;
00335 Window *z_back;
00336
00337 template <class NWID>
00338 inline const NWID *GetWidget(uint widnum) const;
00339 template <class NWID>
00340 inline NWID *GetWidget(uint widnum);
00341
00342 const Scrollbar *GetScrollbar(uint widnum) const;
00343 Scrollbar *GetScrollbar(uint widnum);
00344
00345 const QueryString *GetQueryString(uint widnum) const;
00346 QueryString *GetQueryString(uint widnum);
00347
00348 virtual const char *GetFocusedText() const;
00349 virtual const char *GetCaret() const;
00350 virtual const char *GetMarkedText(size_t *length) const;
00351 virtual Point GetCaretPosition() const;
00352 virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
00353 virtual const char *GetTextCharacterAtPosition(const Point &pt) const;
00354
00355 void InitNested(WindowNumber number = 0);
00356 void CreateNestedTree(bool fill_nested = true);
00357 void FinishInitNested(WindowNumber window_number = 0);
00358
00362 inline void SetTimeout()
00363 {
00364 this->flags |= WF_TIMEOUT;
00365 this->timeout_timer = TIMEOUT_DURATION;
00366 }
00367
00371 inline void SetWhiteBorder()
00372 {
00373 this->flags |= WF_WHITE_BORDER;
00374 this->white_border_timer = WHITE_BORDER_DURATION;
00375 }
00376
00377 void DisableAllWidgetHighlight();
00378 void SetWidgetHighlight(byte widget_index, TextColour highlighted_colour);
00379 bool IsWidgetHighlighted(byte widget_index) const;
00380
00388 inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00389 {
00390 assert(widget_index < this->nested_array_size);
00391 if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
00392 }
00393
00398 inline void DisableWidget(byte widget_index)
00399 {
00400 SetWidgetDisabledState(widget_index, true);
00401 }
00402
00407 inline void EnableWidget(byte widget_index)
00408 {
00409 SetWidgetDisabledState(widget_index, false);
00410 }
00411
00417 inline bool IsWidgetDisabled(byte widget_index) const
00418 {
00419 assert(widget_index < this->nested_array_size);
00420 return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
00421 }
00422
00428 inline bool IsWidgetFocused(byte widget_index) const
00429 {
00430 return this->nested_focus != NULL && this->nested_focus->index == widget_index;
00431 }
00432
00439 inline bool IsWidgetGloballyFocused(byte widget_index) const
00440 {
00441 return _focused_window == this && IsWidgetFocused(widget_index);
00442 }
00443
00449 inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00450 {
00451 assert(widget_index < this->nested_array_size);
00452 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
00453 }
00454
00459 inline void ToggleWidgetLoweredState(byte widget_index)
00460 {
00461 assert(widget_index < this->nested_array_size);
00462 bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00463 this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
00464 }
00465
00470 inline void LowerWidget(byte widget_index)
00471 {
00472 SetWidgetLoweredState(widget_index, true);
00473 }
00474
00479 inline void RaiseWidget(byte widget_index)
00480 {
00481 SetWidgetLoweredState(widget_index, false);
00482 }
00483
00489 inline bool IsWidgetLowered(byte widget_index) const
00490 {
00491 assert(widget_index < this->nested_array_size);
00492 return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00493 }
00494
00495 void UnfocusFocusedWidget();
00496 bool SetFocusedWidget(int widget_index);
00497
00498 EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode);
00499 virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end);
00500
00501 void HandleButtonClick(byte widget);
00502 int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;
00503
00504 void RaiseButtons(bool autoraise = false);
00505 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00506 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00507 void SetWidgetDirty(byte widget_index) const;
00508
00509 void DrawWidgets() const;
00510 void DrawViewport() const;
00511 void DrawSortButtonState(int widget, SortButtonState state) const;
00512
00513 void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00514
00515 void SetDirty() const;
00516 void ReInit(int rx = 0, int ry = 0);
00517
00519 inline bool IsShaded() const
00520 {
00521 return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL;
00522 }
00523
00524 void SetShaded(bool make_shaded);
00525
00526 void InvalidateData(int data = 0, bool gui_scope = true);
00527 void ProcessScheduledInvalidations();
00528 void ProcessHighlightedInvalidations();
00529
00530
00531
00536 virtual void OnInit() { }
00537
00538 virtual void ApplyDefaults();
00539
00547 virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number);
00548
00553 virtual void OnPaint()
00554 {
00555 this->DrawWidgets();
00556 }
00557
00564 virtual void DrawWidget(const Rect &r, int widget) const {}
00565
00578 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {}
00579
00586 virtual void SetStringParameters(int widget) const {}
00587
00591 virtual void OnFocus() {}
00592
00593 virtual void OnFocusLost();
00594
00602 virtual EventState OnKeyPress(WChar key, uint16 keycode) { return ES_NOT_HANDLED; }
00603
00604 virtual EventState OnHotkey(int hotkey);
00605
00611 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00612
00613
00620 virtual void OnClick(Point pt, int widget, int click_count) {}
00621
00629 virtual bool OnRightClick(Point pt, int widget) { return false; }
00630
00636 virtual void OnHover(Point pt, int widget) {}
00637
00643 virtual void OnMouseDrag(Point pt, int widget) {}
00644
00650 virtual void OnDragDrop(Point pt, int widget) {}
00651
00656 virtual void OnScroll(Point delta) {}
00657
00664 virtual void OnMouseOver(Point pt, int widget) {}
00665
00670 virtual void OnMouseWheel(int wheel) {}
00671
00672
00676 virtual void OnMouseLoop() {}
00677
00681 virtual void OnTick() {}
00682
00686 virtual void OnHundredthTick() {}
00687
00691 virtual void OnTimeout() {}
00692
00693
00698 virtual void OnResize() {}
00699
00705 virtual void OnDropdownSelect(int widget, int index) {}
00706
00707 virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close);
00708
00713 virtual void OnEditboxChanged(int widget) {}
00714
00721 virtual void OnQueryTextFinished(char *str) {}
00722
00728 virtual void OnInvalidateData(int data = 0, bool gui_scope = true) {}
00729
00736 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00737
00743 virtual bool OnVehicleSelect(const struct Vehicle *v) { return false; }
00744
00748 virtual void OnPlaceObjectAbort() {}
00749
00750
00758 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00759
00769 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00770
00778 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00779
00780
00781
00786 virtual bool IsNewGRFInspectable() const { return false; }
00787
00794 virtual void ShowNewGRFInspectWindow() const { NOT_REACHED(); }
00795 };
00796
00803 template <class NWID>
00804 inline NWID *Window::GetWidget(uint widnum)
00805 {
00806 if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL;
00807 NWID *nwid = dynamic_cast<NWID *>(this->nested_array[widnum]);
00808 assert(nwid != NULL);
00809 return nwid;
00810 }
00811
00813 template <>
00814 inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
00815 {
00816 if (widnum >= this->nested_array_size) return NULL;
00817 return this->nested_array[widnum];
00818 }
00819
00826 template <class NWID>
00827 inline const NWID *Window::GetWidget(uint widnum) const
00828 {
00829 return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
00830 }
00831
00832
00836 class PickerWindowBase : public Window {
00837
00838 public:
00839 PickerWindowBase(WindowDesc *desc, Window *parent) : Window(desc)
00840 {
00841 this->parent = parent;
00842 }
00843
00844 virtual ~PickerWindowBase();
00845 };
00846
00847 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00848 Window *FindWindowFromPt(int x, int y);
00849
00856 template <typename Wcls>
00857 Wcls *AllocateWindowDescFront(WindowDesc *desc, int window_number)
00858 {
00859 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00860 return new Wcls(desc, window_number);
00861 }
00862
00863 void RelocateAllWindows(int neww, int newh);
00864
00865
00866 enum TooltipCloseCondition {
00867 TCC_RIGHT_CLICK,
00868 TCC_LEFT_CLICK,
00869 TCC_HOVER,
00870 };
00871
00872 void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = NULL, TooltipCloseCondition close_tooltip = TCC_HOVER);
00873
00874
00875 int GetWidgetFromPos(const Window *w, int x, int y);
00876
00878 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00879 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00880 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00881 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00882
00883 extern Point _cursorpos_drag_start;
00884
00885 extern int _scrollbar_start_pos;
00886 extern int _scrollbar_size;
00887 extern byte _scroller_click_timeout;
00888
00889 extern bool _scrolling_viewport;
00890 extern bool _mouse_hovering;
00891
00893 enum SpecialMouseMode {
00894 WSM_NONE,
00895 WSM_DRAGDROP,
00896 WSM_SIZING,
00897 WSM_PRESIZE,
00898 };
00899 extern SpecialMouseMode _special_mouse_mode;
00900
00901 void SetFocusedWindow(Window *w);
00902
00903 void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y);
00904
00905 #endif