/***************************************************************************** * Copyright (c) 2014-2020 OpenRCT2 developers * * For a complete list of all authors, please refer to contributors.md * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 * * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static constexpr const rct_string_id WINDOW_TITLE = STR_SIGN; static constexpr const int32_t WW = 113; static constexpr const int32_t WH = 96; // clang-format off enum WINDOW_SIGN_WIDGET_IDX { WIDX_BACKGROUND, WIDX_TITLE, WIDX_CLOSE, WIDX_VIEWPORT, WIDX_SIGN_TEXT, WIDX_SIGN_DEMOLISH, WIDX_MAIN_COLOUR, WIDX_TEXT_COLOUR }; // 0x9AEE00 static rct_widget window_sign_widgets[] = { WINDOW_SHIM(WINDOW_TITLE, WW, WH), MakeWidget({ 3, 17}, {85, 60}, WindowWidgetType::Viewport, WindowColour::Secondary, STR_VIEWPORT ), // Viewport MakeWidget({WW - 25, 19}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_RENAME, STR_CHANGE_SIGN_TEXT_TIP ), // change sign button MakeWidget({WW - 25, 67}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_DEMOLISH, STR_DEMOLISH_SIGN_TIP ), // demolish button MakeWidget({ 5, WH - 16}, {12, 12}, WindowWidgetType::ColourBtn, WindowColour::Secondary, 0xFFFFFFFF, STR_SELECT_MAIN_SIGN_COLOUR_TIP), // Main colour MakeWidget({ 17, WH - 16}, {12, 12}, WindowWidgetType::ColourBtn, WindowColour::Secondary, 0xFFFFFFFF, STR_SELECT_TEXT_COLOUR_TIP ), // Text colour { WIDGETS_END }, }; // clang-format on class SignWindow final : public Window { private: bool _isSmall = false; Banner* _banner = nullptr; void ShowTextInput() { if (_banner != nullptr) { auto bannerText = _banner->GetText(); window_text_input_raw_open(this, WIDX_SIGN_TEXT, STR_SIGN_TEXT_TITLE, STR_SIGN_TEXT_PROMPT, bannerText.c_str(), 32); } } public: void OnOpen() override { widgets = window_sign_widgets; enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_SIGN_TEXT) | (1 << WIDX_SIGN_DEMOLISH) | (1 << WIDX_MAIN_COLOUR) | (1 << WIDX_TEXT_COLOUR); WindowInitScrollWidgets(this); } /* * Initializes the window and sets it's number and if it's small * @return true if successfull */ bool Initialize(rct_windownumber windowNumber, const bool isSmall) { number = windowNumber; _isSmall = isSmall; _banner = GetBanner(number); if (_banner == nullptr) return false; auto signViewPosition = _banner->position.ToCoordsXY().ToTileCentre(); auto* tileElement = banner_get_tile_element(number); if (tileElement == nullptr) return false; int32_t viewZ = tileElement->GetBaseZ(); frame_no = viewZ; if (_isSmall) { list_information_type = tileElement->AsWall()->GetPrimaryColour(); var_492 = tileElement->AsWall()->GetSecondaryColour(); SceneryEntry = tileElement->AsWall()->GetEntryIndex(); } else { list_information_type = tileElement->AsLargeScenery()->GetPrimaryColour(); var_492 = tileElement->AsLargeScenery()->GetSecondaryColour(); SceneryEntry = tileElement->AsLargeScenery()->GetEntryIndex(); } // Create viewport rct_widget& viewportWidget = window_sign_widgets[WIDX_VIEWPORT]; viewport_create( this, windowPos + ScreenCoordsXY{ viewportWidget.left + 1, viewportWidget.top + 1 }, viewportWidget.width() - 1, viewportWidget.height() - 1, 0, { signViewPosition, viewZ }, 0, SPRITE_INDEX_NULL); viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; Invalidate(); return true; } void OnMouseUp(rct_widgetindex widgetIndex) override { switch (widgetIndex) { case WIDX_CLOSE: Close(); break; case WIDX_SIGN_DEMOLISH: { auto* tileElement = banner_get_tile_element(number); if (tileElement == nullptr) { Close(); } auto bannerCoords = _banner->position.ToCoordsXY(); if (_isSmall) { CoordsXYZD wallLocation = { bannerCoords, tileElement->GetBaseZ(), tileElement->GetDirection() }; auto wallRemoveAction = WallRemoveAction(wallLocation); GameActions::Execute(&wallRemoveAction); } else { auto sceneryRemoveAction = LargeSceneryRemoveAction( { bannerCoords, tileElement->GetBaseZ(), tileElement->GetDirection() }, tileElement->AsLargeScenery()->GetSequenceIndex()); GameActions::Execute(&sceneryRemoveAction); } break; } case WIDX_SIGN_TEXT: ShowTextInput(); break; } } void OnMouseDown(rct_widgetindex widgetIndex) override { rct_widget* widget = &widgets[widgetIndex]; switch (widgetIndex) { case WIDX_MAIN_COLOUR: WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(list_information_type)); break; case WIDX_TEXT_COLOUR: WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(var_492)); break; } } void OnDropdown(rct_widgetindex widgetIndex, int32_t dropdownIndex) override { switch (widgetIndex) { case WIDX_MAIN_COLOUR: { if (dropdownIndex == -1) return; list_information_type = dropdownIndex; auto signSetStyleAction = SignSetStyleAction(number, dropdownIndex, var_492, !_isSmall); GameActions::Execute(&signSetStyleAction); break; } case WIDX_TEXT_COLOUR: { if (dropdownIndex == -1) return; var_492 = dropdownIndex; auto signSetStyleAction = SignSetStyleAction(number, list_information_type, dropdownIndex, !_isSmall); GameActions::Execute(&signSetStyleAction); break; } default: return; } Invalidate(); } void OnTextInput(rct_widgetindex widgetIndex, std::string_view text) override { if (widgetIndex == WIDX_SIGN_TEXT && !text.empty()) { auto signSetNameAction = SignSetNameAction(number, std::string(text)); GameActions::Execute(&signSetNameAction); } } void OnPrepareDraw() override { rct_widget* main_colour_btn = &window_sign_widgets[WIDX_MAIN_COLOUR]; rct_widget* text_colour_btn = &window_sign_widgets[WIDX_TEXT_COLOUR]; if (_isSmall) { rct_scenery_entry* scenery_entry = get_wall_entry(SceneryEntry); main_colour_btn->type = WindowWidgetType::Empty; text_colour_btn->type = WindowWidgetType::Empty; if (scenery_entry->wall.flags & WALL_SCENERY_HAS_PRIMARY_COLOUR) { main_colour_btn->type = WindowWidgetType::ColourBtn; } if (scenery_entry->wall.flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) { text_colour_btn->type = WindowWidgetType::ColourBtn; } } else { rct_scenery_entry* scenery_entry = get_large_scenery_entry(SceneryEntry); main_colour_btn->type = WindowWidgetType::Empty; text_colour_btn->type = WindowWidgetType::Empty; if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR) { main_colour_btn->type = WindowWidgetType::ColourBtn; } if (scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR) { text_colour_btn->type = WindowWidgetType::ColourBtn; } } main_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(list_information_type) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; text_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(var_492) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; } void OnDraw(rct_drawpixelinfo& dpi) override { DrawWidgets(dpi); if (viewport != nullptr) { window_draw_viewport(&dpi, this); } } void OnViewportRotate() override { RemoveViewport(); auto banner = GetBanner(number); auto signViewPos = CoordsXYZ{ banner->position.ToCoordsXY().ToTileCentre(), frame_no }; // Create viewport rct_widget* viewportWidget = &window_sign_widgets[WIDX_VIEWPORT]; viewport_create( this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 }, viewportWidget->width() - 1, viewportWidget->height() - 1, 0, signViewPos, 0, SPRITE_INDEX_NULL); if (viewport != nullptr) viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; Invalidate(); } }; /** * * rct2: 0x006BA305 */ rct_window* window_sign_open(rct_windownumber number) { auto* w = static_cast(window_bring_to_front_by_number(WC_BANNER, number)); if (w != nullptr) return w; w = WindowCreate(WC_BANNER, WW, WH, 0); if (w == nullptr) return nullptr; bool result = w->Initialize(number, false); if (result != true) return nullptr; return w; } /** * * rct2: 0x6E5F52 */ rct_window* window_sign_small_open(rct_windownumber number) { auto* w = static_cast(window_bring_to_front_by_number(WC_BANNER, number)); if (w != nullptr) return w; w = WindowCreate(WC_BANNER, WW, WH, 0); if (w == nullptr) return nullptr; bool result = w->Initialize(number, true); if (result != true) return nullptr; return w; }