window_gui.h

Go to the documentation of this file.
00001 /* $Id: window_gui.h 18607 2009-12-22 20:53:28Z alberth $ */
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   bool SetFocusedWidget(byte widget_index);
00523 
00524   void HandleButtonClick(byte widget);
00525 
00526   void RaiseButtons(bool autoraise = false);
00527   void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
00528   void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
00529   void SetWidgetDirty(byte widget_index) const;
00530 
00531   void DrawWidgets() const;
00532   void DrawViewport() const;
00533   void DrawSortButtonState(int widget, SortButtonState state) const;
00534 
00535   void DeleteChildWindows(WindowClass wc = WC_INVALID) const;
00536 
00537   void SetDirty() const;
00538   void ReInit(int rx = 0, int ry = 0);
00539 
00541   inline bool IsShaded() const
00542   {
00543     return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL;
00544   }
00545 
00546   void SetShaded(bool make_shaded);
00547 
00552   void InvalidateData(int data = 0)
00553   {
00554     this->SetDirty();
00555     this->OnInvalidateData(data);
00556   }
00557 
00558   /*** Event handling ***/
00559 
00564   virtual void OnInit() { }
00565 
00574   virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number);
00575 
00580   virtual void OnPaint() {}
00581 
00588   virtual void DrawWidget(const Rect &r, int widget) const {}
00589 
00602   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) {}
00603 
00610   virtual void SetStringParameters(int widget) const {}
00611 
00615   virtual void OnFocus() {}
00616 
00620   virtual void OnFocusLost() {}
00621 
00629   virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
00630 
00636   virtual EventState OnCTRLStateChange() { return ES_NOT_HANDLED; }
00637 
00638 
00644   virtual void OnClick(Point pt, int widget) {}
00645 
00651   virtual void OnDoubleClick(Point pt, int widget) {}
00652 
00658   virtual void OnRightClick(Point pt, int widget) {}
00659 
00665   virtual void OnDragDrop(Point pt, int widget) {}
00666 
00671   virtual void OnScroll(Point delta) {}
00672 
00679   virtual void OnMouseOver(Point pt, int widget) {}
00680 
00685   virtual void OnMouseWheel(int wheel) {}
00686 
00687 
00691   virtual void OnMouseLoop() {}
00692 
00696   virtual void OnTick() {}
00697 
00701   virtual void OnHundredthTick() {}
00702 
00706   virtual void OnTimeout() {}
00707 
00708 
00713   virtual void OnResize() {}
00714 
00720   virtual void OnDropdownSelect(int widget, int index) {}
00721 
00727   virtual void OnQueryTextFinished(char *str) {}
00728 
00733   virtual void OnInvalidateData(int data = 0) {}
00734 
00735 
00742   virtual void OnPlaceObject(Point pt, TileIndex tile) {}
00743 
00747   virtual void OnPlaceObjectAbort() {}
00748 
00749 
00757   virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) {}
00758 
00768   virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) {}
00769 
00777   virtual void OnPlacePresize(Point pt, TileIndex tile) {}
00778 
00779   /*** End of the event handling ***/
00780 };
00781 
00787 template <class NWID>
00788 inline NWID *Window::GetWidget(uint widnum)
00789 {
00790   if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL;
00791   NWID *nwid = dynamic_cast<NWID *>(this->nested_array[widnum]);
00792   assert(nwid != NULL);
00793   return nwid;
00794 }
00795 
00797 template <>
00798 inline const NWidgetBase *Window::GetWidget<NWidgetBase>(uint widnum) const
00799 {
00800   if (widnum >= this->nested_array_size) return NULL;
00801   return this->nested_array[widnum];
00802 }
00803 
00809 template <class NWID>
00810 inline const NWID *Window::GetWidget(uint widnum) const
00811 {
00812   return const_cast<Window *>(this)->GetWidget<NWID>(widnum);
00813 }
00814 
00815 
00819 class PickerWindowBase : public Window {
00820 
00821 public:
00822   PickerWindowBase(Window *parent) : Window()
00823   {
00824     this->parent = parent;
00825   };
00826 
00827   virtual ~PickerWindowBase();
00828 };
00829 
00833 enum WindowFlags {
00834   WF_TIMEOUT_TRIGGER   = 1,       
00835   WF_TIMEOUT_BEGIN     = 7,       
00836   WF_TIMEOUT_MASK      = 7,       
00837   WF_DRAGGING          = 1 <<  3, 
00838   WF_SCROLL_UP         = 1 <<  4, 
00839   WF_SCROLL_DOWN       = 1 <<  5, 
00840   WF_SCROLL_MIDDLE     = 1 <<  6, 
00841   WF_SCROLL2           = 1 <<  7,
00842   WF_HSCROLL           = 1 <<  8,
00843   WF_SIZING_RIGHT      = 1 <<  9, 
00844   WF_SIZING_LEFT       = 1 << 10, 
00845   WF_SIZING            = WF_SIZING_RIGHT | WF_SIZING_LEFT, 
00846   WF_STICKY            = 1 << 11, 
00847 
00848   WF_DISABLE_VP_SCROLL = 1 << 12, 
00849 
00850   WF_WHITE_BORDER_ONE  = 1 << 13,
00851   WF_WHITE_BORDER_MASK = 1 << 14 | WF_WHITE_BORDER_ONE,
00852 };
00853 
00854 Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
00855 Window *FindWindowFromPt(int x, int y);
00856 
00863 template <typename Wcls>
00864 Wcls *AllocateWindowDescFront(const WindowDesc *desc, int window_number)
00865 {
00866   if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
00867   return new Wcls(desc, window_number);
00868 }
00869 
00870 void RelocateAllWindows(int neww, int newh);
00871 
00872 /* misc_gui.cpp */
00873 void GuiShowTooltips(StringID str, uint paramcount = 0, const uint64 params[] = NULL, bool use_left_mouse_button = false);
00874 
00875 /* widget.cpp */
00876 int GetWidgetFromPos(const Window *w, int x, int y);
00877 
00879 #define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start)  for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID)
00880 #define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID)
00881 #define FOR_ALL_WINDOWS_FROM_BACK(w)  FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window)
00882 #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window)
00883 
00884 extern Point _cursorpos_drag_start;
00885 
00886 extern int _scrollbar_start_pos;
00887 extern int _scrollbar_size;
00888 extern byte _scroller_click_timeout;
00889 
00890 extern bool _scrolling_scrollbar;
00891 extern bool _scrolling_viewport;
00892 
00893 extern byte _special_mouse_mode;
00894 enum SpecialMouseMode {
00895   WSM_NONE     = 0,
00896   WSM_DRAGDROP = 1,
00897   WSM_SIZING   = 2,
00898   WSM_PRESIZE  = 3,
00899 };
00900 
00901 Window *GetCallbackWnd();
00902 
00903 void SetFocusedWindow(Window *w);
00904 bool EditBoxInGlobalFocus();
00905 
00906 void ScrollbarClickHandler(Window *w, const NWidgetCore *nw, int x, int y);
00907 
00908 #endif /* WINDOW_GUI_H */

Generated on Wed Dec 23 23:27:57 2009 for OpenTTD by  doxygen 1.5.6