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

Generated on Mon Feb 16 23:12:13 2009 for openttd by  doxygen 1.5.6