diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7951048ee0f90..597c4331f52f9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -139,6 +139,7 @@ add_files(
driver.cpp
driver.h
dropdown.cpp
+ dropdown_common_type.h
dropdown_func.h
dropdown_type.h
economy.cpp
diff --git a/src/company_gui.cpp b/src/company_gui.cpp
index 74ce478601c7f..a72569f1a94b4 100644
--- a/src/company_gui.cpp
+++ b/src/company_gui.cpp
@@ -24,6 +24,7 @@
#include "strings_func.h"
#include "timer/timer_game_economy.h"
#include "dropdown_type.h"
+#include "dropdown_common_type.h"
#include "tilehighlight_func.h"
#include "company_base.h"
#include "core/geometry_func.hpp"
diff --git a/src/dropdown.cpp b/src/dropdown.cpp
index 1e334e365e15c..7c7285a8e8120 100644
--- a/src/dropdown.cpp
+++ b/src/dropdown.cpp
@@ -10,6 +10,7 @@
#include "stdafx.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
+#include "dropdown_common_type.h"
#include "strings_func.h"
#include "timer/timer.h"
#include "timer/timer_window.h"
diff --git a/src/dropdown_common_type.h b/src/dropdown_common_type.h
new file mode 100644
index 0000000000000..a851c216ec2c6
--- /dev/null
+++ b/src/dropdown_common_type.h
@@ -0,0 +1,178 @@
+/*
+ * This file is part of OpenTTD.
+ * 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.
+ * 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.
+ * 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 .
+ */
+
+/** @file dropdown_common_type.h Common drop down list components. */
+
+#ifndef DROPDOWN_COMMON_TYPE_H
+#define DROPDOWN_COMMON_TYPE_H
+
+#include "gfx_func.h"
+#include "gfx_type.h"
+#include "palette_func.h"
+#include "string_func.h"
+#include "strings_func.h"
+#include "table/strings.h"
+#include "window_gui.h"
+
+/**
+ * Drop down divider component.
+ * @tparam TBase Base component.
+ * @tparam TFs Font size -- used to determine height.
+ */
+template
+class DropDownDivider : public TBase {
+public:
+ template
+ explicit DropDownDivider(Args&&... args) : TBase(std::forward(args)...) {}
+
+ bool Selectable() const override { return false; }
+ uint Height() const override { return std::max(GetCharacterHeight(TFs), this->TBase::Height()); }
+
+ void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const override
+ {
+ uint8_t c1 = GetColourGradient(bg_colour, SHADE_DARK);
+ uint8_t c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST);
+
+ int mid = CenterBounds(full.top, full.bottom, 0);
+ GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1);
+ GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2);
+ }
+};
+
+/**
+ * Drop down string component.
+ * @tparam TBase Base component.
+ * @tparam TFs Font size.
+ * @tparam TEnd Position string at end if true, or start if false.
+ */
+template
+class DropDownString : public TBase {
+ std::string string; ///< String to be drawn.
+ Dimension dim; ///< Dimensions of string.
+public:
+ template
+ explicit DropDownString(StringID string, Args&&... args) : TBase(std::forward(args)...)
+ {
+ this->SetString(GetString(string));
+ }
+
+ template
+ explicit DropDownString(const std::string &string, Args&&... args) : TBase(std::forward(args)...)
+ {
+ SetDParamStr(0, string);
+ this->SetString(GetString(STR_JUST_RAW_STRING));
+ }
+
+ void SetString(std::string &&string)
+ {
+ this->string = std::move(string);
+ this->dim = GetStringBoundingBox(this->string, TFs);
+ }
+
+ uint Height() const override
+ {
+ return std::max(this->dim.height, this->TBase::Height());
+ }
+
+ uint Width() const override { return this->dim.width + this->TBase::Width(); }
+
+ void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
+ {
+ bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
+ DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs);
+ this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, bg_colour);
+ }
+
+ /**
+ * Natural sorting comparator function for DropDownList::sort().
+ * @param first Left side of comparison.
+ * @param second Right side of comparison.
+ * @return true if \a first precedes \a second.
+ * @warning All items in the list need to be derivates of DropDownListStringItem.
+ */
+ static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second)
+ {
+ const std::string &str1 = static_cast(first.get())->string;
+ const std::string &str2 = static_cast(second.get())->string;
+ return StrNaturalCompare(str1, str2) < 0;
+ }
+};
+
+/**
+ * Drop down icon component.
+ * @tparam TBase Base component.
+ * @tparam TEnd Position icon at end if true, or start if false.
+ */
+template
+class DropDownIcon : public TBase {
+ SpriteID sprite; ///< Sprite ID to be drawn.
+ PaletteID palette; ///< Palette ID to use.
+ Dimension dsprite; ///< Bounding box dimensions of sprite.
+ Dimension dbounds; ///< Bounding box dimensions of bounds.
+public:
+ template
+ explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette)
+ {
+ this->dsprite = GetSpriteSize(this->sprite);
+ this->dbounds = this->dsprite;
+ }
+
+ template
+ explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette), dbounds(dim)
+ {
+ this->dsprite = GetSpriteSize(this->sprite);
+ }
+
+ uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
+ uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
+
+ void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
+ {
+ bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
+ Rect ir = r.WithWidth(this->dbounds.width, rtl);
+ DrawSprite(this->sprite, this->palette, CenterBounds(ir.left, ir.right, this->dsprite.width), CenterBounds(r.top, r.bottom, this->dsprite.height));
+ this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, bg_colour);
+ }
+};
+
+/**
+ * Drop down checkmark component.
+ * @tparam TBase Base component.
+ * @tparam TFs Font size.
+ * @tparam TEnd Position checkmark at end if true, or start if false.
+ */
+template
+class DropDownCheck : public TBase {
+ bool checked; ///< Is item checked.
+ Dimension dim; ///< Dimension of checkmark.
+public:
+ template
+ explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward(args)...), checked(checked)
+ {
+ this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs);
+ }
+
+ uint Height() const override { return std::max(this->dim.height, this->TBase::Height()); }
+ uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
+
+ void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
+ {
+ bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
+ if (this->checked) {
+ DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs);
+ }
+ this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, bg_colour);
+ }
+};
+
+/* Commonly used drop down list items. */
+using DropDownListDividerItem = DropDownDivider;
+using DropDownListStringItem = DropDownString;
+using DropDownListIconItem = DropDownIcon>;
+using DropDownListCheckedItem = DropDownCheck>;
+
+#endif /* DROPDOWN_COMMON_TYPE_H */
diff --git a/src/dropdown_type.h b/src/dropdown_type.h
index fd102b43f2560..1a6cb71eb1608 100644
--- a/src/dropdown_type.h
+++ b/src/dropdown_type.h
@@ -14,9 +14,6 @@
#include "gfx_func.h"
#include "gfx_type.h"
#include "palette_func.h"
-#include "string_func.h"
-#include "strings_func.h"
-#include "table/strings.h"
#include "window_gui.h"
/**
@@ -47,163 +44,6 @@ class DropDownListItem {
}
};
-/**
- * Drop down divider component.
- * @tparam TBase Base component.
- * @tparam TFs Font size -- used to determine height.
- */
-template
-class DropDownDivider : public TBase {
-public:
- template
- explicit DropDownDivider(Args&&... args) : TBase(std::forward(args)...) {}
-
- bool Selectable() const override { return false; }
- uint Height() const override { return std::max(GetCharacterHeight(TFs), this->TBase::Height()); }
-
- void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const override
- {
- uint8_t c1 = GetColourGradient(bg_colour, SHADE_DARK);
- uint8_t c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST);
-
- int mid = CenterBounds(full.top, full.bottom, 0);
- GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1);
- GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2);
- }
-};
-
-/**
- * Drop down string component.
- * @tparam TBase Base component.
- * @tparam TFs Font size.
- * @tparam TEnd Position string at end if true, or start if false.
- */
-template
-class DropDownString : public TBase {
- std::string string; ///< String to be drawn.
- Dimension dim; ///< Dimensions of string.
-public:
- template
- explicit DropDownString(StringID string, Args&&... args) : TBase(std::forward(args)...)
- {
- this->SetString(GetString(string));
- }
-
- template
- explicit DropDownString(const std::string &string, Args&&... args) : TBase(std::forward(args)...)
- {
- SetDParamStr(0, string);
- this->SetString(GetString(STR_JUST_RAW_STRING));
- }
-
- void SetString(std::string &&string)
- {
- this->string = std::move(string);
- this->dim = GetStringBoundingBox(this->string, TFs);
- }
-
- uint Height() const override
- {
- return std::max(this->dim.height, this->TBase::Height());
- }
-
- uint Width() const override { return this->dim.width + this->TBase::Width(); }
-
- void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
- {
- bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
- DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), this->string, this->GetColour(sel), SA_CENTER, false, TFs);
- this->TBase::Draw(full, r.Indent(this->dim.width, rtl), sel, bg_colour);
- }
-
- /**
- * Natural sorting comparator function for DropDownList::sort().
- * @param first Left side of comparison.
- * @param second Right side of comparison.
- * @return true if \a first precedes \a second.
- * @warning All items in the list need to be derivates of DropDownListStringItem.
- */
- static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second)
- {
- const std::string &str1 = static_cast(first.get())->string;
- const std::string &str2 = static_cast(second.get())->string;
- return StrNaturalCompare(str1, str2) < 0;
- }
-};
-
-/**
- * Drop down icon component.
- * @tparam TBase Base component.
- * @tparam TEnd Position icon at end if true, or start if false.
- */
-template
-class DropDownIcon : public TBase {
- SpriteID sprite; ///< Sprite ID to be drawn.
- PaletteID palette; ///< Palette ID to use.
- Dimension dsprite; ///< Bounding box dimensions of sprite.
- Dimension dbounds; ///< Bounding box dimensions of bounds.
-public:
- template
- explicit DropDownIcon(SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette)
- {
- this->dsprite = GetSpriteSize(this->sprite);
- this->dbounds = this->dsprite;
- }
-
- template
- explicit DropDownIcon(const Dimension &dim, SpriteID sprite, PaletteID palette, Args&&... args) : TBase(std::forward(args)...), sprite(sprite), palette(palette), dbounds(dim)
- {
- this->dsprite = GetSpriteSize(this->sprite);
- }
-
- uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
- uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
-
- void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
- {
- bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
- Rect ir = r.WithWidth(this->dbounds.width, rtl);
- DrawSprite(this->sprite, this->palette, CenterBounds(ir.left, ir.right, this->dsprite.width), CenterBounds(r.top, r.bottom, this->dsprite.height));
- this->TBase::Draw(full, r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, bg_colour);
- }
-};
-
-/**
- * Drop down checkmark component.
- * @tparam TBase Base component.
- * @tparam TFs Font size.
- * @tparam TEnd Position checkmark at end if true, or start if false.
- */
-template
-class DropDownCheck : public TBase {
- bool checked; ///< Is item checked.
- Dimension dim; ///< Dimension of checkmark.
-public:
- template
- explicit DropDownCheck(bool checked, Args&&... args) : TBase(std::forward(args)...), checked(checked)
- {
- this->dim = GetStringBoundingBox(STR_JUST_CHECKMARK, TFs);
- }
-
- uint Height() const override { return std::max(this->dim.height, this->TBase::Height()); }
- uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
-
- void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
- {
- bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
- if (this->checked) {
- DrawStringMultiLine(r.WithWidth(this->dim.width, rtl), STR_JUST_CHECKMARK, this->GetColour(sel), SA_CENTER, false, TFs);
- }
- this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, bg_colour);
- }
-};
-
-/* Commonly used drop down list items. */
-using DropDownListDividerItem = DropDownDivider;
-using DropDownListStringItem = DropDownString;
-using DropDownListIconItem = DropDownIcon>;
-using DropDownListCheckedItem = DropDownCheck>;
-
/**
* A drop down list is a collection of drop down list items.
*/
diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp
index 723df35436ef5..8c34d91f8e0b3 100644
--- a/src/genworld_gui.cpp
+++ b/src/genworld_gui.cpp
@@ -19,6 +19,7 @@
#include "fios.h"
#include "string_func.h"
#include "dropdown_type.h"
+#include "dropdown_common_type.h"
#include "dropdown_func.h"
#include "querystring_gui.h"
#include "town.h"
diff --git a/src/settings.cpp b/src/settings.cpp
index 6ba8df735e190..bb4f0966d6d98 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -32,6 +32,7 @@
#include "command_func.h"
#include "console_func.h"
#include "genworld.h"
+#include "string_func.h"
#include "window_func.h"
#include "company_func.h"
#include "rev.h"
diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp
index 8c467dc90a331..6304b7771e08d 100644
--- a/src/settings_gui.cpp
+++ b/src/settings_gui.cpp
@@ -21,6 +21,7 @@
#include "string_func.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
+#include "dropdown_common_type.h"
#include "slider_func.h"
#include "highscore.h"
#include "base_media_base.h"
diff --git a/src/station_gui.cpp b/src/station_gui.cpp
index 3f03a1ae68f53..a9c45fb5dad00 100644
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -21,6 +21,7 @@
#include "window_func.h"
#include "viewport_func.h"
#include "dropdown_type.h"
+#include "dropdown_common_type.h"
#include "dropdown_func.h"
#include "station_base.h"
#include "waypoint_base.h"
diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
index 04d7387cb99a5..26fcfa798d292 100644
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -15,6 +15,7 @@
#include "command_func.h"
#include "dropdown_type.h"
#include "dropdown_func.h"
+#include "dropdown_common_type.h"
#include "vehicle_gui.h"
#include "rail_gui.h"
#include "road.h"