window_gui.h

Go to the documentation of this file.
00001 /* $Id: window_gui.h 18675 2009-12-31 18:11:03Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef WINDOW_GUI_H
00013 #define WINDOW_GUI_H
00014 
00015 #include "core/geometry_func.hpp"
00016 #include "core/math_func.hpp"
00017 #include "vehicle_type.h"
00018 #include "viewport_type.h"
00019 #include "company_type.h"
00020 #include "core/alloc_type.hpp"
00021 #include "window_type.h"
00022 #include "tile_type.h"
00023 #include "widget_type.h"
00024 
00028 enum FrameFlags {
00029   FR_NONE         =  0,
00030   FR_TRANSPARENT  =  1 << 0,  
00031   FR_BORDERONLY   =  1 << 4,  
00032   FR_LOWERED      =  1 << 5,  
00033   FR_DARKENED     =  1 << 6,  
00034 };
00035 
00036 DECLARE_ENUM_AS_BIT_SET(FrameFlags);
00037 
00039 enum WidgetDrawDistances {
00040   /* WWT_IMGBTN(_2) */
00041   WD_IMGBTN_LEFT    = 1,      
00042   WD_IMGBTN_RIGHT   = 2,      
00043   WD_IMGBTN_TOP     = 1,      
00044   WD_IMGBTN_BOTTOM  = 2,      
00045 
00046   /* WWT_INSET */
00047   WD_INSET_LEFT  = 2,         
00048   WD_INSET_RIGHT = 2,         
00049   WD_INSET_TOP   = 1,         
00050 
00051   WD_VSCROLLBAR_WIDTH  = 12,  
00052 
00053   WD_HSCROLLBAR_HEIGHT = 12,  
00054 
00055   /* FrameRect widgets, all text buttons, panel, editbox */
00056   WD_FRAMERECT_LEFT   = 2,    
00057   WD_FRAMERECT_RIGHT  = 2,    
00058   WD_FRAMERECT_TOP    = 1,    
00059   WD_FRAMERECT_BOTTOM = 1,    
00060 
00061   /* Extra space at top/bottom of text panels */
00062   WD_TEXTPANEL_TOP    = 6,    
00063   WD_TEXTPANEL_BOTTOM = 6,    
00064 
00065   /* WWT_FRAME */
00066   WD_FRAMETEXT_LEFT   = 6,    
00067   WD_FRAMETEXT_RIGHT  = 6,    
00068   WD_FRAMETEXT_TOP    = 6,    
00069   WD_FRAMETEXT_BOTTOM = 6,    
00070 
00071   /* WWT_MATRIX */
00072   WD_MATRIX_LEFT   = 2,       
00073   WD_MATRIX_RIGHT  = 2,       
00074   WD_MATRIX_TOP    = 3,       
00075   WD_MATRIX_BOTTOM = 1,       
00076 
00077   /* WWT_SHADEBOX */
00078   WD_SHADEBOX_WIDTH  = 12,    
00079   WD_SHADEBOX_LEFT   = 2,     
00080   WD_SHADEBOX_RIGHT  = 2,     
00081   WD_SHADEBOX_TOP    = 3,     
00082   WD_SHADEBOX_BOTTOM = 3,     
00083 
00084   /* WWT_STICKYBOX */
00085   WD_STICKYBOX_WIDTH  = 12,   
00086   WD_STICKYBOX_LEFT   = 2,    
00087   WD_STICKYBOX_RIGHT  = 2,    
00088   WD_STICKYBOX_TOP    = 3,    
00089   WD_STICKYBOX_BOTTOM = 3,    
00090 
00091   /* WWT_RESIZEBOX */
00092   WD_RESIZEBOX_WIDTH  = 12,   
00093   WD_RESIZEBOX_LEFT   = 3,    
00094   WD_RESIZEBOX_RIGHT  = 2,    
00095   WD_RESIZEBOX_TOP    = 3,    
00096   WD_RESIZEBOX_BOTTOM = 2,    
00097 
00098   /* WWT_CLOSEBOX */
00099   WD_CLOSEBOX_WIDTH  = 11,    
00100   WD_CLOSEBOX_LEFT   = 2,     
00101   WD_CLOSEBOX_RIGHT  = 1,     
00102   WD_CLOSEBOX_TOP    = 2,     
00103   WD_CLOSEBOX_BOTTOM = 2,     
00104 
00105   /* WWT_CAPTION */
00106   WD_CAPTION_HEIGHT     = 14, 
00107   WD_CAPTIONTEXT_LEFT   = 2,  
00108   WD_CAPTIONTEXT_RIGHT  = 2,  
00109   WD_CAPTIONTEXT_TOP    = 2,  
00110   WD_CAPTIONTEXT_BOTTOM = 2,  
00111 
00112   /* Dropdown widget. */
00113   WD_DROPDOWN_HEIGHT     = 12, 
00114   WD_DROPDOWNTEXT_LEFT   = 2,  
00115   WD_DROPDOWNTEXT_RIGHT  = 14, 
00116   WD_DROPDOWNTEXT_TOP    = 1,  
00117   WD_DROPDOWNTEXT_BOTTOM = 1,  
00118 
00119   WD_SORTBUTTON_ARROW_WIDTH = 11, 
00120 
00121   WD_PAR_VSEP_NORMAL = 2,      
00122   WD_PAR_VSEP_WIDE   = 8,      
00123 };
00124 
00125 /* wiget.cpp */
00126 void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags);
00127 
00128 /* window.cpp */
00129 extern Window *_z_front_window;
00130 extern Window *_z_back_window;
00131 extern Window *_focused_window;
00132 
00133 
00135 enum WindowPosition {
00136   WDP_MANUAL,        
00137   WDP_AUTO,          
00138   WDP_CENTER,        
00139   WDP_ALIGN_TOOLBAR, 
00140 };
00141 
00142 Point GetToolbarAlignedWindowPosition(int window_width);
00143 
00147 struct WindowDesc : ZeroedMemoryAllocator {
00148 
00149   WindowDesc(WindowPosition default_pos, int16 def_width, int16 def_height,
00150       WindowClass window_class, WindowClass parent_class, uint32 flags,
00151       const NWidgetPart *nwid_parts, int16 nwid_length);
00152 
00153   ~WindowDesc();
00154 
00155   WindowPosition default_pos;    
00156   int16 default_width;           
00157   int16 default_height;          
00158   WindowClass cls;               
00159   WindowClass parent_cls;        
00160   uint32 flags;                  
00161   const NWidgetPart *nwid_parts; 
00162   int16 nwid_length;             
00163 };
00164 
00168 enum WindowDefaultFlag {
00169   WDF_CONSTRUCTION    =   1 << 0, 
00170   WDF_UNCLICK_BUTTONS =   1 << 1, 
00171   WDF_MODAL           =   1 << 2, 
00172   WDF_NO_FOCUS        =   1 << 3, 
00173 };
00174 
00178 class Scrollbar {
00179 private:
00180   const bool is_vertical; 
00181   uint16 count;           
00182   uint16 cap;             
00183   uint16 pos;             
00184 
00185 public:
00186   Scrollbar(bool is_vertical) : is_vertical(is_vertical)
00187   {
00188   }
00189 
00194   FORCEINLINE uint16 GetCount() const
00195   {
00196     return this->count;
00197   }
00198 
00203   FORCEINLINE uint16 GetCapacity() const
00204   {
00205     return this->cap;
00206   }
00207 
00212   FORCEINLINE uint16 GetPosition() const
00213   {
00214     return this->pos;
00215   }
00216 
00222   FORCEINLINE bool IsVisible(uint16 item) const
00223   {
00224     return IsInsideBS(item, this->GetPosition(), this->GetCapacity());
00225   }
00226 
00232   void SetCount(int num)
00233   {
00234     assert(num >= 0);
00235     assert(num <= MAX_UVALUE(uint16));
00236 
00237     this->count = num;
00238     num -= this->cap;
00239     if (num < 0) num = 0;
00240     if (num < this->pos) this->pos = num;
00241   }
00242 
00248   void SetCapacity(int capacity)
00249   {
00250     assert(capacity > 0);
00251     assert(capacity <= MAX_UVALUE(uint16));
00252 
00253     this->cap = capacity;
00254     if (this->cap + this->pos > this->count) this->pos = max(0, this->count - this->cap);
00255   }
00256 
00257   void SetCapacityFromWidget(Window *w, int widget, int padding = 0);
00258 
00263   void SetPosition(int position)
00264   {
00265     assert(position >= 0);
00266     assert(this->count <= this->cap ? (position == 0) : (position + this->cap <= this->count));
00267     this->pos = position;
00268   }
00269 
00275   void UpdatePosition(int difference)
00276   {
00277     if (difference == 0) return;
00278     this->SetPosition(Clamp(this->pos + difference, 0, max(this->count - this->cap, 0)));
00279   }
00280 
00287   void ScrollTowards(int position)
00288   {
00289     if (position < this->GetPosition()) {
00290       /* scroll up to the item */
00291       this->SetPosition(position);
00292     } else if (position >= this->GetPosition() + this->GetCapacity()) {
00293       /* scroll down so that the item is at the bottom */
00294       this->SetPosition(position - this->GetCapacity() + 1);
00295     }
00296   }
00297 };
00298 
00302 struct ResizeInfo {
00303   uint step_width;  
00304   uint step_height; 
00305 };
00306 
00308 enum SortButtonState {
00309   SBS_OFF,  
00310   SBS_DOWN, 
00311   SBS_UP,   
00312 };
00313 
00321 struct ViewportData : ViewPort {
00322   VehicleID follow_vehicle; 
00323   int32 scrollpos_x;        
00324   int32 scrollpos_y;        
00325   int32 dest_scrollpos_x;   
00326   int32 dest_scrollpos_y;   
00327 };
00328 
00332 struct Window : ZeroedMemoryAllocator {
00334   enum EventState {
00335     ES_HANDLED,     
00336     ES_NOT_HANDLED, 
00337   };
00338 
00339 protected:
00340   void InitializeData(WindowClass cls, int window_number, uint32 desc_flags);
00341   void InitializePositionSize(int x, int y, int min_width, int min_height);
00342   void FindWindowPlacementAndResize(int def_width, int def_height);
00343 
00344 public:
00345   Window();
00346 
00347   virtual ~Window();
00348 
00355   FORCEINLINE void *operator new[](size_t size)
00356   {
00357     NOT_REACHED();
00358   }
00359 
00365   FORCEINLINE void operator delete(void *ptr)
00366   {
00367   }
00368 
00369   uint16 flags4;              
00370   WindowClass window_class;   
00371   WindowNumber window_number; 
00372 
00373   int left;   
00374   int top;    
00375   int width;  
00376   int height; 
00377 
00378   Scrollbar hscroll;  
00379   Scrollbar vscroll;  
00380   Scrollbar vscroll2; 
00381   ResizeInfo resize;  
00382 
00383   Owner owner;        
00384 
00385   ViewportData *viewport;          
00386   uint32 desc_flags;               
00387   const NWidgetCore *nested_focus; 
00388   NWidgetBase *nested_root;        
00389   NWidgetBase **nested_array;      
00390   uint nested_array_size;          
00391   NWidgetStacked *shade_select;    
00392   Dimension unshaded_size;         
00393 
00394   Window *parent;                  
00395   Window *z_front;                 
00396   Window *z_back;                  
00397 
00398   template <class NWID>
00399   inline const NWID *GetWidget(uint widnum) const;
00400   template <class NWID>
00401   inline NWID *GetWidget(uint widnum);
00402 
00403 
00404   void InitNested(const WindowDesc *desc, WindowNumber number = 0);
00405   void CreateNestedTree(const WindowDesc *desc, bool fill_nested = true);
00406   void FinishInitNested(const WindowDesc *desc, WindowNumber window_number);
00407 
00415   inline void SetWidgetDisabledState(byte widget_index, bool disab_stat)
00416   {
00417     assert(widget_index < this->nested_array_size);
00418     if (this->nested_array[widget_index] != NULL) this->GetWidget<NWidgetCore>(widget_index)->SetDisabled(disab_stat);
00419   }
00420 
00425   inline void DisableWidget(byte widget_index)
00426   {
00427     SetWidgetDisabledState(widget_index, true);
00428   }
00429 
00434   inline void EnableWidget(byte widget_index)
00435   {
00436     SetWidgetDisabledState(widget_index, false);
00437   }
00438 
00444   inline bool IsWidgetDisabled(byte widget_index) const
00445   {
00446     assert(widget_index < this->nested_array_size);
00447     return this->GetWidget<NWidgetCore>(widget_index)->IsDisabled();
00448   }
00449 
00455   inline bool IsWidgetFocused(byte widget_index) const
00456   {
00457     return this->nested_focus != NULL && this->nested_focus->index == widget_index;
00458   }
00459 
00466   inline bool IsWidgetGloballyFocused(byte widget_index) const
00467   {
00468     return _focused_window == this && IsWidgetFocused(widget_index);
00469   }
00470 
00476   inline void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
00477   {
00478     assert(widget_index < this->nested_array_size);
00479     this->GetWidget<NWidgetCore>(widget_index)->SetLowered(lowered_stat);
00480   }
00481 
00486   inline void ToggleWidgetLoweredState(byte widget_index)
00487   {
00488     assert(widget_index < this->nested_array_size);
00489     bool lowered_state = this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00490     this->GetWidget<NWidgetCore>(widget_index)->SetLowered(!lowered_state);
00491   }
00492 
00497   inline void LowerWidget(byte widget_index)
00498   {
00499     SetWidgetLoweredState(widget_index, true);
00500   }
00501 
00506   inline void RaiseWidget(byte widget_index)
00507   {
00508     SetWidgetLoweredState(widget_index, false);
00509   }
00510 
00516   inline bool IsWidgetLowered(byte widget_index) const
00517   {
00518     assert(widget_index < this->nested_array_size);
00519     return this->GetWidget<NWidgetCore>(widget_index)->IsLowered();
00520   }
00521 
00522   void UnfocusFocusedWidget();
00523   bool SetFocusedWidget(byte widget_index);
00524 
00525   void HandleButtonClick(byte widget);
00526 
00527   void RaiseButtons(bool autoraise = false);
00528   void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00529   void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00530   void SetWidgetDirty(byte widget_index) const;
00531 
00532   void DrawWidgets() const;
00533   void DrawViewport() const;
00534   void DrawSortButtonState(int widget, SortButtonState state) const;
00535 
00536   void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00537 
00538   void SetDirty() const;
00539   void ReInit(int rx = 0, int ry = 0);
00540 
00542   inline bool IsShaded() const
00543   {
00544     return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL;
00545   }
00546 
00547   void SetShaded(bool make_shaded);
00548 
00553   void InvalidateData(int data = 0)
00554   {
00555     this->SetDirty();
00556     this->OnInvalidateData(data);
00557   }
00558 
00559   /*** Event handling ***/
00560 
00565   virtual void OnInit() { }
00566 
00575   virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number);
00576 
00581   virtual void OnPaint() {}
00582 
00589   virtual void DrawWidget(const Rect &r, int widget) const {}
00590 
00603   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {}
00604 
00611   virtual void SetStringParameters(int widget) const {}
00612 
00616   virtual void OnFocus() {}
00617 
00621   virtual void OnFocusLost() {}
00622 
00630   virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00631 
00637   virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00638 
00639 
00645   virtual void OnClick(Point pt, int widget) {}
00646 
00652   virtual void OnDoubleClick(Point pt, int widget) {}
00653 
00659   virtual void OnRightClick(Point pt, int widget) {}
00660 
00666   virtual void OnDragDrop(Point pt, int widget) {}
00667 
00672   virtual void OnScroll(Point delta) {}
00673 
00680   virtual void OnMouseOver(Point pt, int widget) {}
00681 
00686   virtual void OnMouseWheel(int wheel) {}
00687 
00688 
00692   virtual void OnMouseLoop() {}
00693 
00697   virtual void OnTick() {}
00698 
00702   virtual void OnHundredthTick() {}
00703 
00707   virtual void OnTimeout() {}
00708 
00709 
00714   virtual void OnResize() {}
00715 
00721   virtual void OnDropdownSelect(int widget, int index) {}
00722 
00728   virtual void OnQueryTextFinished(char *str) {}
00729 
00734   virtual void OnInvalidateData(int data = 0) {}
00735 
00736 
00743   virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00744 
00748   virtual void OnPlaceObjectAbort() {}
00749 
00750 
00758   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00759 
00769   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00770 
00778   virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00779 
00780   /*** End of the event handling ***/
00781 };
00782 
00788 template <class NWID>
00789 inline NWID *Window::GetWidget(uint widnum)
00790 {
00791   if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL;
00792   NWID *nwid = dynamic_cast<NWID *>(this->nested_array[widnum]);
00793   assert(nwid != NULL);
00794   return nwid;
00795 }
00796 
00798 template <>
00799 inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
00800 {
00801   if (widnum >= this->nested_array_size) return NULL;
00802   return this->nested_array[widnum];
00803 }
00804 
00810 template <class NWID>
00811 inline const NWID *Window::GetWidget(uint widnum) const
00812 {
00813   return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
00814 }
00815 
00816 
00820 class PickerWindowBase : public Window {
00821 
00822 public:
00823   PickerWindowBase(Window *parent) : Window()
00824   {
00825     this->parent = parent;
00826   };
00827 
00828   virtual ~PickerWindowBase();
00829 };
00830 
00834 enum WindowFlags {
00835   WF_TIMEOUT_TRIGGER   = 1,       
00836   WF_TIMEOUT_BEGIN     = 7,       
00837   WF_TIMEOUT_MASK      = 7,       
00838   WF_DRAGGING          = 1 <<  3, 
00839   WF_SCROLL_UP         = 1 <<  4, 
00840   WF_SCROLL_DOWN       = 1 <<  5, 
00841   WF_SCROLL_MIDDLE     = 1 <<  6, 
00842   WF_SCROLL2           = 1 <<  7,
00843   WF_HSCROLL           = 1 <<  8,
00844   WF_SIZING_RIGHT      = 1 <<  9, 
00845   WF_SIZING_LEFT       = 1 << 10, 
00846   WF_SIZING            = WF_SIZING_RIGHT | WF_SIZING_LEFT, 
00847   WF_STICKY            = 1 << 11, 
00848 
00849   WF_DISABLE_VP_SCROLL = 1 << 12, 
00850 
00851   WF_WHITE_BORDER_ONE  = 1 << 13,
00852   WF_WHITE_BORDER_MASK = 1 << 14 | WF_WHITE_BORDER_ONE,
00853 };
00854 
00855 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00856 Window *FindWindowFromPt(int x, int y);
00857 
00864 template <typename Wcls>
00865 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00866 {
00867   if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00868   return new Wcls(desc, window_number);
00869 }
00870 
00871 void RelocateAllWindows(int neww, int newh);
00872 
00873 /* misc_gui.cpp */
00874 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00875 
00876 /* widget.cpp */
00877 int GetWidgetFromPos(const Window *w, int x, int y);
00878 
00880 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start)  for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00881 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00882 #define FOR_ALL_WINDOWS_FROM_BACK(w)  FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00883 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00884 
00885 extern Point _cursorpos_drag_start;
00886 
00887 extern int _scrollbar_start_pos;
00888 extern int _scrollbar_size;
00889 extern byte _scroller_click_timeout;
00890 
00891 extern bool _scrolling_scrollbar;
00892 extern bool _scrolling_viewport;
00893 
00894 extern byte _special_mouse_mode;
00895 enum SpecialMouseMode {
00896   WSM_NONE     = 0,
00897   WSM_DRAGDROP = 1,
00898   WSM_SIZING   = 2,
00899   WSM_PRESIZE  = 3,
00900 };
00901 
00902 Window *GetCallbackWnd();
00903 
00904 void SetFocusedWindow(Window *w);
00905 bool EditBoxInGlobalFocus();
00906 
00907 void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y);
00908 
00909 #endif /* WINDOW_GUI_H */

Generated on Tue Jan 5 21:03:01 2010 for OpenTTD by  doxygen 1.5.6