# window_gui.h

Go to the documentation of this file.

    00001 /* $Id: window_gui.h 15723 2009-03-15 15:12:06Z rubidium $ */
    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 : 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   /* Don't allow arrays; arrays of Windows are pointless as you need
    00143    * to destruct them all at the same time too, which is kinda hard. */
    00144   FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
    00145   /* Don't free the window directly; it corrupts the linked list when iterating */
    00146   FORCEINLINE void operator delete(void *ptr, size_t size) {}
    00147
    00148   uint16 flags4;
    00149   WindowClass window_class;
    00150   WindowNumber window_number;
    00151
    00152   int left;
    00153   int top;
    00154   int width;
    00155   int height;
    00156
    00157   Scrollbar hscroll;
    00158   Scrollbar vscroll;
    00159   Scrollbar vscroll2;
    00160   ResizeInfo resize;
    00161
    00162   Owner owner;
    00163
    00164   ViewportData *viewport;
    00165   Widget *widget;
    00166   uint widget_count;
    00167   uint32 desc_flags;
    00168   const Widget *focused_widget;
    00169
    00170   Window *parent;
    00171   Window *z_front;
    00172   Window *z_back;
    00173
    00181   inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
    00182   {
    00183     assert(widget_index < this->widget_count);
    00184     SB(this->widget[widget_index].display_flags, WIDG_DISABLED, 1, !!disab_stat);
    00185   }
    00186
    00191   inline void DisableWidget(byte widget_index)
    00192   {
    00193     SetWidgetDisabledState(widget_index, true);
    00194   }
    00195
    00200   inline void EnableWidget(byte widget_index)
    00201   {
    00202     SetWidgetDisabledState(widget_index, false);
    00203   }
    00204
    00210   inline bool IsWidgetDisabled(byte widget_index) const
    00211   {
    00212     assert(widget_index < this->widget_count);
    00213     return HasBit(this->widget[widget_index].display_flags, WIDG_DISABLED);
    00214   }
    00215
    00223   inline void SetWidgetHiddenState(byte widget_index, bool hidden_stat)
    00224   {
    00225     assert(widget_index < this->widget_count);
    00226     SB(this->widget[widget_index].display_flags, WIDG_HIDDEN, 1, !!hidden_stat);
    00227   }
    00228
    00233   inline void HideWidget(byte widget_index)
    00234   {
    00235     SetWidgetHiddenState(widget_index, true);
    00236   }
    00237
    00242   inline void ShowWidget(byte widget_index)
    00243   {
    00244     SetWidgetHiddenState(widget_index, false);
    00245   }
    00246
    00252   inline bool IsWidgetHidden(byte widget_index) const
    00253   {
    00254     assert(widget_index < this->widget_count);
    00255     return HasBit(this->widget[widget_index].display_flags, WIDG_HIDDEN);
    00256   }
    00257
    00263   inline void SetFocusedWidget(byte widget_index)
    00264   {
    00265     if (widget_index < this->widget_count) {
    00266       /* Repaint the widget that loss focus. A focused edit box may else leave the caret left on the screen */
    00267       if (this->focused_widget && this->focused_widget - this->widget != widget_index) {
    00268         this->InvalidateWidget(this->focused_widget - this->widget);
    00269       }
    00270       this->focused_widget = &this->widget[widget_index];
    00271     }
    00272   }
    00273
    00279   inline bool IsWidgetFocused(byte widget_index) const
    00280   {
    00281     return this->focused_widget == &this->widget[widget_index];
    00282   }
    00283
    00290   inline bool IsWidgetGloballyFocused(byte widget_index) const
    00291   {
    00292     return _focused_window == this && IsWidgetFocused(widget_index);
    00293   }
    00294
    00300   inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
    00301   {
    00302     assert(widget_index < this->widget_count);
    00303     SB(this->widget[widget_index].display_flags, WIDG_LOWERED, 1, !!lowered_stat);
    00304   }
    00305
    00310   inline void ToggleWidgetLoweredState(byte widget_index)
    00311   {
    00312     assert(widget_index < this->widget_count);
    00313     ToggleBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
    00314   }
    00315
    00320   inline void LowerWidget(byte widget_index)
    00321   {
    00322     SetWidgetLoweredState(widget_index, true);
    00323   }
    00324
    00329   inline void RaiseWidget(byte widget_index)
    00330   {
    00331     SetWidgetLoweredState(widget_index, false);
    00332   }
    00333
    00339   inline bool IsWidgetLowered(byte widget_index) const
    00340   {
    00341     assert(widget_index < this->widget_count);
    00342     return HasBit(this->widget[widget_index].display_flags, WIDG_LOWERED);
    00343   }
    00344
    00350   inline void AlignWidgetRight(byte widget_index_a, byte widget_index_b)
    00351   {
    00352     assert(widget_index_a < this->widget_count);
    00353     assert(widget_index_b < this->widget_count);
    00354     int w = this->widget[widget_index_a].right - this->widget[widget_index_a].left;
    00355     this->widget[widget_index_a].right = this->widget[widget_index_b].left - 1;
    00356     this->widget[widget_index_a].left  = this->widget[widget_index_a].right - w;
    00357   }
    00358
    00364   inline int GetWidgetWidth(byte widget_index) const
    00365   {
    00366     assert(widget_index < this->widget_count);
    00367     return this->widget[widget_index].right - this->widget[widget_index].left + 1;
    00368   }
    00369
    00370   void HandleButtonClick(byte widget);
    00371   bool HasWidgetOfType(WidgetType widget_type) const;
    00372
    00373   void RaiseButtons();
    00374   void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
    00375   void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
    00376   void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
    00377   void InvalidateWidget(byte widget_index) const;
    00378
    00379   void DrawWidgets() const;
    00380   void DrawViewport() const;
    00381   void DrawSortButtonState(int widget, SortButtonState state) const;
    00382
    00383   void DeleteChildWindows() const;
    00384
    00385   void SetDirty() const;
    00386
    00387   /*** Event handling ***/
    00388
    00392   virtual void OnPaint() {}
    00393
    00397   virtual void OnFocus() {}
    00398
    00402   virtual void OnFocusLost() {}
    00403
    00411   virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
    00412
    00418   virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
    00419
    00420
    00426   virtual void OnClick(Point pt, int widget) {}
    00427
    00433   virtual void OnDoubleClick(Point pt, int widget) {}
    00434
    00440   virtual void OnRightClick(Point pt, int widget) {}
    00441
    00447   virtual void OnDragDrop(Point pt, int widget) {}
    00448
    00453   virtual void OnScroll(Point delta) {}
    00454
    00461   virtual void OnMouseOver(Point pt, int widget) {}
    00462
    00467   virtual void OnMouseWheel(int wheel) {}
    00468
    00469
    00473   virtual void OnMouseLoop() {}
    00474
    00478   virtual void OnTick() {}
    00479
    00483   virtual void OnHundredthTick() {}
    00484
    00488   virtual void OnTimeout() {}
    00489
    00490
    00496   virtual void OnResize(Point new_size, Point delta) {}
    00497
    00503   virtual void OnDropdownSelect(int widget, int index) {}
    00504
    00510   virtual void OnQueryTextFinished(char *str) {}
    00511
    00516   virtual void OnInvalidateData(int data = 0) {}
    00517
    00518
    00525   virtual void OnPlaceObject(Point pt, TileIndex tile) {}
    00526
    00530   virtual void OnPlaceObjectAbort() {}
    00531
    00532
    00540   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
    00541
    00551   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
    00552
    00560   virtual void OnPlacePresize(Point pt, TileIndex tile) {}
    00561
    00562   /*** End of the event handling ***/
    00563 };
    00564
    00568 class PickerWindowBase : public Window {
    00569
    00570 public:
    00571   PickerWindowBase(const WindowDesc *desc, Window *parent) : Window(desc)
    00572   {
    00573     this->parent = parent;
    00574   };
    00575
    00576   virtual ~PickerWindowBase();
    00577 };
    00578
    00582 enum WindowFlags {
    00583   WF_TIMEOUT_TRIGGER   = 1,
    00584   WF_TIMEOUT_BEGIN     = 7,
    00585   WF_TIMEOUT_MASK      = 7,
    00586   WF_DRAGGING          = 1 <<  3,
    00587   WF_SCROLL_UP         = 1 <<  4,
    00588   WF_SCROLL_DOWN       = 1 <<  5,
    00589   WF_SCROLL_MIDDLE     = 1 <<  6,
    00590   WF_HSCROLL           = 1 <<  7,
    00591   WF_SIZING            = 1 <<  8,
    00592   WF_STICKY            = 1 <<  9,
    00593
    00594   WF_DISABLE_VP_SCROLL = 1 << 10,
    00595
    00596   WF_WHITE_BORDER_ONE  = 1 << 11,
    00597   WF_WHITE_BORDER_MASK = 1 << 12 | WF_WHITE_BORDER_ONE,
    00598   WF_SCROLL2           = 1 << 13,
    00599 };
    00600
    00601 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
    00602 Window *FindWindowFromPt(int x, int y);
    00603
    00610 template <typename Wcls>
    00611 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
    00612 {
    00613   if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
    00614   return new Wcls(desc, window_number);
    00615 }
    00616
    00617 void RelocateAllWindows(int neww, int newh);
    00618
    00619 /* misc_gui.cpp */
    00620 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
    00621
    00622 /* widget.cpp */
    00623 int GetWidgetFromPos(const Window *w, int x, int y);
    00624
    00626 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start)  for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
    00627 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
    00628 #define FOR_ALL_WINDOWS_FROM_BACK(w)  FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
    00629 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
    00630
    00631 extern Point _cursorpos_drag_start;
    00632
    00633 extern int _scrollbar_start_pos;
    00634 extern int _scrollbar_size;
    00635 extern byte _scroller_click_timeout;
    00636
    00637 extern bool _scrolling_scrollbar;
    00638 extern bool _scrolling_viewport;
    00639
    00640 extern byte _special_mouse_mode;
    00641 enum SpecialMouseMode {
    00642   WSM_NONE     = 0,
    00643   WSM_DRAGDROP = 1,
    00644   WSM_SIZING   = 2,
    00645   WSM_PRESIZE  = 3,
    00646 };
    00647
    00648 Window *GetCallbackWnd();
    00649
    00650 void SetFocusedWindow(Window *w);
    00651 const Widget *GetGloballyFocusedWidget();
    00652 bool EditBoxInGlobalFocus();
    00653
    00654 void ScrollbarClickHandler(Window *w, const Widget *wi, int x, int y);
    00655
    00656 void ResizeButtons(Window *w, byte left, byte right);
    00657
    00658 void ResizeWindowForWidget(Window *w, uint widget, int delta_x, int delta_y);
    00659
    00660 void SetVScrollCount(Window *w, int num);
    00661 void SetVScroll2Count(Window *w, int num);
    00662 void SetHScrollCount(Window *w, int num);
    00663
    00664 #endif /* WINDOW_GUI_H */