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.
This commit is contained in:
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,
};
class DropDownListColourItem : public DropDownListItem {
class DropDownListColourItem : public DropDownListStringItem {
public:
DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {}
StringID String() const
{
return this->result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[this->result];
}
DropDownListColourItem(int result, bool masked) : DropDownListStringItem(result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[result], result, masked) {}
uint Width() const override
{

View File

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

View File

@ -311,7 +311,7 @@ struct GSConfigWindow : public Window {
DropDownList list;
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);

View File

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

View File

@ -398,7 +398,7 @@ struct NewGRFParametersWindow : public Window {
DropDownList list;
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);
@ -955,7 +955,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false));
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

View File

@ -2371,18 +2371,16 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option)
const RailtypeInfo *rti = GetRailTypeInfo(rt);
StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING);
DropDownListParamStringItem *item;
SetDParam(0, rti->strings.menu_text);
SetDParam(1, rti->max_speed);
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 {
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));
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) {

View File

@ -1834,18 +1834,16 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b
const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
DropDownListParamStringItem *item;
SetDParam(0, rti->strings.menu_text);
SetDParam(1, rti->max_speed);
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 {
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));
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) {
@ -1880,11 +1878,11 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts)
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;
DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt));
item->SetDimension(d);
item->SetParam(0, rti->strings.menu_text);
item->SetParam(1, rti->max_speed / 2);
list.emplace_back(item);
}

View File

@ -469,7 +469,7 @@ struct ScriptSettingsWindow : public Window {
DropDownList list;
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);

View File

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

View File

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

View File

@ -692,7 +692,7 @@ static const int LTMN_HIGHSCORE = -9; ///< Show highscrore table
static void AddDropDownLeagueTableOptions(DropDownList &list) {
if (LeagueTable::GetNumItems() > 0) {
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 {
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);
}
DropDownListStringItem::DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(GetString(string))
{
}
uint DropDownListStringItem::Width() const
{
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)
{
std::string str1 = GetString(static_cast<const DropDownListStringItem*>(first.get())->String());
std::string str2 = GetString(static_cast<const DropDownListStringItem*>(second.get())->String());
std::string str1 = static_cast<const DropDownListStringItem*>(first.get())->String();
std::string str2 = static_cast<const DropDownListStringItem*>(second.get())->String();
return StrNaturalCompare(str1, str2) < 0;
}
StringID DropDownListParamStringItem::String() const
{
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)
DropDownListIconItem::DropDownListIconItem(SpriteID sprite, PaletteID pal, StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked), sprite(sprite), pal(pal)
{
this->dim = GetSpriteSize(sprite);
this->sprite_y = dim.height;
@ -82,7 +74,7 @@ uint DropDownListIconItem::Height(uint 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

View File

@ -37,48 +37,23 @@ public:
*/
class DropDownListStringItem : public DropDownListItem {
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; }
uint Width() 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);
};
/**
* 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.
*/
class DropDownListIconItem : public DropDownListParamStringItem {
class DropDownListIconItem : public DropDownListStringItem {
SpriteID sprite;
PaletteID pal;
Dimension dim;