widget_type.h

Go to the documentation of this file.
00001 /* $Id: widget_type.h 23640 2011-12-20 17:57:56Z truebrain $ */
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_SHADEBOX,   
00064   WWT_STICKYBOX,  
00065   WWT_DEBUGBOX,   
00066   WWT_RESIZEBOX,  
00067   WWT_CLOSEBOX,   
00068   WWT_DROPDOWN,   
00069   WWT_EDITBOX,    
00070   WWT_LAST,       
00071 
00072   /* Nested widget types. */
00073   NWID_HORIZONTAL,      
00074   NWID_HORIZONTAL_LTR,  
00075   NWID_VERTICAL,        
00076   NWID_MATRIX,          
00077   NWID_SPACER,          
00078   NWID_SELECTION,       
00079   NWID_VIEWPORT,        
00080   NWID_BUTTON_DROPDOWN, 
00081   NWID_HSCROLLBAR,      
00082   NWID_VSCROLLBAR,      
00083 
00084   /* Nested widget part types. */
00085   WPT_RESIZE,       
00086   WPT_MINSIZE,      
00087   WPT_MINTEXTLINES, 
00088   WPT_FILL,         
00089   WPT_DATATIP,      
00090   WPT_PADDING,      
00091   WPT_PIPSPACE,     
00092   WPT_ENDCONTAINER, 
00093   WPT_FUNCTION,     
00094   WPT_SCROLLBAR,    
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   WWT_PUSHARROWBTN  = WWT_ARROWBTN | WWB_PUSHBUTTON,
00105 };
00106 
00108 enum SizingType {
00109   ST_SMALLEST, 
00110   ST_RESIZE,   
00111 };
00112 
00113 /* Forward declarations. */
00114 class NWidgetCore;
00115 class Scrollbar;
00116 
00123 class NWidgetBase : public ZeroedMemoryAllocator {
00124 public:
00125   NWidgetBase(WidgetType tp);
00126 
00127   virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
00128   virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) = 0;
00129 
00130   virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
00131 
00132   virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
00133   virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
00134 
00135   virtual bool IsHighlighted() const { return false; }
00136   virtual TextColour GetHighlightColour() const { return TC_INVALID; }
00137   virtual void SetHighlighted(TextColour highlight_colour) {}
00138 
00146   inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
00147   {
00148     this->padding_top = top;
00149     this->padding_right = right;
00150     this->padding_bottom = bottom;
00151     this->padding_left = left;
00152   }
00153 
00154   inline uint GetHorizontalStepSize(SizingType sizing) const;
00155   inline uint GetVerticalStepSize(SizingType sizing) const;
00156 
00157   virtual void Draw(const Window *w) = 0;
00158   virtual void SetDirty(const Window *w) const;
00159 
00160   WidgetType type;      
00161   uint fill_x;          
00162   uint fill_y;          
00163   uint resize_x;        
00164   uint resize_y;        
00165   /* Size of the widget in the smallest window possible.
00166    * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
00167    */
00168   uint smallest_x;      
00169   uint smallest_y;      
00170   /* Current widget size (that is, after resizing). */
00171   uint current_x;       
00172   uint current_y;       
00173 
00174   uint pos_x;           
00175   uint pos_y;           
00176 
00177   NWidgetBase *next;    
00178   NWidgetBase *prev;    
00179 
00180   uint8 padding_top;    
00181   uint8 padding_right;  
00182   uint8 padding_bottom; 
00183   uint8 padding_left;   
00184 
00185 protected:
00186   inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height);
00187 };
00188 
00193 inline uint NWidgetBase::GetHorizontalStepSize(SizingType sizing) const
00194 {
00195   return (sizing == ST_RESIZE) ? this->resize_x : this->fill_x;
00196 }
00197 
00202 inline uint NWidgetBase::GetVerticalStepSize(SizingType sizing) const
00203 {
00204   return (sizing == ST_RESIZE) ? this->resize_y : this->fill_y;
00205 }
00206 
00215 inline void NWidgetBase::StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height)
00216 {
00217   this->pos_x = x;
00218   this->pos_y = y;
00219   if (sizing == ST_SMALLEST) {
00220     this->smallest_x = given_width;
00221     this->smallest_y = given_height;
00222   }
00223   this->current_x = given_width;
00224   this->current_y = given_height;
00225 }
00226 
00227 
00232 class NWidgetResizeBase : public NWidgetBase {
00233 public:
00234   NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y);
00235 
00236   void SetMinimalSize(uint min_x, uint min_y);
00237   void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size);
00238   void SetFill(uint fill_x, uint fill_y);
00239   void SetResize(uint resize_x, uint resize_y);
00240 
00241   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00242 
00243   uint min_x; 
00244   uint min_y; 
00245 };
00246 
00248 enum NWidgetDisplay {
00249   /* Generic. */
00250   NDB_LOWERED         = 0, 
00251   NDB_DISABLED        = 1, 
00252   /* Viewport widget. */
00253   NDB_NO_TRANSPARENCY = 2, 
00254   NDB_SHADE_GREY      = 3, 
00255   NDB_SHADE_DIMMED    = 4, 
00256   /* Button dropdown widget. */
00257   NDB_DROPDOWN_ACTIVE = 5, 
00258   /* Scrollbar widget. */
00259   NDB_SCROLLBAR_UP    = 6, 
00260   NDB_SCROLLBAR_DOWN  = 7, 
00261   /* Generic. */
00262   NDB_HIGHLIGHT       = 8, 
00263 
00264   ND_LOWERED  = 1 << NDB_LOWERED,                
00265   ND_DISABLED = 1 << NDB_DISABLED,               
00266   ND_HIGHLIGHT = 1 << NDB_HIGHLIGHT,             
00267   ND_NO_TRANSPARENCY = 1 << NDB_NO_TRANSPARENCY, 
00268   ND_SHADE_GREY      = 1 << NDB_SHADE_GREY,      
00269   ND_SHADE_DIMMED    = 1 << NDB_SHADE_DIMMED,    
00270   ND_DROPDOWN_ACTIVE = 1 << NDB_DROPDOWN_ACTIVE, 
00271   ND_SCROLLBAR_UP    = 1 << NDB_SCROLLBAR_UP,    
00272   ND_SCROLLBAR_DOWN  = 1 << NDB_SCROLLBAR_DOWN,  
00273   ND_SCROLLBAR_BTN   = ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN, 
00274 };
00275 DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay)
00276 
00277 
00281 class NWidgetCore : public NWidgetResizeBase {
00282 public:
00283   NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint16 widget_data, StringID tool_tip);
00284 
00285   void SetIndex(int index);
00286   void SetDataTip(uint16 widget_data, StringID tool_tip);
00287 
00288   inline void SetLowered(bool lowered);
00289   inline bool IsLowered() const;
00290   inline void SetDisabled(bool disabled);
00291   inline bool IsDisabled() const;
00292 
00293   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00294   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00295   /* virtual */ bool IsHighlighted() const;
00296   /* virtual */ TextColour GetHighlightColour() const;
00297   /* virtual */ void SetHighlighted(TextColour highlight_colour);
00298 
00299   NWidgetDisplay disp_flags; 
00300   Colours colour;            
00301   int index;                 
00302   uint16 widget_data;        
00303   StringID tool_tip;         
00304   int scrollbar_index;       
00305   TextColour highlight_colour; 
00306 };
00307 
00312 inline void NWidgetCore::SetHighlighted(TextColour highlight_colour)
00313 {
00314   this->disp_flags = highlight_colour != TC_INVALID ? SETBITS(this->disp_flags, ND_HIGHLIGHT) : CLRBITS(this->disp_flags, ND_HIGHLIGHT);
00315   this->highlight_colour = highlight_colour;
00316 }
00317 
00319 inline bool NWidgetCore::IsHighlighted() const
00320 {
00321   return HasBit(this->disp_flags, NDB_HIGHLIGHT);
00322 }
00323 
00325 inline TextColour NWidgetCore::GetHighlightColour() const
00326 {
00327   return this->highlight_colour;
00328 }
00329 
00334 inline void NWidgetCore::SetLowered(bool lowered)
00335 {
00336   this->disp_flags = lowered ? SETBITS(this->disp_flags, ND_LOWERED) : CLRBITS(this->disp_flags, ND_LOWERED);
00337 }
00338 
00340 inline bool NWidgetCore::IsLowered() const
00341 {
00342   return HasBit(this->disp_flags, NDB_LOWERED);
00343 }
00344 
00349 inline void NWidgetCore::SetDisabled(bool disabled)
00350 {
00351   this->disp_flags = disabled ? SETBITS(this->disp_flags, ND_DISABLED) : CLRBITS(this->disp_flags, ND_DISABLED);
00352 }
00353 
00355 inline bool NWidgetCore::IsDisabled() const
00356 {
00357   return HasBit(this->disp_flags, NDB_DISABLED);
00358 }
00359 
00360 
00365 class NWidgetContainer : public NWidgetBase {
00366 public:
00367   NWidgetContainer(WidgetType tp);
00368   ~NWidgetContainer();
00369 
00370   void Add(NWidgetBase *wid);
00371   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00372 
00374   inline bool IsEmpty() { return head == NULL; }
00375 
00376   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00377 
00378 protected:
00379   NWidgetBase *head; 
00380   NWidgetBase *tail; 
00381 };
00382 
00384 enum StackedZeroSizePlanes {
00385   SZSP_VERTICAL = INT_MAX / 2, 
00386   SZSP_HORIZONTAL,             
00387   SZSP_NONE,                   
00388 
00389   SZSP_BEGIN = SZSP_VERTICAL,  
00390 };
00391 
00402 class NWidgetStacked : public NWidgetContainer {
00403 public:
00404   NWidgetStacked();
00405 
00406   void SetIndex(int index);
00407 
00408   void SetupSmallestSize(Window *w, bool init_array);
00409   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00410   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00411 
00412   /* virtual */ void Draw(const Window *w);
00413   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00414 
00415   void SetDisplayedPlane(int plane);
00416 
00417   int shown_plane; 
00418   int index;       
00419 };
00420 
00422 enum NWidContainerFlags {
00423   NCB_EQUALSIZE = 0, 
00424 
00425   NC_NONE = 0,                       
00426   NC_EQUALSIZE = 1 << NCB_EQUALSIZE, 
00427 };
00428 DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags)
00429 
00430 
00431 class NWidgetPIPContainer : public NWidgetContainer {
00432 public:
00433   NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE);
00434 
00435   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00436 
00437   /* virtual */ void Draw(const Window *w);
00438   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00439 
00440 protected:
00441   NWidContainerFlags flags; 
00442   uint8 pip_pre;            
00443   uint8 pip_inter;          
00444   uint8 pip_post;           
00445 };
00446 
00451 class NWidgetHorizontal : public NWidgetPIPContainer {
00452 public:
00453   NWidgetHorizontal(NWidContainerFlags flags = NC_NONE);
00454 
00455   void SetupSmallestSize(Window *w, bool init_array);
00456   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00457 };
00458 
00463 class NWidgetHorizontalLTR : public NWidgetHorizontal {
00464 public:
00465   NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
00466 
00467   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00468 };
00469 
00474 class NWidgetVertical : public NWidgetPIPContainer {
00475 public:
00476   NWidgetVertical(NWidContainerFlags flags = NC_NONE);
00477 
00478   void SetupSmallestSize(Window *w, bool init_array);
00479   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00480 };
00481 
00490 class NWidgetMatrix : public NWidgetPIPContainer {
00491 public:
00492   NWidgetMatrix();
00493 
00494   void SetIndex(int index);
00495   void SetColour(Colours colour);
00496   void SetClicked(int clicked);
00497   void SetCount(int count);
00498   void SetScrollbar(Scrollbar *sb);
00499 
00500   void SetupSmallestSize(Window *w, bool init_array);
00501   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00502   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00503 
00504   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00505   /* virtual */ void Draw(const Window *w);
00506 protected:
00507   int index;      
00508   Colours colour; 
00509   int clicked;    
00510   int count;      
00511   Scrollbar *sb;  
00512 private:
00513   int widget_w;   
00514   int widget_h;   
00515   int widgets_x;  
00516   int widgets_y;  
00517 
00518   void GetScrollOffsets(int &start_x, int &start_y, int &base_offs_x, int &base_offs_y);
00519 };
00520 
00521 
00526 class NWidgetSpacer : public NWidgetResizeBase {
00527 public:
00528   NWidgetSpacer(int length, int height);
00529 
00530   void SetupSmallestSize(Window *w, bool init_array);
00531   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00532 
00533   /* virtual */ void Draw(const Window *w);
00534   /* virtual */ void SetDirty(const Window *w) const;
00535   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00536 };
00537 
00542 class NWidgetBackground : public NWidgetCore {
00543 public:
00544   NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
00545   ~NWidgetBackground();
00546 
00547   void Add(NWidgetBase *nwid);
00548   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
00549 
00550   void SetupSmallestSize(Window *w, bool init_array);
00551   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
00552 
00553   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
00554 
00555   /* virtual */ void Draw(const Window *w);
00556   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
00557   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
00558 
00559 private:
00560   NWidgetPIPContainer *child; 
00561 };
00562 
00572 class NWidgetViewport : public NWidgetCore {
00573 public:
00574   NWidgetViewport(int index);
00575 
00576   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00577   /* virtual */ void Draw(const Window *w);
00578 
00579   void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
00580   void UpdateViewportCoordinates(Window *w);
00581 };
00582 
00586 class Scrollbar {
00587 private:
00588   const bool is_vertical; 
00589   uint16 count;           
00590   uint16 cap;             
00591   uint16 pos;             
00592   uint16 stepsize;        
00593 
00594 public:
00596   enum ScrollbarStepping {
00597     SS_RAW,             
00598     SS_SMALL,           
00599     SS_BIG,             
00600   };
00601 
00602   Scrollbar(bool is_vertical) : is_vertical(is_vertical), stepsize(1)
00603   {
00604   }
00605 
00610   inline uint16 GetCount() const
00611   {
00612     return this->count;
00613   }
00614 
00619   inline uint16 GetCapacity() const
00620   {
00621     return this->cap;
00622   }
00623 
00628   inline uint16 GetPosition() const
00629   {
00630     return this->pos;
00631   }
00632 
00638   inline bool IsVisible(uint16 item) const
00639   {
00640     return IsInsideBS(item, this->GetPosition(), this->GetCapacity());
00641   }
00642 
00647   inline bool IsVertical() const
00648   {
00649     return this->is_vertical;
00650   }
00651 
00656   void SetStepSize(uint16 stepsize)
00657   {
00658     assert(stepsize > 0);
00659     this->stepsize = stepsize;
00660   }
00661 
00667   void SetCount(int num)
00668   {
00669     assert(num >= 0);
00670     assert(num <= MAX_UVALUE(uint16));
00671 
00672     this->count = num;
00673     num -= this->cap;
00674     if (num < 0) num = 0;
00675     if (num < this->pos) this->pos = num;
00676   }
00677 
00683   void SetCapacity(int capacity)
00684   {
00685     assert(capacity > 0);
00686     assert(capacity <= MAX_UVALUE(uint16));
00687 
00688     this->cap = capacity;
00689     if (this->cap + this->pos > this->count) this->pos = max(0, this->count - this->cap);
00690   }
00691 
00692   void SetCapacityFromWidget(Window *w, int widget, int padding = 0);
00693 
00698   void SetPosition(int position)
00699   {
00700     assert(position >= 0);
00701     assert(this->count <= this->cap ? (position == 0) : (position + this->cap <= this->count));
00702     this->pos = position;
00703   }
00704 
00711   void UpdatePosition(int difference, ScrollbarStepping unit = SS_SMALL)
00712   {
00713     if (difference == 0) return;
00714     switch (unit) {
00715       case SS_SMALL: difference *= this->stepsize; break;
00716       case SS_BIG:   difference *= this->cap; break;
00717       default: break;
00718     }
00719     this->SetPosition(Clamp(this->pos + difference, 0, max(this->count - this->cap, 0)));
00720   }
00721 
00728   void ScrollTowards(int position)
00729   {
00730     if (position < this->GetPosition()) {
00731       /* scroll up to the item */
00732       this->SetPosition(position);
00733     } else if (position >= this->GetPosition() + this->GetCapacity()) {
00734       /* scroll down so that the item is at the bottom */
00735       this->SetPosition(position - this->GetCapacity() + 1);
00736     }
00737   }
00738 
00739   int GetScrolledRowFromWidget(int clickpos, const Window * const w, int widget, int padding = 0, int line_height = -1) const;
00740 };
00741 
00747 class NWidgetScrollbar : public NWidgetCore, public Scrollbar {
00748 public:
00749   NWidgetScrollbar(WidgetType tp, Colours colour, int index);
00750 
00751   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00752   /* virtual */ void Draw(const Window *w);
00753 
00754   static void InvalidateDimensionCache();
00755   static Dimension GetVerticalDimension();
00756   static Dimension GetHorizontalDimension();
00757 
00758 private:
00759   static Dimension vertical_dimension;   
00760   static Dimension horizontal_dimension; 
00761 };
00762 
00767 class NWidgetLeaf : public NWidgetCore {
00768 public:
00769   NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
00770 
00771   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
00772   /* virtual */ void Draw(const Window *w);
00773 
00774   bool ButtonHit(const Point &pt);
00775 
00776   static void InvalidateDimensionCache();
00777 private:
00778   static Dimension shadebox_dimension;  
00779   static Dimension debugbox_dimension;  
00780   static Dimension stickybox_dimension; 
00781   static Dimension resizebox_dimension; 
00782   static Dimension closebox_dimension;  
00783 };
00784 
00792 static inline uint ComputeMaxSize(uint base, uint max_space, uint step)
00793 {
00794   if (base >= max_space || step == 0) return base;
00795   if (step == 1) return max_space;
00796   uint increment = max_space - base;
00797   increment -= increment % step;
00798   return base + increment;
00799 }
00800 
00852 struct NWidgetPartDataTip {
00853   uint16 data;      
00854   StringID tooltip; 
00855 };
00856 
00861 struct NWidgetPartWidget {
00862   Colours colour; 
00863   int16 index;    
00864 };
00865 
00870 struct NWidgetPartPaddings {
00871   uint8 top, right, bottom, left; 
00872 };
00873 
00878 struct NWidgetPartPIP {
00879   uint8 pre, inter, post; 
00880 };
00881 
00886 struct NWidgetPartTextLines {
00887   uint8 lines;   
00888   uint8 spacing; 
00889   FontSize size; 
00890 };
00891 
00898 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
00899 
00904 struct NWidgetPart {
00905   WidgetType type;                         
00906   union {
00907     Point xy;                        
00908     NWidgetPartDataTip data_tip;     
00909     NWidgetPartWidget widget;        
00910     NWidgetPartPaddings padding;     
00911     NWidgetPartPIP pip;              
00912     NWidgetPartTextLines text_lines; 
00913     NWidgetFunctionType *func_ptr;   
00914     NWidContainerFlags cont_flags;   
00915   } u;
00916 };
00917 
00924 static inline NWidgetPart SetResize(int16 dx, int16 dy)
00925 {
00926   NWidgetPart part;
00927 
00928   part.type = WPT_RESIZE;
00929   part.u.xy.x = dx;
00930   part.u.xy.y = dy;
00931 
00932   return part;
00933 }
00934 
00941 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
00942 {
00943   NWidgetPart part;
00944 
00945   part.type = WPT_MINSIZE;
00946   part.u.xy.x = x;
00947   part.u.xy.y = y;
00948 
00949   return part;
00950 }
00951 
00959 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
00960 {
00961   NWidgetPart part;
00962 
00963   part.type = WPT_MINTEXTLINES;
00964   part.u.text_lines.lines = lines;
00965   part.u.text_lines.spacing = spacing;
00966   part.u.text_lines.size = size;
00967 
00968   return part;
00969 }
00970 
00977 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
00978 {
00979   NWidgetPart part;
00980 
00981   part.type = WPT_FILL;
00982   part.u.xy.x = fill_x;
00983   part.u.xy.y = fill_y;
00984 
00985   return part;
00986 }
00987 
00993 static inline NWidgetPart EndContainer()
00994 {
00995   NWidgetPart part;
00996 
00997   part.type = WPT_ENDCONTAINER;
00998 
00999   return part;
01000 }
01001 
01008 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
01009 {
01010   NWidgetPart part;
01011 
01012   part.type = WPT_DATATIP;
01013   part.u.data_tip.data = data;
01014   part.u.data_tip.tooltip = tip;
01015 
01016   return part;
01017 }
01018 
01028 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
01029 {
01030   NWidgetPart part;
01031 
01032   part.type = WPT_PADDING;
01033   part.u.padding.top = top;
01034   part.u.padding.right = right;
01035   part.u.padding.bottom = bottom;
01036   part.u.padding.left = left;
01037 
01038   return part;
01039 }
01040 
01046 static inline NWidgetPart SetPadding(uint8 padding)
01047 {
01048   return SetPadding(padding, padding, padding, padding);
01049 }
01050 
01058 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
01059 {
01060   NWidgetPart part;
01061 
01062   part.type = WPT_PIPSPACE;
01063   part.u.pip.pre = pre;
01064   part.u.pip.inter = inter;
01065   part.u.pip.post = post;
01066 
01067   return part;
01068 }
01069 
01077 static inline NWidgetPart SetScrollbar(int index)
01078 {
01079   NWidgetPart part;
01080 
01081   part.type = WPT_SCROLLBAR;
01082   part.u.widget.index = index;
01083 
01084   return part;
01085 }
01086 
01096 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
01097 {
01098   NWidgetPart part;
01099 
01100   part.type = tp;
01101   part.u.widget.colour = col;
01102   part.u.widget.index = idx;
01103 
01104   return part;
01105 }
01106 
01113 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
01114 {
01115   NWidgetPart part;
01116 
01117   part.type = tp;
01118   part.u.cont_flags = cont_flags;
01119 
01120   return part;
01121 }
01122 
01128 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
01129 {
01130   NWidgetPart part;
01131 
01132   part.type = WPT_FUNCTION;
01133   part.u.func_ptr = func_ptr;
01134 
01135   return part;
01136 }
01137 
01138 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
01139 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
01140 
01141 NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, int max_length, StringID button_tooltip);
01142 
01143 #endif /* WIDGET_TYPE_H */