1
0
Fork 0

Codechange: Make DropDownListStringItem preformat and remove other implementations. (#11063)

Having to choose between DropDownListStringItem, DropDownListCharStringItem, and DropDownListParamStringItem depending on whether to draw a StringID, a raw string, or a StringID with extra parameters was needlessly complex.

Instead, allow passing a StringID or raw string to DropDownListStringItem. This will preformat the StringID into a raw string, and can therefore accept parameters via the normal SetDParam mechanism.

This also means that strings no longer need to be formatted on every draw.
pull/11061/head
PeterN 2023-06-23 09:30:13 +01:00 committed by GitHub
parent 321f01602a
commit d42a78f3e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 48 additions and 100 deletions

View File

@ -588,14 +588,9 @@ static const LiveryClass _livery_class[LS_END] = {
LC_ROAD, LC_ROAD, LC_ROAD, LC_ROAD,
}; };
class DropDownListColourItem : public DropDownListItem { class DropDownListColourItem : public DropDownListStringItem {
public: public:
DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {} DropDownListColourItem(int result, bool masked) : DropDownListStringItem(result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[result], result, masked) {}
StringID String() const
{
return this->result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[this->result];
}
uint Width() const override uint Width() const override
{ {

View File

@ -90,9 +90,8 @@ struct SetDateWindow : Window {
case WID_SD_YEAR: case WID_SD_YEAR:
for (TimerGameCalendar::Year i = this->min_year; i <= this->max_year; i++) { for (TimerGameCalendar::Year i = this->min_year; i <= this->max_year; i++) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); SetDParam(0, i);
item->SetParam(0, i); list.emplace_back(new DropDownListStringItem(STR_JUST_INT, i, false));
list.emplace_back(item);
} }
selected = this->date.year; selected = this->date.year;
break; break;

View File

@ -311,7 +311,7 @@ struct GSConfigWindow : public Window {
DropDownList list; DropDownList list;
for (int i = config_item.min_value; i <= config_item.max_value; i++) { for (int i = config_item.min_value; i <= config_item.max_value; i++) {
list.emplace_back(new DropDownListCharStringItem(config_item.labels.find(i)->second, i, false)); list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false));
} }
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE); ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);

View File

@ -355,9 +355,8 @@ static DropDownList BuildMapsizeDropDown()
DropDownList list; DropDownList list;
for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) {
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); SetDParam(0, 1LL << i);
item->SetParam(0, 1LL << i); list.emplace_back(new DropDownListStringItem(STR_JUST_INT, i, false));
list.emplace_back(item);
} }
return list; return list;

View File

@ -398,7 +398,7 @@ struct NewGRFParametersWindow : public Window {
DropDownList list; DropDownList list;
for (uint32 i = par_info.min_value; i <= par_info.max_value; i++) { for (uint32 i = par_info.min_value; i <= par_info.max_value; i++) {
list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false)); list.emplace_back(new DropDownListStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false));
} }
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE); ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);
@ -955,7 +955,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false));
for (uint i = 0; i < this->grf_presets.size(); i++) { for (uint i = 0; i < this->grf_presets.size(); i++) {
list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i], i, false)); list.emplace_back(new DropDownListStringItem(this->grf_presets[i], i, false));
} }
this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window

View File

@ -2371,18 +2371,16 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
const RailtypeInfo *rti = GetRailTypeInfo(rt); const RailtypeInfo *rti = GetRailTypeInfo(rt);
StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING); SetDParam(0, rti->strings.menu_text);
DropDownListParamStringItem *item; SetDParam(1, rti->max_speed);
if (for_replacement) { if (for_replacement) {
item = new DropDownListParamStringItem(str, rt, !HasBit(avail_railtypes, rt)); list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt)));
} else { } else {
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt)); DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt));
iconitem->SetDimension(d); iconitem->SetDimension(d);
item = iconitem; list.emplace_back(iconitem);
} }
item->SetParam(0, rti->strings.menu_text);
item->SetParam(1, rti->max_speed);
list.emplace_back(item);
} }
if (list.size() == 0) { if (list.size() == 0) {

View File

@ -1834,18 +1834,16 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
const RoadTypeInfo *rti = GetRoadTypeInfo(rt); const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
DropDownListParamStringItem *item; SetDParam(0, rti->strings.menu_text);
SetDParam(1, rti->max_speed);
if (for_replacement) { if (for_replacement) {
item = new DropDownListParamStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)); list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)));
} else { } else {
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
iconitem->SetDimension(d); iconitem->SetDimension(d);
item = iconitem; list.emplace_back(iconitem);
} }
item->SetParam(0, rti->strings.menu_text);
item->SetParam(1, rti->max_speed / 2);
list.emplace_back(item);
} }
if (list.size() == 0) { if (list.size() == 0) {
@ -1880,11 +1878,11 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
const RoadTypeInfo *rti = GetRoadTypeInfo(rt); const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
SetDParam(0, rti->strings.menu_text);
SetDParam(1, rti->max_speed);
StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING;
DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
item->SetDimension(d); item->SetDimension(d);
item->SetParam(0, rti->strings.menu_text);
item->SetParam(1, rti->max_speed / 2);
list.emplace_back(item); list.emplace_back(item);
} }

