# 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_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 */