From 4a9974fda620633ed4c8bc7d9ee0d6801b00ca75 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sun, 13 Sep 2020 16:15:28 -0400 Subject: [PATCH 1/4] Introduce mechanism for configuring dropdown menu with static data For menus with static content, provide a mechanism for building the menu items as a constexpr array, allowing developers to specify menus more concisely and to put the data into the .rodata section where it can be quickly copied through. --- src/openrct2-ui/interface/Dropdown.h | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/openrct2-ui/interface/Dropdown.h b/src/openrct2-ui/interface/Dropdown.h index 8bc20503fb..83c7962aa9 100644 --- a/src/openrct2-ui/interface/Dropdown.h +++ b/src/openrct2-ui/interface/Dropdown.h @@ -11,6 +11,7 @@ #include #include +#include constexpr const rct_string_id DROPDOWN_SEPARATOR = 0; constexpr const rct_string_id DROPDOWN_FORMAT_COLOUR_PICKER = 0xFFFE; @@ -50,3 +51,53 @@ void window_dropdown_show_colour(rct_window* w, rct_widget* widget, uint8_t drop void window_dropdown_show_colour_available( rct_window* w, rct_widget* widget, uint8_t dropdownColour, uint8_t selectedColour, uint32_t availableColours); uint32_t dropdown_get_appropriate_image_dropdown_items_per_row(uint32_t numItems); + +namespace Dropdown +{ + struct Item + { + constexpr Item(int32_t _expectedItemIndex, uint32_t _itemFormat, rct_string_id _stringId) + : expectedItemIndex(_expectedItemIndex) + , itemFormat(_itemFormat) + , stringId(_stringId) + { + } + + int32_t expectedItemIndex; + uint32_t itemFormat; + rct_string_id stringId; + }; + + constexpr Item ToggleOption(int32_t _expectedItemIndex, rct_string_id _stringId) + { + return Item(_expectedItemIndex, STR_TOGGLE_OPTION, _stringId); + } + + constexpr Item Separator() + { + return Item(-1, DROPDOWN_SEPARATOR, STR_EMPTY); + } + + template void SetItems(const Dropdown::Item (&items)[N]) + { + for (int i = 0; i < N; ++i) + { + const Item& item = items[i]; + gDropdownItemsFormat[i] = item.itemFormat; + gDropdownItemsArgs[i] = item.stringId; + } + } + + template constexpr bool ItemIDsMatchIndices(const Dropdown::Item (&items)[N]) + { + for (int i = 0; i < N; ++i) + { + const Dropdown::Item& item = items[i]; + if (item.expectedItemIndex >= 0 && item.expectedItemIndex != i) + return false; + } + + return true; + } + +} // namespace Dropdown From ce99928b81bced477a84e046ebc6c3224dde1dc0 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sun, 13 Sep 2020 16:15:53 -0400 Subject: [PATCH 2/4] Convert view menu to use new constexpr menu specification --- src/openrct2-ui/windows/TopToolbar.cpp | 51 +++++++++++--------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 6576112633..63a6075095 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3618,42 +3618,33 @@ static void top_toolbar_network_menu_dropdown(int16_t dropdownIndex) } } +constexpr Dropdown::Item viewMenuItems[] = { + Dropdown::ToggleOption(DDIDX_UNDERGROUND_INSIDE, STR_UNDERGROUND_VIEW), + Dropdown::ToggleOption(DDIDX_HIDE_BASE, STR_REMOVE_BASE_LAND), + Dropdown::ToggleOption(DDIDX_HIDE_VERTICAL, STR_REMOVE_VERTICAL_FACES), + Dropdown::Separator(), + Dropdown::ToggleOption(DDIDX_SEETHROUGH_RIDES, STR_SEE_THROUGH_RIDES), + Dropdown::ToggleOption(DDIDX_SEETHROUGH_SCENARY, STR_SEE_THROUGH_SCENERY), + Dropdown::ToggleOption(DDIDX_SEETHROUGH_PATHS, STR_SEE_THROUGH_PATHS), + Dropdown::ToggleOption(DDIDX_INVISIBLE_SUPPORTS, STR_INVISIBLE_SUPPORTS), + Dropdown::ToggleOption(DDIDX_INVISIBLE_PEEPS, STR_INVISIBLE_PEOPLE), + Dropdown::Separator(), + Dropdown::ToggleOption(DDIDX_LAND_HEIGHTS, STR_HEIGHT_MARKS_ON_LAND), + Dropdown::ToggleOption(DDIDX_TRACK_HEIGHTS, STR_HEIGHT_MARKS_ON_RIDE_TRACKS), + Dropdown::ToggleOption(DDIDX_PATH_HEIGHTS, STR_HEIGHT_MARKS_ON_PATHS), + Dropdown::Separator(), + Dropdown::ToggleOption(DDIDX_VIEW_CLIPPING, STR_VIEW_CLIPPING_MENU), + Dropdown::ToggleOption(DDIDX_HIGHLIGHT_PATH_ISSUES, STR_HIGHLIGHT_PATH_ISSUES_MENU), +}; +static_assert(Dropdown::ItemIDsMatchIndices(viewMenuItems)); + /** * * rct2: 0x0066CDE4 */ static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) { - gDropdownItemsFormat[0] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[1] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[2] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[3] = STR_EMPTY; - gDropdownItemsFormat[4] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[5] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[6] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[7] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[8] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[9] = STR_EMPTY; - gDropdownItemsFormat[10] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[11] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[12] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[13] = DROPDOWN_SEPARATOR; - gDropdownItemsFormat[DDIDX_VIEW_CLIPPING] = STR_TOGGLE_OPTION; - gDropdownItemsFormat[DDIDX_HIGHLIGHT_PATH_ISSUES] = STR_TOGGLE_OPTION; - - gDropdownItemsArgs[0] = STR_UNDERGROUND_VIEW; - gDropdownItemsArgs[1] = STR_REMOVE_BASE_LAND; - gDropdownItemsArgs[2] = STR_REMOVE_VERTICAL_FACES; - gDropdownItemsArgs[4] = STR_SEE_THROUGH_RIDES; - gDropdownItemsArgs[5] = STR_SEE_THROUGH_SCENERY; - gDropdownItemsArgs[6] = STR_SEE_THROUGH_PATHS; - gDropdownItemsArgs[7] = STR_INVISIBLE_SUPPORTS; - gDropdownItemsArgs[8] = STR_INVISIBLE_PEOPLE; - gDropdownItemsArgs[10] = STR_HEIGHT_MARKS_ON_LAND; - gDropdownItemsArgs[11] = STR_HEIGHT_MARKS_ON_RIDE_TRACKS; - gDropdownItemsArgs[12] = STR_HEIGHT_MARKS_ON_PATHS; - gDropdownItemsArgs[DDIDX_VIEW_CLIPPING] = STR_VIEW_CLIPPING_MENU; - gDropdownItemsArgs[DDIDX_HIGHLIGHT_PATH_ISSUES] = STR_HIGHLIGHT_PATH_ISSUES_MENU; + Dropdown::SetItems(viewMenuItems); window_dropdown_show_text( { w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[1] | 0x80, 0, From a51d8e4deb561dccd042343ec10e3115e89b407d Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sun, 13 Sep 2020 16:16:05 -0400 Subject: [PATCH 3/4] Convert cheats menu to use new constexpr menu specification --- src/openrct2-ui/windows/TopToolbar.cpp | 39 +++++++++----------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 63a6075095..f9b27ea157 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3447,33 +3447,22 @@ static void top_toolbar_rotate_menu_dropdown(int16_t dropdownIndex) } } +constexpr Dropdown::Item cheatsMenuItems[] = { + Dropdown::ToggleOption(DDIDX_CHEATS, STR_CHEAT_TITLE), + Dropdown::ToggleOption(DDIDX_TILE_INSPECTOR, STR_DEBUG_DROPDOWN_TILE_INSPECTOR), + Dropdown::ToggleOption(DDIDX_OBJECT_SELECTION, STR_DEBUG_DROPDOWN_OBJECT_SELECTION), + Dropdown::ToggleOption(DDIDX_INVENTIONS_LIST, STR_DEBUG_DROPDOWN_INVENTIONS_LIST), + Dropdown::ToggleOption(DDIDX_SCENARIO_OPTIONS, STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS), + Dropdown::Separator(), + Dropdown::ToggleOption(DDIDX_ENABLE_SANDBOX_MODE, STR_ENABLE_SANDBOX_MODE), + Dropdown::ToggleOption(DDIDX_DISABLE_CLEARANCE_CHECKS, STR_DISABLE_CLEARANCE_CHECKS), + Dropdown::ToggleOption(DDIDX_DISABLE_SUPPORT_LIMITS, STR_DISABLE_SUPPORT_LIMITS), +}; +static_assert(Dropdown::ItemIDsMatchIndices(cheatsMenuItems)); + static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) { - gDropdownItemsFormat[DDIDX_CHEATS] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_CHEATS] = STR_CHEAT_TITLE; - - gDropdownItemsFormat[DDIDX_TILE_INSPECTOR] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_TILE_INSPECTOR] = STR_DEBUG_DROPDOWN_TILE_INSPECTOR; - - gDropdownItemsFormat[DDIDX_OBJECT_SELECTION] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_OBJECT_SELECTION] = STR_DEBUG_DROPDOWN_OBJECT_SELECTION; - - gDropdownItemsFormat[DDIDX_INVENTIONS_LIST] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_INVENTIONS_LIST] = STR_DEBUG_DROPDOWN_INVENTIONS_LIST; - - gDropdownItemsFormat[DDIDX_SCENARIO_OPTIONS] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_SCENARIO_OPTIONS] = STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS; - - gDropdownItemsFormat[5] = STR_EMPTY; - - gDropdownItemsFormat[DDIDX_ENABLE_SANDBOX_MODE] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_ENABLE_SANDBOX_MODE] = STR_ENABLE_SANDBOX_MODE; - - gDropdownItemsFormat[DDIDX_DISABLE_CLEARANCE_CHECKS] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_DISABLE_CLEARANCE_CHECKS] = STR_DISABLE_CLEARANCE_CHECKS; - - gDropdownItemsFormat[DDIDX_DISABLE_SUPPORT_LIMITS] = STR_TOGGLE_OPTION; - gDropdownItemsArgs[DDIDX_DISABLE_SUPPORT_LIMITS] = STR_DISABLE_SUPPORT_LIMITS; + Dropdown::SetItems(cheatsMenuItems); window_dropdown_show_text( { w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[0] | 0x80, 0, From 4f31ddaca4e1bf9f15f528ebbcc71e692c7de013 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sun, 13 Sep 2020 16:30:17 -0400 Subject: [PATCH 4/4] Make menu data declarations local to the functions using them --- src/openrct2-ui/windows/TopToolbar.cpp | 74 ++++++++++++++------------ 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index f9b27ea157..0d747e510c 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3447,22 +3447,24 @@ static void top_toolbar_rotate_menu_dropdown(int16_t dropdownIndex) } } -constexpr Dropdown::Item cheatsMenuItems[] = { - Dropdown::ToggleOption(DDIDX_CHEATS, STR_CHEAT_TITLE), - Dropdown::ToggleOption(DDIDX_TILE_INSPECTOR, STR_DEBUG_DROPDOWN_TILE_INSPECTOR), - Dropdown::ToggleOption(DDIDX_OBJECT_SELECTION, STR_DEBUG_DROPDOWN_OBJECT_SELECTION), - Dropdown::ToggleOption(DDIDX_INVENTIONS_LIST, STR_DEBUG_DROPDOWN_INVENTIONS_LIST), - Dropdown::ToggleOption(DDIDX_SCENARIO_OPTIONS, STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS), - Dropdown::Separator(), - Dropdown::ToggleOption(DDIDX_ENABLE_SANDBOX_MODE, STR_ENABLE_SANDBOX_MODE), - Dropdown::ToggleOption(DDIDX_DISABLE_CLEARANCE_CHECKS, STR_DISABLE_CLEARANCE_CHECKS), - Dropdown::ToggleOption(DDIDX_DISABLE_SUPPORT_LIMITS, STR_DISABLE_SUPPORT_LIMITS), -}; -static_assert(Dropdown::ItemIDsMatchIndices(cheatsMenuItems)); - static void top_toolbar_init_cheats_menu(rct_window* w, rct_widget* widget) { - Dropdown::SetItems(cheatsMenuItems); + using namespace Dropdown; + + constexpr Item items[] = { + ToggleOption(DDIDX_CHEATS, STR_CHEAT_TITLE), + ToggleOption(DDIDX_TILE_INSPECTOR, STR_DEBUG_DROPDOWN_TILE_INSPECTOR), + ToggleOption(DDIDX_OBJECT_SELECTION, STR_DEBUG_DROPDOWN_OBJECT_SELECTION), + ToggleOption(DDIDX_INVENTIONS_LIST, STR_DEBUG_DROPDOWN_INVENTIONS_LIST), + ToggleOption(DDIDX_SCENARIO_OPTIONS, STR_DEBUG_DROPDOWN_SCENARIO_OPTIONS), + Separator(), + ToggleOption(DDIDX_ENABLE_SANDBOX_MODE, STR_ENABLE_SANDBOX_MODE), + ToggleOption(DDIDX_DISABLE_CLEARANCE_CHECKS, STR_DISABLE_CLEARANCE_CHECKS), + ToggleOption(DDIDX_DISABLE_SUPPORT_LIMITS, STR_DISABLE_SUPPORT_LIMITS), + }; + static_assert(ItemIDsMatchIndices(items)); + + SetItems(items); window_dropdown_show_text( { w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[0] | 0x80, 0, @@ -3607,33 +3609,35 @@ static void top_toolbar_network_menu_dropdown(int16_t dropdownIndex) } } -constexpr Dropdown::Item viewMenuItems[] = { - Dropdown::ToggleOption(DDIDX_UNDERGROUND_INSIDE, STR_UNDERGROUND_VIEW), - Dropdown::ToggleOption(DDIDX_HIDE_BASE, STR_REMOVE_BASE_LAND), - Dropdown::ToggleOption(DDIDX_HIDE_VERTICAL, STR_REMOVE_VERTICAL_FACES), - Dropdown::Separator(), - Dropdown::ToggleOption(DDIDX_SEETHROUGH_RIDES, STR_SEE_THROUGH_RIDES), - Dropdown::ToggleOption(DDIDX_SEETHROUGH_SCENARY, STR_SEE_THROUGH_SCENERY), - Dropdown::ToggleOption(DDIDX_SEETHROUGH_PATHS, STR_SEE_THROUGH_PATHS), - Dropdown::ToggleOption(DDIDX_INVISIBLE_SUPPORTS, STR_INVISIBLE_SUPPORTS), - Dropdown::ToggleOption(DDIDX_INVISIBLE_PEEPS, STR_INVISIBLE_PEOPLE), - Dropdown::Separator(), - Dropdown::ToggleOption(DDIDX_LAND_HEIGHTS, STR_HEIGHT_MARKS_ON_LAND), - Dropdown::ToggleOption(DDIDX_TRACK_HEIGHTS, STR_HEIGHT_MARKS_ON_RIDE_TRACKS), - Dropdown::ToggleOption(DDIDX_PATH_HEIGHTS, STR_HEIGHT_MARKS_ON_PATHS), - Dropdown::Separator(), - Dropdown::ToggleOption(DDIDX_VIEW_CLIPPING, STR_VIEW_CLIPPING_MENU), - Dropdown::ToggleOption(DDIDX_HIGHLIGHT_PATH_ISSUES, STR_HIGHLIGHT_PATH_ISSUES_MENU), -}; -static_assert(Dropdown::ItemIDsMatchIndices(viewMenuItems)); - /** * * rct2: 0x0066CDE4 */ static void top_toolbar_init_view_menu(rct_window* w, rct_widget* widget) { - Dropdown::SetItems(viewMenuItems); + using namespace Dropdown; + + constexpr Item items[] = { + ToggleOption(DDIDX_UNDERGROUND_INSIDE, STR_UNDERGROUND_VIEW), + ToggleOption(DDIDX_HIDE_BASE, STR_REMOVE_BASE_LAND), + ToggleOption(DDIDX_HIDE_VERTICAL, STR_REMOVE_VERTICAL_FACES), + Separator(), + ToggleOption(DDIDX_SEETHROUGH_RIDES, STR_SEE_THROUGH_RIDES), + ToggleOption(DDIDX_SEETHROUGH_SCENARY, STR_SEE_THROUGH_SCENERY), + ToggleOption(DDIDX_SEETHROUGH_PATHS, STR_SEE_THROUGH_PATHS), + ToggleOption(DDIDX_INVISIBLE_SUPPORTS, STR_INVISIBLE_SUPPORTS), + ToggleOption(DDIDX_INVISIBLE_PEEPS, STR_INVISIBLE_PEOPLE), + Separator(), + ToggleOption(DDIDX_LAND_HEIGHTS, STR_HEIGHT_MARKS_ON_LAND), + ToggleOption(DDIDX_TRACK_HEIGHTS, STR_HEIGHT_MARKS_ON_RIDE_TRACKS), + ToggleOption(DDIDX_PATH_HEIGHTS, STR_HEIGHT_MARKS_ON_PATHS), + Separator(), + ToggleOption(DDIDX_VIEW_CLIPPING, STR_VIEW_CLIPPING_MENU), + ToggleOption(DDIDX_HIGHLIGHT_PATH_ISSUES, STR_HIGHLIGHT_PATH_ISSUES_MENU), + }; + static_assert(ItemIDsMatchIndices(items)); + + SetItems(items); window_dropdown_show_text( { w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[1] | 0x80, 0,