# 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/bitmath_func.hpp"
    00016 #include "strings_type.h"
    00017 #include "gfx_type.h"
    00018
    00019 enum {
    00020   WIDGET_LIST_END = -1,
    00021 };
    00022
    00024 enum MatrixWidgetValues {
    00025   /* Number of column bits of the WWT_MATRIX widget data. */
    00026   MAT_COL_START = 0,
    00027   MAT_COL_BITS  = 8,
    00028
    00029   /* Number of row bits of the WWT_MATRIX widget data. */
    00030   MAT_ROW_START = 8,
    00031   MAT_ROW_BITS  = 8,
    00032 };
    00033
    00035 enum ArrowWidgetValues {
    00036   AWV_DECREASE,
    00037   AWV_INCREASE,
    00038   AWV_LEFT,
    00039   AWV_RIGHT,
    00040 };
    00041
    00045 enum WidgetType {
    00046   /* Window widget types. */
    00047   WWT_EMPTY,
    00048
    00049   WWT_PANEL,
    00050   WWT_INSET,
    00051   WWT_IMGBTN,
    00052   WWT_IMGBTN_2,
    00053
    00054   WWT_TEXTBTN,
    00055   WWT_TEXTBTN_2,
    00056   WWT_LABEL,
    00057   WWT_TEXT,
    00058   WWT_MATRIX,
    00059   WWT_SCROLLBAR,
    00060   WWT_FRAME,
    00061   WWT_CAPTION,
    00062
    00063   WWT_HSCROLLBAR,
    00064   WWT_SHADEBOX,
    00065   WWT_STICKYBOX,
    00066   WWT_SCROLL2BAR,
    00067   WWT_RESIZEBOX,
    00068   WWT_CLOSEBOX,
    00069   WWT_DROPDOWN,
    00070   WWT_EDITBOX,
    00071   WWT_LAST,
    00072
    00073   /* Nested widget types. */
    00074   NWID_HORIZONTAL,
    00075   NWID_HORIZONTAL_LTR,
    00076   NWID_VERTICAL,
    00077   NWID_SPACER,
    00078   NWID_SELECTION,
    00079   NWID_VIEWPORT,
    00080   NWID_BUTTON_DROPDOWN,
    00081   NWID_BUTTON_ARROW,
    00082
    00083   /* Nested widget part types. */
    00084   WPT_RESIZE,
    00085   WPT_MINSIZE,
    00086   WPT_MINTEXTLINES,
    00087   WPT_FILL,
    00088   WPT_DATATIP,
    00089   WPT_PADDING,
    00090   WPT_PIPSPACE,
    00091   WPT_ENDCONTAINER,
    00092   WPT_FUNCTION,
    00093
    00094   /* Pushable window widget types. */
    00095   WWT_MASK = 0x7F,
    00096
    00097   WWB_PUSHBUTTON  = 1 << 7,
    00098
    00099   WWT_PUSHBTN     = WWT_PANEL   | WWB_PUSHBUTTON,
    00100   WWT_PUSHTXTBTN  = WWT_TEXTBTN | WWB_PUSHBUTTON,
    00101   WWT_PUSHIMGBTN  = WWT_IMGBTN  | WWB_PUSHBUTTON,
    00102 };
    00103
    00105 enum SizingType {
    00106   ST_SMALLEST,
    00107   ST_RESIZE,
    00108 };
    00109
    00110 /* Forward declarations. */
    00111 class NWidgetCore;
    00112 class Scrollbar;
    00113
    00120 class NWidgetBase : public ZeroedMemoryAllocator {
    00121 public:
    00122   NWidgetBase(WidgetType tp);
    00123
    00124   virtual void SetupSmallestSize(Window *w, bool init_array) = 0;
    00125   virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) = 0;
    00126
    00127   virtual void FillNestedArray(NWidgetBase **array, uint length) = 0;
    00128
    00129   virtual NWidgetCore *GetWidgetFromPos(int x, int y) = 0;
    00130   virtual NWidgetBase *GetWidgetOfType(WidgetType tp);
    00131
    00139   inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
    00140   {
    00141     this->padding_top = top;
    00142     this->padding_right = right;
    00143     this->padding_bottom = bottom;
    00144     this->padding_left = left;
    00145   };
    00146
    00147   inline uint GetHorizontalStepSize(SizingType sizing) const;
    00148   inline uint GetVerticalStepSize(SizingType sizing) const;
    00149
    00150   virtual void Draw(const Window *w) = 0;
    00151   virtual void SetDirty(const Window *w) const;
    00152
    00153   WidgetType type;
    00154   uint fill_x;
    00155   uint fill_y;
    00156   uint resize_x;
    00157   uint resize_y;
    00158   /* Size of the widget in the smallest window possible.
    00159    * Computed by #SetupSmallestSize() followed by #AssignSizePosition().
    00160    */
    00161   uint smallest_x;
    00162   uint smallest_y;
    00163   /* Current widget size (that is, after resizing). */
    00164   uint current_x;
    00165   uint current_y;
    00166
    00167   uint pos_x;
    00168   uint pos_y;
    00169
    00170   NWidgetBase *next;
    00171   NWidgetBase *prev;
    00172
    00173   uint8 padding_top;
    00174   uint8 padding_right;
    00175   uint8 padding_bottom;
    00176   uint8 padding_left;
    00177
    00178 protected:
    00179   inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height);
    00180 };
    00181
    00186 inline uint NWidgetBase::GetHorizontalStepSize(SizingType sizing) const
    00187 {
    00188   return (sizing == ST_RESIZE) ? this->resize_x : this->fill_x;
    00189 }
    00190
    00195 inline uint NWidgetBase::GetVerticalStepSize(SizingType sizing) const
    00196 {
    00197   return (sizing == ST_RESIZE) ? this->resize_y : this->fill_y;
    00198 }
    00199
    00202 class NWidgetResizeBase : public NWidgetBase {
    00203 public:
    00204   NWidgetResizeBase(WidgetType tp, uint fill_x, uint fill_y);
    00205
    00206   void SetMinimalSize(uint min_x, uint min_y);
    00207   void SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size);
    00208   void SetFill(uint fill_x, uint fill_y);
    00209   void SetResize(uint resize_x, uint resize_y);
    00210
    00211   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00212
    00213   uint min_x;
    00214   uint min_y;
    00215 };
    00216
    00218 enum NWidgetDisplay {
    00219   /* Generic. */
    00220   NDB_LOWERED         = 0,
    00221   NDB_DISABLED        = 1,
    00222   /* Viewport widget. */
    00223   NDB_NO_TRANSPARENCY = 2,
    00224   NDB_SHADE_GREY      = 3,
    00225   NDB_SHADE_DIMMED    = 4,
    00226   /* Button dropdown widget. */
    00227   NDB_DROPDOWN_ACTIVE = 5,
    00228
    00229   ND_LOWERED  = 1 << NDB_LOWERED,
    00230   ND_DISABLED = 1 << NDB_DISABLED,
    00231   ND_NO_TRANSPARENCY = 1 << NDB_NO_TRANSPARENCY,
    00232   ND_SHADE_GREY      = 1 << NDB_SHADE_GREY,
    00233   ND_SHADE_DIMMED    = 1 << NDB_SHADE_DIMMED,
    00234   ND_DROPDOWN_ACTIVE = 1 << NDB_DROPDOWN_ACTIVE,
    00235 };
    00236 DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay);
    00237
    00240 class NWidgetCore : public NWidgetResizeBase {
    00241 public:
    00242   NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y, uint16 widget_data, StringID tool_tip);
    00243
    00244   void SetIndex(int index);
    00245   void SetDataTip(uint16 widget_data, StringID tool_tip);
    00246
    00247   inline void SetLowered(bool lowered);
    00248   inline bool IsLowered() const;
    00249   inline void SetDisabled(bool disabled);
    00250   inline bool IsDisabled() const;
    00251
    00252   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00253   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00254
    00255   virtual Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const = 0;
    00256
    00257   NWidgetDisplay disp_flags;
    00258   Colours colour;
    00259   int index;
    00260   uint16 widget_data;
    00261   StringID tool_tip;
    00262 };
    00263
    00268 inline void NWidgetCore::SetLowered(bool lowered)
    00269 {
    00270   this->disp_flags = lowered ? SETBITS(this->disp_flags, ND_LOWERED) : CLRBITS(this->disp_flags, ND_LOWERED);
    00271 }
    00272
    00274 inline bool NWidgetCore::IsLowered() const
    00275 {
    00276   return HasBit(this->disp_flags, NDB_LOWERED);
    00277 }
    00278
    00283 inline void NWidgetCore::SetDisabled(bool disabled)
    00284 {
    00285   this->disp_flags = disabled ? SETBITS(this->disp_flags, ND_DISABLED) : CLRBITS(this->disp_flags, ND_DISABLED);
    00286 }
    00287
    00289 inline bool NWidgetCore::IsDisabled() const
    00290 {
    00291   return HasBit(this->disp_flags, NDB_DISABLED);
    00292 }
    00293
    00294
    00297 class NWidgetContainer : public NWidgetBase {
    00298 public:
    00299   NWidgetContainer(WidgetType tp);
    00300   ~NWidgetContainer();
    00301
    00302   void Add(NWidgetBase *wid);
    00303   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00304
    00306   inline bool IsEmpty() { return head == NULL; };
    00307
    00308   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
    00309
    00310 protected:
    00311   NWidgetBase *head;
    00312   NWidgetBase *tail;
    00313 };
    00314
    00316 enum StackedZeroSizePlanes {
    00317   SZSP_VERTICAL = INT_MAX / 2,
    00318   SZSP_HORIZONTAL,
    00319   SZSP_NONE,
    00320
    00321   SZSP_BEGIN = SZSP_VERTICAL,
    00322 };
    00323
    00333 class NWidgetStacked : public NWidgetContainer {
    00334 public:
    00335   NWidgetStacked();
    00336
    00337   void SetIndex(int index);
    00338
    00339   void SetupSmallestSize(Window *w, bool init_array);
    00340   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00341   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00342
    00343   /* virtual */ void Draw(const Window *w);
    00344   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00345
    00346   void SetDisplayedPlane(int plane);
    00347
    00348   int shown_plane;
    00349   int index;
    00350 };
    00351
    00353 enum NWidContainerFlags {
    00354   NCB_EQUALSIZE = 0,
    00355
    00356   NC_NONE = 0,
    00357   NC_EQUALSIZE = 1 << NCB_EQUALSIZE,
    00358 };
    00359 DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags);
    00360
    00362 class NWidgetPIPContainer : public NWidgetContainer {
    00363 public:
    00364   NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = NC_NONE);
    00365
    00366   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
    00367
    00368   /* virtual */ void Draw(const Window *w);
    00369   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00370
    00371 protected:
    00372   NWidContainerFlags flags;
    00373   uint8 pip_pre;
    00374   uint8 pip_inter;
    00375   uint8 pip_post;
    00376 };
    00377
    00380 class NWidgetHorizontal : public NWidgetPIPContainer {
    00381 public:
    00382   NWidgetHorizontal(NWidContainerFlags flags = NC_NONE);
    00383
    00384   void SetupSmallestSize(Window *w, bool init_array);
    00385   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00386 };
    00387
    00390 class NWidgetHorizontalLTR : public NWidgetHorizontal {
    00391 public:
    00392   NWidgetHorizontalLTR(NWidContainerFlags flags = NC_NONE);
    00393
    00394   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00395 };
    00396
    00399 class NWidgetVertical : public NWidgetPIPContainer {
    00400 public:
    00401   NWidgetVertical(NWidContainerFlags flags = NC_NONE);
    00402
    00403   void SetupSmallestSize(Window *w, bool init_array);
    00404   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00405 };
    00406
    00407
    00410 class NWidgetSpacer : public NWidgetResizeBase {
    00411 public:
    00412   NWidgetSpacer(int length, int height);
    00413
    00414   void SetupSmallestSize(Window *w, bool init_array);
    00415   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00416
    00417   /* virtual */ void Draw(const Window *w);
    00418   /* virtual */ void SetDirty(const Window *w) const;
    00419   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00420 };
    00421
    00424 class NWidgetBackground : public NWidgetCore {
    00425 public:
    00426   NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL);
    00427   ~NWidgetBackground();
    00428
    00429   void Add(NWidgetBase *nwid);
    00430   void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post);
    00431
    00432   void SetupSmallestSize(Window *w, bool init_array);
    00433   void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
    00434
    00435   /* virtual */ void FillNestedArray(NWidgetBase **array, uint length);
    00436
    00437   /* virtual */ void Draw(const Window *w);
    00438   /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y);
    00439   /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp);
    00440   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00441
    00442 private:
    00443   NWidgetPIPContainer *child;
    00444 };
    00445
    00454 class NWidgetViewport : public NWidgetCore {
    00455 public:
    00456   NWidgetViewport(int index);
    00457
    00458   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
    00459   /* virtual */ void Draw(const Window *w);
    00460   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00461
    00462   void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom);
    00463   void UpdateViewportCoordinates(Window *w);
    00464 };
    00465
    00468 class NWidgetLeaf : public NWidgetCore {
    00469 public:
    00470   NWidgetLeaf(WidgetType tp, Colours colour, int index, uint16 data, StringID tip);
    00471
    00472   /* virtual */ void SetupSmallestSize(Window *w, bool init_array);
    00473   /* virtual */ void Draw(const Window *w);
    00474   /* virtual */ Scrollbar *FindScrollbar(Window *w, bool allow_next = true) const;
    00475
    00476   bool ButtonHit(const Point &pt);
    00477
    00478   static void InvalidateDimensionCache();
    00479 private:
    00480   static Dimension shadebox_dimension;
    00481   static Dimension stickybox_dimension;
    00482   static Dimension resizebox_dimension;
    00483   static Dimension closebox_dimension;
    00484 };
    00485
    00535 struct NWidgetPartDataTip {
    00536   uint16 data;
    00537   StringID tooltip;
    00538 };
    00539
    00542 struct NWidgetPartWidget {
    00543   Colours colour;
    00544   int16 index;
    00545 };
    00546
    00549 struct NWidgetPartPaddings {
    00550   uint8 top, right, bottom, left;
    00551 };
    00552
    00555 struct NWidgetPartPIP {
    00556   uint8 pre, inter, post;
    00557 };
    00558
    00561 struct NWidgetPartTextLines {
    00562   uint8 lines;
    00563   uint8 spacing;
    00564   FontSize size;
    00565 };
    00566
    00572 typedef NWidgetBase *NWidgetFunctionType(int *biggest_index);
    00573
    00576 struct NWidgetPart {
    00577   WidgetType type;
    00578   union {
    00579     Point xy;
    00580     NWidgetPartDataTip data_tip;
    00581     NWidgetPartWidget widget;
    00582     NWidgetPartPaddings padding;
    00583     NWidgetPartPIP pip;
    00584     NWidgetPartTextLines text_lines;
    00585     NWidgetFunctionType *func_ptr;
    00586     NWidContainerFlags cont_flags;
    00587   } u;
    00588 };
    00589
    00596 static inline NWidgetPart SetResize(int16 dx, int16 dy)
    00597 {
    00598   NWidgetPart part;
    00599
    00600   part.type = WPT_RESIZE;
    00601   part.u.xy.x = dx;
    00602   part.u.xy.y = dy;
    00603
    00604   return part;
    00605 }
    00606
    00613 static inline NWidgetPart SetMinimalSize(int16 x, int16 y)
    00614 {
    00615   NWidgetPart part;
    00616
    00617   part.type = WPT_MINSIZE;
    00618   part.u.xy.x = x;
    00619   part.u.xy.y = y;
    00620
    00621   return part;
    00622 }
    00623
    00631 static inline NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size = FS_NORMAL)
    00632 {
    00633   NWidgetPart part;
    00634
    00635   part.type = WPT_MINTEXTLINES;
    00636   part.u.text_lines.lines = lines;
    00637   part.u.text_lines.spacing = spacing;
    00638   part.u.text_lines.size = size;
    00639
    00640   return part;
    00641 }
    00642
    00649 static inline NWidgetPart SetFill(uint fill_x, uint fill_y)
    00650 {
    00651   NWidgetPart part;
    00652
    00653   part.type = WPT_FILL;
    00654   part.u.xy.x = fill_x;
    00655   part.u.xy.y = fill_y;
    00656
    00657   return part;
    00658 }
    00659
    00665 static inline NWidgetPart EndContainer()
    00666 {
    00667   NWidgetPart part;
    00668
    00669   part.type = WPT_ENDCONTAINER;
    00670
    00671   return part;
    00672 }
    00673
    00679 static inline NWidgetPart SetDataTip(uint16 data, StringID tip)
    00680 {
    00681   NWidgetPart part;
    00682
    00683   part.type = WPT_DATATIP;
    00684   part.u.data_tip.data = data;
    00685   part.u.data_tip.tooltip = tip;
    00686
    00687   return part;
    00688 }
    00689
    00699 static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
    00700 {
    00701   NWidgetPart part;
    00702
    00703   part.type = WPT_PADDING;
    00704   part.u.padding.top = top;
    00705   part.u.padding.right = right;
    00706   part.u.padding.bottom = bottom;
    00707   part.u.padding.left = left;
    00708
    00709   return part;
    00710 }
    00711
    00717 static inline NWidgetPart SetPadding(uint8 padding)
    00718 {
    00719   return SetPadding(padding, padding, padding, padding);
    00720 }
    00721
    00729 static inline NWidgetPart SetPIP(uint8 pre, uint8 inter, uint8 post)
    00730 {
    00731   NWidgetPart part;
    00732
    00733   part.type = WPT_PIPSPACE;
    00734   part.u.pip.pre = pre;
    00735   part.u.pip.inter = inter;
    00736   part.u.pip.post = post;
    00737
    00738   return part;
    00739 }
    00740
    00750 static inline NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx = -1)
    00751 {
    00752   NWidgetPart part;
    00753
    00754   part.type = tp;
    00755   part.u.widget.colour = col;
    00756   part.u.widget.index = idx;
    00757
    00758   return part;
    00759 }
    00760
    00767 static inline NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = NC_NONE)
    00768 {
    00769   NWidgetPart part;
    00770
    00771   part.type = tp;
    00772   part.u.cont_flags = cont_flags;
    00773
    00774   return part;
    00775 }
    00776
    00782 static inline NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
    00783 {
    00784   NWidgetPart part;
    00785
    00786   part.type = WPT_FUNCTION;
    00787   part.u.func_ptr = func_ptr;
    00788
    00789   return part;
    00790 }
    00791
    00792 NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container);
    00793 NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select);
    00794
    00795 #endif /* WIDGET_TYPE_H */