From 8e1750b7751d2a6a8a3c65aa44b09ae2f7193354 Mon Sep 17 00:00:00 2001 From: Gal B Date: Sat, 4 Dec 2021 16:51:24 +0200 Subject: [PATCH 1/2] Refactor Custom Currency window to class --- src/openrct2-ui/windows/CustomCurrency.cpp | 374 ++++++++++----------- 1 file changed, 178 insertions(+), 196 deletions(-) diff --git a/src/openrct2-ui/windows/CustomCurrency.cpp b/src/openrct2-ui/windows/CustomCurrency.cpp index 4716de5bd4..46e65876ab 100644 --- a/src/openrct2-ui/windows/CustomCurrency.cpp +++ b/src/openrct2-ui/windows/CustomCurrency.cpp @@ -42,204 +42,186 @@ static rct_widget window_custom_currency_widgets[] = { WIDGETS_END, }; - -static void CustomCurrencyWindowMousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget *widget); -static void CustomCurrencyWindowMouseup(rct_window *w, rct_widgetindex widgetIndex); -static void CustomCurrencyWindowDropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex); -static void CustomCurrencyWindowTextInput(struct rct_window *w, rct_widgetindex widgetIndex, char *text); -static void CustomCurrencyWindowPaint(rct_window *w, rct_drawpixelinfo *dpi); - - -static rct_window_event_list _windowCustomCurrencyEvents([](auto& events) -{ - events.mouse_up = &CustomCurrencyWindowMouseup; - events.mouse_down = &CustomCurrencyWindowMousedown; - events.dropdown = &CustomCurrencyWindowDropdown; - events.text_input = &CustomCurrencyWindowTextInput; - events.paint = &CustomCurrencyWindowPaint; -}); // clang-format on +class CustomCurrencyWindow final : public Window +{ +public: + void OnOpen() override + { + widgets = window_custom_currency_widgets; + enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_RATE) | (1ULL << WIDX_RATE_UP) | (1ULL << WIDX_RATE_DOWN) + | (1ULL << WIDX_SYMBOL_TEXT) | (1ULL << WIDX_AFFIX_DROPDOWN) | (1ULL << WIDX_AFFIX_DROPDOWN_BUTTON); + hold_down_widgets = (1ULL << WIDX_RATE_UP) | (1ULL << WIDX_RATE_DOWN); + WindowInitScrollWidgets(this); + colours[0] = COLOUR_LIGHT_BROWN; + colours[1] = COLOUR_LIGHT_BROWN; + colours[2] = COLOUR_LIGHT_BROWN; + } + + void OnMouseDown(rct_widgetindex widgetIndex) override + { + auto* widget = &widgets[widgetIndex - 1]; + + switch (widgetIndex) + { + case WIDX_CLOSE: + Close(); + break; + case WIDX_RATE_UP: + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate += 1; + gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; + config_save_default(); + window_invalidate_all(); + break; + case WIDX_RATE_DOWN: + if (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate > 1) + { + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate -= 1; + gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; + config_save_default(); + window_invalidate_all(); + } + break; + case WIDX_AFFIX_DROPDOWN_BUTTON: + gDropdownItemsFormat[0] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[0] = STR_PREFIX; + + gDropdownItemsFormat[1] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[1] = STR_SUFFIX; + + WindowDropdownShowTextCustomWidth( + { windowPos.x + widget->left, windowPos.y + widget->top }, widget->height() + 1, colours[1], 0, + Dropdown::Flag::StayOpen, 2, widget->width() - 3); + + if (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode == CurrencyAffix::Prefix) + { + Dropdown::SetChecked(0, true); + } + else + { + Dropdown::SetChecked(1, true); + } + + break; + case WIDX_SYMBOL_TEXT: + WindowTextInputRawOpen( + this, WIDX_SYMBOL_TEXT, STR_CUSTOM_CURRENCY_SYMBOL_INPUT_TITLE, STR_CUSTOM_CURRENCY_SYMBOL_INPUT_DESC, {}, + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, CURRENCY_SYMBOL_MAX_SIZE); + break; + } + } + + void OnMouseUp(rct_widgetindex widgetIndex) override + { + switch (widgetIndex) + { + case WIDX_RATE: + WindowTextInputOpen( + this, WIDX_RATE, STR_RATE_INPUT_TITLE, STR_RATE_INPUT_DESC, {}, STR_FORMAT_INTEGER, + static_cast(CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate), + CURRENCY_RATE_MAX_NUM_DIGITS); + break; + } + } + + void OnDropdown(rct_widgetindex widgetIndex, int32_t dropdownIndex) override + { + if (dropdownIndex == -1) + return; + + if (widgetIndex == WIDX_AFFIX_DROPDOWN_BUTTON) + { + if (dropdownIndex == 0) + { + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_ascii = CurrencyAffix::Prefix; + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode = CurrencyAffix::Prefix; + } + else if (dropdownIndex == 1) + { + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_ascii = CurrencyAffix::Suffix; + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode = CurrencyAffix::Suffix; + } + + gConfigGeneral.custom_currency_affix = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode; + config_save_default(); + + window_invalidate_all(); + } + } + + void OnTextInput(rct_widgetindex widgetIndex, std::string_view text) override + { + if (text.empty()) + return; + int32_t rate; + char* end; + switch (widgetIndex) + { + case WIDX_SYMBOL_TEXT: + safe_strcpy( + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, std::string(text).c_str(), + CURRENCY_SYMBOL_MAX_SIZE); + + safe_strcpy( + gConfigGeneral.custom_currency_symbol, CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, + CURRENCY_SYMBOL_MAX_SIZE); + + config_save_default(); + window_invalidate_all(); + break; + + case WIDX_RATE: + rate = strtol(std::string(text).c_str(), &end, 10); + if (*end == '\0') + { + CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate = rate; + gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; + config_save_default(); + window_invalidate_all(); + } + break; + } + } + + void OnDraw(rct_drawpixelinfo& dpi) override + { + auto ft = Formatter::Common(); + ft.Add(MONEY(10, 0)); + + DrawWidgets(dpi); + + auto screenCoords = windowPos + ScreenCoordsXY{ 10, 30 }; + + DrawTextBasic(&dpi, screenCoords, STR_RATE, {}, { colours[1] }); + + int32_t baseExchange = CurrencyDescriptors[EnumValue(CurrencyType::Pounds)].rate; + ft = Formatter(); + ft.Add(baseExchange); + DrawTextBasic(&dpi, screenCoords + ScreenCoordsXY{ 200, 0 }, STR_CUSTOM_CURRENCY_EQUIVALENCY, ft, { colours[1] }); + + screenCoords.y += 20; + + DrawTextBasic(&dpi, screenCoords, STR_CURRENCY_SYMBOL_TEXT, {}, { colours[1] }); + + screenCoords = windowPos + + ScreenCoordsXY{ window_custom_currency_widgets[WIDX_SYMBOL_TEXT].left + 1, + window_custom_currency_widgets[WIDX_SYMBOL_TEXT].top }; + + gfx_draw_string( + &dpi, screenCoords, CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, { colours[1] }); + + auto drawPos = windowPos + + ScreenCoordsXY{ window_custom_currency_widgets[WIDX_AFFIX_DROPDOWN].left + 1, + window_custom_currency_widgets[WIDX_AFFIX_DROPDOWN].top }; + rct_string_id stringId = (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode == CurrencyAffix::Prefix) + ? STR_PREFIX + : STR_SUFFIX; + DrawTextBasic(&dpi, drawPos, stringId, {}, { colours[1] }); + } +}; + rct_window* CustomCurrencyWindowOpen() { - rct_window* window; - - // Check if window is already open - window = window_bring_to_front_by_class(WC_CUSTOM_CURRENCY_CONFIG); - if (window != nullptr) - return window; - - window = WindowCreateCentred(400, 100, &_windowCustomCurrencyEvents, WC_CUSTOM_CURRENCY_CONFIG, 0); - window->widgets = window_custom_currency_widgets; - window->enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_RATE) | (1ULL << WIDX_RATE_UP) | (1ULL << WIDX_RATE_DOWN) - | (1ULL << WIDX_SYMBOL_TEXT) | (1ULL << WIDX_AFFIX_DROPDOWN) | (1ULL << WIDX_AFFIX_DROPDOWN_BUTTON); - - window->hold_down_widgets = (1ULL << WIDX_RATE_UP) | (1ULL << WIDX_RATE_DOWN); - WindowInitScrollWidgets(window); - window->colours[0] = COLOUR_LIGHT_BROWN; - window->colours[1] = COLOUR_LIGHT_BROWN; - window->colours[2] = COLOUR_LIGHT_BROWN; - - return window; -} - -static void CustomCurrencyWindowMousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget) -{ - widget = &w->widgets[widgetIndex - 1]; - - switch (widgetIndex) - { - case WIDX_CLOSE: - window_close(w); - break; - - case WIDX_RATE_UP: - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate += 1; - gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; - config_save_default(); - window_invalidate_all(); - break; - - case WIDX_RATE_DOWN: - if (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate > 1) - { - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate -= 1; - gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; - config_save_default(); - window_invalidate_all(); - } - break; - - case WIDX_AFFIX_DROPDOWN_BUTTON: - gDropdownItemsFormat[0] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[0] = STR_PREFIX; - - gDropdownItemsFormat[1] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[1] = STR_SUFFIX; - - WindowDropdownShowTextCustomWidth( - { w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1, w->colours[1], 0, - Dropdown::Flag::StayOpen, 2, widget->width() - 3); - - if (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode == CurrencyAffix::Prefix) - { - Dropdown::SetChecked(0, true); - } - else - { - Dropdown::SetChecked(1, true); - } - - break; - - case WIDX_SYMBOL_TEXT: - WindowTextInputRawOpen( - w, WIDX_SYMBOL_TEXT, STR_CUSTOM_CURRENCY_SYMBOL_INPUT_TITLE, STR_CUSTOM_CURRENCY_SYMBOL_INPUT_DESC, {}, - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, CURRENCY_SYMBOL_MAX_SIZE); - break; - } -} - -static void CustomCurrencyWindowMouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) - { - case WIDX_RATE: - WindowTextInputOpen( - w, WIDX_RATE, STR_RATE_INPUT_TITLE, STR_RATE_INPUT_DESC, {}, STR_FORMAT_INTEGER, - static_cast(CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate), CURRENCY_RATE_MAX_NUM_DIGITS); - break; - } -} - -static void CustomCurrencyWindowDropdown([[maybe_unused]] rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) -{ - if (dropdownIndex == -1) - return; - - if (widgetIndex == WIDX_AFFIX_DROPDOWN_BUTTON) - { - if (dropdownIndex == 0) - { - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_ascii = CurrencyAffix::Prefix; - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode = CurrencyAffix::Prefix; - } - else if (dropdownIndex == 1) - { - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_ascii = CurrencyAffix::Suffix; - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode = CurrencyAffix::Suffix; - } - - gConfigGeneral.custom_currency_affix = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode; - config_save_default(); - - window_invalidate_all(); - } -} - -static void CustomCurrencyWindowTextInput([[maybe_unused]] struct rct_window* w, rct_widgetindex widgetIndex, char* text) -{ - if (text == nullptr) - return; - int32_t rate; - char* end; - switch (widgetIndex) - { - case WIDX_SYMBOL_TEXT: - safe_strcpy(CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, text, CURRENCY_SYMBOL_MAX_SIZE); - - safe_strcpy( - gConfigGeneral.custom_currency_symbol, CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, - CURRENCY_SYMBOL_MAX_SIZE); - - config_save_default(); - window_invalidate_all(); - break; - - case WIDX_RATE: - rate = strtol(text, &end, 10); - if (*end == '\0') - { - CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate = rate; - gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; - config_save_default(); - window_invalidate_all(); - } - break; - } -} - -static void CustomCurrencyWindowPaint(rct_window* w, rct_drawpixelinfo* dpi) -{ - auto ft = Formatter::Common(); - ft.Add(MONEY(10, 0)); - - WindowDrawWidgets(w, dpi); - - auto screenCoords = w->windowPos + ScreenCoordsXY{ 10, 30 }; - - DrawTextBasic(dpi, screenCoords, STR_RATE, {}, { w->colours[1] }); - - int32_t baseExchange = CurrencyDescriptors[EnumValue(CurrencyType::Pounds)].rate; - ft = Formatter(); - ft.Add(baseExchange); - DrawTextBasic(dpi, screenCoords + ScreenCoordsXY{ 200, 0 }, STR_CUSTOM_CURRENCY_EQUIVALENCY, ft, { w->colours[1] }); - - screenCoords.y += 20; - - DrawTextBasic(dpi, screenCoords, STR_CURRENCY_SYMBOL_TEXT, {}, { w->colours[1] }); - - screenCoords = w->windowPos - + ScreenCoordsXY{ window_custom_currency_widgets[WIDX_SYMBOL_TEXT].left + 1, - window_custom_currency_widgets[WIDX_SYMBOL_TEXT].top }; - - gfx_draw_string(dpi, screenCoords, CurrencyDescriptors[EnumValue(CurrencyType::Custom)].symbol_unicode, { w->colours[1] }); - - auto drawPos = w->windowPos - + ScreenCoordsXY{ window_custom_currency_widgets[WIDX_AFFIX_DROPDOWN].left + 1, - window_custom_currency_widgets[WIDX_AFFIX_DROPDOWN].top }; - rct_string_id stringId = (CurrencyDescriptors[EnumValue(CurrencyType::Custom)].affix_unicode == CurrencyAffix::Prefix) - ? STR_PREFIX - : STR_SUFFIX; - DrawTextBasic(dpi, drawPos, stringId, {}, { w->colours[1] }); + return WindowFocusOrCreate(WC_CUSTOM_CURRENCY_CONFIG, WW, WH, WF_CENTRE_SCREEN); } From 1a6fffb64a868b4c192bacc4476c991d8354124c Mon Sep 17 00:00:00 2001 From: Gal B Date: Sat, 4 Dec 2021 19:20:39 +0200 Subject: [PATCH 2/2] Replace strtol with Parse in CustomCurrency window --- src/openrct2-ui/windows/CustomCurrency.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/windows/CustomCurrency.cpp b/src/openrct2-ui/windows/CustomCurrency.cpp index 46e65876ab..7b0babf421 100644 --- a/src/openrct2-ui/windows/CustomCurrency.cpp +++ b/src/openrct2-ui/windows/CustomCurrency.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -154,8 +155,9 @@ public: { if (text.empty()) return; + int32_t rate; - char* end; + switch (widgetIndex) { case WIDX_SYMBOL_TEXT: @@ -172,9 +174,10 @@ public: break; case WIDX_RATE: - rate = strtol(std::string(text).c_str(), &end, 10); - if (*end == '\0') + const auto res = String::Parse(text); + if (res.has_value()) { + rate = res.value(); CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate = rate; gConfigGeneral.custom_currency_rate = CurrencyDescriptors[EnumValue(CurrencyType::Custom)].rate; config_save_default();