Changeset - r27635:9224ce9d4476
[Not reviewed]
master
0 13 0
PeterN - 15 months ago 2023-06-23 08:30:13
peter1138@openttd.org
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.
13 files changed with 48 insertions and 100 deletions:
0 comments (0 inline, 0 general)
src/company_gui.cpp
Show inline comments
 
@@ -588,14 +588,9 @@ static const LiveryClass _livery_class[L
 
	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
 
	{
src/date_gui.cpp
Show inline comments
 
@@ -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;
src/game/game_gui.cpp
Show inline comments
 
@@ -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);
src/genworld_gui.cpp
Show inline comments
 
@@ -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;
src/newgrf_gui.cpp
Show inline comments
 
@@ -398,7 +398,7 @@ struct NewGRFParametersWindow : public W
 

	
 
							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, New
 
				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
src/rail_gui.cpp
Show inline comments
 
@@ -2371,18 +2371,16 @@ DropDownList GetRailTypeDropDownList(boo
 

	
 
		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) {
src/road_gui.cpp
Show inline comments
 
@@ -1834,18 +1834,16 @@ DropDownList GetRoadTypeDropDownList(Roa
 

	
 
		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
 

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

	
src/script/script_gui.cpp
Show inline comments
 
@@ -469,7 +469,7 @@ struct ScriptSettingsWindow : public Win
 

	
 
							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);
src/settings_gui.cpp
Show inline comments
 
@@ -82,7 +82,7 @@ static DropDownList BuildSetDropDownList
 

	
 
	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;
 

	
src/story_gui.cpp
Show inline comments
 
@@ -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++;
 
		}
 

	
src/toolbar_gui.cpp
Show inline comments
 
@@ -692,7 +692,7 @@ static const int LTMN_HIGHSCORE         
 
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));
src/widgets/dropdown.cpp
Show inline comments
 
@@ -32,6 +32,10 @@ void DropDownListItem::Draw(const Rect &
 
	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 
 
 */
 
/* 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 w
 

	
 
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
src/widgets/dropdown_type.h
Show inline comments
 
@@ -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;
0 comments (0 inline, 0 general)