diff --git a/src/openrct2-ui/windows/SceneryScatter.cpp b/src/openrct2-ui/windows/SceneryScatter.cpp index 61a44cdd21..a3fdb13051 100644 --- a/src/openrct2-ui/windows/SceneryScatter.cpp +++ b/src/openrct2-ui/windows/SceneryScatter.cpp @@ -7,11 +7,11 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include #include #include #include #include +#include #include #include @@ -51,175 +51,156 @@ static rct_widget window_scenery_scatter_widgets[] = { }; // clang-format on -static void WindowSceneryScatterClose(rct_window* w); -static void WindowSceneryScatterMouseup(rct_window* w, rct_widgetindex widgetIndex); -static void WindowSceneryScatterMousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget); -static void WindowSceneryScatterInvalidate(rct_window* w); -static void WindowSceneryScatterPaint(rct_window* w, rct_drawpixelinfo* dpi); -static void WindowSceneryScatterTextinput(rct_window* w, rct_widgetindex widgetIndex, char* text); -static void WindowSceneryScatterInputsize(rct_window* w, rct_widgetindex widgetindex); - -// clang-format off -static rct_window_event_list window_clear_scenery_events([](auto& events) +class SceneryScatterWindow final : public rct_window { - events.close = &WindowSceneryScatterClose; - events.mouse_up = &WindowSceneryScatterMouseup; - events.mouse_down = &WindowSceneryScatterMousedown; - events.text_input = &WindowSceneryScatterTextinput; - events.invalidate = &WindowSceneryScatterInvalidate; - events.paint = &WindowSceneryScatterPaint; -}); -// clang-format on - -rct_window* WindowSceneryScatterOpen() -{ - rct_window* window; - - // Check if window is already open - window = window_find_by_class(WC_SCENERY_SCATTER); - if (window != nullptr) - return window; - - window = WindowCreateAutoPos(86, 100, &window_clear_scenery_events, WC_SCENERY_SCATTER, 0); - - window->widgets = window_scenery_scatter_widgets; - window->enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT) - | (1ULL << WIDX_PREVIEW) | (1ULL << WIDX_DENSITY_LOW) | (1ULL << WIDX_DENSITY_MEDIUM) | (1ULL << WIDX_DENSITY_HIGH); - window->hold_down_widgets = (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT); - WindowInitScrollWidgets(window); - window_push_others_below(window); - - gWindowSceneryScatterEnabled = true; - gWindowSceneryScatterSize = 16; - gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; - - return window; -} - -static void WindowSceneryScatterClose([[maybe_unused]] rct_window* w) -{ - gWindowSceneryScatterEnabled = false; -} - -static void WindowSceneryScatterMouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) +public: + void OnOpen() override { - case WIDX_CLOSE: - window_close(w); - break; + widgets = window_scenery_scatter_widgets; + enabled_widgets = (1ULL << WIDX_CLOSE) | (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT) | (1ULL << WIDX_PREVIEW) + | (1ULL << WIDX_DENSITY_LOW) | (1ULL << WIDX_DENSITY_MEDIUM) | (1ULL << WIDX_DENSITY_HIGH); + hold_down_widgets = (1ULL << WIDX_INCREMENT) | (1ULL << WIDX_DECREMENT); + WindowInitScrollWidgets(this); + window_push_others_below(this); - case WIDX_PREVIEW: - WindowSceneryScatterInputsize(w, widgetIndex); - break; - - case WIDX_DENSITY_LOW: - gWindowSceneryScatterDensity = ScatterToolDensity::LowDensity; - break; - - case WIDX_DENSITY_MEDIUM: - gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; - break; - - case WIDX_DENSITY_HIGH: - gWindowSceneryScatterDensity = ScatterToolDensity::HighDensity; - break; + gWindowSceneryScatterEnabled = true; + gWindowSceneryScatterSize = 16; + gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; } -} -static void WindowSceneryScatterMousedown(rct_window* w, rct_widgetindex widgetIndex, [[maybe_unused]] rct_widget* widget) -{ - switch (widgetIndex) + void OnClose() override { - case WIDX_DECREMENT: - // Decrement land tool size, if it stays within the limit - gWindowSceneryScatterSize = std::max(MINIMUM_TOOL_SIZE, gWindowSceneryScatterSize - 1); - w->Invalidate(); - break; - - case WIDX_INCREMENT: - // Increment land tool size, if it stays within the limit - gWindowSceneryScatterSize = std::min(MAXIMUM_TOOL_SIZE, gWindowSceneryScatterSize + 1); - w->Invalidate(); - break; + gWindowSceneryScatterEnabled = false; } -} -static void WindowSceneryScatterTextinput(rct_window* w, rct_widgetindex widgetIndex, char* text) -{ - int32_t size; - char* end; - - if (widgetIndex != WIDX_PREVIEW || text == nullptr) - return; - - size = strtol(text, &end, 10); - if (*end == '\0') + void InputSize(const rct_widgetindex widgetIndex) { + uint8_t maxLength = 0; + Formatter ft; + switch (widgetIndex) { case WIDX_PREVIEW: - size = std::max(MINIMUM_TOOL_SIZE, size); - size = std::min(MAXIMUM_TOOL_SIZE, size); - gWindowSceneryScatterSize = size; + ft.Add(MINIMUM_TOOL_SIZE); + ft.Add(MAXIMUM_TOOL_SIZE); + maxLength = 3; break; } - w->Invalidate(); + WindowTextInputOpen(this, widgetIndex, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, ft, STR_NONE, STR_NONE, maxLength); } -} -static void WindowSceneryScatterInputsize(rct_window* w, rct_widgetindex widgetindex) -{ - uint8_t maxlen = 0; - Formatter ft; - - switch (widgetindex) + void OnMouseUp(rct_widgetindex widgetIndex) override { - case WIDX_PREVIEW: - ft.Add(MINIMUM_TOOL_SIZE); - ft.Add(MAXIMUM_TOOL_SIZE); - maxlen = 3; - break; + switch (widgetIndex) + { + case WIDX_CLOSE: + window_close(this); + break; + + case WIDX_PREVIEW: + InputSize(widgetIndex); + break; + + case WIDX_DENSITY_LOW: + gWindowSceneryScatterDensity = ScatterToolDensity::LowDensity; + break; + + case WIDX_DENSITY_MEDIUM: + gWindowSceneryScatterDensity = ScatterToolDensity::MediumDensity; + break; + + case WIDX_DENSITY_HIGH: + gWindowSceneryScatterDensity = ScatterToolDensity::HighDensity; + break; + } } - WindowTextInputOpen(w, widgetindex, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, ft, STR_NONE, STR_NONE, maxlen); -} -static void WindowSceneryScatterInvalidate(rct_window* w) -{ - // Set the preview image button to be pressed down - w->pressed_widgets = (1ULL << WIDX_PREVIEW); - - // Set density buttons' pressed state. - switch (gWindowSceneryScatterDensity) + void OnMouseDown(const rct_widgetindex widgetIndex) override { - case ScatterToolDensity::LowDensity: - w->pressed_widgets |= (1ULL << WIDX_DENSITY_LOW); - break; + switch (widgetIndex) + { + case WIDX_DECREMENT: + // Decrement land tool size, if it stays within the limit + gWindowSceneryScatterSize = std::max(MINIMUM_TOOL_SIZE, gWindowSceneryScatterSize - 1); + Invalidate(); + break; - case ScatterToolDensity::MediumDensity: - w->pressed_widgets |= (1ULL << WIDX_DENSITY_MEDIUM); - break; - - case ScatterToolDensity::HighDensity: - w->pressed_widgets |= (1ULL << WIDX_DENSITY_HIGH); - break; + case WIDX_INCREMENT: + // Increment land tool size, if it stays within the limit + gWindowSceneryScatterSize = std::min(MAXIMUM_TOOL_SIZE, gWindowSceneryScatterSize + 1); + Invalidate(); + break; + } } - // Update the preview image (for tool sizes up to 7) - window_scenery_scatter_widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gWindowSceneryScatterSize); -} - -static void WindowSceneryScatterPaint(rct_window* w, rct_drawpixelinfo* dpi) -{ - WindowDrawWidgets(w, dpi); - - // Draw area as a number for tool sizes bigger than 7 - if (gWindowSceneryScatterSize > MAX_TOOL_SIZE_WITH_SPRITE) + void OnTextInput(const rct_widgetindex widgetIndex, const std::string_view text) override { - auto preview = window_scenery_scatter_widgets[WIDX_PREVIEW]; - auto screenCoords = ScreenCoordsXY{ w->windowPos.x + preview.midX(), w->windowPos.y + preview.midY() }; - auto ft = Formatter(); - ft.Add(gWindowSceneryScatterSize); - DrawTextBasic(dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE }); + if (widgetIndex != WIDX_PREVIEW || text.empty()) + return; + + const auto res = String::Parse(text); + + if (res.has_value()) + { + switch (widgetIndex) + { + case WIDX_PREVIEW: + gWindowSceneryScatterSize = std::clamp(res.value(), MINIMUM_TOOL_SIZE, MAXIMUM_TOOL_SIZE); + break; + } + Invalidate(); + } } + + void OnPrepareDraw() override + { + // Set the preview image button to be pressed down + pressed_widgets = (1ULL << WIDX_PREVIEW); + + // Set density buttons' pressed state. + switch (gWindowSceneryScatterDensity) + { + case ScatterToolDensity::LowDensity: + pressed_widgets |= (1ULL << WIDX_DENSITY_LOW); + break; + + case ScatterToolDensity::MediumDensity: + pressed_widgets |= (1ULL << WIDX_DENSITY_MEDIUM); + break; + + case ScatterToolDensity::HighDensity: + pressed_widgets |= (1ULL << WIDX_DENSITY_HIGH); + break; + } + + // Update the preview image (for tool sizes up to 7) + widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gWindowSceneryScatterSize); + } + + void OnDraw(rct_drawpixelinfo& dpi) override + { + WindowDrawWidgets(this, &dpi); + + // Draw area as a number for tool sizes bigger than 7 + if (gWindowSceneryScatterSize > MAX_TOOL_SIZE_WITH_SPRITE) + { + const auto& preview = widgets[WIDX_PREVIEW]; + const auto screenCoords = ScreenCoordsXY{ windowPos.x + preview.midX(), windowPos.y + preview.midY() }; + auto ft = Formatter(); + ft.Add(gWindowSceneryScatterSize); + DrawTextBasic(&dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, ft, { TextAlignment::CENTRE }); + } + } +}; + +rct_window* WindowSceneryScatterOpen() +{ + // Check if window is already open + auto* window = window_find_by_class(WC_SCENERY_SCATTER); + if (window == nullptr) + { + window = WindowCreate(WC_SCENERY_SCATTER, 86, 100); + } + + return window; }