26#include "table/strings.h"
32static constexpr uint MAX_BADGE_HEIGHT = 12;
33static constexpr uint MAX_BADGE_WIDTH = MAX_BADGE_HEIGHT * 2;
46 if (badge.class_index != class_index)
continue;
49 if (ps.
sprite == 0)
continue;
52 if (d.width > MAX_BADGE_WIDTH)
break;
55 d.width = std::min(d.width, MAX_BADGE_WIDTH);
76 if (class_badge->
name == STR_NULL)
continue;
78 Dimension size = GetBadgeMaximalDimension(class_index, feature);
79 if (size.width == 0)
continue;
83 this->gui_classes.emplace_back(class_index, config.column, config.show_icon, sort_order, size, class_badge->
label);
84 if (size.width != 0 && config.show_icon) max_column = std::max(max_column, config.column);
87 std::sort(std::begin(this->gui_classes), std::end(this->gui_classes));
90 this->column_widths.resize(max_column + 1);
91 for (
const auto &el : this->gui_classes) {
92 if (!el.visible || el.size.width == 0)
continue;
97 for (uint &badge_width : this->column_widths) {
98 if (badge_width == 0)
continue;
109 return std::accumulate(std::begin(this->column_widths), std::end(this->column_widths), 0U);
121 if (badges.empty())
return r.top;
129 if (class_badge ==
nullptr || class_badge->
name == STR_NULL)
continue;
132 for (
const BadgeID &index : badges) {
134 if (badge ==
nullptr || badge->
name == STR_NULL)
continue;
145 if (s.empty())
continue;
166 for (
const auto &gc : gui_classes.GetClasses()) {
167 if (gc.column_group != column_group)
continue;
168 if (!gc.visible)
continue;
171 for (
const BadgeID &index : badges) {
176 if (ps.
sprite == 0)
continue;
187template <
class TBase,
bool TEnd = true, FontSize TFs = FS_NORMAL>
190 template <
typename... Args>
191 explicit DropDownBadges(
const std::shared_ptr<GUIBadgeClasses> &gui_classes, std::span<const BadgeID> badges,
GrfSpecFeature feature, std::optional<TimerGameCalendar::Date> introduction_date, Args &&...args) :
192 TBase(std::forward<Args>(args)...), gui_classes(gui_classes), badges(badges), feature(feature), introduction_date(introduction_date)
194 for (
const auto &gc : gui_classes->GetClasses()) {
195 if (gc.column_group != 0)
continue;
197 dim.height = std::max<uint>(dim.height,
ScaleGUITrad(gc.size.height));
204 uint
Height()
const override
206 return std::max<uint>(this->dim.height, this->TBase::Height());
209 uint Width()
const override
211 if (this->dim.width == 0)
return this->TBase::Width();
215 int OnClick(
const Rect &r,
const Point &pt)
const override
217 if (this->dim.width == 0) {
218 return this->TBase::OnClick(r, pt);
225 void Draw(
const Rect &full,
const Rect &r,
bool sel,
int click_result, Colours bg_colour)
const override
227 if (this->dim.width == 0) {
228 this->TBase::Draw(full, r, sel, click_result, bg_colour);
231 DrawBadgeColumn(r.
WithWidth(this->dim.width, rtl), 0, *this->gui_classes, this->badges, this->feature, this->introduction_date, PAL_NONE);
237 std::shared_ptr<GUIBadgeClasses> gui_classes;
239 const std::span<const BadgeID> badges;
241 const std::optional<TimerGameCalendar::Date> introduction_date;
249std::unique_ptr<DropDownListItem> MakeDropDownListBadgeItem(
const std::shared_ptr<GUIBadgeClasses> &gui_classes, std::span<const BadgeID> badges,
GrfSpecFeature feature, std::optional<TimerGameCalendar::Date> introduction_date, std::string &&str,
int value,
bool masked,
bool shaded)
251 return std::make_unique<DropDownListBadgeItem>(gui_classes, badges, feature, introduction_date,
"", std::move(str), value, masked, shaded);
254std::unique_ptr<DropDownListItem> MakeDropDownListBadgeItem(
const std::shared_ptr<GUIBadgeClasses> &gui_classes, std::span<const BadgeID> badges,
GrfSpecFeature feature, std::optional<TimerGameCalendar::Date> introduction_date,
Money cost, std::string &&str,
int value,
bool masked,
bool shaded)
256 return std::make_unique<DropDownListBadgeItem>(gui_classes, badges, feature, introduction_date,
GetString(STR_JUST_CURRENCY_SHORT, cost), std::move(str), value, masked, shaded);
259std::unique_ptr<DropDownListItem> MakeDropDownListBadgeIconItem(
const std::shared_ptr<GUIBadgeClasses> &gui_classes, std::span<const BadgeID> badges,
GrfSpecFeature feature, std::optional<TimerGameCalendar::Date> introduction_date,
Money cost,
const Dimension &dim,
SpriteID sprite,
PaletteID palette, std::string &&str,
int value,
bool masked,
bool shaded)
261 return std::make_unique<DropDownListBadgeIconItem>(gui_classes, badges, feature, introduction_date,
GetString(STR_JUST_CURRENCY_SHORT, cost), dim, sprite, palette, std::move(str), value, masked, shaded);
267template <
class TBase,
bool TEnd = true, FontSize TFs = FS_NORMAL>
270 template <
typename... Args>
276 uint
Height()
const override
281 uint Width()
const override
286 int OnClick(
const Rect &r,
const Point &pt)
const override
298 void Draw(
const Rect &full,
const Rect &r,
bool sel,
int click_result, Colours bg_colour)
const override
304 if (sel && click_result != 0) {
305 if (click_result == this->click_up) state = 1;
306 if (click_result == this->click_down) state = 2;
310 DrawUpDownButtons(br.left, br.top, this->button_colour, state, this->click_up != 0, this->click_down != 0);
324enum BadgeClick :
int {
327 BADGE_CLICK_MOVE_DOWN,
328 BADGE_CLICK_TOGGLE_ICON,
329 BADGE_CLICK_TOGGLE_FILTER,
332DropDownList BuildBadgeClassConfigurationList(
const GUIBadgeClasses &gui_classes, uint columns, std::span<const StringID> column_separators)
336 list.push_back(MakeDropDownListStringItem(STR_BADGE_CONFIG_RESET, INT_MAX));
337 if (gui_classes.GetClasses().empty())
return list;
338 list.push_back(MakeDropDownListDividerItem());
341 const BadgeClassID front = gui_classes.GetClasses().front().class_index;
342 const BadgeClassID back = gui_classes.GetClasses().back().class_index;
344 for (uint i = 0; i < columns; ++i) {
345 for (
const auto &gc : gui_classes.GetClasses()) {
346 if (gc.column_group != i)
continue;
347 if (gc.size.width == 0)
continue;
349 bool first = (i == 0 && gc.class_index == front);
350 bool last = (i == columns - 1 && gc.class_index == back);
351 list.push_back(std::make_unique<DropDownListToggleMoverItem>(first ? 0 : BADGE_CLICK_MOVE_UP, last ? 0 : BADGE_CLICK_MOVE_DOWN, COLOUR_YELLOW, gc.visible, BADGE_CLICK_TOGGLE_ICON, COLOUR_YELLOW, COLOUR_GREY,
GetString(
GetClassBadge(gc.class_index)->name), gc.class_index.base()));
354 if (i >= column_separators.size())
continue;
356 if (column_separators[i] == STR_NULL) {
357 list.push_back(MakeDropDownListDividerItem());
359 list.push_back(MakeDropDownListStringItem(column_separators[i], INT_MIN + i,
false,
true));
363 list.push_back(MakeDropDownListDividerItem());
366 for (
const BadgeClassID &badge_class_index : gui_classes.Classes()) {
371 list.push_back(std::make_unique<DropDownListToggleItem>(config.show_filter, BADGE_CLICK_TOGGLE_FILTER, COLOUR_YELLOW, COLOUR_GREY,
GetString(badge->
name), (1U << 16) | badge_class_index.base()));
383static void BadgeClassToggleVisibility(
GrfSpecFeature feature,
Badge &class_badge,
int click_result, BadgeFilterChoices &choices)
387 if (it == std::end(config))
return;
389 if (click_result == BADGE_CLICK_TOGGLE_ICON) it->show_icon = !it->show_icon;
390 if (click_result == BADGE_CLICK_TOGGLE_FILTER) {
391 it->show_filter = !it->show_filter;
392 if (!it->show_filter) ResetBadgeFilter(choices, class_badge.
class_index);
404 if (gui_classes.GetClasses().empty())
return;
408 if (it == std::end(config))
return;
411 if (pos_cur == std::begin(gui_classes.GetClasses())) {
412 if (it->column > 0) --it->column;
417 if (it->column > pos_prev->column) {
421 std::rotate(pos_prev, it, std::next(it));
434 if (gui_classes.GetClasses().empty())
return;
438 if (it == std::end(config))
return;
441 if (std::next(pos_cur) == std::end(gui_classes.GetClasses())) {
442 if (it->column < columns - 1) ++it->column;
447 if (it->column < pos_next->column) {
451 std::rotate(it, std::next(it), std::next(pos_next));
463bool HandleBadgeConfigurationDropDownClick(
GrfSpecFeature feature, uint columns,
int result,
int click_result, BadgeFilterChoices &choices)
465 if (result == INT_MAX) {
471 if (class_badge ==
nullptr)
return false;
473 switch (click_result) {
474 case BADGE_CLICK_MOVE_DOWN:
475 BadgeClassMoveNext(feature, *class_badge, columns);
477 case BADGE_CLICK_MOVE_UP:
478 BadgeClassMovePrevious(feature, *class_badge);
480 case BADGE_CLICK_TOGGLE_ICON:
481 case BADGE_CLICK_TOGGLE_FILTER:
482 BadgeClassToggleVisibility(feature, *class_badge, click_result, choices);
493 , feature(feature), badge_class(badge_class)
499std::string NWidgetBadgeFilter::GetStringParameter(
const BadgeFilterChoices &choices)
const
502 if (it == std::end(choices)) {
520 list.push_back(MakeDropDownListDividerItem());
527 auto start = list.size();
532 if (badge.
class_index != this->badge_class)
continue;
533 if (badge.
index == bc->index)
continue;
534 if (badge.
name == STR_NULL)
continue;
539 list.push_back(MakeDropDownListStringItem(badge.
name, badge.
index.base()));
541 list.push_back(MakeDropDownListIconItem(d, ps.
sprite, ps.
pal, badge.
name, badge.
index.base()));
568 if (!config.show_filter)
continue;
570 container.
Add(std::make_unique<NWidgetBadgeFilter>(colour, widget, feature, class_index));
574 return {first, widget};
582void ResetBadgeFilter(BadgeFilterChoices &choices,
BadgeClassID badge_class_index)
584 choices.erase(badge_class_index);
593void SetBadgeFilter(BadgeFilterChoices &choices,
BadgeID badge_index)
596 assert(badge !=
nullptr);
std::string label
Class label.
BadgeClassID class_index
Index of class this badge belongs to.
std::string label
Label of badge.
BadgeID index
Index assigned to badge.
BadgeFlags flags
Display flags.
GrfSpecFeatures features
Bitmask of which features use this badge.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Drop down element that draws a list of badges.
Drop down component that shows extra buttons to indicate that the item can be moved up or down.
int click_down
Click result for down button. Button is inactive if 0.
Colours button_colour
Colour of buttons.
int click_up
Click result for up button. Button is inactive if 0.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Natural sorting comparator function for DropDownList::sort().
Drop down boolean toggle component.
Drop down component that makes the item unselectable.
Flat set implementation that uses a sorted vector for storage.
std::pair< const_iterator, bool > insert(const Tkey &key)
Insert a key into the set, if it does not already exist.
uint GetTotalColumnsWidth() const
Get total width of all columns.
Utility class to create a list of badge classes used by a feature.
Common drop down list components.
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
Flat set container implementation.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
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.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
@ FS_SMALL
Index of the small font in the font tables.
@ SA_CENTER
Center both horizontally and vertically.
uint32_t PaletteID
The number of the palette.
Base for the NewGRF implementation.
Badge * GetBadge(BadgeID index)
Get a badge if it exists.
std::span< const Badge > GetBadges()
Get a read-only view of badges.
PalSpriteID GetBadgeSprite(const Badge &badge, GrfSpecFeature feature, std::optional< TimerGameCalendar::Date > introduction_date, PaletteID remap)
Get sprite for the given badge.
Badge * GetClassBadge(BadgeClassID class_index)
Get the badge for a badge class index.
Functions related to NewGRF badges.
void ResetBadgeClassConfiguration(GrfSpecFeature feature)
Reset badge class configuration for a feature.
std::pair< const BadgeClassConfigItem &, int > GetBadgeClassConfigItem(GrfSpecFeature feature, std::string_view label)
Get configuration for a badge class.
std::span< BadgeClassConfigItem > GetBadgeClassConfiguration(GrfSpecFeature feature)
Get the badge user configuration for a feature.
Functions related to NewGRF badge configuration.
GUI functions related to NewGRF badges.
Types related to NewGRF badges.
@ NameListStop
Stop adding names to the name list after this badge.
@ NameListFirstOnly
Don't add this name to the name list if not first.
@ HasText
Internal flag set if the badge has text.
A number of safeguards to prevent using unsafe methods.
void DrawUpDownButtons(int x, int y, Colours button_colour, uint8_t state, bool clickable_up, bool clickable_down)
Draw [^][v] buttons.
Functions for setting GUIs.
#define SETTING_BUTTON_WIDTH
Width of setting buttons.
#define SETTING_BUTTON_HEIGHT
Height of setting buttons.
Definition of base types and functions in a cross-platform compatible way.
std::string_view GetListSeparator()
Get the list separator string for the current language.
void AppendStringInPlace(std::string &result, StringID string)
Resolve the given StringID and append in place into an existing std::string with formatting but no pa...
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
TextDirection _current_text_dir
Text direction of the currently selected language.
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.
uint sort_order
Order of element.
std::string_view label
Class label (string owned by the class badge)
BadgeClassID class_index
Badge class index.
uint8_t column_group
Column group in UI. 0 = left, 1 = centre, 2 = right.
Combination of a palette sprite and a 'real' sprite.
SpriteID sprite
The 'real' sprite.
PaletteID pal
The palette (use PAL_NONE) if not needed)
Specification of a rectangle with absolute coordinates of all edges.
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.
bool Contains(const Point &pt) const
Test if a point falls inside this Rect.
int16_t Height
Fixed point type for heights.
Definition of the game-calendar-timer.
Functions, definitions and such used only by the GUI.
Functions related to zooming.
@ Normal
The normal zoom level.