/***************************************************************************** * 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 StringId WINDOW_TITLE = STR_SIGN; static constexpr const int32_t WW = 113; static constexpr const int32_t WH = 96; // clang-format off enum WindowSignWidgetIdx { 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; ObjectEntryIndex _sceneryEntry = OBJECT_ENTRY_INDEX_NULL; colour_t _mainColour = {}; colour_t _textColour = {}; BannerIndex GetBannerIndex() const { return BannerIndex::FromUnderlying(number); } void ShowTextInput() { auto* banner = GetBanner(GetBannerIndex()); if (banner != nullptr) { auto bannerText = banner->GetText(); WindowTextInputRawOpen(this, WIDX_SIGN_TEXT, STR_SIGN_TEXT_TITLE, STR_SIGN_TEXT_PROMPT, {}, bannerText.c_str(), 32); } } public: void OnOpen() override { widgets = window_sign_widgets; 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; auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { return false; } auto signViewPosition = banner->position.ToCoordsXY().ToTileCentre(); auto* tileElement = banner_get_tile_element(GetBannerIndex()); if (tileElement == nullptr) return false; int32_t viewZ = tileElement->GetBaseZ(); frame_no = viewZ; if (_isSmall) { auto* wallElement = tileElement->AsWall(); if (wallElement == nullptr) { return false; } _mainColour = wallElement->GetPrimaryColour(); _textColour = wallElement->GetSecondaryColour(); _sceneryEntry = wallElement->GetEntryIndex(); } else { auto* sceneryElement = tileElement->AsLargeScenery(); if (sceneryElement == nullptr) { return false; } _mainColour = sceneryElement->GetPrimaryColour(); _textColour = sceneryElement->GetSecondaryColour(); _sceneryEntry = sceneryElement->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, Focus(CoordsXYZ{ signViewPosition, viewZ })); viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; Invalidate(); return true; } void OnMouseUp(rct_widgetindex widgetIndex) override { auto* banner = GetBanner(GetBannerIndex()); if (banner == nullptr) { Close(); return; } switch (widgetIndex) { case WIDX_CLOSE: Close(); break; case WIDX_SIGN_DEMOLISH: { auto* tileElement = banner_get_tile_element(GetBannerIndex()); if (tileElement == nullptr) { Close(); return; } 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(_mainColour)); break; case WIDX_TEXT_COLOUR: WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(_textColour)); break; } } void OnDropdown(rct_widgetindex widgetIndex, int32_t dropdownIndex) override { switch (widgetIndex) { case WIDX_MAIN_COLOUR: { if (dropdownIndex == -1) return; _mainColour = dropdownIndex; auto signSetStyleAction = SignSetStyleAction(GetBannerIndex(), dropdownIndex, _textColour, !_isSmall); GameActions::Execute(&signSetStyleAction); break; } case WIDX_TEXT_COLOUR: { if (dropdownIndex == -1) return; _textColour = dropdownIndex; auto signSetStyleAction = SignSetStyleAction(GetBannerIndex(), _mainColour, 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(GetBannerIndex(), 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) { auto* wallEntry = get_wall_entry(_sceneryEntry); main_colour_btn->type = WindowWidgetType::Empty; text_colour_btn->type = WindowWidgetType::Empty; if (wallEntry->flags & WALL_SCENERY_HAS_PRIMARY_COLOUR) { main_colour_btn->type = WindowWidgetType::ColourBtn; } if (wallEntry->flags & WALL_SCENERY_HAS_SECONDARY_COLOUR) { text_colour_btn->type = WindowWidgetType::ColourBtn; } } else { auto* sceneryEntry = get_large_scenery_entry(_sceneryEntry); main_colour_btn->type = WindowWidgetType::Empty; text_colour_btn->type = WindowWidgetType::Empty; if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR) { main_colour_btn->type = WindowWidgetType::ColourBtn; } if (sceneryEntry->flags & LARGE_SCENERY_FLAG_HAS_SECONDARY_COLOUR) { text_colour_btn->type = WindowWidgetType::ColourBtn; } } main_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(_mainColour) | IMAGE_TYPE_TRANSPARENT | SPR_PALETTE_BTN; text_colour_btn->image = SPRITE_ID_PALETTE_COLOUR_1(_textColour) | 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(GetBannerIndex()); if (banner == nullptr) { return; } 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, Focus(CoordsXYZ{ signViewPos })); if (viewport != nullptr) viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0; Invalidate(); } }; /** * * rct2: 0x006BA305 */ rct_window* WindowSignOpen(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* WindowSignSmallOpen(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; }