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 */

Generated on Mon Mar 9 23:33:53 2009 for openttd by  doxygen 1.5.6