OpenTTD Source 20250610-master-g8c90be8c9f
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 <http://www.gnu.org/licenses/>.
6 */
7
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 "strings_func.h"
20#include "window_gui.h"
21
22#include "table/strings.h"
23
29template <class TBase, FontSize TFs = FS_NORMAL>
30class DropDownDivider : public TBase {
31public:
32 template <typename... Args>
33 explicit DropDownDivider(Args&&... args) : TBase(std::forward<Args>(args)...) {}
34
35 bool Selectable() const override { return false; }
36 uint Height() const override { return std::max<uint>(GetCharacterHeight(TFs), this->TBase::Height()); }
37
38 void Draw(const Rect &full, const Rect &, bool, int, Colours bg_colour) const override
39 {
40 uint8_t c1 = GetColourGradient(bg_colour, SHADE_DARK);
41 uint8_t c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST);
42
43 int mid = CentreBounds(full.top, full.bottom, 0);
44 GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1);
45 GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2);
46 }
47};
48
55template <class TBase, FontSize TFs = FS_NORMAL, bool TEnd = false>
56class DropDownString : public TBase {
57 std::string string;
59public:
60 template <typename... Args>
61 explicit DropDownString(std::string &&string, Args&&... args) : TBase(std::forward<Args>(args)...)
62 {
63 this->SetString(std::move(string));
64 }
65
66 void SetString(std::string &&string)
67 {
68 this->string = std::move(string);
69 this->dim = GetStringBoundingBox(this->string, TFs);
70 }
71
72 uint Height() const override
73 {
74 return std::max<uint>(this->dim.height, this->TBase::Height());
75 }
76
77 uint Width() const override { return this->dim.width + this->TBase::Width(); }
78
79 int OnClick(const Rect &r, const Point &pt) const override
80 {
81 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
82 return this->TBase::OnClick(r.Indent(this->dim.width, rtl), pt);
83 }
84
85 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
86 {
87 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
88 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs);
89 this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, click_result, bg_colour);
90 }
91
99 static bool NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second)
100 {
101 const std::string &str1 = static_cast<const DropDownString*>(first.get())->string;
102 const std::string &str2 = static_cast<const DropDownString*>(second.get())->string;
103 return StrNaturalCompare(str1, str2) < 0;
104 }
105};
106
112template <class TBase, bool TEnd = false>
113class DropDownIcon : public TBase {
118public:
119 template <typename... Args>
120 explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette)
121 {
122 this->dsprite = GetSpriteSize(this->sprite);
123 this->dbounds = this->dsprite;
124 }
125
126 template <typename... Args>
127 explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward<Args>(args)...), sprite(sprite), palette(palette), dbounds(dim)
128 {
129 this->dsprite = GetSpriteSize(this->sprite);
130 }
131
132 uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
133 uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
134
135 int OnClick(const Rect &r, const Point &pt) const override
136 {
137 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
138 return this->TBase::OnClick(r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), pt);
139 }
140
141 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
142 {
143 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
144 Rect ir = r.WithWidth(this->dbounds.width, rtl);
145 DrawSprite(this->sprite, this->palette, CentreBounds(ir.left, ir.right, this->dsprite.width), CentreBounds(r.top, r.bottom, this->dsprite.height));
146 this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, click_result, bg_colour);
147 }
148};
149
156template <class TBase, bool TEnd = false, FontSize TFs = FS_NORMAL>
157class DropDownCheck : public TBase {
158 bool checked;
160public:
161 template <typename... Args>
162 explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward<Args>(args)...), checked(checked)
163 {
164 this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs);
165 }
166
167 uint Height() const override { return std::max<uint>(this->dim.height, this->TBase::Height()); }
168 uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
169
170 int OnClick(const Rect &r, const Point &pt) const override
171 {
172 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
173 return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), pt);
174 }
175
176 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
177 {
178 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
179 if (this->checked) {
180 DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs);
181 }
182 this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour);
183 }
184};
185
191template <class TBase, bool TEnd = false>
192class DropDownToggle : public TBase {
193 bool on;
194 int click;
197public:
198 template <typename... Args>
199 explicit DropDownToggle(bool on, int click, Colours button_colour, Colours background_colour, Args&&... args)
200 : TBase(std::forward<Args>(args)...), on(on), click(click), button_colour(button_colour), background_colour(background_colour)
201 {
202 }
203
204 uint Height() const override
205 {
206 return std::max<uint>(SETTING_BUTTON_HEIGHT + WidgetDimensions::scaled.vsep_normal, this->TBase::Height());
207 }
208
209 uint Width() const override
210 {
211 return SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide + this->TBase::Width();
212 }
213
214 int OnClick(const Rect &r, const Point &pt) const override
215 {
216 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
217 int w = SETTING_BUTTON_WIDTH;
218
219 if (r.WithWidth(w, rtl).CentreTo(w, SETTING_BUTTON_HEIGHT).Contains(pt)) return this->click;
220
221 return this->TBase::OnClick(r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), pt);
222 }
223
224 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
225 {
226 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
227 int w = SETTING_BUTTON_WIDTH;
228
229 Rect br = r.WithWidth(w, rtl).CentreTo(w, SETTING_BUTTON_HEIGHT);
230 DrawBoolButton(br.left, br.top, this->button_colour, this->background_colour, this->on, true);
231
232 this->TBase::Draw(full, r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour);
233 }
234};
235
241template <class TBase, bool TEnd = false>
242class DropDownIndent : public TBase {
243 uint indent;
244public:
245 template <typename... Args>
246 explicit DropDownIndent(uint indent, Args&&... args) : TBase(std::forward<Args>(args)...), indent(indent) {}
247
248 uint Width() const override { return this->indent * WidgetDimensions::scaled.hsep_indent + this->TBase::Width(); }
249
250 int OnClick(const Rect &r, const Point &pt) const override
251 {
252 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
253 return this->TBase::OnClick(r.Indent(this->indent * WidgetDimensions::scaled.hsep_indent, rtl), pt);
254 }
255
256 void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override
257 {
258 bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
259 this->TBase::Draw(full, r.Indent(this->indent * WidgetDimensions::scaled.hsep_indent, rtl), sel, click_result, bg_colour);
260 }
261};
262
267template <class TBase, FontSize TFs = FS_NORMAL>
268class DropDownUnselectable : public TBase {
269public:
270 template <typename... Args>
271 explicit DropDownUnselectable(Args&&... args) : TBase(std::forward<Args>(args)...) {}
272
273 bool Selectable() const override { return false; }
274};
275
276/* Commonly used drop down list items. */
281
282#endif /* DROPDOWN_COMMON_TYPE_H */
Drop down checkmark component.
Dimension dim
Dimension of checkmark.
bool checked
Is item checked.
Drop down divider component.
Drop down icon component.
PaletteID palette
Palette ID to use.
Dimension dbounds
Bounding box dimensions of bounds.
Dimension dsprite
Bounding box dimensions of sprite.
SpriteID sprite
Sprite ID to be drawn.
Drop down indent component.
Drop down string component.
std::string string
String to be drawn.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
Dimension dim
Dimensions of string.
Drop down boolean toggle component.
Colours button_colour
Colour of toggle button.
int click
Click result when toggle used.
Colours background_colour
Colour of toggle background.
Drop down component that makes the item unselectable.
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
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
int hsep_indent
Width of indentation for tree layouts.
Definition window_gui.h:63
Types related to the drop down widget.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:77
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:958
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:887
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:115
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:1024
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:775
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:393
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
uint8_t GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
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:425
Functions related to low-level strings.
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:57
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.
Coordinates of a point in 2D.
Specification of a rectangle with absolute coordinates of all edges.
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Rect CentreTo(int width, int height) const
Centre a dimension within this Rect.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
bool Contains(const Point &pt) const
Test if a point falls inside this Rect.
int16_t Height
Fixed point type for heights.
Definition tgp.cpp:153
Functions, definitions and such used only by the GUI.