OpenTTD Source: src/widgets/dropdown_type.h Source File

OpenTTD Source 14.0-RC3

dropdown_type.h
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10 #ifndef WIDGETS_DROPDOWN_TYPE_H
11 #define WIDGETS_DROPDOWN_TYPE_H
12
13 #include "../window_type.h"
14 #include "../gfx_func.h"
15 #include "../gfx_type.h"
16 #include "../palette_func.h"
17 #include "../string_func.h"
18 #include "../strings_func.h"
19 #include "../table/strings.h"
20 #include "../window_gui.h"
21
25 class DropDownListItem {
26 public:
27 int result;
28 bool masked;
29 bool shaded;
30
31 explicit DropDownListItem(int result, bool masked = false, bool shaded = false) : result(result), masked(masked), shaded(shaded) {}
32 virtual ~DropDownListItem() = default;
33
34 virtual bool Selectable() const { return true; }
35 virtual uint Height() const { return 0; }
36 virtual uint Width() const { return 0; }
37
38 virtual void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const
39 {
40 if (this->masked) GfxFillRect(full, _colour_gradient[bg_colour][5], FILLRECT_CHECKER);
41 }
42
43 TextColour GetColour(bool sel) const
44 {
45 if (this->shaded) return (sel ? TC_SILVER : TC_GREY) | TC_NO_SHADE;
46 return sel ? TC_WHITE : TC_BLACK;
47 }
48 };
49
55 template<class TBase, FontSize TFs = FS_NORMAL>
56 class DropDownDivider : public TBase {
57 public:
58 template <typename... Args>
59 explicit DropDownDivider(Args&&... args) : TBase(std::forward<Args>(args)...) {}
60
61 bool Selectable() const override { return false; }
62 uint Height() const override { return std::max<uint>(GetCharacterHeight(TFs), this->TBase::Height()); }
63
64 void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const override
65 {
66 uint8_t c1 = _colour_gradient[bg_colour][3];
67 uint8_t c2 = _colour_gradient[bg_colour][7];
68
69 int mid = CenterBounds(full.top, full.bottom, 0);
70 GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1);
71 GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2);
72 }
73 };
74
81 template<class TBase, FontSize TFs = FS_NORMAL, bool TEnd = false>
82 class DropDownString : public TBase {
83 std::string string;
84 Dimension dim;
85 public:
86 template <typename... Args>
87 explicit DropDownString(StringID string, Args&&... args) : TBase(std::forward<Args>(args)...)
88 {
89 this->SetString(GetString(string));
90 }
91
92 template <typename... Args>
93 explicit DropDownString(const std::string &string, Args&&... args) : TBase(std::forward<Args>(args)...)
94 {
95 SetDParamStr(0, string);
96 this->SetString(GetString(STR_JUST_RAW_STRING));
97 }
98
99 void SetString(std::string &&string)
100 {
101 this->string = std::move(string);
102 this->dim = GetStringBoundingBox(this->string, TFs);
103 }
104
105 uint Height() const override
106 {
107 return std::max<uint>(this->dim.height, this->TBase::Height());
108 }
109
110 uint Width() const override { return this->dim.width + this->TBase::Width(); }
111
112 void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
113 {
114 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
115 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs);
116 this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, bg_colour);
117 }
118
126 static bool NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second)
127 {
128 const std::string &str1 = static_cast<const DropDownString*>(first.get())->string;
129 const std::string &str2 = static_cast<const DropDownString*>(second.get())->string;
130 return StrNaturalCompare(str1, str2) < 0;
131 }
132 };
133
139 template<class TBase, bool TEnd = false>
140 class DropDownIcon : public TBase {
141 SpriteID sprite;
142 PaletteID palette;
143 Dimension dsprite;
144 Dimension dbounds;
145 public:
146 template <typename... Args>
147 explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette)
148 {
149 this->dsprite = GetSpriteSize(this->sprite);
150 this->dbounds = this->dsprite;
151 }
152
153 template <typename... Args>
154 explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette), dbounds(dim)
155 {
156 this->dsprite = GetSpriteSize(this->sprite);
157 }
158
159 uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
160 uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
161
162 void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
163 {
164 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
165 Rect ir = r.WithWidth(this->dbounds.width, rtl);
166 DrawSprite(this->sprite, this->palette, CenterBounds(ir.left, ir.right, this->dsprite.width), CenterBounds(r.top, r.bottom, this->dsprite.height));
167 this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, bg_colour);
168 }
169 };
170
177 template<class TBase, bool TEnd = false, FontSize TFs = FS_NORMAL>
178 class DropDownCheck : public TBase {
179 bool checked;
180 Dimension dim;
181 public:
182 template <typename... Args>
183 explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward<Args>(args)...), checked(checked)
184 {
185 this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs);
186 }
187
188 uint Height() const override { return std::max<uint>(this->dim.height, this->TBase::Height()); }
189 uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
190
191 void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
192 {
193 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
194 if (this->checked) {
195 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs);
196 }
197 this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, bg_colour);
198 }
199 };
200
201 /* Commonly used drop down list items. */
202 using DropDownListDividerItem = DropDownDivider<DropDownListItem>;
203 using DropDownListStringItem = DropDownString<DropDownListItem>;
204 using DropDownListIconItem = DropDownIcon<DropDownString<DropDownListItem>>;
205 using DropDownListCheckedItem = DropDownCheck<DropDownString<DropDownListItem>>;
206
210 typedef std::vector<std::unique_ptr<const DropDownListItem>> DropDownList;
211
212 void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, bool instant_close = false, bool persist = false);
213
214 void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width = 0, bool instant_close = false, bool persist = false);
215
216 Dimension GetDropDownListDimension(const DropDownList &list);
217
218 void ReplaceDropDownList(Window *parent, DropDownList &&list);
219
220 #endif /* WIDGETS_DROPDOWN_TYPE_H */
ShowDropDownListAt
void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, bool instant_close=false, bool persist=false)
Show a drop down list.
Definition: dropdown.cpp:351
DropDownDivider
Drop down divider component.
Definition: dropdown_type.h:56
DropDownListItem::result
int result
Result value to return to window on selection.
Definition: dropdown_type.h:27
Height
int16_t Height
Fixed point type for heights.
Definition: tgp.cpp:153
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:30
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition: window_gui.h:68
DropDownString::NatSortFunc
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
Definition: dropdown_type.h:126
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
DropDownList
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Definition: dropdown_type.h:210
GetDropDownListDimension
Dimension GetDropDownListDimension(const DropDownList &list)
Determine width and height required to fully display a DropDownList.
Definition: dropdown.cpp:328
FILLRECT_CHECKER
@ FILLRECT_CHECKER
Draw only every second pixel, used for greying-out.
Definition: gfx_type.h:294
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:253
StrNaturalCompare
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition: string.cpp:585
DropDownListItem
Base list item class from which others are derived.
Definition: dropdown_type.h:25
WidgetDimensions::hsep_wide
int hsep_wide
Wide horizontal spacing.
Definition: window_gui.h:64
PaletteID
uint32_t PaletteID
The number of the palette.
Definition: gfx_type.h:18
_colour_gradient
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Definition: palette.cpp:26
DropDownIcon
Drop down icon component.
Definition: dropdown_type.h:140
DropDownIcon::dbounds
Dimension dbounds
Bounding box dimensions of bounds.
Definition: dropdown_type.h:144
DropDownListItem::shaded
bool shaded
Shaded item, affects text colour.
Definition: dropdown_type.h:29
WidgetID
int WidgetID
Widget ID.
Definition: window_type.h:18
DropDownIcon::sprite
SpriteID sprite
Sprite ID to be drawn.
Definition: dropdown_type.h:141
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition: geometry_type.hpp:198
TC_NO_SHADE
@ TC_NO_SHADE
Do not add shading to this text colour.
Definition: gfx_type.h:277
Rect::WithWidth
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Definition: geometry_type.hpp:185
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:1003
CenterBounds
int CenterBounds(int min, int max, int size)
Determine where to draw a centred object inside a widget.
Definition: gfx_func.h:166
GfxFillRect
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition: gfx.cpp:113
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
DropDownString::string
std::string string
String to be drawn.
Definition: dropdown_type.h:83
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:937
DrawStringMultiLine
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:771
DropDownString::dim
Dimension dim
Dimensions of string.
Definition: dropdown_type.h:84
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition: strings.cpp:327
SetDParamStr
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:352
SA_CENTER
@ SA_CENTER
Center both horizontally and vertically.
Definition: gfx_type.h:348
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition: fontcache.cpp:78
DropDownCheck
Drop down checkmark component.
Definition: dropdown_type.h:178
WidgetDimensions::bevel
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition: window_gui.h:40
Window
Data structure for an opened window.
Definition: window_gui.h:267
ShowDropDownList
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width=0, bool instant_close=false, bool persist=false)
Show a drop down list.
Definition: dropdown.cpp:369
DropDownCheck::dim
Dimension dim
Dimension of checkmark.
Definition: dropdown_type.h:180
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition: geometry_type.hpp:75
DropDownCheck::checked
bool checked
Is item checked.
Definition: dropdown_type.h:179
DropDownString
Drop down string component.
Definition: dropdown_type.h:82
DropDownListItem::masked
bool masked
Masked and unselectable item.
Definition: dropdown_type.h:28
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition: window_gui.h:63
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition: strings_type.h:24
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:56
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:848
DropDownIcon::palette
PaletteID palette
Palette ID to use.
Definition: dropdown_type.h:142
DropDownIcon::dsprite
Dimension dsprite
Bounding box dimensions of sprite.
Definition: dropdown_type.h:143