# 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 };
    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 */