widget_type.h

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