widget_type.h

Go to the documentation of this file.
00001 /* $Id: widget_type.h 18606 2009-12-22 20:43:25Z 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 WIDGET_TYPE_H
00013 #define WIDGET_TYPE_H
00014 
00015 #include "core/bitmath_func.hpp"
00016 #include "strings_type.h"
00017 #include "gfx_type.h"
00018 
00019 enum {
00020   WIDGET_LIST_END = -1, 
00021 };
00022 
00024 enum MatrixWidgetValues {
00025   /* Number of column bits of the WWT_MATRIX widget data. */
00026   MAT_COL_START = 0, 
00027   MAT_COL_BITS  = 8, 
00028 
00029   /* Number of row bits of the WWT_MATRIX widget data. */
00030   MAT_ROW_START = 8, 
00031   MAT_ROW_BITS  = 8, 
00032 };
00033 
00035 enum ArrowWidgetValues {
00036   AWV_DECREASE, 
00037   AWV_INCREASE, 
00038   AWV_LEFT,     
00039   AWV_RIGHT,    
00040 };
00041 
00045 enum WidgetType {
00046   /* Window widget types. */
00047   WWT_EMPTY,      
00048 
00049   WWT_PANEL,      
00050   WWT_INSET,      
00051   WWT_IMGBTN,     
00052   WWT_IMGBTN_2,   
00053 
00054   WWT_TEXTBTN,    
00055   WWT_TEXTBTN_2,  
00056   WWT_LABEL,      
00057   WWT_TEXT,       
00058   WWT_MATRIX,     
00059   WWT_SCROLLBAR,  
00060   WWT_FRAME,      
00061   WWT_CAPTION,    
00062 
00063   WWT_HSCROLLBAR, 
00064   WWT_SHADEBOX,   
00065   WWT_STICKYBOX,  
00066   WWT_SCROLL2BAR, 
00067   WWT_RESIZEBOX,  
00068   WWT_CLOSEBOX,   
00069   WWT_DROPDOWN,   
00070   WWT_EDITBOX,    
00071   WWT_LAST,       
00072 
00073   /* Nested widget types. */
00074   NWID_HORIZONTAL,      
00075   NWID_HORIZONTAL_LTR,  
00076   NWID_VERTICAL,        
00077   NWID_SPACER,          
00078   NWID_SELECTION,       
00079   NWID_VIEWPORT,        
00080   NWID_BUTTON_DROPDOWN, 
00081   NWID_BUTTON_ARROW,    
00082 
00083   /* Nested widget part types. */
00084   WPT_RESIZE,       
00085   WPT_MINSIZE,      
00086   WPT_MINTEXTLINES, 
00087   WPT_FILL,         
00088   WPT_DATATIP,      
00089   WPT_PADDING,      
00090   WPT_PIPSPACE,     
00091   WPT_ENDCONTAINER, 
00092   WPT_FUNCTION,     
00093 
00094   /* Pushable window widget types. */
00095   WWT_MASK = 0x7F,
00096 
00097   WWB_PUSHBUTTON  = 1 << 7,
00098 
00099   WWT_PUSHBTN     = WWT_PANEL   | WWB_PUSHBUTTON,
00100   WWT_PUSHTXTBTN  = WWT_TEXTBTN | WWB_PUSHBUTTON,
00101   WWT_PUSHIMGBTN  = WWT_IMGBTN  | WWB_PUSHBUTTON,
00102 };
00103 
00105 enum SizingType {
00106   ST_SMALLEST, 
00107   ST_RESIZE,   
00108 };
00109 
00110 /* Forward declarations. */
00111 class NWidgetCore;
00112 class Scrollbar;
00113 
00120 class NWidgetBase : public ZeroedMemoryAllocator {
00121 public:
00122   NWidgetBase(WidgetType tp);
00123 
00124   virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
00125   virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) = 0;
00126 
00127   virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
00128 
00129   virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
00130   virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
00131 
00139   inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
00140   {
00141     this->padding_top = top;
00142     this->padding_right = right;
00143     this->padding_bottom = bottom;
00144     this->padding_left = left;
00145   };
00146 
00147   inline uint GetHorizontalStepSize(SizingType sizing) const;
00148   inline uint GetVerticalStepSize(SizingType sizing) const;
00149 
00150   virtual void Draw(const Window *w) = 0;
00151   virtual void SetDirty(const Window *w) const;
00152 
00153   WidgetType type;      
00154   uint fill_x;          
00155   uint fill_y;          
00156   uint resize_x;        
00157   uint resize_y;        
00158   /* Size of the widget in the smallest window possible.
00159    * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
00160    */
00161   uint smallest_x;      
00162   uint smallest_y;      
00163   /* Current widget size (that is, after resizing). */
00164   uint current_x;       
00165   uint current_y;       
00166 
00167   uint pos_x;           
00168   uint pos_y;           
00169 
00170   NWidgetBase *next;    
00171   NWidgetBase *prev;    
00172 
00173   uint8 padding_top;    
00174   uint8 padding_right;  
00175   uint8 padding_bottom; 
00176   uint8 padding_left;   
00177 
00178 protected:
00179   inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height);
00180 };
00181 
00186 inline uint NWidgetBase::GetHorizontalStepSize(SizingType sizing) const
00187 {
00188   return (sizing == ST_RESIZE) ? this->resize_x : this->fill_x;
00189 }
00190 
00195 inline uint NWidgetBase::GetVerticalStepSize(SizingType sizing) const
00196 {
00197   return (sizing == ST_RESIZE) ? this->resize_y : this->fill_y;
00198 }
00199 
00202 class NWidgetResizeBase : public NWidgetBase {
00203 public:
00204   NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y);
00205 
00206   void SetMinimalSize(uint min_x, uint min_y);
00207   void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size);
00208   void SetFill(uint fill_x, uint fill_y);
00209   void SetResize(uint resize_x, uint resize_y);
00210 
00211   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00212 
00213   uint min_x; 
00214   uint min_y; 
00215 };
00216 
00218 enum NWidgetDisplay {
00219   /* Generic. */
00220   NDB_LOWERED         = 0, 
00221   NDB_DISABLED        = 1, 
00222   /* Viewport widget. */
00223   NDB_NO_TRANSPARENCY = 2, 
00224   NDB_SHADE_GREY      = 3, 
00225   NDB_SHADE_DIMMED    = 4, 
00226   /* Button dropdown widget. */
00227   NDB_DROPDOWN_ACTIVE = 5, 
00228 
00229   ND_LOWERED  = 1 << NDB_LOWERED,                
00230   ND_DISABLED = 1 << NDB_DISABLED,               
00231   ND_NO_TRANSPARENCY = 1 << NDB_NO_TRANSPARENCY, 
00232   ND_SHADE_GREY      = 1 << NDB_SHADE_GREY,      
00233   ND_SHADE_DIMMED    = 1 << NDB_SHADE_DIMMED,    
00234   ND_DROPDOWN_ACTIVE = 1 << NDB_DROPDOWN_ACTIVE, 
00235 };
00236 DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay);
00237 
00240 class NWidgetCore : public NWidgetResizeBase {
00241 public:
00242   NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint16 widget_data, StringID tool_tip);
00243 
00244   void SetIndex(int index);
00245   void SetDataTip(uint16 widget_data, StringID tool_tip);
00246 
00247   inline void SetLowered(bool lowered);
00248   inline bool IsLowered() const;
00249   inline void SetDisabled(bool disabled);
00250   inline bool IsDisabled() const;
00251 
00252   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00253   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00254 
00255   virtual Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const = 0;
00256 
00257   NWidgetDisplay disp_flags; 
00258   Colours colour;            
00259   int index;                 
00260   uint16 widget_data;        
00261   StringID tool_tip;         
00262 };
00263 
00268 inline void NWidgetCore::SetLowered(bool lowered)
00269 {
00270   this->disp_flags = lowered ? SETBITS(this->disp_flags, ND_LOWERED) : CLRBITS(this->disp_flags, ND_LOWERED);
00271 }
00272 
00274 inline bool NWidgetCore::IsLowered() const
00275 {
00276   return HasBit(this->disp_flags, NDB_LOWERED);
00277 }
00278 
00283 inline void NWidgetCore::SetDisabled(bool disabled)
00284 {
00285   this->disp_flags = disabled ? SETBITS(this->disp_flags, ND_DISABLED) : CLRBITS(this->disp_flags, ND_DISABLED);
00286 }
00287 
00289 inline bool NWidgetCore::IsDisabled() const
00290 {
00291   return HasBit(this->disp_flags, NDB_DISABLED);
00292 }
00293 
00294 
00297 class NWidgetContainer : public NWidgetBase {
00298 public:
00299   NWidgetContainer(WidgetType tp);
00300   ~NWidgetContainer();
00301 
00302   void Add(NWidgetBase *wid);
00303   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00304 
00306   inline bool IsEmpty() { return head == NULL; };
00307 
00308   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00309 
00310 protected:
00311   NWidgetBase *head; 
00312   NWidgetBase *tail; 
00313 };
00314 
00316 enum StackedZeroSizePlanes {
00317   SZSP_VERTICAL = INT_MAX / 2, 
00318   SZSP_HORIZONTAL,             
00319   SZSP_NONE,                   
00320 
00321   SZSP_BEGIN = SZSP_VERTICAL,  
00322 };
00323 
00333 class NWidgetStacked : public NWidgetContainer {
00334 public:
00335   NWidgetStacked();
00336 
00337   void SetIndex(int index);
00338 
00339   void SetupSmallestSize(Window *w, bool init_array);
00340   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00341   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00342 
00343   /* virtual */ void Draw(const Window *w);
00344   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00345 
00346   void SetDisplayedPlane(int plane);
00347 
00348   int shown_plane; 
00349   int index;       
00350 };
00351 
00353 enum NWidContainerFlags {
00354   NCB_EQUALSIZE = 0, 
00355 
00356   NC_NONE = 0,                       
00357   NC_EQUALSIZE = 1 << NCB_EQUALSIZE, 
00358 };
00359 DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags);
00360 
00362 class NWidgetPIPContainer : public NWidgetContainer {
00363 public:
00364   NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE);
00365 
00366   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00367 
00368   /* virtual */ void Draw(const Window *w);
00369   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00370 
00371 protected:
00372   NWidContainerFlags flags; 
00373   uint8 pip_pre;            
00374   uint8 pip_inter;          
00375   uint8 pip_post;           
00376 };
00377 
00380 class NWidgetHorizontal : public NWidgetPIPContainer {
00381 public:
00382   NWidgetHorizontal(NWidContainerFlags flags = NC_NONE);
00383 
00384   void SetupSmallestSize(Window *w, bool init_array);
00385   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00386 };
00387 
00390 class NWidgetHorizontalLTR : public NWidgetHorizontal {
00391 public:
00392   NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
00393 
00394   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00395 };
00396 
00399 class NWidgetVertical : public NWidgetPIPContainer {
00400 public:
00401   NWidgetVertical(NWidContainerFlags flags = NC_NONE);
00402 
00403   void SetupSmallestSize(Window *w, bool init_array);
00404   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00405 };
00406 
00407 
00410 class NWidgetSpacer : public NWidgetResizeBase {
00411 public:
00412   NWidgetSpacer(int length, int height);
00413 
00414   void SetupSmallestSize(Window *w, bool init_array);
00415   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00416 
00417   /* virtual */ void Draw(const Window *w);
00418   /* virtual */ void SetDirty(const Window *w) const;
00419   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00420 };
00421 
00424 class NWidgetBackground : public NWidgetCore {
00425 public:
00426   NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
00427   ~NWidgetBackground();
00428 
00429   void Add(NWidgetBase *nwid);
00430   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00431 
00432   void SetupSmallestSize(Window *w, bool init_array);
00433   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00434 
00435   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00436 
00437   /* virtual */ void Draw(const Window *w);
00438   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00439   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00440   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
00441 
00442 private:
00443   NWidgetPIPContainer *child; 
00444 };
00445 
00454 class NWidgetViewport : public NWidgetCore {
00455 public:
00456   NWidgetViewport(int index);
00457 
00458   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00459   /* virtual */ void Draw(const Window *w);
00460   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
00461 
00462   void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
00463   void UpdateViewportCoordinates(Window *w);
00464 };
00465 
00468 class NWidgetLeaf : public NWidgetCore {
00469 public:
00470   NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
00471 
00472   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00473   /* virtual */ void Draw(const Window *w);
00474   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
00475 
00476   bool ButtonHit(const Point &pt);
00477 
00478   static void InvalidateDimensionCache();
00479 private:
00480   static Dimension shadebox_dimension;  
00481   static Dimension stickybox_dimension; 
00482   static Dimension resizebox_dimension; 
00483   static Dimension closebox_dimension;  
00484 };
00485 
00535 struct NWidgetPartDataTip {
00536   uint16 data;      
00537   StringID tooltip; 
00538 };
00539 
00542 struct NWidgetPartWidget {
00543   Colours colour; 
00544   int16 index;    
00545 };
00546 
00549 struct NWidgetPartPaddings {
00550   uint8 top, right, bottom, left; 
00551 };
00552 
00555 struct NWidgetPartPIP {
00556   uint8 pre, inter, post; 
00557 };
00558 
00561 struct NWidgetPartTextLines {
00562   uint8 lines;   
00563   uint8 spacing; 
00564   FontSize size; 
00565 };
00566 
00572 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
00573 
00576 struct NWidgetPart {
00577   WidgetType type;                         
00578   union {
00579     Point xy;                        
00580     NWidgetPartDataTip data_tip;     
00581     NWidgetPartWidget widget;        
00582     NWidgetPartPaddings padding;     
00583     NWidgetPartPIP pip;              
00584     NWidgetPartTextLines text_lines; 
00585     NWidgetFunctionType *func_ptr;   
00586     NWidContainerFlags cont_flags;   
00587   } u;
00588 };
00589 
00596 static inline NWidgetPart SetResize(int16 dx, int16 dy)
00597 {
00598   NWidgetPart part;
00599 
00600   part.type = WPT_RESIZE;
00601   part.u.xy.x = dx;
00602   part.u.xy.y = dy;
00603 
00604   return part;
00605 }
00606 
00613 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
00614 {
00615   NWidgetPart part;
00616 
00617   part.type = WPT_MINSIZE;
00618   part.u.xy.x = x;
00619   part.u.xy.y = y;
00620 
00621   return part;
00622 }
00623 
00631 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
00632 {
00633   NWidgetPart part;
00634 
00635   part.type = WPT_MINTEXTLINES;
00636   part.u.text_lines.lines = lines;
00637   part.u.text_lines.spacing = spacing;
00638   part.u.text_lines.size = size;
00639 
00640   return part;
00641 }
00642 
00649 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
00650 {
00651   NWidgetPart part;
00652 
00653   part.type = WPT_FILL;
00654   part.u.xy.x = fill_x;
00655   part.u.xy.y = fill_y;
00656 
00657   return part;
00658 }
00659 
00665 static inline NWidgetPart EndContainer()
00666 {
00667   NWidgetPart part;
00668 
00669   part.type = WPT_ENDCONTAINER;
00670 
00671   return part;
00672 }
00673 
00679 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
00680 {
00681   NWidgetPart part;
00682 
00683   part.type = WPT_DATATIP;
00684   part.u.data_tip.data = data;
00685   part.u.data_tip.tooltip = tip;
00686 
00687   return part;
00688 }
00689 
00699 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
00700 {
00701   NWidgetPart part;
00702 
00703   part.type = WPT_PADDING;
00704   part.u.padding.top = top;
00705   part.u.padding.right = right;
00706   part.u.padding.bottom = bottom;
00707   part.u.padding.left = left;
00708 
00709   return part;
00710 }
00711 
00717 static inline NWidgetPart SetPadding(uint8 padding)
00718 {
00719   return SetPadding(padding, padding, padding, padding);
00720 }
00721 
00729 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
00730 {
00731   NWidgetPart part;
00732 
00733   part.type = WPT_PIPSPACE;
00734   part.u.pip.pre = pre;
00735   part.u.pip.inter = inter;
00736   part.u.pip.post = post;
00737 
00738   return part;
00739 }
00740 
00750 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
00751 {
00752   NWidgetPart part;
00753 
00754   part.type = tp;
00755   part.u.widget.colour = col;
00756   part.u.widget.index = idx;
00757 
00758   return part;
00759 }
00760 
00767 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
00768 {
00769   NWidgetPart part;
00770 
00771   part.type = tp;
00772   part.u.cont_flags = cont_flags;
00773 
00774   return part;
00775 }
00776 
00782 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
00783 {
00784   NWidgetPart part;
00785 
00786   part.type = WPT_FUNCTION;
00787   part.u.func_ptr = func_ptr;
00788 
00789   return part;
00790 }
00791 
00792 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
00793 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
00794 
00795 #endif /* WIDGET_TYPE_H */

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