# window_gui.h

Go to the documentation of this file.

    00001 /* $Id: window_gui.h 15428 2009-02-09 02:57:15Z 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
    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   /* Don't allow arrays; arrays of Windows are pointless as you need
    00134    * to destruct them all at the same time too, which is kinda hard. */
    00135   FORCEINLINE void *operator new[](size_t size) { NOT_REACHED(); }
    00136   /* Don't free the window directly; it corrupts the linked list when iterating */
    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   /*** Event handling ***/
    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   /*** End of the event handling ***/
    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 /* misc_gui.cpp */
    00434 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
    00435
    00436 /* widget.cpp */
    00437 int GetWidgetFromPos(const Window *w, int x, int y);
    00438
    00439 /* window.cpp */
    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     /* Repaint the widget that loss focus. A focused edit box may else leave the caret left on the screen */
    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 /* WINDOW_GUI_H */