OpenRCT2/src/openrct2-ui/windows/Banner.cpp

315 lines
10 KiB
C++
Raw Normal View History

2014-05-09 10:04:40 +02:00
/*****************************************************************************
* Copyright (c) 2014-2022 OpenRCT2 developers
2014-05-09 10:04:40 +02:00
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
2014-05-09 10:04:40 +02:00
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
2014-05-09 10:04:40 +02:00
*****************************************************************************/
2018-06-22 23:21:44 +02:00
#include <openrct2-ui/interface/Dropdown.h>
2018-01-03 00:13:37 +01:00
#include <openrct2-ui/interface/Viewport.h>
#include <openrct2-ui/interface/Widget.h>
2017-09-06 15:09:18 +02:00
#include <openrct2-ui/windows/Window.h>
2017-11-30 18:17:06 +01:00
#include <openrct2/Game.h>
Split actions hpp files into separate h and cpp files (#13548) * Split up SmallSceneryPlace/Remove Added undo function for Remove Scenery * Refactor: Balloon and Banner actions hpp=>h/cpp * Refactor: rename all action *.hpp files to *.cpp This is preparation for separation in later commits. Note that without the complete set of commits in this branch, the code will not build. * Refactor Clear, Climate, Custom, and Footpath actions hpp=>h/cpp * VSCode: add src subdirectories to includePath * Refactor Guest actions hpp=>h/cpp * Refactor Land actions hpp=>h/cpp * Refactor LargeScenery actions hpp=>h/cpp * Refactor Load, Maze, Network actions hpp=>h/cpp * Refactor Park actions hpp=>h/cpp * Refactor/style: move private function declarations in actions *.h Previous action .h files included private function declarations with private member variables, before public function declarations. This commit re-orders the header files to the following order: - public member variables - private member variables - public functions - private functions * Refactor Pause action hpp=>h/cpp * Refactor Peep, Place, Player actions hpp=>h/cpp * Refactor Ride actions hpp=>h/cpp * Refactor Scenario, Set*, Sign* actions hpp=>h/cpp * Refactor SmallScenerySetColourAction hpp=>h/cpp * Refactor Staff actions hpp=>h/cpp * Refactor Surface, Tile, Track* actions hpp=>h/cpp * Refactor Wall and Water actions hpp=>h/cpp * Fix various includes and other compile errors Update includes for tests. Move static function declarations to .h files Add explicit includes to various files that were previously implicit (the required header was a nested include in an action hpp file, and the action .h file does not include that header) Move RideSetStatus string enum to the cpp file to avoid unused imports * Xcode: modify project file for actions refactor * Cleanup whitespace and end-of-file newlines Co-authored-by: duncanspumpkin <duncans_pumpkin@hotmail.co.uk>
2020-12-10 07:39:10 +01:00
#include <openrct2/actions/BannerRemoveAction.h>
#include <openrct2/actions/BannerSetNameAction.h>
#include <openrct2/actions/BannerSetStyleAction.h>
2018-06-22 23:21:44 +02:00
#include <openrct2/config/Config.h>
2018-01-06 18:32:25 +01:00
#include <openrct2/localisation/Localisation.h>
2017-09-06 15:09:18 +02:00
#include <openrct2/sprites.h>
2018-03-19 23:28:40 +01:00
#include <openrct2/world/Banner.h>
#include <openrct2/world/Scenery.h>
2014-10-21 18:59:47 +02:00
2020-05-09 17:05:01 +02:00
static constexpr const int32_t WW = 113;
static constexpr const int32_t WH = 96;
2022-07-31 14:22:58 +02:00
static constexpr const StringId WINDOW_TITLE = STR_BANNER_WINDOW_TITLE;
2014-05-09 10:04:40 +02:00
// clang-format off
enum WindowBannerWidgetIdx {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_VIEWPORT,
WIDX_BANNER_TEXT,
WIDX_BANNER_NO_ENTRY,
WIDX_BANNER_DEMOLISH,
WIDX_MAIN_COLOUR,
WIDX_TEXT_COLOUR_DROPDOWN,
WIDX_TEXT_COLOUR_DROPDOWN_BUTTON
2014-05-09 10:04:40 +02:00
};
2022-07-31 14:22:58 +02:00
static constexpr const StringId BannerColouredTextFormats[] = {
STR_TEXT_COLOR_BLACK,
STR_TEXT_COLOR_GREY,
STR_TEXT_COLOR_WHITE,
STR_TEXT_COLOR_RED,
STR_TEXT_COLOR_GREEN,
STR_TEXT_COLOR_YELLOW,
STR_TEXT_COLOR_TOPAZ,
STR_TEXT_COLOR_CELADON,
STR_TEXT_COLOR_BABYBLUE,
STR_TEXT_COLOR_PALELAVENDER,
STR_TEXT_COLOR_PALEGOLD,
STR_TEXT_COLOR_LIGHTPINK,
STR_TEXT_COLOR_PEARLAQUA,
STR_TEXT_COLOR_PALESILVER,
};
static rct_widget window_banner_widgets[] = {
2020-05-09 16:44:21 +02:00
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
MakeWidget({ 3, 17}, {85, 60}, WindowWidgetType::Viewport, WindowColour::Secondary, 0x0FFFFFFFE ), // tab content panel
MakeWidget({WW - 25, 19}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_RENAME, STR_CHANGE_BANNER_TEXT_TIP ), // change banner button
MakeWidget({WW - 25, 43}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_NO_ENTRY, STR_SET_AS_NO_ENTRY_BANNER_TIP ), // no entry button
MakeWidget({WW - 25, 67}, {24, 24}, WindowWidgetType::FlatBtn, WindowColour::Secondary, SPR_DEMOLISH, STR_DEMOLISH_BANNER_TIP ), // demolish button
MakeWidget({ 5, WH - 16}, {12, 12}, WindowWidgetType::ColourBtn, WindowColour::Secondary, 0xFFFFFFFF, STR_SELECT_MAIN_SIGN_COLOUR_TIP), // high money
MakeWidget({ 43, WH - 16}, {39, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary ), // high money
MakeWidget({ 70, WH - 15}, {11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH, STR_SELECT_TEXT_COLOUR_TIP ), // high money
2021-09-26 11:11:42 +02:00
WIDGETS_END,
2014-05-09 10:04:40 +02:00
};
// clang-format on
2014-05-09 10:04:40 +02:00
class BannerWindow final : public Window
2014-05-09 10:04:40 +02:00
{
private:
2021-03-22 19:56:24 +01:00
CoordsXYZ _bannerViewPos;
void CreateViewport()
{
rct_widget* viewportWidget = &window_banner_widgets[WIDX_VIEWPORT];
viewport_create(
this, windowPos + ScreenCoordsXY{ viewportWidget->left + 1, viewportWidget->top + 1 },
(viewportWidget->width()) - 1, (viewportWidget->height()) - 1, Focus(_bannerViewPos));
if (viewport != nullptr)
viewport->flags = gConfigGeneral.always_show_gridlines ? VIEWPORT_FLAG_GRIDLINES : 0;
Invalidate();
}
2021-11-24 18:58:07 +01:00
BannerIndex GetBannerIndex() const
{
return BannerIndex::FromUnderlying(number);
}
BannerElement* GetBannerElement()
2018-06-22 23:21:44 +02:00
{
2021-11-24 18:58:07 +01:00
auto* banner = GetBanner(GetBannerIndex());
if (banner == nullptr)
{
return nullptr;
}
TileElement* tileElement = MapGetFirstElementAt(banner->position);
if (tileElement == nullptr)
2018-06-22 23:21:44 +02:00
{
return nullptr;
}
do
{
auto* bannerElement = tileElement->AsBanner();
if (bannerElement == nullptr)
{
continue;
}
2021-11-24 18:58:07 +01:00
if (bannerElement->GetIndex() == GetBannerIndex())
{
return bannerElement;
}
} while (!(tileElement++)->IsLastForTile());
return nullptr;
}
public:
void OnOpen() override
{
widgets = window_banner_widgets;
WindowInitScrollWidgets(*this);
}
2017-09-06 15:09:18 +02:00
2021-03-22 20:03:22 +01:00
void Initialise(rct_windownumber _number)
{
number = _number;
2021-11-24 18:58:07 +01:00
auto* banner = GetBanner(BannerIndex::FromUnderlying(number));
2014-05-09 10:04:40 +02:00
auto* bannerElement = GetBannerElement();
if (bannerElement == nullptr)
2021-03-22 20:03:22 +01:00
return;
_bannerViewPos = CoordsXYZ{ banner->position.ToCoordsXY().ToTileCentre(), bannerElement->GetBaseZ() };
CreateViewport();
}
2022-08-21 18:49:23 +02:00
void OnMouseDown(WidgetIndex widgetIndex) override
2018-06-22 23:21:44 +02:00
{
rct_widget* widget = &widgets[widgetIndex];
2021-11-24 18:58:07 +01:00
auto* banner = GetBanner(GetBannerIndex());
if (banner == nullptr)
{
Close();
return;
}
switch (widgetIndex)
{
case WIDX_MAIN_COLOUR:
WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), banner->colour);
break;
case WIDX_TEXT_COLOUR_DROPDOWN_BUTTON:
2018-06-22 23:21:44 +02:00
for (int32_t i = 0; i < 13; ++i)
{
gDropdownItems[i].Format = STR_DROPDOWN_MENU_LABEL;
gDropdownItems[i].Args = BannerColouredTextFormats[i + 1];
}
2018-06-22 23:21:44 +02:00
// Switch to the dropdown box widget.
widget--;
2018-06-22 23:21:44 +02:00
WindowDropdownShowTextCustomWidth(
{ widget->left + windowPos.x, widget->top + windowPos.y }, widget->height() + 1, colours[1], 0,
Dropdown::Flag::StayOpen, 13, widget->width() - 3);
2018-06-22 23:21:44 +02:00
Dropdown::SetChecked(banner->text_colour - 1, true);
break;
}
}
2014-05-09 10:04:40 +02:00
2022-08-21 18:49:23 +02:00
void OnMouseUp(WidgetIndex widgetIndex) override
2018-06-22 23:21:44 +02:00
{
2021-11-24 18:58:07 +01:00
auto* banner = GetBanner(GetBannerIndex());
if (banner == nullptr)
{
Close();
return;
}
switch (widgetIndex)
2019-04-07 11:10:36 +02:00
{
case WIDX_CLOSE:
Close();
2018-06-22 23:21:44 +02:00
break;
case WIDX_BANNER_DEMOLISH:
{
auto* bannerElement = GetBannerElement();
if (bannerElement == nullptr)
break;
auto bannerRemoveAction = BannerRemoveAction(
{ banner->position.ToCoordsXY(), bannerElement->GetBaseZ(), bannerElement->GetPosition() });
GameActions::Execute(&bannerRemoveAction);
break;
}
case WIDX_BANNER_TEXT:
WindowTextInputRawOpen(
this, WIDX_BANNER_TEXT, STR_BANNER_TEXT, STR_ENTER_BANNER_TEXT, {}, banner->GetText().c_str(), 32);
break;
case WIDX_BANNER_NO_ENTRY:
{
textinput_cancel();
auto bannerSetStyle = BannerSetStyleAction(
2021-11-24 18:58:07 +01:00
BannerSetStyleType::NoEntry, GetBannerIndex(), banner->flags ^ BANNER_FLAG_NO_ENTRY);
GameActions::Execute(&bannerSetStyle);
2018-06-22 23:21:44 +02:00
break;
}
2019-04-07 11:10:36 +02:00
}
}
2014-05-09 10:04:40 +02:00
2022-08-21 18:49:23 +02:00
void OnDropdown(WidgetIndex widgetIndex, int32_t dropdownIndex) override
{
switch (widgetIndex)
{
case WIDX_MAIN_COLOUR:
{
if (dropdownIndex == -1)
break;
2014-05-09 10:04:40 +02:00
2021-11-24 18:58:07 +01:00
auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::PrimaryColour, GetBannerIndex(), dropdownIndex);
GameActions::Execute(&bannerSetStyle);
break;
}
case WIDX_TEXT_COLOUR_DROPDOWN_BUTTON:
{
if (dropdownIndex == -1)
break;
2021-11-24 18:58:07 +01:00
auto bannerSetStyle = BannerSetStyleAction(BannerSetStyleType::TextColour, GetBannerIndex(), dropdownIndex + 1);
GameActions::Execute(&bannerSetStyle);
break;
}
}
}
2014-10-21 18:59:47 +02:00
2022-08-21 18:49:23 +02:00
void OnTextInput(WidgetIndex widgetIndex, std::string_view text) override
2017-11-22 23:06:56 +01:00
{
if (widgetIndex == WIDX_BANNER_TEXT)
{
2021-11-24 18:58:07 +01:00
auto bannerSetNameAction = BannerSetNameAction(GetBannerIndex(), std::string(text));
GameActions::Execute(&bannerSetNameAction);
}
2017-11-22 23:06:56 +01:00
}
2015-10-20 20:16:30 +02:00
void OnViewportRotate() override
2018-06-22 23:21:44 +02:00
{
RemoveViewport();
CreateViewport();
}
2014-10-21 18:59:47 +02:00
void OnDraw(rct_drawpixelinfo& dpi) override
{
DrawWidgets(dpi);
2014-05-09 10:04:40 +02:00
if (viewport != nullptr)
{
window_draw_viewport(&dpi, *this);
}
}
2014-05-09 10:04:40 +02:00
void OnPrepareDraw() override
2018-06-22 23:21:44 +02:00
{
2021-11-24 18:58:07 +01:00
auto* banner = GetBanner(GetBannerIndex());
if (banner == nullptr)
{
return;
}
2021-03-22 19:58:43 +01:00
rct_widget* colourBtn = &window_banner_widgets[WIDX_MAIN_COLOUR];
colourBtn->type = WindowWidgetType::Empty;
auto* bannerEntry = GetBannerEntry(banner->type);
if (bannerEntry != nullptr && (bannerEntry->flags & BANNER_ENTRY_FLAG_HAS_PRIMARY_COLOUR))
{
2021-03-22 19:58:43 +01:00
colourBtn->type = WindowWidgetType::ColourBtn;
}
pressed_widgets &= ~(1ULL << WIDX_BANNER_NO_ENTRY);
disabled_widgets &= ~(
(1ULL << WIDX_BANNER_TEXT) | (1ULL << WIDX_TEXT_COLOUR_DROPDOWN) | (1ULL << WIDX_TEXT_COLOUR_DROPDOWN_BUTTON));
if (banner->flags & BANNER_FLAG_NO_ENTRY)
{
pressed_widgets |= (1ULL << WIDX_BANNER_NO_ENTRY);
disabled_widgets |= (1ULL << WIDX_BANNER_TEXT) | (1ULL << WIDX_TEXT_COLOUR_DROPDOWN)
| (1ULL << WIDX_TEXT_COLOUR_DROPDOWN_BUTTON);
}
colourBtn->image = GetColourButtonImage(banner->colour).ToUInt32();
2021-03-22 19:58:43 +01:00
rct_widget* dropDownWidget = &window_banner_widgets[WIDX_TEXT_COLOUR_DROPDOWN];
dropDownWidget->text = BannerColouredTextFormats[banner->text_colour];
}
};
2014-10-21 18:59:47 +02:00
/**
*
* rct2: 0x006BA305
*/
rct_window* WindowBannerOpen(rct_windownumber number)
2014-10-21 18:59:47 +02:00
{
auto w = static_cast<BannerWindow*>(window_bring_to_front_by_number(WindowClass::Banner, number));
if (w != nullptr)
return w;
w = WindowCreate<BannerWindow>(WindowClass::Banner, WW, WH, 0);
if (w != nullptr)
2021-03-22 20:03:22 +01:00
w->Initialise(number);
return w;
2014-10-21 18:59:47 +02:00
}