widget_type.h

Go to the documentation of this file.
00001 /* $Id: widget_type.h 25864 2013-10-13 19:18:30Z 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_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 
00781   static Dimension dropdown_dimension;  
00782 private:
00783   static Dimension shadebox_dimension;  
00784   static Dimension debugbox_dimension;  
00785   static Dimension defsizebox_dimension; 
00786   static Dimension stickybox_dimension; 
00787   static Dimension resizebox_dimension; 
00788   static Dimension closebox_dimension;  
00789 };
00790 
00798 static inline uint ComputeMaxSize(uint base, uint max_space, uint step)
00799 {
00800   if (base >= max_space || step == 0) return base;
00801   if (step == 1) return max_space;
00802   uint increment = max_space - base;
00803   increment -= increment % step;
00804   return base + increment;
00805 }
00806 
00858 struct NWidgetPartDataTip {
00859   uint16 data;      
00860   StringID tooltip; 
00861 };
00862 
00867 struct NWidgetPartWidget {
00868   Colours colour; 
00869   int16 index;    
00870 };
00871 
00876 struct NWidgetPartPaddings {
00877   uint8 top, right, bottom, left; 
00878 };
00879 
00884 struct NWidgetPartPIP {
00885   uint8 pre, inter, post; 
00886 };
00887 
00892 struct NWidgetPartTextLines {
00893   uint8 lines;   
00894   uint8 spacing; 
00895   FontSize size; 
00896 };
00897 
00904 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
00905 
00910 struct NWidgetPart {
00911   WidgetType type;                         
00912   union {
00913     Point xy;                        
00914     NWidgetPartDataTip data_tip;     
00915     NWidgetPartWidget widget;        
00916     NWidgetPartPaddings padding;     
00917     NWidgetPartPIP pip;              
00918     NWidgetPartTextLines text_lines; 
00919     NWidgetFunctionType *func_ptr;   
00920     NWidContainerFlags cont_flags;   
00921   } u;
00922 };
00923 
00930 static inline NWidgetPart SetResize(int16 dx, int16 dy)
00931 {
00932   NWidgetPart part;
00933 
00934   part.type = WPT_RESIZE;
00935   part.u.xy.x = dx;
00936   part.u.xy.y = dy;
00937 
00938   return part;
00939 }
00940 
00947 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
00948 {
00949   NWidgetPart part;
00950 
00951   part.type = WPT_MINSIZE;
00952   part.u.xy.x = x;
00953   part.u.xy.y = y;
00954 
00955   return part;
00956 }
00957 
00965 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
00966 {
00967   NWidgetPart part;
00968 
00969   part.type = WPT_MINTEXTLINES;
00970   part.u.text_lines.lines = lines;
00971   part.u.text_lines.spacing = spacing;
00972   part.u.text_lines.size = size;
00973 
00974   return part;
00975 }
00976 
00983 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
00984 {
00985   NWidgetPart part;
00986 
00987   part.type = WPT_FILL;
00988   part.u.xy.x = fill_x;
00989   part.u.xy.y = fill_y;
00990 
00991   return part;
00992 }
00993 
00999 static inline NWidgetPart EndContainer()
01000 {
01001   NWidgetPart part;
01002 
01003   part.type = WPT_ENDCONTAINER;
01004 
01005   return part;
01006 }
01007 
01014 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
01015 {
01016   NWidgetPart part;
01017 
01018   part.type = WPT_DATATIP;
01019   part.u.data_tip.data = data;
01020   part.u.data_tip.tooltip = tip;
01021 
01022   return part;
01023 }
01024 
01032 static inline NWidgetPart SetMatrixDataTip(uint8 cols, uint8 rows, StringID tip)
01033 {
01034   return SetDataTip((rows << MAT_ROW_START) | (cols << MAT_COL_START), tip);
01035 }
01036 
01046 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
01047 {
01048   NWidgetPart part;
01049 
01050   part.type = WPT_PADDING;
01051   part.u.padding.top = top;
01052   part.u.padding.right = right;
01053   part.u.padding.bottom = bottom;
01054   part.u.padding.left = left;
01055 
01056   return part;
01057 }
01058 
01064 static inline NWidgetPart SetPadding(uint8 padding)
01065 {
01066   return SetPadding(padding, padding, padding, padding);
01067 }
01068 
01076 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
01077 {
01078   NWidgetPart part;
01079 
01080   part.type = WPT_PIPSPACE;
01081   part.u.pip.pre = pre;
01082   part.u.pip.inter = inter;
01083   part.u.pip.post = post;
01084 
01085   return part;
01086 }
01087 
01095 static inline NWidgetPart SetScrollbar(int index)
01096 {
01097   NWidgetPart part;
01098 
01099   part.type = WPT_SCROLLBAR;
01100   part.u.widget.index = index;
01101 
01102   return part;
01103 }
01104 
01114 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
01115 {
01116   NWidgetPart part;
01117 
01118   part.type = tp;
01119   part.u.widget.colour = col;
01120   part.u.widget.index = idx;
01121 
01122   return part;
01123 }
01124 
01131 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
01132 {
01133   NWidgetPart part;
01134 
01135   part.type = tp;
01136   part.u.cont_flags = cont_flags;
01137 
01138   return part;
01139 }
01140 
01146 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
01147 {
01148   NWidgetPart part;
01149 
01150   part.type = WPT_FUNCTION;
01151   part.u.func_ptr = func_ptr;
01152 
01153   return part;
01154 }
01155 
01156 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
01157 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
01158 
01159 NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, int max_length, StringID button_tooltip);
01160 
01161 #endif /* WIDGET_TYPE_H */