00001
00002
00003
00004
00005
00006
00007
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
00028 MAT_COL_START = 0,
00029 MAT_COL_BITS = 8,
00030
00031
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
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
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
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
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
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
00161
00162
00163 uint smallest_x;
00164 uint smallest_y;
00165
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
00222 NDB_LOWERED = 0,
00223 NDB_DISABLED = 1,
00224
00225 NDB_NO_TRANSPARENCY = 2,
00226 NDB_SHADE_GREY = 3,
00227 NDB_SHADE_DIMMED = 4,
00228
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 void FillNestedArray(NWidgetBase **array, uint length);
00255 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 void FillNestedArray(NWidgetBase **array, uint length);
00306
00308 inline bool IsEmpty() { return head == NULL; };
00309
00310 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 void FillNestedArray(NWidgetBase **array, uint length);
00344
00345 void Draw(const Window *w);
00346 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 void Draw(const Window *w);
00371 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 void FillNestedArray(NWidgetBase **array, uint length);
00418
00419 void Draw(const Window *w);
00420 void SetDirty(const Window *w) const;
00421 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 void FillNestedArray(NWidgetBase **array, uint length);
00438
00439 void Draw(const Window *w);
00440 NWidgetCore *GetWidgetFromPos(int x, int y);
00441 NWidgetBase *GetWidgetOfType(WidgetType tp);
00442 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 void SetupSmallestSize(Window *w, bool init_array);
00461 void Draw(const Window *w);
00462 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 void SetupSmallestSize(Window *w, bool init_array);
00475 void Draw(const Window *w);
00476 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