View File

@ -469,7 +469,7 @@ struct ScriptSettingsWindow : public Window {
DropDownList list; DropDownList list;
for (int i = config_item.min_value; i <= config_item.max_value; i++) { for (int i = config_item.min_value; i <= config_item.max_value; i++) {
list.emplace_back(new DropDownListCharStringItem(config_item.labels.find(i)->second, i, false)); list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false));
} }
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE); ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);

View File

@ -82,7 +82,7 @@ static DropDownList BuildSetDropDownList(int *selected_index, bool allow_selecti
DropDownList list; DropDownList list;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
list.emplace_back(new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i))); list.emplace_back(new DropDownListStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i)));
} }
return list; return list;
@ -246,20 +246,19 @@ struct GameOptionsWindow : Window {
bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished(); bool hide_language = IsReleasedVersion() && !_languages[i].IsReasonablyFinished();
if (hide_language) continue; if (hide_language) continue;
bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold; bool hide_percentage = IsReleasedVersion() || _languages[i].missing < _settings_client.gui.missing_strings_threshold;
auto item = new DropDownListParamStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false);
if (&_languages[i] == _current_language) { if (&_languages[i] == _current_language) {
*selected_index = i; *selected_index = i;
item->SetParamStr(0, _languages[i].own_name); SetDParamStr(0, _languages[i].own_name);
} else { } else {
/* Especially with sprite-fonts, not all localized /* Especially with sprite-fonts, not all localized
* names can be rendered. So instead, we use the * names can be rendered. So instead, we use the
* international names for anything but the current * international names for anything but the current
* selected language. This avoids showing a few ???? * selected language. This avoids showing a few ????
* entries in the dropdown list. */ * entries in the dropdown list. */
item->SetParamStr(0, _languages[i].name); SetDParamStr(0, _languages[i].name);
} }
item->SetParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS); SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS);
list.emplace_back(item); list.emplace_back(new DropDownListStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false));
} }
std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
break; break;
@ -270,10 +269,9 @@ struct GameOptionsWindow : Window {
*selected_index = GetCurrentResolutionIndex(); *selected_index = GetCurrentResolutionIndex();
for (uint i = 0; i < _resolutions.size(); i++) { for (uint i = 0; i < _resolutions.size(); i++) {
auto item = new DropDownListParamStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false); SetDParam(0, _resolutions[i].width);
item->SetParam(0, _resolutions[i].width); SetDParam(1, _resolutions[i].height);
item->SetParam(1, _resolutions[i].height); list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false));
list.emplace_back(item);
} }
break; break;
@ -281,9 +279,8 @@ struct GameOptionsWindow : Window {
for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) { for (auto it = _refresh_rates.begin(); it != _refresh_rates.end(); it++) {
auto i = std::distance(_refresh_rates.begin(), it); auto i = std::distance(_refresh_rates.begin(), it);
if (*it == _settings_client.gui.refresh_rate) *selected_index = i; if (*it == _settings_client.gui.refresh_rate) *selected_index = i;
auto item = new DropDownListParamStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false); SetDParam(0, *it);
item->SetParam(0, *it); list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false));
list.emplace_back(item);
} }
break; break;

View File

@ -252,18 +252,13 @@ protected:
uint16 page_num = 1; uint16 page_num = 1;
for (const StoryPage *p : this->story_pages) { for (const StoryPage *p : this->story_pages) {
bool current_page = p->index == this->selected_page_id; bool current_page = p->index == this->selected_page_id;
DropDownListStringItem *item = nullptr;
if (!p->title.empty()) { if (!p->title.empty()) {
item = new DropDownListCharStringItem(p->title, p->index, current_page); list.emplace_back(new DropDownListStringItem(p->title, p->index, current_page));
} else { } else {
/* No custom title => use a generic page title with page number. */ /* No custom title => use a generic page title with page number. */
DropDownListParamStringItem *str_item = SetDParam(0, page_num);
new DropDownListParamStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page); list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page));
str_item->SetParam(0, page_num);
item = str_item;
} }
list.emplace_back(item);
page_num++; page_num++;
} }

View File

@ -692,7 +692,7 @@ static const int LTMN_HIGHSCORE = -9; ///< Show highscrore table
static void AddDropDownLeagueTableOptions(DropDownList &list) { static void AddDropDownLeagueTableOptions(DropDownList &list) {
if (LeagueTable::GetNumItems() > 0) { if (LeagueTable::GetNumItems() > 0) {
for (LeagueTable *lt : LeagueTable::Iterate()) { for (LeagueTable *lt : LeagueTable::Iterate()) {
list.emplace_back(new DropDownListCharStringItem(lt->title, lt->index, false)); list.emplace_back(new DropDownListStringItem(lt->title, lt->index, false));
} }
} else { } else {
list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false)); list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false));

