OpenTTD Source 20260311-master-g511d3794ce
dropdown_common_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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef DROPDOWN_COMMON_TYPE_H
11#define DROPDOWN_COMMON_TYPE_H
12
13#include "dropdown_type.h"
14#include "gfx_func.h"
15#include "gfx_type.h"
16#include "palette_func.h"
17#include "settings_gui.h"
18#include "string_func.h"
19#include "stringfilter_type.h"
20#include "strings_func.h"
21#include "window_gui.h"
22
23#include "table/strings.h"
24
30template <class TBase, FontSize TFs = FS_NORMAL>
31class DropDownDivider : public TBase {
32public:
33 template <typename... Args>
34 explicit DropDownDivider(Args&&... args) : TBase(std::forward<Args>(args)...) {}
35
36 bool Selectable() const override { return false; }
37 uint Height() const override { return std::max<uint>(GetCharacterHeight(TFs), this->TBase::Height()); }
38
39 void Draw(const Rect &full, const Rect &, bool, int, Colours bg_colour) const override
40 {
41 PixelColour c1 = GetColourGradient(bg_colour, SHADE_DARK);
42 PixelColour c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST);
43
44 int mid = CentreBounds(full.top, full.bottom, 0);
45 GfxFillRect(full.WithY(mid - WidgetDimensions::scaled.bevel.bottom, mid - 1), c1);
46 GfxFillRect(full.WithY(mid, mid + WidgetDimensions::scaled.bevel.top - 1), c2);
47 }
48};
49
56template <class TBase, FontSize TFs = FS_NORMAL, bool TEnd = false>
57class DropDownString : public TBase {
58 std::string string;
60public:
61 template <typename... Args>
62 explicit DropDownString(std::string &&string, Args&&... args) : TBase(std::forward<Args>(args)...)
63 {
64 this->SetString(std::move(string));
65 }
66
68 void FilterText(StringFilter &string_filter) const override
69 {
70 string_filter.AddLine(this->string);
71 this->TBase::FilterText(string_filter);
72 }
73
74 void SetString(std::string &&string)
75 {
76 this->string = std::move(string);
77 this->dim = GetStringBoundingBox(this->string, TFs);
78 }
79
80 uint Height() const override
81 {
82 return std::max<uint>(this->dim.height, this->TBase::Height());
83 }
84
85 uint Width() const override { return this->dim.width + this->TBase::Width(); }
86
87 int OnClick(const Rect &r, const Point &pt) const override
88 {
89 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
90 return this->TBase::OnClick(r.Indent(this->dim.width, rtl), pt);
91 }
92
93 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
94 {
95 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
96 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs);
97 this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, click_result, bg_colour);
98 }
99
107 static bool NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second)
108 {
109 const std::string &str1 = static_cast<const DropDownString*>(first.get())->string;
110 const std::string &str2 = static_cast<const DropDownString*>(second.get())->string;
111 return StrNaturalCompare(str1, str2) < 0;
112 }
113};
114
120template <class TBase, bool TEnd = false>
121class DropDownIcon : public TBase {
126public:
127 template <typename... Args>
128 explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette)
129 {
130 this->dsprite = GetSpriteSize(this->sprite);
131 this->dbounds = this->dsprite;
132 }
133
134 template <typename... Args>
135 explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette), dbounds(dim)
136 {
137 this->dsprite = GetSpriteSize(this->sprite);
138 }
139
140 uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
141 uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
142
143 int OnClick(const Rect &r, const Point &pt) const override
144 {
145 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
146 return this->TBase::OnClick(r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), pt);
147 }
148
149 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
150 {
151 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
152 Rect ir = r.WithWidth(this->dbounds.width, rtl);
153 DrawSprite(this->sprite, this->palette, CentreBounds(ir.left, ir.right, this->dsprite.width), CentreBounds(r.top, r.bottom, this->dsprite.height));
154 this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, click_result, bg_colour);
155 }
156};
157
164template <class TBase, bool TEnd = false, FontSize TFs = FS_NORMAL>
165class DropDownCheck : public TBase {
166 bool checked;
168public:
169 template <typename... Args>
170 explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward<Args>(args)...), checked(checked)
171 {
172 this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs);
173 }
174
175 uint Height() const override { return std::max<uint>(this->dim.height, this->TBase::Height()); }
176 uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
177
178 int OnClick(const Rect &r, const Point &pt) const override
179 {
180 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
181 return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), pt);
182 }
183
184 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
185 {
186 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
187 if (this->checked) {
188 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs);
189 }
190 this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour);
191 }
192};
193
199template <class TBase, bool TEnd = false>
200class DropDownToggle : public TBase {
201 bool on;
202 int click;
205public:
206 template <typename... Args>
207 explicit DropDownToggle(bool on, int click, Colours button_colour, Colours background_colour, Args&&... args)
208 : TBase(std::forward<Args>(args)...), on(on), click(click), button_colour(button_colour), background_colour(background_colour)
209 {
210 }
211
212 uint Height() const override
213 {
214 return std::max<uint>(SETTING_BUTTON_HEIGHT + WidgetDimensions::scaled.vsep_normal, this->TBase::Height());
215 }
216
217 uint Width() const override
218 {
219 return SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide + this->TBase::Width();
220 }
221
222 int OnClick(const Rect &r, const Point &pt) const override
223 {
224 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
225 int w = SETTING_BUTTON_WIDTH;
226
227 if (r.WithWidth(w, rtl).CentreToHeight(SETTING_BUTTON_HEIGHT).Contains(pt)) return this->click;
228
229 return this->TBase::OnClick(r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), pt);
230 }
231
232 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
233 {
234 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
235 int w = SETTING_BUTTON_WIDTH;
236
238 DrawBoolButton(br.left, br.top, this->button_colour, this->background_colour, this->on, true);
239
240 this->TBase::Draw(full, r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour);
241 }
242};
243
249template <class TBase, bool TEnd = false>
250class DropDownIndent : public TBase {
251 uint indent;
252public:
253 template <typename... Args>
254 explicit DropDownIndent(uint indent, Args&&... args) : TBase(std::forward<Args>(args)...), indent(indent) {}
255
256 uint Width() const override { return this->indent * WidgetDimensions::scaled.hsep_indent + this->TBase::Width(); }
257
258 int OnClick(const Rect &r, const Point &pt) const override
259 {
260 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
261 return this->TBase::OnClick(r.Indent(this->indent * WidgetDimensions::scaled.hsep_indent, rtl), pt);
262 }
263
264 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
265 {
266 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
267 this->TBase::Draw(full, r.Indent(this->indent * WidgetDimensions::scaled.hsep_indent, rtl), sel, click_result, bg_colour);
268 }
269};
270
276template <class TBase, bool TEnd = false>
277class DropDownSpacer : public TBase {
278public:
279 template <typename... Args>
280 explicit DropDownSpacer(Args&&... args) : TBase(std::forward<Args>(args)...) {}
281
282 uint Width() const override { return WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
283
284 int OnClick(const Rect &r, const Point &pt) const override
285 {
286 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
287 return this->TBase::OnClick(r.Indent(WidgetDimensions::scaled.hsep_wide, rtl), pt);
288 }
289
290 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
291 {
292 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
293 this->TBase::Draw(full, r.Indent(WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour);
294 }
295};
296
301template <class TBase, FontSize TFs = FS_NORMAL>
302class DropDownUnselectable : public TBase {
303public:
304 template <typename... Args>
305 explicit DropDownUnselectable(Args&&... args) : TBase(std::forward<Args>(args)...) {}
306
307 bool Selectable() const override { return false; }
308};
309
314
315#endif /* DROPDOWN_COMMON_TYPE_H */
Dimension dim
Dimension of checkmark.
bool checked
Is item checked.
Drop down divider component.
Drop down icon component.
Drop down indent component.
Drop down string component.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
void FilterText(StringFilter &string_filter) const override
Add text from this dropdown item to a string filter.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
int hsep_wide
Wide horizontal spacing.
Definition window_gui.h:62
int hsep_normal
Normal horizontal spacing.
Definition window_gui.h:61
DropDownIcon< DropDownString< DropDownListItem > > DropDownListIconItem
Drop down list item that contains a single string and an icon.
DropDownDivider< DropDownListItem > DropDownListDividerItem
Drop down list item that divides list horizontally into two parts.
DropDownIndent< DropDownCheck< DropDownString< DropDownListItem > > > DropDownListCheckedItem
Drop down list item with a single string and a space for tick.
DropDownString< DropDownListItem > DropDownListStringItem
Drop down list item that contains a single string.
Types related to the drop down widget.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:972
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:900
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:1038
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:788
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:116
Functions related to the gfx engine.
Types related to the graphics and/or input devices.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:398
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
#define Rect
Macro that prevents name conflicts between included headers.
#define Point
Macro that prevents name conflicts between included headers.
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:393
Functions related to palettes.
void DrawBoolButton(int x, int y, Colours button_colour, Colours background, bool state, bool clickable)
Draw a toggle button.
Functions for setting GUIs.
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
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:429
Functions related to low-level strings.
Searching and filtering using a stringterm.
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
Dimensions (a width and height) of a rectangle in 2D.
Colour for pixel/line drawing.
Definition gfx_type.h:405
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Rect CentreToHeight(int height) const
Centre a vertical dimension within this Rect.
Rect WithY(int new_top, int new_bottom) const
Create a new Rect, replacing the top and bottom coordiates.
bool Contains(const Point &pt) const
Test if a point falls inside this Rect.
String filter and state.
int16_t Height
Fixed point type for heights.
Definition tgp.cpp:152
Functions, definitions and such used only by the GUI.