diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index f788b06a44..ac28477e69 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1759,7 +1759,7 @@ struct BuildVehicleWindow : Window { case WID_BV_CONFIGURE_BADGES: if (this->badge_classes.GetClasses().empty()) break; - ShowDropDownList(this, this->BuildBadgeConfigurationList(), -1, widget, 0, false, true); + ShowDropDownList(this, this->BuildBadgeConfigurationList(), -1, widget, 0, DropDownOption::Persist); break; case WID_BV_SHOW_HIDE: { @@ -1786,7 +1786,7 @@ struct BuildVehicleWindow : Window { default: if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { PaletteID palette = SPR_2CCMAP_BASE + Company::Get(_local_company)->GetCompanyRecolourOffset(LS_DEFAULT); - ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(palette), -1, widget, 0, false); + ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(palette), -1, widget, 0); } break; } diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 7b099b1af7..ccd449eef8 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -86,8 +86,7 @@ struct DropdownWindow : Window { int selected_click_result = -1; ///< Click result value, from the OnClick handler of the selected item. uint8_t click_delay = 0; ///< Timer to delay selection. bool drag_mode = true; - bool instant_close = false; ///< Close the window when the mouse button is raised. - bool persist = false; ///< Persist dropdown menu. + DropDownOptions options; ///< Options for this drop down menu. int scrolling = 0; ///< If non-zero, auto-scroll the item list (one time). Point position{}; ///< Position of the topleft corner of the window. Scrollbar *vscroll = nullptr; @@ -101,18 +100,16 @@ struct DropdownWindow : Window { * @param selected Initial selected result of the list. * @param button Widget of the parent window doing the dropdown. * @param wi_rect Rect of the button that opened the dropdown. - * @param instant_close Close the window when the mouse button is raised. * @param wi_colour Colour of the parent widget. - * @param persist Dropdown menu will persist. + * @param options Drop Down options for this menu. */ - DropdownWindow(Window *parent, DropDownList &&list, int selected, WidgetID button, const Rect wi_rect, bool instant_close, Colours wi_colour, bool persist) + DropdownWindow(Window *parent, DropDownList &&list, int selected, WidgetID button, const Rect wi_rect, Colours wi_colour, DropDownOptions options) : Window(_dropdown_desc) , parent_button(button) , wi_rect(wi_rect) , list(std::move(list)) , selected_result(selected) - , instant_close(instant_close) - , persist(persist) + , options(options) { assert(!this->list.empty()); @@ -138,7 +135,7 @@ struct DropdownWindow : Window { Point pt = _cursor.pos; pt.x -= this->parent->left; pt.y -= this->parent->top; - this->parent->OnDropdownClose(pt, this->parent_button, this->selected_result, this->selected_click_result, this->instant_close); + this->parent->OnDropdownClose(pt, this->parent_button, this->selected_result, this->selected_click_result, this->options.Test(DropDownOption::InstantClose)); /* Set flag on parent widget to indicate that we have just closed. */ NWidgetCore *nwc = this->parent->GetWidget(this->parent_button); @@ -148,7 +145,7 @@ struct DropdownWindow : Window { void OnFocusLost(bool closing) override { if (!closing) { - this->instant_close = false; + this->options.Reset(DropDownOption::InstantClose); this->Close(); } } @@ -316,7 +313,7 @@ struct DropdownWindow : Window { if (this->click_delay != 0 && --this->click_delay == 0) { /* Close the dropdown, so it doesn't affect new window placement. * Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */ - if (!this->persist) this->Close(); + if (!this->options.Test(DropDownOption::Persist)) this->Close(); this->parent->OnDropdownSelect(this->parent_button, this->selected_result, this->selected_click_result); return; } @@ -327,7 +324,7 @@ struct DropdownWindow : Window { if (!_left_button_clicked) { this->drag_mode = false; if (!this->GetDropDownItem(result, click_result)) { - if (this->instant_close) this->Close(); + if (this->options.Test(DropDownOption::InstantClose)) this->Close(); return; } this->click_delay = 2; @@ -395,14 +392,12 @@ Dimension GetDropDownListDimension(const DropDownList &list) * @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. * @param wi_rect Coord of the parent drop down button, used to position the dropdown menu. - * @param instant_close Set to true if releasing mouse button should close the - * list regardless of where the cursor is. - * @param persist Set if this dropdown should stay open after an option is selected. + * @param options Drop Down options for this menu. */ -void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, bool instant_close, bool persist) +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, DropDownOptions options) { CloseWindowByClass(WC_DROPDOWN_MENU); - new DropdownWindow(w, std::move(list), selected, button, wi_rect, instant_close, wi_colour, persist); + new DropdownWindow(w, std::move(list), selected, button, wi_rect, wi_colour, options); } /** @@ -413,11 +408,9 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID b * @param button The widget within the parent window that is used to determine * the list's location. * @param width Override the minimum width determined by the selected widget and list contents. - * @param instant_close Set to true if releasing mouse button should close the - * list regardless of where the cursor is. - * @param persist Set if this dropdown should stay open after an option is selected. + * @param options Drop Down options for this menu. */ -void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, bool instant_close, bool persist) +void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options) { /* Handle the beep of the player's click. */ SndClickBeep(); @@ -443,7 +436,7 @@ void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID but } } - ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, instant_close, persist); + ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, options); } /** @@ -469,5 +462,5 @@ void ShowDropDownMenu(Window *w, std::span strings, int selected ++i; } - if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width); + if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width, {}); } diff --git a/src/dropdown_type.h b/src/dropdown_type.h index 5e6057d1ee..9afc546aa4 100644 --- a/src/dropdown_type.h +++ b/src/dropdown_type.h @@ -10,6 +10,7 @@ #ifndef DROPDOWN_TYPE_H #define DROPDOWN_TYPE_H +#include "core/enum_type.hpp" #include "window_type.h" #include "gfx_func.h" #include "gfx_type.h" @@ -54,9 +55,15 @@ public: */ typedef std::vector> DropDownList; -void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, bool instant_close = false, bool persist = false); +enum class DropDownOption : uint8_t { + InstantClose, ///< Set if releasing mouse button should close the list regardless of where the cursor is. + Persist, ///< Set if this dropdown should stay open after an option is selected. +}; +using DropDownOptions = EnumBitSet; -void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width = 0, bool instant_close = false, bool persist = false); +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, WidgetID button, Rect wi_rect, Colours wi_colour, DropDownOptions options = {}); + +void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width = 0, DropDownOptions options = {}); Dimension GetDropDownListDimension(const DropDownList &list); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index e4ef5ea450..cde5fa8008 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1650,7 +1650,7 @@ private: wi_rect.bottom = pt.y; w->dd_client_id = client_id; - ShowDropDownListAt(w, std::move(list), -1, WID_CL_MATRIX, wi_rect, COLOUR_GREY, true); + ShowDropDownListAt(w, std::move(list), -1, WID_CL_MATRIX, wi_rect, COLOUR_GREY, DropDownOption::InstantClose); } /** @@ -1671,7 +1671,7 @@ private: wi_rect.bottom = pt.y; w->dd_company_id = company_id; - ShowDropDownListAt(w, std::move(list), -1, WID_CL_MATRIX, wi_rect, COLOUR_GREY, true); + ShowDropDownListAt(w, std::move(list), -1, WID_CL_MATRIX, wi_rect, COLOUR_GREY, DropDownOption::InstantClose); } /** * Chat button on a Client is clicked. diff --git a/src/picker_gui.cpp b/src/picker_gui.cpp index 73b81281c0..4fc16d0fd8 100644 --- a/src/picker_gui.cpp +++ b/src/picker_gui.cpp @@ -442,12 +442,12 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int) case WID_PW_CONFIGURE_BADGES: if (this->badge_classes.GetClasses().empty()) break; - ShowDropDownList(this, BuildBadgeClassConfigurationList(this->badge_classes, 1, {}), -1, widget, 0, false, true); + ShowDropDownList(this, BuildBadgeClassConfigurationList(this->badge_classes, 1, {}), -1, widget, 0, DropDownOption::Persist); break; default: if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { - ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(), -1, widget, 0, false); + ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(), -1, widget, 0); } break; } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 161c0b5640..6b7089cd7a 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -692,7 +692,7 @@ public: case WID_STL_CARGODROPDOWN: this->filter_expanded = false; - ShowDropDownList(this, this->BuildCargoDropDownList(this->filter_expanded), -1, widget, 0, false, true); + ShowDropDownList(this, this->BuildCargoDropDownList(this->filter_expanded), -1, widget, 0, DropDownOption::Persist); break; } } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 9eeb636f06..38508c3ccf 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -120,6 +120,12 @@ public: } }; +static DropDownOptions GetToolbarDropDownOptions() +{ + if (_settings_client.gui.toolbar_dropdown_autoselect) return DropDownOption::InstantClose; + return {}; +} + /** * Pop up a generic text only menu. * @param w Toolbar @@ -129,7 +135,7 @@ public: */ static void PopupMainToolbarMenu(Window *w, WidgetID widget, DropDownList &&list, int def) { - ShowDropDownList(w, std::move(list), def, widget, 0, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), def, widget, 0, GetToolbarDropDownOptions()); } /** @@ -319,7 +325,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w) list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_HOUSES), STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS)); list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS)); - ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -749,7 +755,7 @@ static CallBackFunction ToolbarGraphsClick(Window *w) if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list); - ShowDropDownList(w, std::move(list), GRMN_OPERATING_PROFIT_GRAPH, WID_TN_GRAPHS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), GRMN_OPERATING_PROFIT_GRAPH, WID_TN_GRAPHS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -760,7 +766,7 @@ static CallBackFunction ToolbarLeagueClick(Window *w) AddDropDownLeagueTableOptions(list); int selected = list[0]->result; - ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -938,7 +944,7 @@ static CallBackFunction ToolbarZoomOutClick(Window *w) static CallBackFunction ToolbarBuildRailClick(Window *w) { - ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -959,7 +965,7 @@ static CallBackFunction MenuClickBuildRail(int index) static CallBackFunction ToolbarBuildRoadClick(Window *w) { - ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TN_ROADS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TN_ROADS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -980,7 +986,7 @@ static CallBackFunction MenuClickBuildRoad(int index) static CallBackFunction ToolbarBuildTramClick(Window *w) { - ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -1003,7 +1009,7 @@ static CallBackFunction ToolbarBuildWaterClick(Window *w) { DropDownList list; list.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0)); - ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -1024,7 +1030,7 @@ static CallBackFunction ToolbarBuildAirClick(Window *w) { DropDownList list; list.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0)); - ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -1047,7 +1053,7 @@ static CallBackFunction ToolbarForestClick(Window *w) list.push_back(MakeDropDownListIconItem(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0)); list.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1)); list.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2)); - ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -1318,7 +1324,7 @@ static CallBackFunction ToolbarScenGenIndustry(Window *w) static CallBackFunction ToolbarScenBuildRoadClick(Window *w) { - ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, GetToolbarDropDownOptions()); return CBF_NONE; } @@ -1337,7 +1343,7 @@ static CallBackFunction ToolbarScenBuildRoad(int index) static CallBackFunction ToolbarScenBuildTramClick(Window *w) { - ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, _settings_client.gui.toolbar_dropdown_autoselect); + ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, GetToolbarDropDownOptions()); return CBF_NONE; }