00001
00002
00005 #ifndef WINDOW_GUI_H
00006 #define WINDOW_GUI_H
00007
00008 #include "core/geometry_type.hpp"
00009 #include "vehicle_type.h"
00010 #include "viewport_type.h"
00011 #include "company_type.h"
00012 #include "core/alloc_type.hpp"
00013 #include "window_type.h"
00014 #include "tile_type.h"
00015 #include "widget_type.h"
00016
00020 enum FrameFlags {
00021 FR_NONE = 0,
00022 FR_TRANSPARENT = 1 << 0,
00023 FR_BORDERONLY = 1 << 4,
00024 FR_LOWERED = 1 << 5,
00025 FR_DARKENED = 1 << 6,
00026 };
00027
00028 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
00029
00030
00031 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
00032
00033
00034 extern Window *_z_front_window;
00035 extern Window *_z_back_window;
00036 extern Window *_focused_window;
00037
00041 struct WindowDesc {
00042 int16 left;
00043 int16 top;
00044 int16 minimum_width;
00045 int16 minimum_height;
00046 int16 default_width;
00047 int16 default_height;
00048 WindowClass cls;
00049 WindowClass parent_cls;
00050 uint32 flags;
00051 const Widget *widgets;
00052 };
00053
00057 enum WindowDefaultFlag {
00058 WDF_STD_TOOLTIPS = 1 << 0,
00059 WDF_DEF_WIDGET = 1 << 1,
00060 WDF_STD_BTN = 1 << 2,
00061 WDF_CONSTRUCTION = 1 << 3,
00062
00063 WDF_UNCLICK_BUTTONS = 1 << 4,
00064 WDF_STICKY_BUTTON = 1 << 5,
00065 WDF_RESIZABLE = 1 << 6,
00066 WDF_MODAL = 1 << 7,
00067
00068 WDF_NO_FOCUS = 1 << 8,
00069 };
00070
00074 enum WindowDefaultPosition {
00075 WDP_AUTO = -1,
00076 WDP_CENTER = -2,
00077 WDP_ALIGN_TBR = -3,
00078 WDP_ALIGN_TBL = -4,
00079 };
00080
00084 struct Scrollbar {
00085 uint16 count;
00086 uint16 cap;
00087 uint16 pos;
00088 };
00089
00093 struct ResizeInfo {
00094 uint width;
00095 uint height;
00096 uint step_width;
00097 uint step_height;
00098 };
00099
00100 enum SortButtonState {
00101 SBS_OFF,
00102 SBS_DOWN,
00103 SBS_UP,
00104 };
00105
00109 struct ViewportData : ViewPort {
00110 VehicleID follow_vehicle;
00111 int32 scrollpos_x;
00112 int32 scrollpos_y;
00113 int32 dest_scrollpos_x;
00114 int32 dest_scrollpos_y;
00115 };
00116
00120 struct Window : ZeroedMemoryAllocator {
00122 enum EventState {
00123 ES_HANDLED,
00124 ES_NOT_HANDLED,
00125 };
00126
00127 protected:
00128 void Initialize(int x, int y, int min_width, int min_height,
00129 WindowClass cls, const Widget *widget, int window_number);
00130 void FindWindowPlacementAndResize(int def_width, int def_height);
00131 void FindWindowPlacementAndResize(const WindowDesc *desc);
00132
00133 public:
00134 Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
00135 Window(const WindowDesc *desc, WindowNumber number = 0);
00136
00137 virtual ~Window();
00138
00139
00140 FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
00141
00142 FORCEINLINE void operator delete(void *ptr, size_t size) {}
00143
00144 uint16 flags4;
00145 WindowClass window_class;
00146 WindowNumber window_number;
00147
00148 int left;
00149 int top;
00150 int width;
00151 int height;
00152
00153 Scrollbar hscroll;
00154 Scrollbar vscroll;
00155 Scrollbar vscroll2;
00156 ResizeInfo resize;
00157
00158 Owner owner;
00159
00160 ViewportData *viewport;
00161 Widget *widget;
00162 uint widget_count;
00163 uint32 desc_flags;
00164 const Widget *focused_widget;
00165
00166 Window *parent;
00167 Window *z_front;
00168 Window *z_back;
00169
00177 inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00178 {
00179 assert(widget_index < this->widget_count);
00180 SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00181 }
00182
00187 inline void DisableWidget(byte widget_index)
00188 {
00189 SetWidgetDisabledState(widget_index, true);
00190 }
00191
00196 inline void EnableWidget(byte widget_index)
00197 {
00198 SetWidgetDisabledState(widget_index, false);
00199 }
00200
00206 inline bool IsWidgetDisabled(byte widget_index) const
00207 {
00208 assert(widget_index < this->widget_count);
00209 return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00210 }
00211
00219 inline void SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00220 {
00221 assert(widget_index < this->widget_count);
00222 SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00223 }
00224
00229 inline void HideWidget(byte widget_index)
00230 {
00231 SetWidgetHiddenState(widget_index, true);
00232 }
00233
00238 inline void ShowWidget(byte widget_index)
00239 {
00240 SetWidgetHiddenState(widget_index, false);
00241 }
00242
00248 inline bool IsWidgetHidden(byte widget_index) const
00249 {
00250 assert(widget_index < this->widget_count);
00251 return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00252 }
00253
00259 inline void SetFocusedWidget(byte widget_index)
00260 {
00261 if (widget_index < this->widget_count) {
00262
00263 if (this->focused_widget && this->focused_widget - this->widget != widget_index) {
00264 this->InvalidateWidget(this->focused_widget - this->widget);
00265 }
00266 this->focused_widget = &this->widget[widget_index];
00267 }
00268 }
00269
00275 inline bool IsWidgetFocused(byte widget_index) const
00276 {
00277 return this->focused_widget == &this->widget[widget_index];
00278 }
00279
00286 inline bool IsWidgetGloballyFocused(byte widget_index) const
00287 {
00288 return _focused_window == this && IsWidgetFocused(widget_index);
00289 }
00290
00296 inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00297 {
00298 assert(widget_index < this->widget_count);
00299 SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00300 }
00301
00306 inline void ToggleWidgetLoweredState(byte widget_index)
00307 {
00308 assert(widget_index < this->widget_count);
00309 ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00310 }
00311
00316 inline void LowerWidget(byte widget_index)
00317 {
00318 SetWidgetLoweredState(widget_index, true);
00319 }
00320
00325 inline void RaiseWidget(byte widget_index)
00326 {
00327 SetWidgetLoweredState(widget_index, false);
00328 }
00329
00335 inline bool IsWidgetLowered(byte widget_index) const
00336 {
00337 assert(widget_index < this->widget_count);
00338 return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00339 }
00340
00346 inline void AlignWidgetRight(byte widget_index_a, byte widget_index_b)
00347 {
00348 assert(widget_index_a < this->widget_count);
00349 assert(widget_index_b < this->widget_count);
00350 int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
00351 this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
00352 this->widget[widget_index_a].left = this->widget[widget_index_a].right - w;
00353 }
00354
00360 inline int GetWidgetWidth(byte widget_index) const
00361 {
00362 assert(widget_index < this->widget_count);
00363 return this->widget[widget_index].right - this->widget[widget_index].left + 1;
00364 }
00365
00366 void HandleButtonClick(byte widget);
00367 bool HasWidgetOfType(WidgetType widget_type) const;
00368
00369 void RaiseButtons();
00370 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00371 void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00372 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00373 void InvalidateWidget(byte widget_index) const;
00374
00375 void DrawWidgets() const;
00376 void DrawViewport() const;
00377 void DrawSortButtonState(int widget, SortButtonState state) const;
00378
00379 void DeleteChildWindows() const;
00380
00381 void SetDirty() const;
00382
00383
00384
00388 virtual void OnPaint() {}
00389
00393 virtual void OnFocus() {}
00394
00398 virtual void OnFocusLost() {}
00399
00407 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00408
00414 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00415
00416
00422 virtual void OnClick(Point pt, int widget) {}
00423
00429 virtual void OnDoubleClick(Point pt, int widget) {}
00430
00436 virtual void OnRightClick(Point pt, int widget) {}
00437
00443 virtual void OnDragDrop(Point pt, int widget) {}
00444
00449 virtual void OnScroll(Point delta) {}
00450
00457 virtual void OnMouseOver(Point pt, int widget) {}
00458
00463 virtual void OnMouseWheel(int wheel) {}
00464
00465
00469 virtual void OnMouseLoop() {}
00470
00474 virtual void OnTick() {}
00475
00479 virtual void OnHundredthTick() {}
00480
00484 virtual void OnTimeout() {}
00485
00486
00492 virtual void OnResize(Point new_size, Point delta) {}
00493
00499 virtual void OnDropdownSelect(int widget, int index) {}
00500
00506 virtual void OnQueryTextFinished(char *str) {}
00507
00512 virtual void OnInvalidateData(int data = 0) {}
00513
00514
00521 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00522
00526 virtual void OnPlaceObjectAbort() {}
00527
00528
00536 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00537
00547 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00548
00556 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00557
00558
00559 };
00560
00564 class PickerWindowBase : public Window {
00565
00566 public:
00567 PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
00568 {
00569 this->parent = parent;
00570 };
00571
00572 virtual ~PickerWindowBase();
00573 };
00574
00578 enum WindowFlags {
00579 WF_TIMEOUT_TRIGGER = 1,
00580 WF_TIMEOUT_BEGIN = 7,
00581 WF_TIMEOUT_MASK = 7,
00582 WF_DRAGGING = 1 << 3,
00583 WF_SCROLL_UP = 1 << 4,
00584 WF_SCROLL_DOWN = 1 << 5,
00585 WF_SCROLL_MIDDLE = 1 << 6,
00586 WF_HSCROLL = 1 << 7,
00587 WF_SIZING = 1 << 8,
00588 WF_STICKY = 1 << 9,
00589
00590 WF_DISABLE_VP_SCROLL = 1 << 10,
00591
00592 WF_WHITE_BORDER_ONE = 1 << 11,
00593 WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00594 WF_SCROLL2 = 1 << 13,
00595 };
00596
00597 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00598 Window *FindWindowFromPt(int x, int y);
00599
00606 template <typename Wcls>
00607 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00608 {
00609 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00610 return new Wcls(desc, window_number);
00611 }
00612
00613 void RelocateAllWindows(int neww, int newh);
00614
00615
00616 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00617
00618
00619 int GetWidgetFromPos(const Window *w, int x, int y);
00620
00622 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00623 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00624 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00625 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00626
00627 extern Point _cursorpos_drag_start;
00628
00629 extern int _scrollbar_start_pos;
00630 extern int _scrollbar_size;
00631 extern byte _scroller_click_timeout;
00632
00633 extern bool _scrolling_scrollbar;
00634 extern bool _scrolling_viewport;
00635
00636 extern byte _special_mouse_mode;
00637 enum SpecialMouseMode {
00638 WSM_NONE = 0,
00639 WSM_DRAGDROP = 1,
00640 WSM_SIZING = 2,
00641 WSM_PRESIZE = 3,
00642 };
00643
00644 Window *GetCallbackWnd();
00645
00646 void SetFocusedWindow(Window *w);
00647 const Widget *GetGloballyFocusedWidget();
00648 bool EditBoxInGlobalFocus();
00649
00650 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00651
00652 void ResizeButtons(Window *w, byte left, byte right);
00653
00654 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
00655
00656 void SetVScrollCount(Window *w, int num);
00657 void SetVScroll2Count(Window *w, int num);
00658 void SetHScrollCount(Window *w, int num);
00659
00660 #endif