From c7b9987d081ae4e0103309b18c93deecc395dec9 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Tue, 2 Apr 2019 21:31:24 +0200 Subject: [PATCH] Codechange: Switch DropDownList to directly use std::vector, thus making AutoDeleteSmallVector obsolete. DropDownListItem are strongly managed using std::unique_ptr to ensure leak-free handling. Appropriate use of move-semantics make intent a lot clearer than parameter comments and allows the compiler to generate copy-free code for most situations. --- src/ai/ai_gui.cpp | 6 +-- src/airport_gui.cpp | 6 +-- src/autoreplace_gui.cpp | 8 +-- src/company_gui.cpp | 8 +-- src/core/smallvec_type.hpp | 30 ----------- src/date_gui.cpp | 10 ++-- src/genworld_gui.cpp | 6 +-- src/group_gui.cpp | 3 +- src/industry_gui.cpp | 24 ++++----- src/music_gui.cpp | 3 +- src/newgrf_gui.cpp | 14 ++--- src/order_gui.cpp | 6 +-- src/rail_gui.cpp | 9 ++-- src/rail_gui.h | 2 +- src/settings_gui.cpp | 105 ++++++++++++++++-------------------- src/settings_gui.h | 2 +- src/story_gui.cpp | 18 +++---- src/toolbar_gui.cpp | 94 ++++++++++++++++---------------- src/vehicle_gui.cpp | 17 +++--- src/vehicle_gui_base.h | 2 +- src/widgets/dropdown.cpp | 56 ++++++++----------- src/widgets/dropdown_type.h | 8 +-- 22 files changed, 184 insertions(+), 253 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 2730070c32..eaf2a9d83b 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -479,12 +479,12 @@ struct AISettingsWindow : public Window { this->clicked_dropdown = true; this->closing_dropdown = false; - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list->push_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); + list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); } - ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); } } } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 7e16717894..d170b0cbbb 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -214,12 +214,12 @@ class BuildAirportWindow : public PickerWindowBase { Scrollbar *vscroll; /** Build a dropdown list of available airport classes */ - static DropDownList *BuildAirportClassDropDown() + static DropDownList BuildAirportClassDropDown() { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - list->push_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false)); + list.emplace_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false)); } return list; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 78c2fdc31c..40f8d8ef2b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -467,10 +467,10 @@ public: break; case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: { - DropDownList *list = new DropDownList(); - list->push_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false)); - list->push_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false)); - ShowDropDownList(this, list, this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false)); + list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false)); + ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); break; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index a3f8a24b6c..1c23a12513 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -602,18 +602,18 @@ private: } } - DropDownList *list = new DropDownList(); + DropDownList list; if (default_livery != NULL) { /* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */ default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END; - list->push_back(new DropDownListColourItem(default_col, false)); + list.emplace_back(new DropDownListColourItem(default_col, false)); } for (uint i = 0; i < lengthof(_colour_dropdown); i++) { - list->push_back(new DropDownListColourItem(i, HasBit(used_colours, i))); + list.emplace_back(new DropDownListColourItem(i, HasBit(used_colours, i))); } byte sel = (default_livery == NULL || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col; - ShowDropDownList(this, list, sel, widget); + ShowDropDownList(this, std::move(list), sel, widget); } static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b) diff --git a/src/core/smallvec_type.hpp b/src/core/smallvec_type.hpp index f43265ebe8..77b03ca6b7 100644 --- a/src/core/smallvec_type.hpp +++ b/src/core/smallvec_type.hpp @@ -99,36 +99,6 @@ public: } }; -/** - * Simple vector template class, with automatic delete. - * - * @note There are no asserts in the class so you have - * to care about that you grab an item which is - * inside the list. - * - * @param T The type of the items stored, must be a pointer - */ -template -class AutoDeleteSmallVector : public std::vector { -public: - ~AutoDeleteSmallVector() - { - this->Clear(); - } - - /** - * Remove all items from the list. - */ - inline void Clear() - { - for (T p : *this) { - delete p; - } - - std::vector::clear(); - } -}; - typedef AutoFreeSmallVector StringList; ///< Type for a list of strings. #endif /* SMALLVEC_TYPE_HPP */ diff --git a/src/date_gui.cpp b/src/date_gui.cpp index d55e7e2b34..900e42bd72 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -68,21 +68,21 @@ struct SetDateWindow : Window { void ShowDateDropDown(int widget) { int selected; - DropDownList *list = new DropDownList(); + DropDownList list; switch (widget) { default: NOT_REACHED(); case WID_SD_DAY: for (uint i = 0; i < 31; i++) { - list->push_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false)); + list.emplace_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false)); } selected = this->date.day; break; case WID_SD_MONTH: for (uint i = 0; i < 12; i++) { - list->push_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false)); + list.emplace_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false)); } selected = this->date.month; break; @@ -91,13 +91,13 @@ struct SetDateWindow : Window { for (Year i = this->min_year; i <= this->max_year; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); item->SetParam(0, i); - list->push_back(item); + list.emplace_back(item); } selected = this->date.year; break; } - ShowDropDownList(this, list, selected, widget); + ShowDropDownList(this, std::move(list), selected, widget); } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 697ce382d7..53cc2d39ea 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -282,14 +282,14 @@ static void LandscapeGenerationCallback(Window *w, bool confirmed) if (confirmed) StartGeneratingLandscape((GenerateLandscapeWindowMode)w->window_number); } -static DropDownList *BuildMapsizeDropDown() +static DropDownList BuildMapsizeDropDown() { - DropDownList *list = new DropDownList(); + 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->push_back(item); + list.emplace_back(item); } return list; diff --git a/src/group_gui.cpp b/src/group_gui.cpp index ecc95064fa..22604fdf35 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -768,8 +768,7 @@ public: break; case WID_GL_MANAGE_VEHICLES_DROPDOWN: { - DropDownList *list = this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index)); - ShowDropDownList(this, list, 0, WID_GL_MANAGE_VEHICLES_DROPDOWN); + ShowDropDownList(this, this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index)), 0, WID_GL_MANAGE_VEHICLES_DROPDOWN); break; } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index eff0a5f73d..2796cd979b 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -2709,34 +2709,30 @@ struct IndustryCargoesWindow : public Window { break; case WID_IC_CARGO_DROPDOWN: { - DropDownList *lst = new DropDownList; + DropDownList lst; const CargoSpec *cs; FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { - lst->push_back(new DropDownListStringItem(cs->name, cs->Index(), false)); + lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false)); } - if (lst->size() == 0) { - delete lst; - break; + if (!lst.empty()) { + int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; + ShowDropDownList(this, std::move(lst), selected, WID_IC_CARGO_DROPDOWN, 0, true); } - int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; - ShowDropDownList(this, lst, selected, WID_IC_CARGO_DROPDOWN, 0, true); break; } case WID_IC_IND_DROPDOWN: { - DropDownList *lst = new DropDownList; + DropDownList lst; for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) { IndustryType ind = _sorted_industry_types[i]; const IndustrySpec *indsp = GetIndustrySpec(ind); if (!indsp->enabled) continue; - lst->push_back(new DropDownListStringItem(indsp->name, ind, false)); + lst.emplace_back(new DropDownListStringItem(indsp->name, ind, false)); } - if (lst->size() == 0) { - delete lst; - break; + if (!lst.empty()) { + int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; + ShowDropDownList(this, std::move(lst), selected, WID_IC_IND_DROPDOWN, 0, true); } - int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; - ShowDropDownList(this, lst, selected, WID_IC_IND_DROPDOWN, 0, true); break; } } diff --git a/src/music_gui.cpp b/src/music_gui.cpp index da63192e02..90fd476690 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -571,8 +571,7 @@ struct MusicTrackSelectionWindow : public Window { case WID_MTS_MUSICSET: { int selected = 0; - DropDownList *dropdown = BuildMusicSetDropDownList(&selected); - ShowDropDownList(this, dropdown, selected, widget, 0, true, false); + ShowDropDownList(this, BuildMusicSetDropDownList(&selected), selected, widget, 0, true, false); break; } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index bd5d07a86a..520882667d 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -376,12 +376,12 @@ struct NewGRFParametersWindow : public Window { this->clicked_dropdown = true; this->closing_dropdown = false; - DropDownList *list = new DropDownList(); + DropDownList list; for (uint32 i = par_info->min_value; i <= par_info->max_value; i++) { - list->push_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.Find(i)->second), i, false)); + list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.Find(i)->second), i, false)); } - ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); } } } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { @@ -924,19 +924,19 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { switch (widget) { case WID_NS_PRESET_LIST: { - DropDownList *list = new DropDownList(); + DropDownList list; /* Add 'None' option for clearing list */ - list->push_back(new DropDownListStringItem(STR_NONE, -1, false)); + list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); for (uint i = 0; i < _grf_preset_list.size(); i++) { if (_grf_preset_list[i] != NULL) { - list->push_back(new DropDownListCharStringItem(_grf_preset_list[i], i, false)); + list.emplace_back(new DropDownListCharStringItem(_grf_preset_list[i], i, false)); } } this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window - ShowDropDownList(this, list, this->preset, WID_NS_PRESET_LIST); + ShowDropDownList(this, std::move(list), this->preset, WID_NS_PRESET_LIST); break; } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 0b1ee2ae66..a48638a858 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1295,11 +1295,11 @@ public: break; case WID_O_COND_VARIABLE: { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; i < lengthof(_order_conditional_variable); i++) { - list->push_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); } - ShowDropDownList(this, list, this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE); + ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE); break; } diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 176e8e6efb..e3d307dc94 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1987,7 +1987,7 @@ void InitializeRailGUI() * @param all_option Whether to add an 'all types' item. * @return The populated and sorted #DropDownList. */ -DropDownList *GetRailTypeDropDownList(bool for_replacement, bool all_option) +DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) { RailTypes used_railtypes; RailTypes avail_railtypes; @@ -2003,11 +2003,10 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement, bool all_option) used_railtypes = GetRailTypes(true); } - DropDownList *list = new DropDownList(); + DropDownList list; if (all_option) { - DropDownListStringItem *item = new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false); - list->push_back(item); + list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false)); } Dimension d = { 0, 0 }; @@ -2038,7 +2037,7 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement, bool all_option) } item->SetParam(0, rti->strings.menu_text); item->SetParam(1, rti->max_speed); - list->push_back(item); + list.emplace_back(item); } return list; } diff --git a/src/rail_gui.h b/src/rail_gui.h index e7a03b9120..0a5f240ab3 100644 --- a/src/rail_gui.h +++ b/src/rail_gui.h @@ -19,6 +19,6 @@ struct Window *ShowBuildRailToolbar(RailType railtype); void ReinitGuiAfterToggleElrail(bool disable); bool ResetSignalVariant(int32 = 0); void InitializeRailGUI(); -DropDownList *GetRailTypeDropDownList(bool for_replacement = false, bool all_option = false); +DropDownList GetRailTypeDropDownList(bool for_replacement = false, bool all_option = false); #endif /* RAIL_GUI_H */ diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index c15f075ecf..34514c86f0 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -122,20 +122,20 @@ static int GetCurRes() static void ShowCustCurrency(); template -static DropDownList *BuildSetDropDownList(int *selected_index, bool allow_selection) +static DropDownList BuildSetDropDownList(int *selected_index, bool allow_selection) { int n = T::GetNumSets(); *selected_index = T::GetIndexOfUsedSet(); - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = 0; i < n; i++) { - list->push_back(new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i))); + list.emplace_back(new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i))); } return list; } -DropDownList *BuildMusicSetDropDownList(int *selected_index) +DropDownList BuildMusicSetDropDownList(int *selected_index) { return BuildSetDropDownList(selected_index, true); } @@ -200,12 +200,11 @@ struct GameOptionsWindow : Window { * @param selected_index Currently selected item * @return the built dropdown list, or NULL if the widget has no dropdown menu. */ - DropDownList *BuildDropDownList(int widget, int *selected_index) const + DropDownList BuildDropDownList(int widget, int *selected_index) const { - DropDownList *list = NULL; + DropDownList list; switch (widget) { case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown - list = new DropDownList(); *selected_index = this->opt->locale.currency; StringID *items = BuildCurrencyDropdown(); uint64 disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies(); @@ -213,18 +212,17 @@ struct GameOptionsWindow : Window { /* Add non-custom currencies; sorted naturally */ for (uint i = 0; i < CURRENCY_END; items++, i++) { if (i == CURRENCY_CUSTOM) continue; - list->push_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); + list.emplace_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); } - QSortT(list->data(), list->size(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); /* Append custom currency at the end */ - list->push_back(new DropDownListItem(-1, false)); // separator line - list->push_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); + list.emplace_back(new DropDownListItem(-1, false)); // separator line + list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); break; } case WID_GO_ROADSIDE_DROPDOWN: { // Setup road-side dropdown - list = new DropDownList(); *selected_index = this->opt->vehicle.road_side; const StringID *items = _driveside_dropdown; uint disabled = 0; @@ -237,13 +235,12 @@ struct GameOptionsWindow : Window { } for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - list->push_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); + list.emplace_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); } break; } case WID_GO_TOWNNAME_DROPDOWN: { // Setup townname dropdown - list = new DropDownList(); *selected_index = this->opt->game_creation.town_name; int enabled_item = (_game_mode == GM_MENU || Town::GetNumItems() == 0) ? -1 : *selected_index; @@ -251,71 +248,66 @@ struct GameOptionsWindow : Window { /* Add and sort newgrf townnames generators */ for (int i = 0; i < _nb_grf_names; i++) { int result = _nb_orig_names + i; - list->push_back(new DropDownListStringItem(_grf_names[i], result, enabled_item != result && enabled_item >= 0)); + list.emplace_back(new DropDownListStringItem(_grf_names[i], result, enabled_item != result && enabled_item >= 0)); } - QSortT(list->data(), list->size(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); - size_t newgrf_size = list->size(); + size_t newgrf_size = list.size(); /* Insert newgrf_names at the top of the list */ if (newgrf_size > 0) { - list->push_back(new DropDownListItem(-1, false)); // separator line + list.emplace_back(new DropDownListItem(-1, false)); // separator line newgrf_size++; } /* Add and sort original townnames generators */ for (int i = 0; i < _nb_orig_names; i++) { - list->push_back(new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, enabled_item != i && enabled_item >= 0)); + list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, enabled_item != i && enabled_item >= 0)); } - QSortT(list->data() + newgrf_size, list->size() - newgrf_size, DropDownListStringItem::NatSortFunc); + std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc); break; } case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown - list = new DropDownList(); *selected_index = _settings_client.gui.autosave; const StringID *items = _autosave_dropdown; for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - list->push_back(new DropDownListStringItem(*items, i, false)); + list.emplace_back(new DropDownListStringItem(*items, i, false)); } break; } case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown - list = new DropDownList(); for (uint i = 0; i < _languages.size(); i++) { if (&_languages[i] == _current_language) *selected_index = i; - list->push_back(new DropDownListStringItem(SPECSTR_LANGUAGE_START + i, i, false)); + list.emplace_back(new DropDownListStringItem(SPECSTR_LANGUAGE_START + i, i, false)); } - QSortT(list->data(), list->size(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); break; } case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown if (_num_resolutions == 0) break; - list = new DropDownList(); *selected_index = GetCurRes(); for (int i = 0; i < _num_resolutions; i++) { - list->push_back(new DropDownListStringItem(SPECSTR_RESOLUTION_START + i, i, false)); + list.emplace_back(new DropDownListStringItem(SPECSTR_RESOLUTION_START + i, i, false)); } break; case WID_GO_GUI_ZOOM_DROPDOWN: { - list = new DropDownList(); *selected_index = ZOOM_LVL_OUT_4X - _gui_zoom; const StringID *items = _gui_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - list->push_back(new DropDownListStringItem(*items, i, _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i)); + list.emplace_back(new DropDownListStringItem(*items, i, _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i)); } break; } case WID_GO_FONT_ZOOM_DROPDOWN: { - list = new DropDownList(); *selected_index = ZOOM_LVL_OUT_4X - _font_zoom; const StringID *items = _font_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - list->push_back(new DropDownListStringItem(*items, i, false)); + list.emplace_back(new DropDownListStringItem(*items, i, false)); } break; } @@ -331,9 +323,6 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_MUSIC_DROPDOWN: list = BuildMusicSetDropDownList(selected_index); break; - - default: - return NULL; } return list; @@ -429,17 +418,16 @@ struct GameOptionsWindow : Window { default: { int selected; - DropDownList *list = this->BuildDropDownList(widget, &selected); - if (list != NULL) { + DropDownList list = this->BuildDropDownList(widget, &selected); + if (!list.empty()) { /* Find the biggest item for the default size. */ - for (const DropDownListItem * const ddli : *list) { + for (const auto &ddli : list) { Dimension string_dim; int width = ddli->Width(); string_dim.width = width + padding.width; string_dim.height = ddli->Height(width) + padding.height; *size = maxdim(*size, string_dim); } - delete list; } } } @@ -477,9 +465,9 @@ struct GameOptionsWindow : Window { default: { int selected; - DropDownList *list = this->BuildDropDownList(widget, &selected); - if (list != NULL) { - ShowDropDownList(this, list, selected, widget); + DropDownList list = this->BuildDropDownList(widget, &selected); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), selected, widget); } else { if (widget == WID_GO_RESOLUTION_DROPDOWN) ShowErrorMessage(STR_ERROR_RESOLUTION_LIST_FAILED, INVALID_STRING_ID, WL_ERROR); } @@ -1952,28 +1940,25 @@ struct GameSettingsWindow : Window { } } - DropDownList *BuildDropDownList(int widget) const + DropDownList BuildDropDownList(int widget) const { - DropDownList *list = NULL; + DropDownList list; switch (widget) { case WID_GS_RESTRICT_DROPDOWN: - list = new DropDownList(); - for (int mode = 0; mode != RM_END; mode++) { /* If we are in adv. settings screen for the new game's settings, * we don't want to allow comparing with new game's settings. */ bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; - list->push_back(new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); + list.emplace_back(new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); } break; case WID_GS_TYPE_DROPDOWN: - list = new DropDownList(); - list->push_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); - list->push_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); - list->push_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); - list->push_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); + list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); + list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); + list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); + list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); break; } return list; @@ -2045,17 +2030,17 @@ struct GameSettingsWindow : Window { break; case WID_GS_RESTRICT_DROPDOWN: { - DropDownList *list = this->BuildDropDownList(widget); - if (list != NULL) { - ShowDropDownList(this, list, this->filter.mode, widget); + DropDownList list = this->BuildDropDownList(widget); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), this->filter.mode, widget); } break; } case WID_GS_TYPE_DROPDOWN: { - DropDownList *list = this->BuildDropDownList(widget); - if (list != NULL) { - ShowDropDownList(this, list, this->filter.type, widget); + DropDownList list = this->BuildDropDownList(widget); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), this->filter.type, widget); } break; } @@ -2128,12 +2113,12 @@ struct GameSettingsWindow : Window { this->valuedropdown_entry = pe; this->valuedropdown_entry->SetButtons(SEF_LEFT_DEPRESSED); - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = sdb->min; i <= (int)sdb->max; i++) { - list->push_back(new DropDownListStringItem(sdb->str_val + i - sdb->min, i, false)); + list.emplace_back(new DropDownListStringItem(sdb->str_val + i - sdb->min, i, false)); } - ShowDropDownListAt(this, list, value, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), value, -1, wi_rect, COLOUR_ORANGE, true); } } this->SetDirty(); diff --git a/src/settings_gui.h b/src/settings_gui.h index 23a343219f..a81fc0a2b3 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.h @@ -24,7 +24,7 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable); void DrawBoolButton(int x, int y, bool state, bool clickable); -DropDownList *BuildMusicSetDropDownList(int *selected_index); +DropDownList BuildMusicSetDropDownList(int *selected_index); /* Actually implemented in music_gui.cpp */ void ChangeMusicSet(int index); diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 5679bbdc6b..c90992c6b7 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -228,9 +228,9 @@ protected: /** * Builds the page selector drop down list. */ - DropDownList *BuildDropDownList() const + DropDownList BuildDropDownList() const { - DropDownList *list = new DropDownList(); + DropDownList list; uint16 page_num = 1; for (const StoryPage *p : this->story_pages) { bool current_page = p->index == this->selected_page_id; @@ -245,16 +245,10 @@ protected: item = str_item; } - list->push_back(item); + list.emplace_back(item); page_num++; } - /* Check if list is empty. */ - if (list->size() == 0) { - delete list; - list = NULL; - } - return list; } @@ -611,8 +605,8 @@ public: { switch (widget) { case WID_SB_SEL_PAGE: { - DropDownList *list = this->BuildDropDownList(); - if (list != NULL) { + DropDownList list = this->BuildDropDownList(); + if (!list.empty()) { /* Get the index of selected page. */ int selected = 0; for (uint16 i = 0; i < this->story_pages.size(); i++) { @@ -621,7 +615,7 @@ public: selected++; } - ShowDropDownList(this, list, selected, widget); + ShowDropDownList(this, std::move(list), selected, widget); } break; } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index eac99f2494..00d0bba0b0 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -181,9 +181,9 @@ public: * @param list List of items * @param def Default item */ -static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int def) +static void PopupMainToolbMenu(Window *w, int widget, DropDownList &&list, int def) { - ShowDropDownList(w, list, def, widget, 0, true, true); + ShowDropDownList(w, std::move(list), def, widget, 0, true, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } @@ -196,11 +196,11 @@ static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int de */ static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count) { - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = 0; i < count; i++) { - list->push_back(new DropDownListStringItem(string + i, i, false)); + list.emplace_back(new DropDownListStringItem(string + i, i, false)); } - PopupMainToolbMenu(w, widget, list, 0); + PopupMainToolbMenu(w, widget, std::move(list), 0); } /** Enum for the Company Toolbar's network related buttons */ @@ -217,37 +217,37 @@ static const int CTMN_SPECTATOR = -4; ///< Show a company window as spectator */ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0) { - DropDownList *list = new DropDownList(); + DropDownList list; switch (widget) { case WID_TN_COMPANIES: if (!_networking) break; /* Add the client list button for the companies menu */ - list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); if (_local_company == COMPANY_SPECTATOR) { - list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached())); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached())); } else { - list->push_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached())); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached())); } break; case WID_TN_STORY: - list->push_back(new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); + list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); break; case WID_TN_GOAL: - list->push_back(new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); + list.emplace_back(new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); break; } for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (!Company::IsValidID(c)) continue; - list->push_back(new DropDownListCompanyItem(c, false, HasBit(grey, c))); + list.emplace_back(new DropDownListCompanyItem(c, false, HasBit(grey, c))); } - PopupMainToolbMenu(w, widget, list, _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); + PopupMainToolbMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); } @@ -317,27 +317,27 @@ enum OptionMenuEntries { */ static CallBackFunction ToolbarOptionsClick(Window *w) { - DropDownList *list = new DropDownList(); - list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); - list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); /* Changes to the per-AI settings don't get send from the server to the clients. Clients get * the settings once they join but never update it. As such don't show the window at all * to network clients. */ - if (!_networking || _network_server) list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false)); - list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); - list->push_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); - list->push_back(new DropDownListItem(-1, false)); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES))); - list->push_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS))); + if (!_networking || _network_server) list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); + list.emplace_back(new DropDownListItem(-1, false)); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS))); - ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true, true); + ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -463,24 +463,24 @@ enum MapMenuEntries { static CallBackFunction ToolbarMapClick(Window *w) { - DropDownList *list = new DropDownList(); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); - PopupMainToolbMenu(w, WID_TN_SMALL_MAP, list, 0); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + PopupMainToolbMenu(w, WID_TN_SMALL_MAP, std::move(list), 0); return CBF_NONE; } static CallBackFunction ToolbarScenMapTownDir(Window *w) { - DropDownList *list = new DropDownList(); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list->push_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); - list->push_back(new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); - list->push_back(new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); - PopupMainToolbMenu(w, WID_TE_SMALL_MAP, list, 0); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + list.emplace_back(new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); + list.emplace_back(new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); + PopupMainToolbMenu(w, WID_TE_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -894,10 +894,10 @@ static CallBackFunction MenuClickBuildRail(int index) static CallBackFunction ToolbarBuildRoadClick(Window *w) { const Company *c = Company::Get(_local_company); - DropDownList *list = new DropDownList(); + DropDownList list; /* Road is always visible and available. */ - list->push_back(new DropDownListIconItem(SPR_IMG_ROAD_X_DIR, PAL_NONE, STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false)); + list.emplace_back(new DropDownListIconItem(SPR_IMG_ROAD_X_DIR, PAL_NONE, STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false)); /* Tram is only visible when there will be a tram, and available when that has been introduced. */ Engine *e; @@ -905,10 +905,10 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w) if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue; - list->push_back(new DropDownListIconItem(SPR_IMG_TRAMWAY_X_DIR, PAL_NONE, STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM))); + list.emplace_back(new DropDownListIconItem(SPR_IMG_TRAMWAY_X_DIR, PAL_NONE, STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM))); break; } - ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true); + ShowDropDownList(w, std::move(list), _last_built_roadtype, WID_TN_ROADS, 140, true, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 647ab44f59..f940926502 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -164,17 +164,17 @@ Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bo * @param show_group If true include group-related stuff. * @return Itemlist for dropdown */ -DropDownList *BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group) +DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group) { - DropDownList *list = new DropDownList(); + DropDownList list; - if (show_autoreplace) list->push_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false)); - list->push_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false)); - list->push_back(new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false)); + if (show_autoreplace) list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false)); + list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false)); + list.emplace_back(new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false)); if (show_group) { - list->push_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false)); - list->push_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false)); + list.emplace_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false)); + list.emplace_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false)); } return list; @@ -1636,8 +1636,7 @@ public: break; case WID_VL_MANAGE_VEHICLES_DROPDOWN: { - DropDownList *list = this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false); - ShowDropDownList(this, list, 0, WID_VL_MANAGE_VEHICLES_DROPDOWN); + ShowDropDownList(this, this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false), 0, WID_VL_MANAGE_VEHICLES_DROPDOWN); break; } diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h index 5755c7fa88..8e75278412 100644 --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.h @@ -47,7 +47,7 @@ struct BaseVehicleListWindow : public Window { void SortVehicleList(); void BuildVehicleList(); Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group); - DropDownList *BuildActionDropdownList(bool show_autoreplace, bool show_group); + DropDownList BuildActionDropdownList(bool show_autoreplace, bool show_group); }; uint GetVehicleListHeight(VehicleType type, uint divisor = 1); diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index d0ad6bc465..cb1382dd65 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -51,11 +51,11 @@ void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool * @return true if \a first precedes \a second. * @warning All items in the list need to be derivates of DropDownListStringItem. */ -/* static */ int DropDownListStringItem::NatSortFunc(const DropDownListItem * const *first, const DropDownListItem * const * second) +/* static */ int DropDownListStringItem::NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second) { char buffer1[512], buffer2[512]; - GetString(buffer1, static_cast(*first)->String(), lastof(buffer1)); - GetString(buffer2, static_cast(*second)->String(), lastof(buffer2)); + GetString(buffer1, static_cast(first.get())->String(), lastof(buffer1)); + GetString(buffer2, static_cast(second.get())->String(), lastof(buffer2)); return strnatcmp(buffer1, buffer2); } @@ -126,7 +126,7 @@ struct DropdownWindow : Window { WindowClass parent_wnd_class; ///< Parent window class. WindowNumber parent_wnd_num; ///< Parent window number. int parent_button; ///< Parent widget number where the window is dropped from. - const DropDownList *list; ///< List with dropdown menu items. + const DropDownList list; ///< List with dropdown menu items. int selected_index; ///< Index of the selected item in the list. byte click_delay; ///< Timer to delay selection. bool drag_mode; @@ -148,10 +148,10 @@ struct DropdownWindow : Window { * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. */ - DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) - : Window(&_dropdown_desc) + DropdownWindow(Window *parent, DropDownList &&list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) + : Window(&_dropdown_desc), list(std::move(list)) { - assert(list->size() > 0); + assert(this->list.size() > 0); this->position = position; @@ -174,18 +174,17 @@ struct DropdownWindow : Window { /* Total length of list */ int list_height = 0; - for (const DropDownListItem *item : *list) { + for (const auto &item : this->list) { list_height += item->Height(items_width); } /* Capacity is the average number of items visible */ - this->vscroll->SetCapacity(size.height * (uint16)list->size() / list_height); - this->vscroll->SetCount((uint16)list->size()); + this->vscroll->SetCapacity(size.height * (uint16)this->list.size() / list_height); + this->vscroll->SetCount((uint16)this->list.size()); this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; this->parent_button = button; - this->list = list; this->selected_index = selected; this->click_delay = 0; this->drag_mode = true; @@ -207,7 +206,6 @@ struct DropdownWindow : Window { pt.y -= w2->top; w2->OnDropdownClose(pt, this->parent_button, this->selected_index, this->instant_close); } - delete this->list; } virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) @@ -229,7 +227,7 @@ struct DropdownWindow : Window { int width = nwi->current_x - 4; int pos = this->vscroll->GetPosition(); - for (const DropDownListItem *item : *this->list) { + for (const auto &item : this->list) { /* Skip items that are scrolled up */ if (--pos >= 0) continue; @@ -255,7 +253,7 @@ struct DropdownWindow : Window { int y = r.top + 2; int pos = this->vscroll->GetPosition(); - for (const DropDownListItem *item : *this->list) { + for (const auto &item : this->list) { int item_height = item->Height(r.right - r.left + 1); /* Skip items that are scrolled up */ @@ -357,8 +355,7 @@ struct DropdownWindow : Window { /** * Show a drop down list. * @param w Parent window for the list. - * @param list Prepopulated DropDownList. Will be deleted when the list is - * closed. + * @param list Prepopulated DropDownList. * @param selected The initially selected list item. * @param button The widget which is passed to Window::OnDropdownSelect and OnDropdownClose. * Unless you override those functions, this should be then widget index of the dropdown button. @@ -368,7 +365,7 @@ struct DropdownWindow : Window { * @param instant_close Set to true if releasing mouse button should close the * list regardless of where the cursor is. */ -void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close) +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close) { DeleteWindowById(WC_DROPDOWN_MENU, 0); @@ -384,7 +381,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /* Total height of list */ uint height = 0; - for (const DropDownListItem *item : *list) { + for (const auto &item : list) { height += item->Height(width); if (auto_width) max_item_width = max(max_item_width, item->Width() + 5); } @@ -412,7 +409,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /* If the dropdown doesn't fully fit, we need a dropdown. */ if (height > available_height) { scroll = true; - uint avg_height = height / (uint)list->size(); + uint avg_height = height / (uint)list.size(); /* Check at least there is space for one item. */ assert(available_height >= avg_height); @@ -435,7 +432,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - (int)width : wi_rect.left), top}; Dimension dw_size = {width, height}; - DropdownWindow *dropdown = new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll); + DropdownWindow *dropdown = new DropdownWindow(w, std::move(list), selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll); /* The dropdown starts scrolling downwards when opening it towards * the top and holding down the mouse button. It can be fooled by @@ -446,8 +443,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /** * Show a drop down list. * @param w Parent window for the list. - * @param list Prepopulated DropDownList. Will be deleted when the list is - * closed. + * @param list Prepopulated DropDownList. * @param selected The initially selected list item. * @param button The widget within the parent window that is used to determine * the list's location. @@ -456,7 +452,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b * @param instant_close Set to true if releasing mouse button should close the * list regardless of where the cursor is. */ -void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close) +void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width, bool auto_width, bool instant_close) { /* Our parent's button widget is used to determine where to place the drop * down list window. */ @@ -483,7 +479,7 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but } } - ShowDropDownListAt(w, list, selected, button, wi_rect, wi_colour, auto_width, instant_close); + ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, auto_width, instant_close); } /** @@ -499,21 +495,15 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but */ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width) { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (!HasBit(hidden_mask, i)) { - list->push_back(new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i))); + list.emplace_back(new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i))); } } - /* No entries in the list? */ - if (list->size() == 0) { - delete list; - return; - } - - ShowDropDownList(w, list, selected, button, width); + if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width); } /** diff --git a/src/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index bf8638a924..26c699f164 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.h @@ -49,7 +49,7 @@ public: void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override; virtual StringID String() const { return this->string; } - static int CDECL NatSortFunc(const DropDownListItem * const *first, const DropDownListItem * const *second); + static int NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second); }; /** @@ -98,10 +98,10 @@ public: /** * A drop down list is a collection of drop down list items. */ -typedef AutoDeleteSmallVector DropDownList; +typedef std::vector> DropDownList; -void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false); +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false); -void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false); +void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false); #endif /* WIDGETS_DROPDOWN_TYPE_H */