diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7951048ee0..597c4331f5 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 74ce478601..a72569f1a9 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 1e334e365e..7c7285a8e8 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 0000000000..a851c216ec --- /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 fd102b43f2..1a6cb71eb1 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 @@ public: } }; -/** - * 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 723df35436..8c34d91f8e 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 6ba8df735e..bb4f0966d6 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 8c467dc90a..6304b7771e 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 3f03a1ae68..a9c45fb5da 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 04d7387cb9..26fcfa798d 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"