widget_type.h

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

Generated on Sat Apr 17 23:24:56 2010 for OpenTTD by  doxygen 1.6.1