View File

@ -32,6 +32,10 @@ void DropDownListItem::Draw(const Rect &r, bool sel, Colours bg_colour) const
GfxFillRect(r.left, mid, r.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2); GfxFillRect(r.left, mid, r.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2);
} }
DropDownListStringItem::DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(GetString(string))
{
}
uint DropDownListStringItem::Width() const uint DropDownListStringItem::Width() const
{ {
return GetStringBoundingBox(this->String()).width + WidgetDimensions::scaled.dropdowntext.Horizontal(); return GetStringBoundingBox(this->String()).width + WidgetDimensions::scaled.dropdowntext.Horizontal();
@ -52,24 +56,12 @@ void DropDownListStringItem::Draw(const Rect &r, bool sel, Colours bg_colour) co
*/ */
/* static */ bool DropDownListStringItem::NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second) /* static */ bool DropDownListStringItem::NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second)
{ {
std::string str1 = GetString(static_cast<const DropDownListStringItem*>(first.get())->String()); std::string str1 = static_cast<const DropDownListStringItem*>(first.get())->String();
std::string str2 = GetString(static_cast<const DropDownListStringItem*>(second.get())->String()); std::string str2 = static_cast<const DropDownListStringItem*>(second.get())->String();
return StrNaturalCompare(str1, str2) < 0; return StrNaturalCompare(str1, str2) < 0;
} }
StringID DropDownListParamStringItem::String() const DropDownListIconItem::DropDownListIconItem(SpriteID sprite, PaletteID pal, StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked), sprite(sprite), pal(pal)
{
for (uint i = 0; i < lengthof(this->decode_params); i++) SetDParam(i, this->decode_params[i]);
return this->string;
}
StringID DropDownListCharStringItem::String() const
{
SetDParamStr(0, this->raw_string);
return this->string;
}
DropDownListIconItem::DropDownListIconItem(SpriteID sprite, PaletteID pal, StringID string, int result, bool masked) : DropDownListParamStringItem(string, result, masked), sprite(sprite), pal(pal)
{ {
this->dim = GetSpriteSize(sprite); this->dim = GetSpriteSize(sprite);
this->sprite_y = dim.height; this->sprite_y = dim.height;
@ -82,7 +74,7 @@ uint DropDownListIconItem::Height(uint width) const
uint DropDownListIconItem::Width() const uint DropDownListIconItem::Width() const
{ {
return DropDownListParamStringItem::Width() + this->dim.width + WidgetDimensions::scaled.hsep_wide; return DropDownListStringItem::Width() + this->dim.width + WidgetDimensions::scaled.hsep_wide;
} }
void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const

View File

@ -37,48 +37,23 @@ public:
*/ */
class DropDownListStringItem : public DropDownListItem { class DropDownListStringItem : public DropDownListItem {
public: public:
StringID string; ///< String ID of item const std::string string; ///< String of item
DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(string) {} DropDownListStringItem(StringID string, int result, bool masked);
DropDownListStringItem(const std::string &string, int result, bool masked) : DropDownListItem(result, masked), string(string) {}
bool Selectable() const override { return true; } bool Selectable() const override { return true; }
uint Width() const override; uint Width() const override;
void Draw(const Rect &r, bool sel, Colours bg_colour) const override; void Draw(const Rect &r, bool sel, Colours bg_colour) const override;
virtual StringID String() const { return this->string; } virtual const std::string &String() const { return this->string; }
static bool NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second); static bool NatSortFunc(std::unique_ptr<const DropDownListItem> const &first, std::unique_ptr<const DropDownListItem> const &second);
}; };
/**
* String list item with parameters.
*/
class DropDownListParamStringItem : public DropDownListStringItem {
public:
uint64 decode_params[10]; ///< Parameters of the string
DropDownListParamStringItem(StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked) {}
StringID String() const override;
void SetParam(uint index, uint64 value) { decode_params[index] = value; }
void SetParamStr(uint index, const char *str) { this->SetParam(index, (uint64)(size_t)str); }
};
/**
* List item containing a C char string.
*/
class DropDownListCharStringItem : public DropDownListStringItem {
public:
std::string raw_string;
DropDownListCharStringItem(const std::string &raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {}
StringID String() const override;
};
/** /**
* List item with icon and string. * List item with icon and string.
*/ */
class DropDownListIconItem : public DropDownListParamStringItem { class DropDownListIconItem : public DropDownListStringItem {
SpriteID sprite; SpriteID sprite;
PaletteID pal; PaletteID pal;
Dimension dim; Dimension dim;