From 96524e2b4a138e56bdce9f7479ea1342f592ef21 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Mon, 15 Mar 2021 23:08:00 +0100 Subject: [PATCH] Convert Land window to class --- src/openrct2-ui/interface/LandTool.cpp | 4 +- src/openrct2-ui/interface/LandTool.h | 4 +- src/openrct2-ui/windows/Land.cpp | 592 +++++++++++-------------- 3 files changed, 272 insertions(+), 328 deletions(-) diff --git a/src/openrct2-ui/interface/LandTool.cpp b/src/openrct2-ui/interface/LandTool.cpp index 834d2d3383..4019c4486d 100644 --- a/src/openrct2-ui/interface/LandTool.cpp +++ b/src/openrct2-ui/interface/LandTool.cpp @@ -56,7 +56,7 @@ uint32_t LandTool::SizeToSpriteIndex(uint16_t size) } } -void LandTool::ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, uint8_t currentSurfaceType) +void LandTool::ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, ObjectEntryIndex currentSurfaceType) { auto& objManager = GetContext()->GetObjectManager(); @@ -90,7 +90,7 @@ void LandTool::ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, uint8 gDropdownDefaultIndex = defaultIndex; } -void LandTool::ShowEdgeStyleDropdown(rct_window* w, rct_widget* widget, uint8_t currentEdgeType) +void LandTool::ShowEdgeStyleDropdown(rct_window* w, rct_widget* widget, ObjectEntryIndex currentEdgeType) { auto& objManager = GetContext()->GetObjectManager(); diff --git a/src/openrct2-ui/interface/LandTool.h b/src/openrct2-ui/interface/LandTool.h index 1a4295aa95..c851ef7838 100644 --- a/src/openrct2-ui/interface/LandTool.h +++ b/src/openrct2-ui/interface/LandTool.h @@ -29,6 +29,6 @@ extern money32 gWaterToolLowerCost; namespace LandTool { uint32_t SizeToSpriteIndex(uint16_t size); - void ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, uint8_t currentSurfaceType); - void ShowEdgeStyleDropdown(rct_window* w, rct_widget* widget, uint8_t currentEdgeType); + void ShowSurfaceStyleDropdown(rct_window* w, rct_widget* widget, ObjectEntryIndex currentSurfaceType); + void ShowEdgeStyleDropdown(rct_window* w, rct_widget* widget, ObjectEntryIndex currentEdgeType); } // namespace LandTool diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index 6aa745e6f4..d36ed53ca6 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -7,19 +7,16 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include #include #include #include #include #include #include -#include #include #include #include #include -#include using namespace OpenRCT2; @@ -52,330 +49,277 @@ static rct_widget window_land_widgets[] = { MakeWidget ({49, 106}, {47, 36}, WindowWidgetType::FlatBtn, WindowColour::Secondary, 0xFFFFFFFF, STR_CHANGE_VERTICAL_LAND_TIP), // wall texture { WIDGETS_END }, }; - -static void window_land_close(rct_window *w); -static void window_land_mouseup(rct_window *w, rct_widgetindex widgetIndex); -static void window_land_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget* widget); -static void window_land_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex); -static void window_land_update(rct_window *w); -static void window_land_invalidate(rct_window *w); -static void window_land_paint(rct_window *w, rct_drawpixelinfo *dpi); -static void window_land_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text); -static void window_land_inputsize(rct_window *w); - -static rct_window_event_list window_land_events([](auto& events) -{ - events.close = &window_land_close; - events.mouse_up = &window_land_mouseup; - events.mouse_down = &window_land_mousedown; - events.dropdown = &window_land_dropdown; - events.update = &window_land_update; - events.text_input = &window_land_textinput; - events.invalidate = &window_land_invalidate; - events.paint = &window_land_paint; -}); // clang-format on -static int32_t _selectedFloorTexture; -static int32_t _selectedWallTexture; +class LandWindow final : public Window +{ +private: + ObjectEntryIndex _selectedFloorTexture = 0; + ObjectEntryIndex _selectedWallTexture = 0; + + void InputSize() + { + TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE; + TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE; + window_text_input_open(this, WIDX_PREVIEW, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, STR_NONE, STR_NONE, 3); + } + +public: + void OnOpen() override + { + widgets = window_land_widgets; + enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_DECREMENT) | (1 << WIDX_INCREMENT) | (1 << WIDX_FLOOR) + | (1 << WIDX_WALL) | (1 << WIDX_MOUNTAINMODE) | (1 << WIDX_PAINTMODE) | (1 << WIDX_PREVIEW); + hold_down_widgets = (1 << WIDX_DECREMENT) | (1 << WIDX_INCREMENT); + WindowInitScrollWidgets(this); + window_push_others_below(this); + + gLandToolSize = 1; + gLandToolTerrainSurface = OBJECT_ENTRY_INDEX_NULL; + gLandToolTerrainEdge = OBJECT_ENTRY_INDEX_NULL; + gLandMountainMode = false; + gLandPaintMode = false; + _selectedFloorTexture = 0; + _selectedWallTexture = 0; + gLandToolRaiseCost = MONEY32_UNDEFINED; + gLandToolLowerCost = MONEY32_UNDEFINED; + } + + void OnClose() override + { + // If the tool wasn't changed, turn tool off + if (land_tool_is_active()) + tool_cancel(); + } + + void OnMouseUp(rct_widgetindex widgetIndex) override + { + switch (widgetIndex) + { + case WIDX_CLOSE: + Close(); + break; + case WIDX_MOUNTAINMODE: + gLandMountainMode ^= 1; + gLandPaintMode = 0; + Invalidate(); + break; + case WIDX_PAINTMODE: + gLandMountainMode = 0; + gLandPaintMode ^= 1; + Invalidate(); + break; + case WIDX_PREVIEW: + InputSize(); + break; + } + } + + void OnMouseDown(rct_widgetindex widgetIndex) override + { + rct_widget* widget = &widgets[widgetIndex]; + switch (widgetIndex) + { + case WIDX_FLOOR: + LandTool::ShowSurfaceStyleDropdown(this, widget, _selectedFloorTexture); + break; + case WIDX_WALL: + LandTool::ShowEdgeStyleDropdown(this, widget, _selectedWallTexture); + break; + case WIDX_PREVIEW: + InputSize(); + break; + case WIDX_DECREMENT: + // Decrement land tool size + gLandToolSize = std::max(MINIMUM_TOOL_SIZE, gLandToolSize - 1); + + // Invalidate the window + Invalidate(); + break; + case WIDX_INCREMENT: + // Increment land tool size + gLandToolSize = std::min(MAXIMUM_TOOL_SIZE, gLandToolSize + 1); + + // Invalidate the window + Invalidate(); + break; + } + } + + void OnDropdown(rct_widgetindex widgetIndex, int32_t dropdownIndex) override + { + int32_t type; + + switch (widgetIndex) + { + case WIDX_FLOOR: + if (dropdownIndex == -1) + dropdownIndex = gDropdownHighlightedIndex; + + type = (dropdownIndex == -1) ? _selectedFloorTexture : dropdownIndex; + + if (gLandToolTerrainSurface == type) + { + gLandToolTerrainSurface = OBJECT_ENTRY_INDEX_NULL; + } + else + { + gLandToolTerrainSurface = type; + _selectedFloorTexture = type; + } + Invalidate(); + break; + case WIDX_WALL: + if (dropdownIndex == -1) + dropdownIndex = gDropdownHighlightedIndex; + + type = (dropdownIndex == -1) ? _selectedWallTexture : dropdownIndex; + + if (gLandToolTerrainEdge == type) + { + gLandToolTerrainEdge = OBJECT_ENTRY_INDEX_NULL; + } + else + { + gLandToolTerrainEdge = type; + _selectedWallTexture = type; + } + Invalidate(); + break; + } + } + + void OnTextInput(rct_widgetindex widgetIndex, std::string_view text) override + { + if (widgetIndex != WIDX_PREVIEW) + return; + + char* end; + int32_t size = strtol(std::string(text).c_str(), &end, 10); + if (*end == '\0') + { + size = std::max(MINIMUM_TOOL_SIZE, size); + size = std::min(MAXIMUM_TOOL_SIZE, size); + gLandToolSize = size; + + Invalidate(); + } + } + + void OnUpdate() override + { + if (!land_tool_is_active()) + Close(); + } + + void OnPrepareDraw() override + { + auto surfaceImage = static_cast(SPR_NONE); + auto edgeImage = static_cast(SPR_NONE); + + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(ObjectType::TerrainSurface, _selectedFloorTexture)); + if (surfaceObj != nullptr) + { + surfaceImage = surfaceObj->IconImageId; + if (surfaceObj->Colour != 255) + { + surfaceImage |= SPRITE_ID_PALETTE_COLOUR_1(surfaceObj->Colour); + } + } + const auto edgeObj = static_cast( + objManager.GetLoadedObject(ObjectType::TerrainEdge, _selectedWallTexture)); + if (edgeObj != nullptr) + { + edgeImage = edgeObj->IconImageId; + } + + pressed_widgets = 0; + SetWidgetPressed(WIDX_PREVIEW, true); + if (gLandToolTerrainSurface != OBJECT_ENTRY_INDEX_NULL) + SetWidgetPressed(WIDX_FLOOR, true); + if (gLandToolTerrainEdge != OBJECT_ENTRY_INDEX_NULL) + SetWidgetPressed(WIDX_WALL, true); + if (gLandMountainMode) + SetWidgetPressed(WIDX_MOUNTAINMODE, true); + if (gLandPaintMode) + SetWidgetPressed(WIDX_PAINTMODE, true); + + widgets[WIDX_FLOOR].image = surfaceImage; + widgets[WIDX_WALL].image = edgeImage; + // Update the preview image (for tool sizes up to 7) + widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gLandToolSize); + } + + void OnDraw(rct_drawpixelinfo& dpi) override + { + ScreenCoordsXY screenCoords; + int32_t numTiles; + money32 price; + rct_widget* previewWidget = &widgets[WIDX_PREVIEW]; + + DrawWidgets(dpi); + + // Draw number for tool sizes bigger than 7 + if (gLandToolSize > MAX_TOOL_SIZE_WITH_SPRITE) + { + screenCoords = { windowPos.x + previewWidget->midX(), windowPos.y + previewWidget->midY() }; + DrawTextBasic( + &dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, &gLandToolSize, + { TextAlignment::CENTRE }); + } + else if (gLandMountainMode) + { + screenCoords = { windowPos.x + previewWidget->left, windowPos.y + previewWidget->top }; + int32_t sprite = gLandToolSize % 2 == 0 ? SPR_G2_MOUNTAIN_TOOL_EVEN : SPR_G2_MOUNTAIN_TOOL_ODD; + gfx_draw_sprite(&dpi, sprite, screenCoords, 0); + WidgetDraw(&dpi, this, WIDX_DECREMENT); + WidgetDraw(&dpi, this, WIDX_INCREMENT); + } + + screenCoords = { windowPos.x + previewWidget->midX(), windowPos.y + previewWidget->bottom + 5 }; + + if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) + { + // Draw raise cost amount + if (gLandToolRaiseCost != MONEY32_UNDEFINED && gLandToolRaiseCost != 0) + DrawTextBasic(&dpi, screenCoords, STR_RAISE_COST_AMOUNT, &gLandToolRaiseCost, { TextAlignment::CENTRE }); + screenCoords.y += 10; + + // Draw lower cost amount + if (gLandToolLowerCost != MONEY32_UNDEFINED && gLandToolLowerCost != 0) + DrawTextBasic(&dpi, screenCoords, STR_LOWER_COST_AMOUNT, &gLandToolLowerCost, { TextAlignment::CENTRE }); + screenCoords.y += 50; + + // Draw paint price + numTiles = gLandToolSize * gLandToolSize; + price = 0; + if (gLandToolTerrainSurface != OBJECT_ENTRY_INDEX_NULL) + { + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(ObjectType::TerrainSurface, gLandToolTerrainSurface)); + if (surfaceObj != nullptr) + { + price += numTiles * surfaceObj->Price; + } + } + + if (gLandToolTerrainEdge != OBJECT_ENTRY_INDEX_NULL) + price += numTiles * 100; + + if (price != 0) + { + auto ft = Formatter(); + ft.Add(price); + DrawTextBasic(&dpi, screenCoords, STR_COST_AMOUNT, ft.Data(), { TextAlignment::CENTRE }); + } + } + } +}; -/** - * - * rct2: 0x00663E7D - */ rct_window* window_land_open() { - rct_window* window; - - // Check if window is already open - window = window_find_by_class(WC_LAND); - if (window != nullptr) - return window; - - window = WindowCreate(ScreenCoordsXY(context_get_width() - 98, 29), 98, 160, &window_land_events, WC_LAND, 0); - window->widgets = window_land_widgets; - window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_DECREMENT) | (1 << WIDX_INCREMENT) | (1 << WIDX_FLOOR) - | (1 << WIDX_WALL) | (1 << WIDX_MOUNTAINMODE) | (1 << WIDX_PAINTMODE) | (1 << WIDX_PREVIEW); - window->hold_down_widgets = (1 << WIDX_DECREMENT) | (1 << WIDX_INCREMENT); - WindowInitScrollWidgets(window); - window_push_others_below(window); - - gLandToolSize = 1; - gLandToolTerrainSurface = OBJECT_ENTRY_INDEX_NULL; - gLandToolTerrainEdge = OBJECT_ENTRY_INDEX_NULL; - gLandMountainMode = false; - gLandPaintMode = false; - _selectedFloorTexture = TERRAIN_GRASS; - _selectedWallTexture = TERRAIN_EDGE_ROCK; - gLandToolRaiseCost = MONEY32_UNDEFINED; - gLandToolLowerCost = MONEY32_UNDEFINED; - - return window; -} - -/** - * - * rct2: 0x006640A5 - */ -static void window_land_close(rct_window* w) -{ - // If the tool wasn't changed, turn tool off - if (land_tool_is_active()) - tool_cancel(); -} - -/** - * - * rct2: 0x00664064 - */ -static void window_land_mouseup(rct_window* w, rct_widgetindex widgetIndex) -{ - switch (widgetIndex) - { - case WIDX_CLOSE: - window_close(w); - break; - case WIDX_MOUNTAINMODE: - gLandMountainMode ^= 1; - gLandPaintMode = 0; - w->Invalidate(); - break; - case WIDX_PAINTMODE: - gLandMountainMode = 0; - gLandPaintMode ^= 1; - w->Invalidate(); - break; - case WIDX_PREVIEW: - window_land_inputsize(w); - break; - } -} - -/** - * - * rct2: 0x0066407B - */ -static void window_land_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget) -{ - switch (widgetIndex) - { - case WIDX_FLOOR: - LandTool::ShowSurfaceStyleDropdown(w, widget, _selectedFloorTexture); - break; - case WIDX_WALL: - LandTool::ShowEdgeStyleDropdown(w, widget, _selectedWallTexture); - break; - case WIDX_PREVIEW: - window_land_inputsize(w); - break; - case WIDX_DECREMENT: - // Decrement land tool size - gLandToolSize = std::max(MINIMUM_TOOL_SIZE, gLandToolSize - 1); - - // Invalidate the window - w->Invalidate(); - break; - case WIDX_INCREMENT: - // Increment land tool size - gLandToolSize = std::min(MAXIMUM_TOOL_SIZE, gLandToolSize + 1); - - // Invalidate the window - w->Invalidate(); - break; - } -} - -/** - * - * rct2: 0x00664090 - */ -static void window_land_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex) -{ - int32_t type; - - switch (widgetIndex) - { - case WIDX_FLOOR: - if (dropdownIndex == -1) - dropdownIndex = gDropdownHighlightedIndex; - - type = (dropdownIndex == -1) ? _selectedFloorTexture : dropdownIndex; - - if (gLandToolTerrainSurface == type) - { - gLandToolTerrainSurface = OBJECT_ENTRY_INDEX_NULL; - } - else - { - gLandToolTerrainSurface = type; - _selectedFloorTexture = type; - } - w->Invalidate(); - break; - case WIDX_WALL: - if (dropdownIndex == -1) - dropdownIndex = gDropdownHighlightedIndex; - - type = (dropdownIndex == -1) ? _selectedWallTexture : dropdownIndex; - - if (gLandToolTerrainEdge == type) - { - gLandToolTerrainEdge = OBJECT_ENTRY_INDEX_NULL; - } - else - { - gLandToolTerrainEdge = type; - _selectedWallTexture = type; - } - w->Invalidate(); - break; - } -} - -static void window_land_textinput(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') - { - size = std::max(MINIMUM_TOOL_SIZE, size); - size = std::min(MAXIMUM_TOOL_SIZE, size); - gLandToolSize = size; - - w->Invalidate(); - } -} - -static void window_land_inputsize(rct_window* w) -{ - TextInputDescriptionArgs[0] = MINIMUM_TOOL_SIZE; - TextInputDescriptionArgs[1] = MAXIMUM_TOOL_SIZE; - window_text_input_open(w, WIDX_PREVIEW, STR_SELECTION_SIZE, STR_ENTER_SELECTION_SIZE, STR_NONE, STR_NONE, 3); -} - -/** - * - * rct2: 0x00664272 - */ -static void window_land_update(rct_window* w) -{ - if (!land_tool_is_active()) - window_close(w); -} - -/** - * - * rct2: 0x00663F20 - */ -static void window_land_invalidate(rct_window* w) -{ - auto surfaceImage = static_cast(SPR_NONE); - auto edgeImage = static_cast(SPR_NONE); - - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( - objManager.GetLoadedObject(ObjectType::TerrainSurface, _selectedFloorTexture)); - if (surfaceObj != nullptr) - { - surfaceImage = surfaceObj->IconImageId; - if (surfaceObj->Colour != 255) - { - surfaceImage |= SPRITE_ID_PALETTE_COLOUR_1(surfaceObj->Colour); - } - } - const auto edgeObj = static_cast( - objManager.GetLoadedObject(ObjectType::TerrainEdge, _selectedWallTexture)); - if (edgeObj != nullptr) - { - edgeImage = edgeObj->IconImageId; - } - - w->pressed_widgets = (1 << WIDX_PREVIEW); - if (gLandToolTerrainSurface != OBJECT_ENTRY_INDEX_NULL) - w->pressed_widgets |= (1 << WIDX_FLOOR); - if (gLandToolTerrainEdge != OBJECT_ENTRY_INDEX_NULL) - w->pressed_widgets |= (1 << WIDX_WALL); - if (gLandMountainMode) - w->pressed_widgets |= (1 << WIDX_MOUNTAINMODE); - if (gLandPaintMode) - w->pressed_widgets |= (1 << WIDX_PAINTMODE); - - window_land_widgets[WIDX_FLOOR].image = surfaceImage; - window_land_widgets[WIDX_WALL].image = edgeImage; - // Update the preview image (for tool sizes up to 7) - window_land_widgets[WIDX_PREVIEW].image = LandTool::SizeToSpriteIndex(gLandToolSize); -} - -/** - * - * rct2: 0x00663F7C - */ -static void window_land_paint(rct_window* w, rct_drawpixelinfo* dpi) -{ - ScreenCoordsXY screenCoords; - int32_t numTiles; - money32 price; - rct_widget* previewWidget = &window_land_widgets[WIDX_PREVIEW]; - - WindowDrawWidgets(w, dpi); - - // Draw number for tool sizes bigger than 7 - if (gLandToolSize > MAX_TOOL_SIZE_WITH_SPRITE) - { - screenCoords = { w->windowPos.x + previewWidget->midX(), w->windowPos.y + previewWidget->midY() }; - DrawTextBasic( - dpi, screenCoords - ScreenCoordsXY{ 0, 2 }, STR_LAND_TOOL_SIZE_VALUE, &gLandToolSize, { TextAlignment::CENTRE }); - } - else if (gLandMountainMode) - { - screenCoords = { w->windowPos.x + previewWidget->left, w->windowPos.y + previewWidget->top }; - int32_t sprite = gLandToolSize % 2 == 0 ? SPR_G2_MOUNTAIN_TOOL_EVEN : SPR_G2_MOUNTAIN_TOOL_ODD; - gfx_draw_sprite(dpi, sprite, screenCoords, 0); - WidgetDraw(dpi, w, WIDX_DECREMENT); - WidgetDraw(dpi, w, WIDX_INCREMENT); - } - - screenCoords = { w->windowPos.x + previewWidget->midX(), w->windowPos.y + previewWidget->bottom + 5 }; - - if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) - { - // Draw raise cost amount - if (gLandToolRaiseCost != MONEY32_UNDEFINED && gLandToolRaiseCost != 0) - DrawTextBasic(dpi, screenCoords, STR_RAISE_COST_AMOUNT, &gLandToolRaiseCost, { TextAlignment::CENTRE }); - screenCoords.y += 10; - - // Draw lower cost amount - if (gLandToolLowerCost != MONEY32_UNDEFINED && gLandToolLowerCost != 0) - DrawTextBasic(dpi, screenCoords, STR_LOWER_COST_AMOUNT, &gLandToolLowerCost, { TextAlignment::CENTRE }); - screenCoords.y += 50; - - // Draw paint price - numTiles = gLandToolSize * gLandToolSize; - price = 0; - if (gLandToolTerrainSurface != OBJECT_ENTRY_INDEX_NULL) - { - auto& objManager = GetContext()->GetObjectManager(); - const auto surfaceObj = static_cast( - objManager.GetLoadedObject(ObjectType::TerrainSurface, gLandToolTerrainSurface)); - if (surfaceObj != nullptr) - { - price += numTiles * surfaceObj->Price; - } - } - - if (gLandToolTerrainEdge != OBJECT_ENTRY_INDEX_NULL) - price += numTiles * 100; - - if (price != 0) - { - auto ft = Formatter(); - ft.Add(price); - DrawTextBasic(dpi, screenCoords, STR_COST_AMOUNT, ft.Data(), { TextAlignment::CENTRE }); - } - } + return WindowFocusOrCreate(WC_LAND, ScreenCoordsXY(context_get_width() - WW, 29), WW, WH, 0); }