# widget_type.h

Go to the documentation of this file.

    00001 /* $Id: widget_type.h 18809 2010-01-15 16:41:15Z rubidium $ */
    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 "strings_type.h"
    00018 #include "gfx_type.h"
    00019 #include "window_type.h"
    00020
    00021 enum {
    00022   WIDGET_LIST_END = -1,
    00023 };
    00024
    00026 enum MatrixWidgetValues {
    00027   /* Number of column bits of the WWT_MATRIX widget data. */
    00028   MAT_COL_START = 0,
    00029   MAT_COL_BITS  = 8,
    00030
    00031   /* Number of row bits of the WWT_MATRIX widget data. */
    00032   MAT_ROW_START = 8,
    00033   MAT_ROW_BITS  = 8,
    00034 };
    00035
    00037 enum ArrowWidgetValues {
    00038   AWV_DECREASE,
    00039   AWV_INCREASE,
    00040   AWV_LEFT,
    00041   AWV_RIGHT,
    00042 };
    00043
    00047 enum WidgetType {
    00048   /* Window widget types. */
    00049   WWT_EMPTY,
    00050
    00051   WWT_PANEL,
    00052   WWT_INSET,
    00053   WWT_IMGBTN,
    00054   WWT_IMGBTN_2,
    00055
    00056   WWT_TEXTBTN,
    00057   WWT_TEXTBTN_2,
    00058   WWT_LABEL,
    00059   WWT_TEXT,
    00060   WWT_MATRIX,
    00061   WWT_SCROLLBAR,
    00062   WWT_FRAME,
    00063   WWT_CAPTION,
    00064
    00065   WWT_HSCROLLBAR,
    00066   WWT_SHADEBOX,
    00067   WWT_STICKYBOX,
    00068   WWT_SCROLL2BAR,
    00069   WWT_RESIZEBOX,
    00070   WWT_CLOSEBOX,
    00071   WWT_DROPDOWN,
    00072   WWT_EDITBOX,
    00073   WWT_LAST,
    00074
    00075   /* Nested widget types. */
    00076   NWID_HORIZONTAL,
    00077   NWID_HORIZONTAL_LTR,
    00078   NWID_VERTICAL,
    00079   NWID_SPACER,
    00080   NWID_SELECTION,
    00081   NWID_VIEWPORT,
    00082   NWID_BUTTON_DROPDOWN,
    00083   NWID_BUTTON_ARROW,
    00084
    00085   /* Nested widget part types. */
    00086   WPT_RESIZE,
    00087   WPT_MINSIZE,
    00088   WPT_MINTEXTLINES,
    00089   WPT_FILL,
    00090   WPT_DATATIP,
    00091   WPT_PADDING,
    00092   WPT_PIPSPACE,
    00093   WPT_ENDCONTAINER,
    00094   WPT_FUNCTION,
    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 };
    00105
    00107 enum SizingType {
    00108   ST_SMALLEST,
    00109   ST_RESIZE,
    00110 };
    00111
    00112 /* Forward declarations. */
    00113 class NWidgetCore;
    00114 class Scrollbar;
    00115
    00122 class NWidgetBase : public ZeroedMemoryAllocator {
    00123 public:
    00124   NWidgetBase(WidgetType tp);
    00125
    00126   virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
    00127   virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) = 0;
    00128
    00129   virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
    00130
    00131   virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
    00132   virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
    00133
    00141   inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
    00142   {
    00143     this->padding_top = top;
    00144     this->padding_right = right;
    00145     this->padding_bottom = bottom;
    00146     this->padding_left = left;
    00147   };
    00148
    00149   inline uint GetHorizontalStepSize(SizingType sizing) const;
    00150   inline uint GetVerticalStepSize(SizingType sizing) const;
    00151
    00152   virtual void Draw(const Window *w) = 0;
    00153   virtual void SetDirty(const Window *w) const;
    00154
    00155   WidgetType type;
    00156   uint fill_x;
    00157   uint fill_y;
    00158   uint resize_x;
    00159   uint resize_y;
    00160   /* Size of the widget in the smallest window possible.
    00161    * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
    00162    */
    00163   uint smallest_x;
    00164   uint smallest_y;
    00165   /* Current widget size (that is, after resizing). */
    00166   uint current_x;
    00167   uint current_y;
    00168
    00169   uint pos_x;
    00170   uint pos_y;
    00171
    00172   NWidgetBase *next;
    00173   NWidgetBase *prev;
    00174
    00175   uint8 padding_top;
    00176   uint8 padding_right;
    00177   uint8 padding_bottom;
    00178   uint8 padding_left;
    00179
    00180 protected:
    00181   inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height);
    00182 };
    00183
    00188 inline uint NWidgetBase::GetHorizontalStepSize(SizingType sizing) const
    00189 {
    00190   return (sizing == ST_RESIZE) ? this->resize_x : this->fill_x;
    00191 }
    00192
    00197 inline uint NWidgetBase::GetVerticalStepSize(SizingType sizing) const
    00198 {
    00199   return (sizing == ST_RESIZE) ? this->resize_y : this->fill_y;
    00200 }
    00201
    00204 class NWidgetResizeBase : public NWidgetBase {
    00205 public:
    00206   NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y);
    00207
    00208   void SetMinimalSize(uint min_x, uint min_y);
    00209   void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size);
    00210   void SetFill(uint fill_x, uint fill_y);
    00211   void SetResize(uint resize_x, uint resize_y);
    00212
    00213   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00214
    00215   uint min_x;
    00216   uint min_y;
    00217 };
    00218
    00220 enum NWidgetDisplay {
    00221   /* Generic. */
    00222   NDB_LOWERED         = 0,
    00223   NDB_DISABLED        = 1,
    00224   /* Viewport widget. */
    00225   NDB_NO_TRANSPARENCY = 2,
    00226   NDB_SHADE_GREY      = 3,
    00227   NDB_SHADE_DIMMED    = 4,
    00228   /* Button dropdown widget. */
    00229   NDB_DROPDOWN_ACTIVE = 5,
    00230
    00231   ND_LOWERED  = 1 << NDB_LOWERED,
    00232   ND_DISABLED = 1 << NDB_DISABLED,
    00233   ND_NO_TRANSPARENCY = 1 << NDB_NO_TRANSPARENCY,
    00234   ND_SHADE_GREY      = 1 << NDB_SHADE_GREY,
    00235   ND_SHADE_DIMMED    = 1 << NDB_SHADE_DIMMED,
    00236   ND_DROPDOWN_ACTIVE = 1 << NDB_DROPDOWN_ACTIVE,
    00237 };
    00238 DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay);
    00239
    00242 class NWidgetCore : public NWidgetResizeBase {
    00243 public:
    00244   NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint16 widget_data, StringID tool_tip);
    00245
    00246   void SetIndex(int index);
    00247   void SetDataTip(uint16 widget_data, StringID tool_tip);
    00248
    00249   inline void SetLowered(bool lowered);
    00250   inline bool IsLowered() const;
    00251   inline void SetDisabled(bool disabled);
    00252   inline bool IsDisabled() const;
    00253
    00254   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00255   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00256
    00257   virtual Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const = 0;
    00258
    00259   NWidgetDisplay disp_flags;
    00260   Colours colour;
    00261   int index;
    00262   uint16 widget_data;
    00263   StringID tool_tip;
    00264 };
    00265
    00270 inline void NWidgetCore::SetLowered(bool lowered)
    00271 {
    00272   this->disp_flags = lowered ? SETBITS(this->disp_flags, ND_LOWERED) : CLRBITS(this->disp_flags, ND_LOWERED);
    00273 }
    00274
    00276 inline bool NWidgetCore::IsLowered() const
    00277 {
    00278   return HasBit(this->disp_flags, NDB_LOWERED);
    00279 }
    00280
    00285 inline void NWidgetCore::SetDisabled(bool disabled)
    00286 {
    00287   this->disp_flags = disabled ? SETBITS(this->disp_flags, ND_DISABLED) : CLRBITS(this->disp_flags, ND_DISABLED);
    00288 }
    00289
    00291 inline bool NWidgetCore::IsDisabled() const
    00292 {
    00293   return HasBit(this->disp_flags, NDB_DISABLED);
    00294 }
    00295
    00296
    00299 class NWidgetContainer : public NWidgetBase {
    00300 public:
    00301   NWidgetContainer(WidgetType tp);
    00302   ~NWidgetContainer();
    00303
    00304   void Add(NWidgetBase *wid);
    00305   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00306
    00308   inline bool IsEmpty() { return head == NULL; };
    00309
    00310   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
    00311
    00312 protected:
    00313   NWidgetBase *head;
    00314   NWidgetBase *tail;
    00315 };
    00316
    00318 enum StackedZeroSizePlanes {
    00319   SZSP_VERTICAL = INT_MAX / 2,
    00320   SZSP_HORIZONTAL,
    00321   SZSP_NONE,
    00322
    00323   SZSP_BEGIN = SZSP_VERTICAL,
    00324 };
    00325
    00335 class NWidgetStacked : public NWidgetContainer {
    00336 public:
    00337   NWidgetStacked();
    00338
    00339   void SetIndex(int index);
    00340
    00341   void SetupSmallestSize(Window *w, bool init_array);
    00342   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00343   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00344
    00345   /* virtual */ void Draw(const Window *w);
    00346   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00347
    00348   void SetDisplayedPlane(int plane);
    00349
    00350   int shown_plane;
    00351   int index;
    00352 };
    00353
    00355 enum NWidContainerFlags {
    00356   NCB_EQUALSIZE = 0,
    00357
    00358   NC_NONE = 0,
    00359   NC_EQUALSIZE = 1 << NCB_EQUALSIZE,
    00360 };
    00361 DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags);
    00362
    00364 class NWidgetPIPContainer : public NWidgetContainer {
    00365 public:
    00366   NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE);
    00367
    00368   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
    00369
    00370   /* virtual */ void Draw(const Window *w);
    00371   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00372
    00373 protected:
    00374   NWidContainerFlags flags;
    00375   uint8 pip_pre;
    00376   uint8 pip_inter;
    00377   uint8 pip_post;
    00378 };
    00379
    00382 class NWidgetHorizontal : public NWidgetPIPContainer {
    00383 public:
    00384   NWidgetHorizontal(NWidContainerFlags flags = NC_NONE);
    00385
    00386   void SetupSmallestSize(Window *w, bool init_array);
    00387   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00388 };
    00389
    00392 class NWidgetHorizontalLTR : public NWidgetHorizontal {
    00393 public:
    00394   NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
    00395
    00396   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00397 };
    00398
    00401 class NWidgetVertical : public NWidgetPIPContainer {
    00402 public:
    00403   NWidgetVertical(NWidContainerFlags flags = NC_NONE);
    00404
    00405   void SetupSmallestSize(Window *w, bool init_array);
    00406   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00407 };
    00408
    00409
    00412 class NWidgetSpacer : public NWidgetResizeBase {
    00413 public:
    00414   NWidgetSpacer(int length, int height);
    00415
    00416   void SetupSmallestSize(Window *w, bool init_array);
    00417   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00418
    00419   /* virtual */ void Draw(const Window *w);
    00420   /* virtual */ void SetDirty(const Window *w) const;
    00421   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00422 };
    00423
    00426 class NWidgetBackground : public NWidgetCore {
    00427 public:
    00428   NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
    00429   ~NWidgetBackground();
    00430
    00431   void Add(NWidgetBase *nwid);
    00432   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
    00433
    00434   void SetupSmallestSize(Window *w, bool init_array);
    00435   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00436
    00437   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00438
    00439   /* virtual */ void Draw(const Window *w);
    00440   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00441   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
    00442   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00443
    00444 private:
    00445   NWidgetPIPContainer *child;
    00446 };
    00447
    00456 class NWidgetViewport : public NWidgetCore {
    00457 public:
    00458   NWidgetViewport(int index);
    00459
    00460   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
    00461   /* virtual */ void Draw(const Window *w);
    00462   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00463
    00464   void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
    00465   void UpdateViewportCoordinates(Window *w);
    00466 };
    00467
    00470 class NWidgetLeaf : public NWidgetCore {
    00471 public:
    00472   NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
    00473
    00474   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
    00475   /* virtual */ void Draw(const Window *w);
    00476   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00477
    00478   bool ButtonHit(const Point &pt);
    00479
    00480   static void InvalidateDimensionCache();
    00481 private:
    00482   static Dimension shadebox_dimension;
    00483   static Dimension stickybox_dimension;
    00484   static Dimension resizebox_dimension;
    00485   static Dimension closebox_dimension;
    00486 };
    00487
    00537 struct NWidgetPartDataTip {
    00538   uint16 data;
    00539   StringID tooltip;
    00540 };
    00541
    00544 struct NWidgetPartWidget {
    00545   Colours colour;
    00546   int16 index;
    00547 };
    00548
    00551 struct NWidgetPartPaddings {
    00552   uint8 top, right, bottom, left;
    00553 };
    00554
    00557 struct NWidgetPartPIP {
    00558   uint8 pre, inter, post;
    00559 };
    00560
    00563 struct NWidgetPartTextLines {
    00564   uint8 lines;
    00565   uint8 spacing;
    00566   FontSize size;
    00567 };
    00568
    00574 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
    00575
    00578 struct NWidgetPart {
    00579   WidgetType type;
    00580   union {
    00581     Point xy;
    00582     NWidgetPartDataTip data_tip;
    00583     NWidgetPartWidget widget;
    00584     NWidgetPartPaddings padding;
    00585     NWidgetPartPIP pip;
    00586     NWidgetPartTextLines text_lines;
    00587     NWidgetFunctionType *func_ptr;
    00588     NWidContainerFlags cont_flags;
    00589   } u;
    00590 };
    00591
    00598 static inline NWidgetPart SetResize(int16 dx, int16 dy)
    00599 {
    00600   NWidgetPart part;
    00601
    00602   part.type = WPT_RESIZE;
    00603   part.u.xy.x = dx;
    00604   part.u.xy.y = dy;
    00605
    00606   return part;
    00607 }
    00608
    00615 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
    00616 {
    00617   NWidgetPart part;
    00618
    00619   part.type = WPT_MINSIZE;
    00620   part.u.xy.x = x;
    00621   part.u.xy.y = y;
    00622
    00623   return part;
    00624 }
    00625
    00633 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
    00634 {
    00635   NWidgetPart part;
    00636
    00637   part.type = WPT_MINTEXTLINES;
    00638   part.u.text_lines.lines = lines;
    00639   part.u.text_lines.spacing = spacing;
    00640   part.u.text_lines.size = size;
    00641
    00642   return part;
    00643 }
    00644
    00651 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
    00652 {
    00653   NWidgetPart part;
    00654
    00655   part.type = WPT_FILL;
    00656   part.u.xy.x = fill_x;
    00657   part.u.xy.y = fill_y;
    00658
    00659   return part;
    00660 }
    00661
    00667 static inline NWidgetPart EndContainer()
    00668 {
    00669   NWidgetPart part;
    00670
    00671   part.type = WPT_ENDCONTAINER;
    00672
    00673   return part;
    00674 }
    00675
    00681 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
    00682 {
    00683   NWidgetPart part;
    00684
    00685   part.type = WPT_DATATIP;
    00686   part.u.data_tip.data = data;
    00687   part.u.data_tip.tooltip = tip;
    00688
    00689   return part;
    00690 }
    00691
    00701 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
    00702 {
    00703   NWidgetPart part;
    00704
    00705   part.type = WPT_PADDING;
    00706   part.u.padding.top = top;
    00707   part.u.padding.right = right;
    00708   part.u.padding.bottom = bottom;
    00709   part.u.padding.left = left;
    00710
    00711   return part;
    00712 }
    00713
    00719 static inline NWidgetPart SetPadding(uint8 padding)
    00720 {
    00721   return SetPadding(padding, padding, padding, padding);
    00722 }
    00723
    00731 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
    00732 {
    00733   NWidgetPart part;
    00734
    00735   part.type = WPT_PIPSPACE;
    00736   part.u.pip.pre = pre;
    00737   part.u.pip.inter = inter;
    00738   part.u.pip.post = post;
    00739
    00740   return part;
    00741 }
    00742
    00752 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
    00753 {
    00754   NWidgetPart part;
    00755
    00756   part.type = tp;
    00757   part.u.widget.colour = col;
    00758   part.u.widget.index = idx;
    00759
    00760   return part;
    00761 }
    00762
    00769 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
    00770 {
    00771   NWidgetPart part;
    00772
    00773   part.type = tp;
    00774   part.u.cont_flags = cont_flags;
    00775
    00776   return part;
    00777 }
    00778
    00784 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
    00785 {
    00786   NWidgetPart part;
    00787
    00788   part.type = WPT_FUNCTION;
    00789   part.u.func_ptr = func_ptr;
    00790
    00791   return part;
    00792 }
    00793
    00794 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
    00795 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
    00796
    00797 #endif /* WIDGET_TYPE_H */