# window_gui.h

Go to the documentation of this file.

    00001 /* $Id: window_gui.h 15627 2009-03-06 03:01:35Z belugas $ */
    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 /* wiget.cpp */
    00031 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
    00032
    00033 /* window.cpp */
    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   /* Don't allow arrays; arrays of Windows are pointless as you need
    00139    * to destruct them all at the same time too, which is kinda hard. */
    00140   FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
    00141   /* Don't free the window directly; it corrupts the linked list when iterating */
    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       /* Repaint the widget that loss focus. A focused edit box may else leave the caret left on the screen */
    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   /*** Event handling ***/
    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   /*** End of the event handling ***/
    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 /* misc_gui.cpp */
    00616 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
    00617
    00618 /* widget.cpp */
    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 /* WINDOW_GUI_H */