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 : ZeroedMemoryAllocator {
00042
00043 WindowDesc(int16 left, int16 top, int16 min_width, int16 min_height, int16 def_width, int16 def_height,
00044 WindowClass window_class, WindowClass parent_class, uint32 flags, const Widget *widgets);
00045
00046 int16 left;
00047 int16 top;
00048 int16 minimum_width;
00049 int16 minimum_height;
00050 int16 default_width;
00051 int16 default_height;
00052 WindowClass cls;
00053 WindowClass parent_cls;
00054 uint32 flags;
00055 const Widget *widgets;
00056 };
00057
00061 enum WindowDefaultFlag {
00062 WDF_STD_TOOLTIPS = 1 << 0,
00063 WDF_DEF_WIDGET = 1 << 1,
00064 WDF_STD_BTN = 1 << 2,
00065 WDF_CONSTRUCTION = 1 << 3,
00066
00067 WDF_UNCLICK_BUTTONS = 1 << 4,
00068 WDF_STICKY_BUTTON = 1 << 5,
00069 WDF_RESIZABLE = 1 << 6,
00070 WDF_MODAL = 1 << 7,
00071
00072 WDF_NO_FOCUS = 1 << 8,
00073 };
00074
00078 enum WindowDefaultPosition {
00079 WDP_AUTO = -1,
00080 WDP_CENTER = -2,
00081 WDP_ALIGN_TBR = -3,
00082 WDP_ALIGN_TBL = -4,
00083 };
00084
00088 struct Scrollbar {
00089 uint16 count;
00090 uint16 cap;
00091 uint16 pos;
00092 };
00093
00097 struct ResizeInfo {
00098 uint width;
00099 uint height;
00100 uint step_width;
00101 uint step_height;
00102 };
00103
00104 enum SortButtonState {
00105 SBS_OFF,
00106 SBS_DOWN,
00107 SBS_UP,
00108 };
00109
00113 struct ViewportData : ViewPort {
00114 VehicleID follow_vehicle;
00115 int32 scrollpos_x;
00116 int32 scrollpos_y;
00117 int32 dest_scrollpos_x;
00118 int32 dest_scrollpos_y;
00119 };
00120
00124 struct Window : ZeroedMemoryAllocator {
00126 enum EventState {
00127 ES_HANDLED,
00128 ES_NOT_HANDLED,
00129 };
00130
00131 protected:
00132 void Initialize(int x, int y, int min_width, int min_height,
00133 WindowClass cls, const Widget *widget, int window_number);
00134 void FindWindowPlacementAndResize(int def_width, int def_height);
00135 void FindWindowPlacementAndResize(const WindowDesc *desc);
00136
00137 public:
00138 Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
00139 Window(const WindowDesc *desc, WindowNumber number = 0);
00140
00141 virtual ~Window();
00142
00149 FORCEINLINE void *operator new[](size_t size)
00150 {
00151 NOT_REACHED();
00152 }
00153
00159 FORCEINLINE void operator delete(void *ptr)
00160 {
00161 }
00162
00163 uint16 flags4;
00164 WindowClass window_class;
00165 WindowNumber window_number;
00166
00167 int left;
00168 int top;
00169 int width;
00170 int height;
00171
00172 Scrollbar hscroll;
00173 Scrollbar vscroll;
00174 Scrollbar vscroll2;
00175 ResizeInfo resize;
00176
00177 Owner owner;
00178
00179 ViewportData *viewport;
00180 Widget *widget;
00181 uint widget_count;
00182 uint32 desc_flags;
00183 const Widget *focused_widget;
00184
00185 Window *parent;
00186 Window *z_front;
00187 Window *z_back;
00188
00196 inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00197 {
00198 assert(widget_index < this->widget_count);
00199 SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00200 }
00201
00206 inline void DisableWidget(byte widget_index)
00207 {
00208 SetWidgetDisabledState(widget_index, true);
00209 }
00210
00215 inline void EnableWidget(byte widget_index)
00216 {
00217 SetWidgetDisabledState(widget_index, false);
00218 }
00219
00225 inline bool IsWidgetDisabled(byte widget_index) const
00226 {
00227 assert(widget_index < this->widget_count);
00228 return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00229 }
00230
00238 inline void SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00239 {
00240 assert(widget_index < this->widget_count);
00241 SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00242 }
00243
00248 inline void HideWidget(byte widget_index)
00249 {
00250 SetWidgetHiddenState(widget_index, true);
00251 }
00252
00257 inline void ShowWidget(byte widget_index)
00258 {
00259 SetWidgetHiddenState(widget_index, false);
00260 }
00261
00267 inline bool IsWidgetHidden(byte widget_index) const
00268 {
00269 assert(widget_index < this->widget_count);
00270 return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00271 }
00272
00278 inline void SetFocusedWidget(byte widget_index)
00279 {
00280 if (widget_index < this->widget_count) {
00281
00282 if (this->focused_widget && this->focused_widget - this->widget != widget_index) {
00283 this->InvalidateWidget(this->focused_widget - this->widget);
00284 }
00285 this->focused_widget = &this->widget[widget_index];
00286 }
00287 }
00288
00294 inline bool IsWidgetFocused(byte widget_index) const
00295 {
00296 return this->focused_widget == &this->widget[widget_index];
00297 }
00298
00305 inline bool IsWidgetGloballyFocused(byte widget_index) const
00306 {
00307 return _focused_window == this && IsWidgetFocused(widget_index);
00308 }
00309
00315 inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00316 {
00317 assert(widget_index < this->widget_count);
00318 SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00319 }
00320
00325 inline void ToggleWidgetLoweredState(byte widget_index)
00326 {
00327 assert(widget_index < this->widget_count);
00328 ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00329 }
00330
00335 inline void LowerWidget(byte widget_index)
00336 {
00337 SetWidgetLoweredState(widget_index, true);
00338 }
00339
00344 inline void RaiseWidget(byte widget_index)
00345 {
00346 SetWidgetLoweredState(widget_index, false);
00347 }
00348
00354 inline bool IsWidgetLowered(byte widget_index) const
00355 {
00356 assert(widget_index < this->widget_count);
00357 return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00358 }
00359
00365 inline void AlignWidgetRight(byte widget_index_a, byte widget_index_b)
00366 {
00367 assert(widget_index_a < this->widget_count);
00368 assert(widget_index_b < this->widget_count);
00369 int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
00370 this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
00371 this->widget[widget_index_a].left = this->widget[widget_index_a].right - w;
00372 }
00373
00379 inline int GetWidgetWidth(byte widget_index) const
00380 {
00381 assert(widget_index < this->widget_count);
00382 return this->widget[widget_index].right - this->widget[widget_index].left + 1;
00383 }
00384
00385 void HandleButtonClick(byte widget);
00386 bool HasWidgetOfType(WidgetType widget_type) const;
00387
00388 void RaiseButtons();
00389 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00390 void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00391 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00392 void InvalidateWidget(byte widget_index) const;
00393
00394 void DrawWidgets() const;
00395 void DrawViewport() const;
00396 void DrawSortButtonState(int widget, SortButtonState state) const;
00397
00398 void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00399
00400 void SetDirty() const;
00401
00402
00403
00407 virtual void OnPaint() {}
00408
00412 virtual void OnFocus() {}
00413
00417 virtual void OnFocusLost() {}
00418
00426 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00427
00433 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00434
00435
00441 virtual void OnClick(Point pt, int widget) {}
00442
00448 virtual void OnDoubleClick(Point pt, int widget) {}
00449
00455 virtual void OnRightClick(Point pt, int widget) {}
00456
00462 virtual void OnDragDrop(Point pt, int widget) {}
00463
00468 virtual void OnScroll(Point delta) {}
00469
00476 virtual void OnMouseOver(Point pt, int widget) {}
00477
00482 virtual void OnMouseWheel(int wheel) {}
00483
00484
00488 virtual void OnMouseLoop() {}
00489
00493 virtual void OnTick() {}
00494
00498 virtual void OnHundredthTick() {}
00499
00503 virtual void OnTimeout() {}
00504
00505
00511 virtual void OnResize(Point new_size, Point delta) {}
00512
00518 virtual void OnDropdownSelect(int widget, int index) {}
00519
00525 virtual void OnQueryTextFinished(char *str) {}
00526
00531 virtual void OnInvalidateData(int data = 0) {}
00532
00533
00540 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00541
00545 virtual void OnPlaceObjectAbort() {}
00546
00547
00555 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00556
00566 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00567
00575 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00576
00577
00578 };
00579
00583 class PickerWindowBase : public Window {
00584
00585 public:
00586 PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
00587 {
00588 this->parent = parent;
00589 };
00590
00591 virtual ~PickerWindowBase();
00592 };
00593
00597 enum WindowFlags {
00598 WF_TIMEOUT_TRIGGER = 1,
00599 WF_TIMEOUT_BEGIN = 7,
00600 WF_TIMEOUT_MASK = 7,
00601 WF_DRAGGING = 1 << 3,
00602 WF_SCROLL_UP = 1 << 4,
00603 WF_SCROLL_DOWN = 1 << 5,
00604 WF_SCROLL_MIDDLE = 1 << 6,
00605 WF_HSCROLL = 1 << 7,
00606 WF_SIZING = 1 << 8,
00607 WF_STICKY = 1 << 9,
00608
00609 WF_DISABLE_VP_SCROLL = 1 << 10,
00610
00611 WF_WHITE_BORDER_ONE = 1 << 11,
00612 WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00613 WF_SCROLL2 = 1 << 13,
00614 };
00615
00616 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00617 Window *FindWindowFromPt(int x, int y);
00618
00625 template <typename Wcls>
00626 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00627 {
00628 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00629 return new Wcls(desc, window_number);
00630 }
00631
00632 void RelocateAllWindows(int neww, int newh);
00633
00634
00635 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00636
00637
00638 int GetWidgetFromPos(const Window *w, int x, int y);
00639
00641 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00642 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00643 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00644 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00645
00646 extern Point _cursorpos_drag_start;
00647
00648 extern int _scrollbar_start_pos;
00649 extern int _scrollbar_size;
00650 extern byte _scroller_click_timeout;
00651
00652 extern bool _scrolling_scrollbar;
00653 extern bool _scrolling_viewport;
00654
00655 extern byte _special_mouse_mode;
00656 enum SpecialMouseMode {
00657 WSM_NONE = 0,
00658 WSM_DRAGDROP = 1,
00659 WSM_SIZING = 2,
00660 WSM_PRESIZE = 3,
00661 };
00662
00663 Window *GetCallbackWnd();
00664
00665 void SetFocusedWindow(Window *w);
00666 const Widget *GetGloballyFocusedWidget();
00667 bool EditBoxInGlobalFocus();
00668
00669 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00670
00671 void ResizeButtons(Window *w, byte left, byte right);
00672
00673 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
00674
00675 void SetVScrollCount(Window *w, int num);
00676 void SetVScroll2Count(Window *w, int num);
00677 void SetHScrollCount(Window *w, int num);
00678
00679 #endif