00001
00002
00003
00004
00005
00006
00007
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
00026 MAT_COL_START = 0,
00027 MAT_COL_BITS = 8,
00028
00029
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
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
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
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
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
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
00159
00160
00161 uint smallest_x;
00162 uint smallest_y;
00163
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
00220 NDB_LOWERED = 0,
00221 NDB_DISABLED = 1,
00222
00223 NDB_NO_TRANSPARENCY = 2,
00224 NDB_SHADE_GREY = 3,
00225 NDB_SHADE_DIMMED = 4,
00226
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 void FillNestedArray(NWidgetBase **array, uint length);
00253 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 void FillNestedArray(NWidgetBase **array, uint length);
00304
00306 inline bool IsEmpty() { return head == NULL; };
00307
00308 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 void FillNestedArray(NWidgetBase **array, uint length);
00342
00343 void Draw(const Window *w);
00344 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 void Draw(const Window *w);
00369 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 void FillNestedArray(NWidgetBase **array, uint length);
00416
00417 void Draw(const Window *w);
00418 void SetDirty(const Window *w) const;
00419 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 void FillNestedArray(NWidgetBase **array, uint length);
00436
00437 void Draw(const Window *w);
00438 NWidgetCore *GetWidgetFromPos(int x, int y);
00439 NWidgetBase *GetWidgetOfType(WidgetType tp);
00440 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 void SetupSmallestSize(Window *w, bool init_array);
00459 void Draw(const Window *w);
00460 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 void SetupSmallestSize(Window *w, bool init_array);
00473 void Draw(const Window *w);
00474 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