widget_type.h

Go to the documentation of this file.
00001 /* $Id$ */
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 "core/math_func.hpp"
00018 #include "strings_type.h"
00019 #include "gfx_type.h"
00020 #include "window_type.h"
00021 
00022 static const int WIDGET_LIST_END = -1; 
00023 
00025 enum MatrixWidgetValues {
00026   /* Number of column bits of the WWT_MATRIX widget data. */
00027   MAT_COL_START = 0, 
00028   MAT_COL_BITS  = 8, 
00029 
00030   /* Number of row bits of the WWT_MATRIX widget data. */
00031   MAT_ROW_START = 8, 
00032   MAT_ROW_BITS  = 8, 
00033 };
00034 
00036 enum ArrowWidgetValues {
00037   AWV_DECREASE, 
00038   AWV_INCREASE, 
00039   AWV_LEFT,     
00040   AWV_RIGHT,    
00041 };
00042 
00046 enum WidgetType {
00047   /* Window widget types. */
00048   WWT_EMPTY,      
00049 
00050   WWT_PANEL,      
00051   WWT_INSET,      
00052   WWT_IMGBTN,     
00053   WWT_IMGBTN_2,   
00054   WWT_ARROWBTN,   
00055   WWT_TEXTBTN,    
00056   WWT_TEXTBTN_2,  
00057   WWT_LABEL,      
00058   WWT_TEXT,       
00059   WWT_MATRIX,     
00060   WWT_FRAME,      
00061   WWT_CAPTION,    
00062 
00063   WWT_DEBUGBOX,   
00064   WWT_SHADEBOX,   
00065   WWT_DEFSIZEBOX, 
00066   WWT_STICKYBOX,  
00067 
00068   WWT_RESIZEBOX,  
00069   WWT_CLOSEBOX,   
00070   WWT_DROPDOWN,   
00071   WWT_EDITBOX,    
00072   WWT_LAST,       
00073 
00074   /* Nested widget types. */
00075   NWID_HORIZONTAL,      
00076   NWID_HORIZONTAL_LTR,  
00077   NWID_VERTICAL,        
00078   NWID_MATRIX,          
00079   NWID_SPACER,          
00080   NWID_SELECTION,       
00081   NWID_VIEWPORT,        
00082   NWID_BUTTON_DROPDOWN, 
00083   NWID_HSCROLLBAR,      
00084   NWID_VSCROLLBAR,      
00085 
00086   /* Nested widget part types. */
00087   WPT_RESIZE,       
00088   WPT_MINSIZE,      
00089   WPT_MINTEXTLINES, 
00090   WPT_FILL,         
00091   WPT_DATATIP,      
00092   WPT_PADDING,      
00093   WPT_PIPSPACE,     
00094   WPT_ENDCONTAINER, 
00095   WPT_FUNCTION,     
00096   WPT_SCROLLBAR,    
00097 
00098   /* Pushable window widget types. */
00099   WWT_MASK = 0x7F,
00100 
00101   WWB_PUSHBUTTON    = 1 << 7,
00102 
00103   WWT_PUSHBTN       = WWT_PANEL    | WWB_PUSHBUTTON,    
00104   WWT_PUSHTXTBTN    = WWT_TEXTBTN  | WWB_PUSHBUTTON,    
00105   WWT_PUSHIMGBTN    = WWT_IMGBTN   | WWB_PUSHBUTTON,    
00106   WWT_PUSHARROWBTN  = WWT_ARROWBTN | WWB_PUSHBUTTON,    
00107   NWID_PUSHBUTTON_DROPDOWN = NWID_BUTTON_DROPDOWN | WWB_PUSHBUTTON,
00108 };
00109 
00111 enum SizingType {
00112   ST_SMALLEST, 
00113   ST_RESIZE,   
00114 };
00115 
00116 /* Forward declarations. */
00117 class NWidgetCore;
00118 class Scrollbar;
00119 
00126 class NWidgetBase : public ZeroedMemoryAllocator {
00127 public:
00128   NWidgetBase(WidgetType tp);
00129 
00130   virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
00131   virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) = 0;
00132 
00133   virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
00134 
00135   virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
00136   virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
00137 
00138   virtual bool IsHighlighted() const { return false; }
00139   virtual TextColour GetHighlightColour() const { return TC_INVALID; }
00140   virtual void SetHighlighted(TextColour highlight_colour) {}
00141 
00149   inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
00150   {
00151     this->padding_top = top;
00152     this->padding_right = right;
00153     this->padding_bottom = bottom;
00154     this->padding_left = left;
00155   }
00156 
00157   inline uint GetHorizontalStepSize(SizingType sizing) const;
00158   inline uint GetVerticalStepSize(SizingType sizing) const;
00159 
00160   virtual void Draw(const Window *w) = 0;
00161   virtual void SetDirty(const Window *w) const;
00162 
00163   WidgetType type;      
00164   uint fill_x;          
00165   uint fill_y;          
00166   uint resize_x;        
00167   uint resize_y;        
00168   /* Size of the widget in the smallest window possible.
00169    * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
00170    */
00171   uint smallest_x;      
00172   uint smallest_y;      
00173   /* Current widget size (that is, after resizing). */
00174   uint current_x;       
00175   uint current_y;       
00176 
00177   uint pos_x;           
00178   uint pos_y;           
00179 
00180   NWidgetBase *next;    
00181   NWidgetBase *prev;    
00182 
00183   uint8 padding_top;    
00184   uint8 padding_right;  
00185   uint8 padding_bottom; 
00186   uint8 padding_left;   
00187 
00188 protected:
00189   inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height);
00190 };
00191 
00196 inline uint NWidgetBase::GetHorizontalStepSize(SizingType sizing) const
00197 {
00198   return (sizing == ST_RESIZE) ? this->resize_x : this->fill_x;
00199 }
00200 
00205 inline uint NWidgetBase::GetVerticalStepSize(SizingType sizing) const
00206 {
00207   return (sizing == ST_RESIZE) ? this->resize_y : this->fill_y;
00208 }
00209 
00218 inline void NWidgetBase::StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height)
00219 {
00220   this->pos_x = x;
00221   this->pos_y = y;
00222   if (sizing == ST_SMALLEST) {
00223     this->smallest_x = given_width;
00224     this->smallest_y = given_height;
00225   }
00226   this->current_x = given_width;
00227   this->current_y = given_height;
00228 }
00229 
00230 
00235 class NWidgetResizeBase : public NWidgetBase {
00236 public:
00237   NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y);
00238 
00239   void SetMinimalSize(uint min_x, uint min_y);
00240   void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size);
00241   void SetFill(uint fill_x, uint fill_y);
00242   void SetResize(uint resize_x, uint resize_y);
00243 
00244   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00245 
00246   uint min_x; 
00247   uint min_y; 
00248 };
00249 
00251 enum NWidgetDisplay {
00252   /* Generic. */
00253   NDB_LOWERED         = 0, 
00254   NDB_DISABLED        = 1, 
00255   /* Viewport widget. */
00256   NDB_NO_TRANSPARENCY = 2, 
00257   NDB_SHADE_GREY      = 3, 
00258   NDB_SHADE_DIMMED    = 4, 
00259   /* Button dropdown widget. */
00260   NDB_DROPDOWN_ACTIVE = 5, 
00261   /* Scrollbar widget. */
00262   NDB_SCROLLBAR_UP    = 6, 
00263   NDB_SCROLLBAR_DOWN  = 7, 
00264   /* Generic. */
00265   NDB_HIGHLIGHT       = 8, 
00266 
00267   ND_LOWERED  = 1 << NDB_LOWERED,                
00268   ND_DISABLED = 1 << NDB_DISABLED,               
00269   ND_HIGHLIGHT = 1 << NDB_HIGHLIGHT,             
00270   ND_NO_TRANSPARENCY = 1 << NDB_NO_TRANSPARENCY, 
00271   ND_SHADE_GREY      = 1 << NDB_SHADE_GREY,      
00272   ND_SHADE_DIMMED    = 1 << NDB_SHADE_DIMMED,    
00273   ND_DROPDOWN_ACTIVE = 1 << NDB_DROPDOWN_ACTIVE, 
00274   ND_SCROLLBAR_UP    = 1 << NDB_SCROLLBAR_UP,    
00275   ND_SCROLLBAR_DOWN  = 1 << NDB_SCROLLBAR_DOWN,  
00276   ND_SCROLLBAR_BTN   = ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN, 
00277 };
00278 DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay)
00279 
00280 
00284 class NWidgetCore : public NWidgetResizeBase {
00285 public:
00286   NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint32 widget_data, StringID tool_tip);
00287 
00288   void SetIndex(int index);
00289   void SetDataTip(uint32 widget_data, StringID tool_tip);
00290 
00291   inline void SetLowered(bool lowered);
00292   inline bool IsLowered() const;
00293   inline void SetDisabled(bool disabled);
00294   inline bool IsDisabled() const;
00295 
00296   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00297   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00298   /* virtual */ bool IsHighlighted() const;
00299   /* virtual */ TextColour GetHighlightColour() const;
00300   /* virtual */ void SetHighlighted(TextColour highlight_colour);
00301 
00302   NWidgetDisplay disp_flags; 
00303   Colours colour;            
00304   int index;                 
00305   uint32 widget_data;        
00306   StringID tool_tip;         
00307   int scrollbar_index;       
00308   TextColour highlight_colour; 
00309 };
00310 
00315 inline void NWidgetCore::SetHighlighted(TextColour highlight_colour)
00316 {
00317   this->disp_flags = highlight_colour != TC_INVALID ? SETBITS(this->disp_flags, ND_HIGHLIGHT) : CLRBITS(this->disp_flags, ND_HIGHLIGHT);
00318   this->highlight_colour = highlight_colour;
00319 }
00320 
00322 inline bool NWidgetCore::IsHighlighted() const
00323 {
00324   return HasBit(this->disp_flags, NDB_HIGHLIGHT);
00325 }
00326 
00328 inline TextColour NWidgetCore::GetHighlightColour() const
00329 {
00330   return this->highlight_colour;
00331 }
00332 
00337 inline void NWidgetCore::SetLowered(bool lowered)
00338 {
00339   this->disp_flags = lowered ? SETBITS(this->disp_flags, ND_LOWERED) : CLRBITS(this->disp_flags, ND_LOWERED);
00340 }
00341 
00343 inline bool NWidgetCore::IsLowered() const
00344 {
00345   return HasBit(this->disp_flags, NDB_LOWERED);
00346 }
00347 
00352 inline void NWidgetCore::SetDisabled(bool disabled)
00353 {
00354   this->disp_flags = disabled ? SETBITS(this->disp_flags, ND_DISABLED) : CLRBITS(this->disp_flags, ND_DISABLED);
00355 }
00356 
00358 inline bool NWidgetCore::IsDisabled() const
00359 {
00360   return HasBit(this->disp_flags, NDB_DISABLED);
00361 }
00362 
00363 
00368 class NWidgetContainer : public NWidgetBase {
00369 public:
00370   NWidgetContainer(WidgetType tp);
00371   ~NWidgetContainer();
00372 
00373   void Add(NWidgetBase *wid);
00374   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00375 
00377   inline bool IsEmpty() { return head == NULL; }
00378 
00379   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00380 
00381 protected:
00382   NWidgetBase *head; 
00383   NWidgetBase *tail; 
00384 };
00385 
00387 enum StackedZeroSizePlanes {
00388   SZSP_VERTICAL = INT_MAX / 2, 
00389   SZSP_HORIZONTAL,             
00390   SZSP_NONE,                   
00391 
00392   SZSP_BEGIN = SZSP_VERTICAL,  
00393 };
00394 
00405 class NWidgetStacked : public NWidgetContainer {
00406 public:
00407   NWidgetStacked();
00408 
00409   void SetIndex(int index);
00410 
00411   void SetupSmallestSize(Window *w, bool init_array);
00412   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00413   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00414 
00415   /* virtual */ void Draw(const Window *w);
00416   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00417 
00418   void SetDisplayedPlane(int plane);
00419 
00420   int shown_plane; 
00421   int index;       
00422 };
00423 
00425 enum NWidContainerFlags {
00426   NCB_EQUALSIZE = 0, 
00427 
00428   NC_NONE = 0,                       
00429   NC_EQUALSIZE = 1 << NCB_EQUALSIZE, 
00430 };
00431 DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags)
00432 
00433 
00434 class NWidgetPIPContainer : public NWidgetContainer {
00435 public:
00436   NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE);
00437 
00438   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00439 
00440   /* virtual */ void Draw(const Window *w);
00441   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00442 
00443 protected:
00444   NWidContainerFlags flags; 
00445   uint8 pip_pre;            
00446   uint8 pip_inter;          
00447   uint8 pip_post;           
00448 };
00449 
00454 class NWidgetHorizontal : public NWidgetPIPContainer {
00455 public:
00456   NWidgetHorizontal(NWidContainerFlags flags = NC_NONE);
00457 
00458   void SetupSmallestSize(Window *w, bool init_array);
00459   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00460 };
00461 
00466 class NWidgetHorizontalLTR : public NWidgetHorizontal {
00467 public:
00468   NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
00469 
00470   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00471 };
00472 
00477 class NWidgetVertical : public NWidgetPIPContainer {
00478 public:
00479   NWidgetVertical(NWidContainerFlags flags = NC_NONE);
00480 
00481   void SetupSmallestSize(Window *w, bool init_array);
00482   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00483 };
00484 
00493 class NWidgetMatrix : public NWidgetPIPContainer {
00494 public:
00495   NWidgetMatrix();
00496 
00497   void SetIndex(int index);
00498   void SetColour(Colours colour);
00499   void SetClicked(int clicked);
00500   void SetCount(int count);
00501   void SetScrollbar(Scrollbar *sb);
00502 
00503   void SetupSmallestSize(Window *w, bool init_array);
00504   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00505   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00506 
00507   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00508   /* virtual */ void Draw(const Window *w);
00509 protected:
00510   int index;      
00511   Colours colour; 
00512   int clicked;    
00513   int count;      
00514   Scrollbar *sb;  
00515 private:
00516   int widget_w;   
00517   int widget_h;   
00518   int widgets_x;  
00519   int widgets_y;  
00520 
00521   void GetScrollOffsets(int &start_x, int &start_y, int &base_offs_x, int &base_offs_y);
00522 };
00523 
00524 
00529 class NWidgetSpacer : public NWidgetResizeBase {
00530 public:
00531   NWidgetSpacer(int length, int height);
00532 
00533   void SetupSmallestSize(Window *w, bool init_array);
00534   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00535 
00536   /* virtual */ void Draw(const Window *w);
00537   /* virtual */ void SetDirty(const Window *w) const;
00538   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00539 };
00540 
00545 class NWidgetBackground : public NWidgetCore {
00546 public:
00547   NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
00548   ~NWidgetBackground();
00549 
00550   void Add(NWidgetBase *nwid);
00551   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00552 
00553   void SetupSmallestSize(Window *w, bool init_array);
00554   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00555 
00556   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00557 
00558   /* virtual */ void Draw(const Window *w);
00559   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00560   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00561 
00562 private:
00563   NWidgetPIPContainer *child; 
00564 };
00565 
00575 class NWidgetViewport : public NWidgetCore {
00576 public:
00577   NWidgetViewport(int index);
00578 
00579   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00580   /* virtual */ void Draw(const Window *w);
00581 
00582   void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
00583   void UpdateViewportCoordinates(Window *w);
00584 };
00585 
00589 class Scrollbar {
00590 private:
00591   const bool is_vertical; 
00592   uint16 count;           
00593   uint16 cap;             
00594   uint16 pos;             
00595   uint16 stepsize;        
00596 
00597 public:
00599   enum ScrollbarStepping {
00600     SS_RAW,             
00601     SS_SMALL,           
00602     SS_BIG,             
00603   };
00604 
00605   Scrollbar(bool is_vertical) : is_vertical(is_vertical), stepsize(1)
00606   {
00607   }
00608 
00613   inline uint16 GetCount() const
00614   {
00615     return this->count;
00616   }
00617 
00622   inline uint16 GetCapacity() const
00623   {
00624     return this->cap;
00625   }
00626 
00631   inline uint16 GetPosition() const
00632   {
00633     return this->pos;
00634   }
00635 
00641   inline bool IsVisible(uint16 item) const
00642   {
00643     return IsInsideBS(item, this->GetPosition(), this->GetCapacity());
00644   }
00645 
00650   inline bool IsVertical() const
00651   {
00652     return this->is_vertical;
00653   }
00654 
00659   void SetStepSize(uint16 stepsize)
00660   {
00661     assert(stepsize > 0);
00662     this->stepsize = stepsize;
00663   }
00664 
00670   void SetCount(int num)
00671   {
00672     assert(num >= 0);
00673     assert(num <= MAX_UVALUE(uint16));
00674 
00675     this->count = num;
00676     num -= this->cap;
00677     if (num < 0) num = 0;
00678     if (num < this->pos) this->pos = num;
00679   }
00680 
00686   void SetCapacity(int capacity)
00687   {
00688     assert(capacity > 0);
00689     assert(capacity <= MAX_UVALUE(uint16));
00690 
00691     this->cap = capacity;
00692     if (this->cap + this->pos > this->count) this->pos = max(0, this->count - this->cap);
00693   }
00694 
00695   void SetCapacityFromWidget(Window *w, int widget, int padding = 0);
00696 
00701   void SetPosition(int position)
00702   {
00703     assert(position >= 0);
00704     assert(this->count <= this->cap ? (position == 0) : (position + this->cap <= this->count));
00705     this->pos = position;
00706   }
00707 
00714   void UpdatePosition(int difference, ScrollbarStepping unit = SS_SMALL)
00715   {
00716     if (difference == 0) return;
00717     switch (unit) {
00718       case SS_SMALL: difference *= this->stepsize; break;
00719       case SS_BIG:   difference *= this->cap; break;
00720       default: break;
00721     }
00722     this->SetPosition(Clamp(this->pos + difference, 0, max(this->count - this->cap, 0)));
00723   }
00724 
00731   void ScrollTowards(int position)
00732   {
00733     if (position < this->GetPosition()) {
00734       /* scroll up to the item */
00735       this->SetPosition(position);
00736     } else if (position >= this->GetPosition() + this->GetCapacity()) {
00737       /* scroll down so that the item is at the bottom */
00738       this->SetPosition(position - this->GetCapacity() + 1);
00739     }
00740   }
00741 
00742   int GetScrolledRowFromWidget(int clickpos, const Window * const w, int widget, int padding = 0, int line_height = -1) const;
00743 };
00744 
00750 class NWidgetScrollbar : public NWidgetCore, public Scrollbar {
00751 public:
00752   NWidgetScrollbar(WidgetType tp, Colours colour, int index);
00753 
00754   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00755   /* virtual */ void Draw(const Window *w);
00756 
00757   static void InvalidateDimensionCache();
00758   static Dimension GetVerticalDimension();
00759   static Dimension GetHorizontalDimension();
00760 
00761 private:
00762   static Dimension vertical_dimension;   
00763   static Dimension horizontal_dimension; 
00764 };
00765 
00770 class NWidgetLeaf : public NWidgetCore {
00771 public:
00772   NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
00773 
00774   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00775   /* virtual */ void Draw(const Window *w);
00776 
00777   bool ButtonHit(const Point &pt);
00778 
00779   static void InvalidateDimensionCache();
00780 private:
00781   static Dimension shadebox_dimension;  
00782   static Dimension debugbox_dimension;  
00783   static Dimension defsizebox_dimension; 
00784   static Dimension stickybox_dimension; 
00785   static Dimension resizebox_dimension; 
00786   static Dimension closebox_dimension;  
00787 };
00788 
00796 static inline uint ComputeMaxSize(uint base, uint max_space, uint step)
00797 {
00798   if (base >= max_space || step == 0) return base;
00799   if (step == 1) return max_space;
00800   uint increment = max_space - base;
00801   increment -= increment % step;
00802   return base + increment;
00803 }
00804 
00856 struct NWidgetPartDataTip {
00857   uint16 data;      
00858   StringID tooltip; 
00859 };
00860 
00865 struct NWidgetPartWidget {
00866   Colours colour; 
00867   int16 index;    
00868 };
00869 
00874 struct NWidgetPartPaddings {
00875   uint8 top, right, bottom, left; 
00876 };
00877 
00882 struct NWidgetPartPIP {
00883   uint8 pre, inter, post; 
00884 };
00885 
00890 struct NWidgetPartTextLines {
00891   uint8 lines;   
00892   uint8 spacing; 
00893   FontSize size; 
00894 };
00895 
00902 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
00903 
00908 struct NWidgetPart {
00909   WidgetType type;                         
00910   union {
00911     Point xy;                        
00912     NWidgetPartDataTip data_tip;     
00913     NWidgetPartWidget widget;        
00914     NWidgetPartPaddings padding;     
00915     NWidgetPartPIP pip;              
00916     NWidgetPartTextLines text_lines; 
00917     NWidgetFunctionType *func_ptr;   
00918     NWidContainerFlags cont_flags;   
00919   } u;
00920 };
00921 
00928 static inline NWidgetPart SetResize(int16 dx, int16 dy)
00929 {
00930   NWidgetPart part;
00931 
00932   part.type = WPT_RESIZE;
00933   part.u.xy.x = dx;
00934   part.u.xy.y = dy;
00935 
00936   return part;
00937 }
00938 
00945 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
00946 {
00947   NWidgetPart part;
00948 
00949   part.type = WPT_MINSIZE;
00950   part.u.xy.x = x;
00951   part.u.xy.y = y;
00952 
00953   return part;
00954 }
00955 
00963 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
00964 {
00965   NWidgetPart part;
00966 
00967   part.type = WPT_MINTEXTLINES;
00968   part.u.text_lines.lines = lines;
00969   part.u.text_lines.spacing = spacing;
00970   part.u.text_lines.size = size;
00971 
00972   return part;
00973 }
00974 
00981 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
00982 {
00983   NWidgetPart part;
00984 
00985   part.type = WPT_FILL;
00986   part.u.xy.x = fill_x;
00987   part.u.xy.y = fill_y;
00988 
00989   return part;
00990 }
00991 
00997 static inline NWidgetPart EndContainer()
00998 {
00999   NWidgetPart part;
01000 
01001   part.type = WPT_ENDCONTAINER;
01002 
01003   return part;
01004 }
01005 
01012 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
01013 {
01014   NWidgetPart part;
01015 
01016   part.type = WPT_DATATIP;
01017   part.u.data_tip.data = data;
01018   part.u.data_tip.tooltip = tip;
01019 
01020   return part;
01021 }
01022 
01032 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
01033 {
01034   NWidgetPart part;
01035 
01036   part.type = WPT_PADDING;
01037   part.u.padding.top = top;
01038   part.u.padding.right = right;
01039   part.u.padding.bottom = bottom;
01040   part.u.padding.left = left;
01041 
01042   return part;
01043 }
01044 
01050 static inline NWidgetPart SetPadding(uint8 padding)
01051 {
01052   return SetPadding(padding, padding, padding, padding);
01053 }
01054 
01062 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
01063 {
01064   NWidgetPart part;
01065 
01066   part.type = WPT_PIPSPACE;
01067   part.u.pip.pre = pre;
01068   part.u.pip.inter = inter;
01069   part.u.pip.post = post;
01070 
01071   return part;
01072 }
01073 
01081 static inline NWidgetPart SetScrollbar(int index)
01082 {
01083   NWidgetPart part;
01084 
01085   part.type = WPT_SCROLLBAR;
01086   part.u.widget.index = index;
01087 
01088   return part;
01089 }
01090 
01100 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
01101 {
01102   NWidgetPart part;
01103 
01104   part.type = tp;
01105   part.u.widget.colour = col;
01106   part.u.widget.index = idx;
01107 
01108   return part;
01109 }
01110 
01117 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
01118 {
01119   NWidgetPart part;
01120 
01121   part.type = tp;
01122   part.u.cont_flags = cont_flags;
01123 
01124   return part;
01125 }
01126 
01132 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
01133 {
01134   NWidgetPart part;
01135 
01136   part.type = WPT_FUNCTION;
01137   part.u.func_ptr = func_ptr;
01138 
01139   return part;
01140 }
01141 
01142 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
01143 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
01144 
01145 NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, int max_length, StringID button_tooltip);
01146 
01147 #endif /* WIDGET_TYPE_H */