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/>.
8 /** @file dropdown_common_type.h Common drop down list components. */
10 #ifndef DROPDOWN_COMMON_TYPE_H
11 #define DROPDOWN_COMMON_TYPE_H
15 #include "palette_func.h"
16 #include "string_func.h"
17 #include "strings_func.h"
18 #include "table/strings.h"
19 #include "window_gui.h"
22 * Drop down divider component.
23 * @tparam TBase Base component.
24 * @tparam TFs Font size -- used to determine height.
26 template <class TBase
, FontSize TFs
= FS_NORMAL
>
27 class DropDownDivider
: public TBase
{
29 template <typename
... Args
>
30 explicit DropDownDivider(Args
&&... args
) : TBase(std::forward
<Args
>(args
)...) {}
32 bool Selectable() const override
{ return false; }
33 uint
Height() const override
{ return std::max
<uint
>(GetCharacterHeight(TFs
), this->TBase::Height()); }
35 void Draw(const Rect
&full
, const Rect
&, bool, Colours bg_colour
) const override
37 uint8_t c1
= GetColourGradient(bg_colour
, SHADE_DARK
);
38 uint8_t c2
= GetColourGradient(bg_colour
, SHADE_LIGHTEST
);
40 int mid
= CenterBounds(full
.top
, full
.bottom
, 0);
41 GfxFillRect(full
.left
, mid
- WidgetDimensions::scaled
.bevel
.bottom
, full
.right
, mid
- 1, c1
);
42 GfxFillRect(full
.left
, mid
, full
.right
, mid
+ WidgetDimensions::scaled
.bevel
.top
- 1, c2
);
47 * Drop down string component.
48 * @tparam TBase Base component.
49 * @tparam TFs Font size.
50 * @tparam TEnd Position string at end if true, or start if false.
52 template <class TBase
, FontSize TFs
= FS_NORMAL
, bool TEnd
= false>
53 class DropDownString
: public TBase
{
54 std::string string
; ///< String to be drawn.
55 Dimension dim
; ///< Dimensions of string.
57 template <typename
... Args
>
58 explicit DropDownString(StringID string
, Args
&&... args
) : TBase(std::forward
<Args
>(args
)...)
60 this->SetString(GetString(string
));
63 template <typename
... Args
>
64 explicit DropDownString(const std::string
&string
, Args
&&... args
) : TBase(std::forward
<Args
>(args
)...)
66 SetDParamStr(0, string
);
67 this->SetString(GetString(STR_JUST_RAW_STRING
));
70 void SetString(std::string
&&string
)
72 this->string
= std::move(string
);
73 this->dim
= GetStringBoundingBox(this->string
, TFs
);
76 uint
Height() const override
78 return std::max
<uint
>(this->dim
.height
, this->TBase::Height());
81 uint
Width() const override
{ return this->dim
.width
+ this->TBase::Width(); }
83 void Draw(const Rect
&full
, const Rect
&r
, bool sel
, Colours bg_colour
) const override
85 bool rtl
= TEnd
^ (_current_text_dir
== TD_RTL
);
86 DrawStringMultiLine(r
.WithWidth(this->dim
.width
, rtl
), this->string
, this->GetColour(sel
), SA_CENTER
, false, TFs
);
87 this->TBase::Draw(full
, r
.Indent(this->dim
.width
, rtl
), sel
, bg_colour
);
91 * Natural sorting comparator function for DropDownList::sort().
92 * @param first Left side of comparison.
93 * @param second Right side of comparison.
94 * @return true if \a first precedes \a second.
95 * @warning All items in the list need to be derivates of DropDownListStringItem.
97 static bool NatSortFunc(std::unique_ptr
<const DropDownListItem
> const &first
, std::unique_ptr
<const DropDownListItem
> const &second
)
99 const std::string
&str1
= static_cast<const DropDownString
*>(first
.get())->string
;
100 const std::string
&str2
= static_cast<const DropDownString
*>(second
.get())->string
;
101 return StrNaturalCompare(str1
, str2
) < 0;
106 * Drop down icon component.
107 * @tparam TBase Base component.
108 * @tparam TEnd Position icon at end if true, or start if false.
110 template <class TBase
, bool TEnd
= false>
111 class DropDownIcon
: public TBase
{
112 SpriteID sprite
; ///< Sprite ID to be drawn.
113 PaletteID palette
; ///< Palette ID to use.
114 Dimension dsprite
; ///< Bounding box dimensions of sprite.
115 Dimension dbounds
; ///< Bounding box dimensions of bounds.
117 template <typename
... Args
>
118 explicit DropDownIcon(SpriteID sprite
, PaletteID palette
, Args
&&... args
) : TBase(std::forward
<Args
>(args
)...), sprite(sprite
), palette(palette
)
120 this->dsprite
= GetSpriteSize(this->sprite
);
121 this->dbounds
= this->dsprite
;
124 template <typename
... Args
>
125 explicit DropDownIcon(const Dimension
&dim
, SpriteID sprite
, PaletteID palette
, Args
&&... args
) : TBase(std::forward
<Args
>(args
)...), sprite(sprite
), palette(palette
), dbounds(dim
)
127 this->dsprite
= GetSpriteSize(this->sprite
);
130 uint
Height() const override
{ return std::max(this->dbounds
.height
, this->TBase::Height()); }
131 uint
Width() const override
{ return this->dbounds
.width
+ WidgetDimensions::scaled
.hsep_normal
+ this->TBase::Width(); }
133 void Draw(const Rect
&full
, const Rect
&r
, bool sel
, Colours bg_colour
) const override
135 bool rtl
= TEnd
^ (_current_text_dir
== TD_RTL
);
136 Rect ir
= r
.WithWidth(this->dbounds
.width
, rtl
);
137 DrawSprite(this->sprite
, this->palette
, CenterBounds(ir
.left
, ir
.right
, this->dsprite
.width
), CenterBounds(r
.top
, r
.bottom
, this->dsprite
.height
));
138 this->TBase::Draw(full
, r
.Indent(this->dbounds
.width
+ WidgetDimensions::scaled
.hsep_normal
, rtl
), sel
, bg_colour
);
143 * Drop down checkmark component.
144 * @tparam TBase Base component.
145 * @tparam TFs Font size.
146 * @tparam TEnd Position checkmark at end if true, or start if false.
148 template <class TBase
, bool TEnd
= false, FontSize TFs
= FS_NORMAL
>
149 class DropDownCheck
: public TBase
{
150 bool checked
; ///< Is item checked.
151 Dimension dim
; ///< Dimension of checkmark.
153 template <typename
... Args
>
154 explicit DropDownCheck(bool checked
, Args
&&... args
) : TBase(std::forward
<Args
>(args
)...), checked(checked
)
156 this->dim
= GetStringBoundingBox(STR_JUST_CHECKMARK
, TFs
);
159 uint
Height() const override
{ return std::max
<uint
>(this->dim
.height
, this->TBase::Height()); }
160 uint
Width() const override
{ return this->dim
.width
+ WidgetDimensions::scaled
.hsep_wide
+ this->TBase::Width(); }
162 void Draw(const Rect
&full
, const Rect
&r
, bool sel
, Colours bg_colour
) const override
164 bool rtl
= TEnd
^ (_current_text_dir
== TD_RTL
);
166 DrawStringMultiLine(r
.WithWidth(this->dim
.width
, rtl
), STR_JUST_CHECKMARK
, this->GetColour(sel
), SA_CENTER
, false, TFs
);
168 this->TBase::Draw(full
, r
.Indent(this->dim
.width
+ WidgetDimensions::scaled
.hsep_wide
, rtl
), sel
, bg_colour
);
172 /* Commonly used drop down list items. */
173 using DropDownListDividerItem
= DropDownDivider
<DropDownListItem
>;
174 using DropDownListStringItem
= DropDownString
<DropDownListItem
>;
175 using DropDownListIconItem
= DropDownIcon
<DropDownString
<DropDownListItem
>>;
176 using DropDownListCheckedItem
= DropDownCheck
<DropDownString
<DropDownListItem
>>;
178 #endif /* DROPDOWN_COMMON_TYPE_H */