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/603/head
PeterN 12 months ago committed by GitHub
parent 321f01602a
commit d42a78f3e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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
{

@ -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;

@ -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);

@ -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;

@ -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

@ -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) {

@ -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);
}

@ -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);

@ -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;

@ -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++;
}

@ -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));

@ -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

@ -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;

Loading…
Cancel
Save