00001
00002
00005 #ifndef WINDOW_GUI_H
00006 #define WINDOW_GUI_H
00007
00008 #include "core/bitmath_func.hpp"
00009 #include "core/geometry_type.hpp"
00010 #include "vehicle_type.h"
00011 #include "viewport_type.h"
00012 #include "company_type.h"
00013 #include "strings_type.h"
00014 #include "core/alloc_type.hpp"
00015 #include "window_type.h"
00016 #include "tile_type.h"
00017
00021 static const int MAX_NUMBER_OF_WINDOWS = 25;
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 enum ResizeFlag {
00051 RESIZE_NONE = 0,
00052
00053 RESIZE_LEFT = 1,
00054 RESIZE_RIGHT = 2,
00055 RESIZE_TOP = 4,
00056 RESIZE_BOTTOM = 8,
00057
00058 RESIZE_LR = RESIZE_LEFT | RESIZE_RIGHT,
00059 RESIZE_RB = RESIZE_RIGHT | RESIZE_BOTTOM,
00060 RESIZE_TB = RESIZE_TOP | RESIZE_BOTTOM,
00061 RESIZE_LRB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_BOTTOM,
00062 RESIZE_LRTB = RESIZE_LEFT | RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
00063 RESIZE_RTB = RESIZE_RIGHT | RESIZE_TOP | RESIZE_BOTTOM,
00064
00065
00066
00067
00068
00069 WIDG_DISABLED = 4,
00070 WIDG_HIDDEN = 5,
00071 WIDG_LOWERED = 6,
00072 };
00073
00074 enum {
00075 WIDGET_LIST_END = -1,
00076 };
00077
00081 struct Widget {
00082 byte type;
00083 byte display_flags;
00084 byte color;
00085 int16 left;
00086 int16 right;
00087 int16 top;
00088 int16 bottom;
00089 uint16 data;
00090 StringID tooltips;
00091 };
00092
00096 enum FrameFlags {
00097 FR_NONE = 0,
00098 FR_TRANSPARENT = 1 << 0,
00099 FR_BORDERONLY = 1 << 4,
00100 FR_LOWERED = 1 << 5,
00101 FR_DARKENED = 1 << 6,
00102 };
00103
00104 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
00105
00106
00107 void DrawFrameRect(int left, int top, int right, int bottom, int color, FrameFlags flags);
00108
00112 struct WindowDesc {
00113 int16 left;
00114 int16 top;
00115 int16 minimum_width;
00116 int16 minimum_height;
00117 int16 default_width;
00118 int16 default_height;
00119 WindowClass cls;
00120 WindowClass parent_cls;
00121 uint32 flags;
00122 const Widget *widgets;
00123 };
00124
00128 enum WindowDefaultFlag {
00129 WDF_STD_TOOLTIPS = 1 << 0,
00130 WDF_DEF_WIDGET = 1 << 1,
00131 WDF_STD_BTN = 1 << 2,
00132
00133 WDF_UNCLICK_BUTTONS = 1 << 4,
00134 WDF_STICKY_BUTTON = 1 << 5,
00135 WDF_RESIZABLE = 1 << 6,
00136 WDF_MODAL = 1 << 7,
00137 };
00138
00142 enum WindowDefaultPosition {
00143 WDP_AUTO = -1,
00144 WDP_CENTER = -2,
00145 WDP_ALIGN_TBR = -3,
00146 WDP_ALIGN_TBL = -4,
00147 };
00148
00152 struct Scrollbar {
00153 uint16 count;
00154 uint16 cap;
00155 uint16 pos;
00156 };
00157
00161 struct ResizeInfo {
00162 uint width;
00163 uint height;
00164 uint step_width;
00165 uint step_height;
00166 };
00167
00168 enum SortButtonState {
00169 SBS_OFF,
00170 SBS_DOWN,
00171 SBS_UP,
00172 };
00173
00177 struct ViewportData : ViewPort {
00178 VehicleID follow_vehicle;
00179 int32 scrollpos_x;
00180 int32 scrollpos_y;
00181 int32 dest_scrollpos_x;
00182 int32 dest_scrollpos_y;
00183 };
00184
00188 struct Window : ZeroedMemoryAllocator {
00190 enum EventState {
00191 ES_HANDLED,
00192 ES_NOT_HANDLED,
00193 };
00194
00195 protected:
00196 void Initialize(int x, int y, int min_width, int min_height,
00197 WindowClass cls, const Widget *widget, int window_number);
00198 void FindWindowPlacementAndResize(int def_width, int def_height);
00199 void FindWindowPlacementAndResize(const WindowDesc *desc);
00200
00201 public:
00202 Window(int x, int y, int width, int height, WindowClass cls, const Widget *widget);
00203 Window(const WindowDesc *desc, WindowNumber number = 0);
00204
00205 virtual ~Window();
00206
00207 uint16 flags4;
00208 WindowClass window_class;
00209 WindowNumber window_number;
00210
00211 int left;
00212 int top;
00213 int width;
00214 int height;
00215
00216 Scrollbar hscroll;
00217 Scrollbar vscroll;
00218 Scrollbar vscroll2;
00219 ResizeInfo resize;
00220
00221 byte caption_color;
00222
00223 ViewportData *viewport;
00224 Widget *widget;
00225 uint widget_count;
00226 uint32 desc_flags;
00227
00228 Window *parent;
00229
00230 void HandleButtonClick(byte widget);
00231
00232 void SetWidgetDisabledState(byte widget_index, bool disab_stat);
00233 void DisableWidget(byte widget_index);
00234 void EnableWidget(byte widget_index);
00235 bool IsWidgetDisabled(byte widget_index) const;
00236 void SetWidgetHiddenState(byte widget_index, bool hidden_stat);
00237 void HideWidget(byte widget_index);
00238 void ShowWidget(byte widget_index);
00239 bool IsWidgetHidden(byte widget_index) const;
00240 void SetWidgetLoweredState(byte widget_index, bool lowered_stat);
00241 void ToggleWidgetLoweredState(byte widget_index);
00242 void LowerWidget(byte widget_index);
00243 void RaiseWidget(byte widget_index);
00244 bool IsWidgetLowered(byte widget_index) const;
00245 void AlignWidgetRight(byte widget_index_a, byte widget_index_b);
00246 int GetWidgetWidth(byte widget_index) const;
00247
00248 void RaiseButtons();
00249 void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00250 void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
00251 void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00252 void InvalidateWidget(byte widget_index) const;
00253
00254 void DrawWidgets() const;
00255 void DrawViewport() const;
00256 void DrawSortButtonState(int widget, SortButtonState state) const;
00257
00258 void DeleteChildWindows() const;
00259
00260 void SetDirty() const;
00261
00262
00263
00267 virtual void OnPaint() {}
00268
00269
00277 virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00278
00284 virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00285
00286
00292 virtual void OnClick(Point pt, int widget) {}
00293
00299 virtual void OnDoubleClick(Point pt, int widget) {}
00300
00306 virtual void OnRightClick(Point pt, int widget) {}
00307
00313 virtual void OnDragDrop(Point pt, int widget) {}
00314
00319 virtual void OnScroll(Point delta) {}
00320
00327 virtual void OnMouseOver(Point pt, int widget) {}
00328
00333 virtual void OnMouseWheel(int wheel) {}
00334
00335
00339 virtual void OnMouseLoop() {}
00340
00344 virtual void OnTick() {}
00345
00349 virtual void OnHundredthTick() {}
00350
00354 virtual void OnTimeout() {}
00355
00356
00362 virtual void OnResize(Point new_size, Point delta) {}
00363
00369 virtual void OnDropdownSelect(int widget, int index) {}
00370
00376 virtual void OnQueryTextFinished(char *str) {}
00377
00382 virtual void OnInvalidateData(int data = 0) {}
00383
00384
00391 virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00392
00396 virtual void OnPlaceObjectAbort() {}
00397
00398
00406 virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00407
00417 virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00418
00426 virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00427
00428
00429 };
00430
00434 class PickerWindowBase : public Window {
00435
00436 public:
00437 PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
00438 {
00439 this->parent = parent;
00440 };
00441
00442 virtual ~PickerWindowBase();
00443 };
00444
00445
00446 enum WindowWidgetBehaviours {
00447 WWB_PUSHBUTTON = 1 << 5,
00448
00449 WWB_MASK = 0xE0,
00450 };
00451
00452
00456 enum WindowWidgetTypes {
00457 WWT_EMPTY,
00458
00459 WWT_PANEL,
00460 WWT_INSET,
00461 WWT_IMGBTN,
00462 WWT_IMGBTN_2,
00463
00464 WWT_TEXTBTN,
00465 WWT_TEXTBTN_2,
00466 WWT_LABEL,
00467 WWT_TEXT,
00468 WWT_MATRIX,
00469 WWT_SCROLLBAR,
00470 WWT_FRAME,
00471 WWT_CAPTION,
00472
00473 WWT_HSCROLLBAR,
00474 WWT_STICKYBOX,
00475 WWT_SCROLL2BAR,
00476 WWT_RESIZEBOX,
00477 WWT_CLOSEBOX,
00478 WWT_DROPDOWN,
00479 WWT_DROPDOWNIN,
00480 WWT_EDITBOX,
00481 WWT_LAST,
00482
00483 WWT_MASK = 0x1F,
00484
00485 WWT_PUSHBTN = WWT_PANEL | WWB_PUSHBUTTON,
00486 WWT_PUSHTXTBTN = WWT_TEXTBTN | WWB_PUSHBUTTON,
00487 WWT_PUSHIMGBTN = WWT_IMGBTN | WWB_PUSHBUTTON,
00488 };
00489
00491 #define WIDGETS_END WWT_LAST, RESIZE_NONE, 0, 0, 0, 0, 0, 0, STR_NULL
00492
00496 enum WindowFlags {
00497 WF_TIMEOUT_TRIGGER = 1,
00498 WF_TIMEOUT_BEGIN = 7,
00499 WF_TIMEOUT_MASK = 7,
00500 WF_DRAGGING = 1 << 3,
00501 WF_SCROLL_UP = 1 << 4,
00502 WF_SCROLL_DOWN = 1 << 5,
00503 WF_SCROLL_MIDDLE = 1 << 6,
00504 WF_HSCROLL = 1 << 7,
00505 WF_SIZING = 1 << 8,
00506 WF_STICKY = 1 << 9,
00507
00508 WF_DISABLE_VP_SCROLL = 1 << 10,
00509
00510 WF_WHITE_BORDER_ONE = 1 << 11,
00511 WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
00512 WF_SCROLL2 = 1 << 13,
00513 };
00514
00515 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00516 Window *FindWindowFromPt(int x, int y);
00517
00524 template <typename Wcls>
00525 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00526 {
00527 if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00528 return new Wcls(desc, window_number);
00529 }
00530
00531 void RelocateAllWindows(int neww, int newh);
00532
00533
00534 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00535
00536
00537 int GetWidgetFromPos(const Window *w, int x, int y);
00538
00539
00540 extern Window *_z_windows[];
00541 extern Window **_last_z_window;
00542
00544 #define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
00545
00551 enum {
00552 SCROLL_CON = 0,
00553 SCROLL_EDIT = 1,
00554 SCROLL_SAVE = 2,
00555 SCROLL_CHAT = 4,
00556 };
00557
00559 extern byte _no_scroll;
00560
00561 extern Point _cursorpos_drag_start;
00562
00563 extern int _scrollbar_start_pos;
00564 extern int _scrollbar_size;
00565 extern byte _scroller_click_timeout;
00566
00567 extern bool _scrolling_scrollbar;
00568 extern bool _scrolling_viewport;
00569
00570 extern byte _special_mouse_mode;
00571 enum SpecialMouseMode {
00572 WSM_NONE = 0,
00573 WSM_DRAGDROP = 1,
00574 WSM_SIZING = 2,
00575 WSM_PRESIZE = 3,
00576 };
00577
00578 Window *GetCallbackWnd();
00579 Window **FindWindowZPosition(const Window *w);
00580
00581 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
00582
00583 void ResizeButtons(Window *w, byte left, byte right);
00584
00585 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
00586
00587 void SetVScrollCount(Window *w, int num);
00588 void SetVScroll2Count(Window *w, int num);
00589 void SetHScrollCount(Window *w, int num);
00590
00591
00599 inline void Window::SetWidgetDisabledState(byte widget_index, bool disab_stat)
00600 {
00601 assert(widget_index < this->widget_count);
00602 SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
00603 }
00604
00609 inline void Window::DisableWidget(byte widget_index)
00610 {
00611 SetWidgetDisabledState(widget_index, true);
00612 }
00613
00618 inline void Window::EnableWidget(byte widget_index)
00619 {
00620 SetWidgetDisabledState(widget_index, false);
00621 }
00622
00628 inline bool Window::IsWidgetDisabled(byte widget_index) const
00629 {
00630 assert(widget_index < this->widget_count);
00631 return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
00632 }
00633
00641 inline void Window::SetWidgetHiddenState(byte widget_index, bool hidden_stat)
00642 {
00643 assert(widget_index < this->widget_count);
00644 SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
00645 }
00646
00651 inline void Window::HideWidget(byte widget_index)
00652 {
00653 SetWidgetHiddenState(widget_index, true);
00654 }
00655
00660 inline void Window::ShowWidget(byte widget_index)
00661 {
00662 SetWidgetHiddenState(widget_index, false);
00663 }
00664
00670 inline bool Window::IsWidgetHidden(byte widget_index) const
00671 {
00672 assert(widget_index < this->widget_count);
00673 return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
00674 }
00675
00681 inline void Window::SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00682 {
00683 assert(widget_index < this->widget_count);
00684 SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
00685 }
00686
00691 inline void Window::ToggleWidgetLoweredState(byte widget_index)
00692 {
00693 assert(widget_index < this->widget_count);
00694 ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00695 }
00696
00701 inline void Window::LowerWidget(byte widget_index)
00702 {
00703 SetWidgetLoweredState(widget_index, true);
00704 }
00705
00710 inline void Window::RaiseWidget(byte widget_index)
00711 {
00712 SetWidgetLoweredState(widget_index, false);
00713 }
00714
00720 inline bool Window::IsWidgetLowered(byte widget_index) const
00721 {
00722 assert(widget_index < this->widget_count);
00723 return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
00724 }
00725
00731 inline void Window::AlignWidgetRight(byte widget_index_a, byte widget_index_b)
00732 {
00733 assert(widget_index_a < this->widget_count);
00734 assert(widget_index_b < this->widget_count);
00735 int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
00736 this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
00737 this->widget[widget_index_a].left = this->widget[widget_index_a].right - w;
00738 }
00739
00745 inline int Window::GetWidgetWidth(byte widget_index) const
00746 {
00747 assert(widget_index < this->widget_count);
00748 return this->widget[widget_index].right - this->widget[widget_index].left + 1;
00749 }
00750
00751 #endif