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
00036 struct WindowDesc {
00037 int16 left;
00038 int16 top;
00039 int16 minimum_width;
00040 int16 minimum_height;
00041 int16 default_width;
00042 int16 default_height;
00043 WindowClass cls;
00044 WindowClass parent_cls;
00045 uint32 flags;
00046 const Widget *widgets;
00047 };
00048
00052 enum WindowDefaultFlag {
00053 WDF_STD_TOOLTIPS = 1 << 0,
00054 WDF_DEF_WIDGET = 1 << 1,
00055 WDF_STD_BTN = 1 << 2,
00056 WDF_CONSTRUCTION = 1 << 3,
00057
00058 WDF_UNCLICK_BUTTONS = 1 << 4,
00059 WDF_STICKY_BUTTON = 1 << 5,
00060 WDF_RESIZABLE = 1 << 6,
00061 WDF_MODAL = 1 << 7,
00062
00063 WDF_NO_FOCUS = 1 << 8,
00064 };
00065
00069 enum WindowDefaultPosition {
00070 WDP_AUTO = -1,
00071 WDP_CENTER = -2,
00072 WDP_ALIGN_TBR = -3,
00073 WDP_ALIGN_TBL = -4,
00074 };
00075
00079 struct Scrollbar {
00080 uint16 count;
00081 uint16 cap;
00082 uint16 pos;
00083 };
00084
00088 struct ResizeInfo {
00089 uint width;
00090 uint height;
00091 uint step_width;
00092 uint step_height;
00093 };
00094
00095 enum SortButtonState {
00096 SBS_OFF,
00097 SBS_DOWN,
00098 SBS_UP,
00099 };
00100
00104 struct ViewportData : ViewPort {
00105 VehicleID follow_vehicle;
00106 int32 scrollpos_x;
00107 int32 scrollpos_y;
00108 int32 dest_scrollpos_x;
00109 int32 dest_scrollpos_y;
00110 };
00111
00115 struct Window : ZeroedMemoryAllocator {
00117 enum EventState {
00118 ES_HANDLED,
00119 ES_NOT_HANDLED,
00120 };
00121
00122 protected:
00123 void Initialize(int x, int y, int min_width, int min_height,
00124 WindowClass cls, const Widget *widget, int window_number);
00125 void FindWindowPlacementAndResize(int def_width, int def_height);
00126 void FindWindowPlacementAndResize(const WindowDesc *desc);
00127
00128 public:
00129 Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
00130 Window(const WindowDesc *desc, WindowNumber number = 0);
00131
00132 virtual ~Window();
00133
00134
00135 FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
00136
00137 FORCEINLINE void operator delete(void *ptr, size_t size) {}
00138
00139 uint16 flags4;
00140 WindowClass window_class;
00141 WindowNumber window_number;
00142
00143 int left;
00144 int top;
00145 int width;
00146 int height;
00147
00148 Scrollbar hscroll;
00149 Scrollbar vscroll;
00150 Scrollbar vscroll2;
00151 ResizeInfo resize;
00152
00153 Owner owner;
00154
00155 ViewportData *viewport;
00156 Widget *widget;
00157 uint widget_count;
00158 uint32 desc_flags;
00159 const Widget *focused_widget;
00160
00161 Window *parent;
00162 Window *z_front;
00163 Window *z_back;
00164
00165 void HandleButtonClick(byte widget);
00166
00167 void SetWidgetDisabledState(byte widget_index, bool disab_stat);
00168 void DisableWidget(byte widget_index);
00169 void EnableWidget(byte widget_index);
00170 bool IsWidgetDisabled(byte widget_index) const;
00171 void SetWidgetHiddenState(byte widget_index, bool hidden_stat);
00172 void HideWidget(byte widget_index);
00173 void ShowWidget(byte widget_index);
00174 bool IsWidgetHidden(byte widget_index) const;
00175 void SetFocusedWidget(byte widget_index);
00176 bool IsWidgetGloballyFocused(byte widget_index) const;
00177 bool IsWidgetFocused(byte widget_index) const;
00178 void SetWidgetLoweredState(byte widget_index, bool lowered_stat);
00179 void ToggleWidgetLoweredState(byte widget_index);
00180 void LowerWidget(byte widget_index);
00181 void RaiseWidget(byte widget_index);
00182 bool IsWidgetLowered(byte widget_index) const;
00183 void AlignWidgetRight(byte widget_index_a, byte widget_index_b);
00184 int GetWidgetWidth(byte widget_index) const;
00185 bool HasWidgetOfType(WidgetType widget_type) const;
00186
00187 void RaiseButtons();
00188 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00189 void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00190 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00191 void InvalidateWidget(byte widget_index) const;
00192
00193 void DrawWidgets() const;
00194 void DrawViewport() const;
00195 void DrawSortButtonState(int widget, SortButtonState state) const;
00196
00197 void DeleteChildWindows() const;
00198
00199 void SetDirty() const;
00200
00201
00202
00206 virtual void OnPaint() {}
00207
00211 virtual void OnFocus() {}
00212
00216 virtual void OnFocusLost() {}
00217
00225 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00226
00232 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00233
00234
00240 virtual void OnClick(Point pt, int widget) {}
00241
00247 virtual void OnDoubleClick(Point pt, int widget) {}
00248
00254 virtual void OnRightClick(Point pt, int widget) {}
00255
00261 virtual void OnDragDrop(Point pt, int widget) {}
00262
00267 virtual void OnScroll(Point delta) {}
00268
00275 virtual void OnMouseOver(Point pt, int widget) {}
00276
00281 virtual void OnMouseWheel(int wheel) {}
00282
00283
00287 virtual void OnMouseLoop() {}
00288
00292 virtual void OnTick() {}
00293
00297 virtual void OnHundredthTick() {}
00298
00302 virtual void OnTimeout() {}
00303
00304
00310 virtual void OnResize(Point new_size, Point delta) {}
00311
00317 virtual void OnDropdownSelect(int widget, int index) {}
00318
00324 virtual void OnQueryTextFinished(char *str) {}
00325
00330 virtual void OnInvalidateData(int data = 0) {}
00331
00332
00339 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00340
00344 virtual void OnPlaceObjectAbort() {}
00345
00346
00354 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00355
00365 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00366
00374 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00375
00376
00377 };
00378
00382 class PickerWindowBase : public Window {
00383
00384 public:
00385 PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
00386 {
00387 this->parent = parent;
00388 };
00389
00390 virtual ~PickerWindowBase();
00391 };
00392
00396 enum WindowFlags {
00397 WF_TIMEOUT_TRIGGER = 1,
00398 WF_TIMEOUT_BEGIN = 7,
00399 WF_TIMEOUT_MASK = 7,
00400 WF_DRAGGING = 1 << 3,
00401 WF_SCROLL_UP = 1 << 4,
00402 WF_SCROLL_DOWN = 1 << 5,
00403 WF_SCROLL_MIDDLE = 1 << 6,
00404 WF_HSCROLL = 1 << 7,
00405 WF_SIZING = 1 << 8,
00406 WF_STICKY = 1 << 9,
00407
00408 WF_DISABLE_VP_SCROLL = 1 << 10,
00409
00410 WF_WHITE_BORDER_ONE = 1 << 11,
00411 WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00412 WF_SCROLL2 = 1 << 13,
00413 };
00414
00415 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00416 Window *FindWindowFromPt(int x, int y);
00417
00424 template <typename Wcls>
00425 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00426 {
00427 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00428 return new Wcls(desc, window_number);
00429 }
00430
00431 void RelocateAllWindows(int neww, int newh);
00432
00433
00434 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00435
00436
00437 int GetWidgetFromPos(const Window *w, int x, int y);
00438
00439
00440 extern Window *_z_front_window;
00441 extern Window *_z_back_window;
00442 extern Window *_focused_window;
00443
00445 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00446 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00447 #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00448 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00449
00450 extern Point _cursorpos_drag_start;
00451
00452 extern int _scrollbar_start_pos;
00453 extern int _scrollbar_size;
00454 extern byte _scroller_click_timeout;
00455
00456 extern bool _scrolling_scrollbar;
00457 extern bool _scrolling_viewport;
00458
00459 extern byte _special_mouse_mode;
00460 enum SpecialMouseMode {
00461 WSM_NONE = 0,
00462 WSM_DRAGDROP = 1,
00463 WSM_SIZING = 2,
00464 WSM_PRESIZE = 3,
00465 };
00466
00467 Window *GetCallbackWnd();
00468
00469 void SetFocusedWindow(Window *w);
00470 const Widget *GetGloballyFocusedWidget();
00471 bool EditBoxInGlobalFocus();
00472
00473 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00474
00475 void ResizeButtons(Window *w, byte left, byte right);
00476
00477 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
00478
00479 void SetVScrollCount(Window *w, int num);
00480 void SetVScroll2Count(Window *w, int num);
00481 void SetHScrollCount(Window *w, int num);
00482
00483
00491 inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat)
00492 {
00493 assert(widget_index < this->widget_count);
00494 SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00495 }
00496
00501 inline void Window::DisableWidget(byte widget_index)
00502 {
00503 SetWidgetDisabledState(widget_index, true);
00504 }
00505
00510 inline void Window::EnableWidget(byte widget_index)
00511 {
00512 SetWidgetDisabledState(widget_index, false);
00513 }
00514
00520 inline bool Window::IsWidgetDisabled(byte widget_index) const
00521 {
00522 assert(widget_index < this->widget_count);
00523 return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00524 }
00525
00533 inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00534 {
00535 assert(widget_index < this->widget_count);
00536 SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00537 }
00538
00543 inline void Window::HideWidget(byte widget_index)
00544 {
00545 SetWidgetHiddenState(widget_index, true);
00546 }
00547
00552 inline void Window::ShowWidget(byte widget_index)
00553 {
00554 SetWidgetHiddenState(widget_index, false);
00555 }
00556
00562 inline bool Window::IsWidgetHidden(byte widget_index) const
00563 {
00564 assert(widget_index < this->widget_count);
00565 return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00566 }
00567
00573 inline void Window::SetFocusedWidget(byte widget_index)
00574 {
00575 if (widget_index < this->widget_count) {
00576
00577 if (this->focused_widget && this->focused_widget - this->widget != widget_index) {
00578 this->InvalidateWidget(this->focused_widget - this->widget);
00579 }
00580 this->focused_widget = &this->widget[widget_index];
00581 }
00582 }
00583
00590 inline bool Window::IsWidgetGloballyFocused(byte widget_index) const
00591 {
00592 return _focused_window == this && IsWidgetFocused(widget_index);
00593 }
00594
00600 inline bool Window::IsWidgetFocused(byte widget_index) const
00601 {
00602 return this->focused_widget == &this->widget[widget_index];
00603 }
00604
00610 inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00611 {
00612 assert(widget_index < this->widget_count);
00613 SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00614 }
00615
00620 inline void Window::ToggleWidgetLoweredState(byte widget_index)
00621 {
00622 assert(widget_index < this->widget_count);
00623 ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00624 }
00625
00630 inline void Window::LowerWidget(byte widget_index)
00631 {
00632 SetWidgetLoweredState(widget_index, true);
00633 }
00634
00639 inline void Window::RaiseWidget(byte widget_index)
00640 {
00641 SetWidgetLoweredState(widget_index, false);
00642 }
00643
00649 inline bool Window::IsWidgetLowered(byte widget_index) const
00650 {
00651 assert(widget_index < this->widget_count);
00652 return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00653 }
00654
00660 inline void Window::AlignWidgetRight(byte widget_index_a, byte widget_index_b)
00661 {
00662 assert(widget_index_a < this->widget_count);
00663 assert(widget_index_b < this->widget_count);
00664 int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
00665 this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
00666 this->widget[widget_index_a].left = this->widget[widget_index_a].right - w;
00667 }
00668
00674 inline int Window::GetWidgetWidth(byte widget_index) const
00675 {
00676 assert(widget_index < this->widget_count);
00677 return this->widget[widget_index].right - this->widget[widget_index].left + 1;
00678 }
00679
00680 #endif