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