2016-05-04 19:24:41 +02:00
|
|
|
/*****************************************************************************
|
2020-07-21 15:04:34 +02:00
|
|
|
* Copyright (c) 2014-2020 OpenRCT2 developers
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
2016-05-04 19:24:41 +02:00
|
|
|
*****************************************************************************/
|
|
|
|
|
2018-03-14 15:22:08 +01:00
|
|
|
#include <cstddef>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2-ui/interface/Widget.h>
|
|
|
|
#include <openrct2-ui/windows/Window.h>
|
2017-08-06 05:22:00 +02:00
|
|
|
#include <openrct2/config/Config.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/drawing/Drawing.h>
|
2017-09-18 17:05:28 +02:00
|
|
|
#include <openrct2/sprites.h>
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-07-31 14:22:58 +02:00
|
|
|
static constexpr const StringId WINDOW_TITLE = STR_NOTIFICATION_SETTINGS;
|
2020-05-05 22:26:14 +02:00
|
|
|
static constexpr const int32_t WH = 300;
|
|
|
|
static constexpr const int32_t WW = 400;
|
2019-10-19 04:02:31 +02:00
|
|
|
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format off
|
2022-01-24 15:48:43 +01:00
|
|
|
enum
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
NOTIFICATION_CATEGORY_PARK,
|
|
|
|
NOTIFICATION_CATEGORY_RIDE,
|
2022-01-24 15:48:43 +01:00
|
|
|
NOTIFICATION_CATEGORY_GUEST,
|
|
|
|
NOTIFICATION_CATEGORY_COUNT
|
2015-12-24 14:16:39 +01:00
|
|
|
};
|
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
struct NotificationDef
|
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t category;
|
2022-07-31 14:22:58 +02:00
|
|
|
StringId caption;
|
2017-06-06 23:24:18 +02:00
|
|
|
size_t config_offset;
|
2018-02-14 09:42:26 +01:00
|
|
|
};
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2021-11-24 17:16:52 +01:00
|
|
|
static constexpr const NotificationDef NewsItemOptionDefinitions[] = {
|
2017-06-06 23:24:18 +02:00
|
|
|
{ NOTIFICATION_CATEGORY_PARK, STR_NOTIFICATION_PARK_AWARD, offsetof(NotificationConfiguration, park_award) },
|
|
|
|
{ NOTIFICATION_CATEGORY_PARK, STR_NOTIFICATION_PARK_MARKETING_CAMPAIGN_FINISHED, offsetof(NotificationConfiguration, park_marketing_campaign_finished) },
|
|
|
|
{ NOTIFICATION_CATEGORY_PARK, STR_NOTIFICATION_PARK_WARNINGS, offsetof(NotificationConfiguration, park_warnings) },
|
|
|
|
{ NOTIFICATION_CATEGORY_PARK, STR_NOTIFICATION_PARK_RATING_WARNINGS, offsetof(NotificationConfiguration, park_rating_warnings) },
|
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_BROKEN_DOWN, offsetof(NotificationConfiguration, ride_broken_down) },
|
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_CRASHED, offsetof(NotificationConfiguration, ride_crashed) },
|
2020-04-16 14:41:39 +02:00
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_CASUALTIES, offsetof(NotificationConfiguration, ride_casualties) },
|
2017-06-06 23:24:18 +02:00
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_WARNINGS, offsetof(NotificationConfiguration, ride_warnings) },
|
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_RESEARCHED, offsetof(NotificationConfiguration, ride_researched) },
|
2020-04-16 14:41:39 +02:00
|
|
|
{ NOTIFICATION_CATEGORY_RIDE, STR_NOTIFICATION_RIDE_VEHICLE_STALLED, offsetof(NotificationConfiguration, ride_stalled_vehicles) },
|
2017-06-06 23:24:18 +02:00
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_WARNINGS, offsetof(NotificationConfiguration, guest_warnings) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_LEFT_PARK, offsetof(NotificationConfiguration, guest_left_park) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_QUEUING_FOR_RIDE, offsetof(NotificationConfiguration, guest_queuing_for_ride) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_ON_RIDE, offsetof(NotificationConfiguration, guest_on_ride) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_LEFT_RIDE, offsetof(NotificationConfiguration, guest_left_ride) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_BOUGHT_ITEM, offsetof(NotificationConfiguration, guest_bought_item) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_USED_FACILITY, offsetof(NotificationConfiguration, guest_used_facility) },
|
|
|
|
{ NOTIFICATION_CATEGORY_GUEST, STR_NOTIFICATION_GUEST_DIED, offsetof(NotificationConfiguration, guest_died) },
|
2015-12-24 14:16:39 +01:00
|
|
|
};
|
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
enum WindowNewsOptionsWidgetIdx
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
WIDX_BACKGROUND,
|
|
|
|
WIDX_TITLE,
|
|
|
|
WIDX_CLOSE,
|
|
|
|
WIDX_TAB_CONTENT_PANEL,
|
2022-01-24 15:48:43 +01:00
|
|
|
WIDX_FIRST_TAB,
|
|
|
|
WIDX_TAB_PARK = WIDX_FIRST_TAB,
|
2017-06-06 23:24:18 +02:00
|
|
|
WIDX_TAB_RIDE,
|
|
|
|
WIDX_TAB_GUEST,
|
|
|
|
WIDX_CHECKBOX_0
|
2015-12-24 14:16:39 +01:00
|
|
|
};
|
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
static rct_widget WindowNewsOptionsWidgets[] = {
|
2020-05-09 16:44:21 +02:00
|
|
|
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
|
2022-01-24 15:48:43 +01:00
|
|
|
MakeWidget({ 0, 43}, {400, 257}, WindowWidgetType::Resize, WindowColour::Secondary), // Tab content panel
|
|
|
|
MakeTab ({ 3, 17} ), // Park tab
|
|
|
|
MakeTab ({34, 17} ), // Ride tab
|
|
|
|
MakeTab ({65, 17} ), // Guest tab
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 7, 49}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
|
|
|
MakeWidget({ 0, 0}, {343, 14}, WindowWidgetType::Checkbox, WindowColour::Tertiary ),
|
2021-09-26 11:11:42 +02:00
|
|
|
WIDGETS_END,
|
2015-12-24 14:16:39 +01:00
|
|
|
};
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format on
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
class NewsOptionsWindow final : public Window
|
2015-12-24 14:16:39 +01:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
public:
|
|
|
|
void OnOpen() override
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
widgets = WindowNewsOptionsWidgets;
|
|
|
|
InitScrollWidgets();
|
|
|
|
colours[0] = COLOUR_GREY;
|
|
|
|
colours[1] = COLOUR_LIGHT_BLUE;
|
|
|
|
colours[2] = COLOUR_LIGHT_BLUE;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2017-08-06 05:22:00 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void OnMouseUp(rct_widgetindex widgetIndex) override
|
2017-06-06 23:24:18 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
switch (widgetIndex)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
case WIDX_CLOSE:
|
|
|
|
Close();
|
|
|
|
break;
|
|
|
|
case WIDX_TAB_PARK:
|
|
|
|
case WIDX_TAB_RIDE:
|
|
|
|
case WIDX_TAB_GUEST:
|
|
|
|
SetPage(widgetIndex - WIDX_FIRST_TAB);
|
|
|
|
break;
|
|
|
|
default:
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
int32_t checkBoxIndex = widgetIndex - WIDX_CHECKBOX_0;
|
|
|
|
if (checkBoxIndex >= 0)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
int32_t matchIndex = 0;
|
|
|
|
for (size_t i = 0; i < std::size(NewsItemOptionDefinitions); i++)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
const NotificationDef* ndef = &NewsItemOptionDefinitions[i];
|
|
|
|
if (ndef->category != page)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (matchIndex == checkBoxIndex)
|
|
|
|
{
|
|
|
|
// Toggle value
|
|
|
|
bool* configValue = GetNotificationValuePtr(ndef);
|
|
|
|
*configValue = !(*configValue);
|
|
|
|
|
|
|
|
config_save_default();
|
|
|
|
|
|
|
|
InvalidateWidget(widgetIndex);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
matchIndex++;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2022-01-24 15:48:43 +01:00
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void OnUpdate() override
|
|
|
|
{
|
|
|
|
// Tab animation
|
|
|
|
frame_no++;
|
|
|
|
InvalidateWidget(WIDX_FIRST_TAB + page);
|
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void OnPrepareDraw() override
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
SetPressedTab();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
// Set checkboxes
|
|
|
|
const auto& baseCheckBox = widgets[WIDX_CHECKBOX_0];
|
|
|
|
int32_t y = baseCheckBox.top;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
int32_t checkboxWidgetIndex = WIDX_CHECKBOX_0;
|
|
|
|
rct_widget* checkboxWidget = &widgets[checkboxWidgetIndex];
|
|
|
|
for (size_t i = 0; i < std::size(NewsItemOptionDefinitions); i++)
|
|
|
|
{
|
|
|
|
const NotificationDef* ndef = &NewsItemOptionDefinitions[i];
|
|
|
|
if (ndef->category != page)
|
|
|
|
continue;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
checkboxWidget->type = WindowWidgetType::Checkbox;
|
|
|
|
checkboxWidget->left = baseCheckBox.left;
|
|
|
|
checkboxWidget->right = baseCheckBox.right;
|
|
|
|
checkboxWidget->top = y;
|
|
|
|
checkboxWidget->bottom = checkboxWidget->top + LIST_ROW_HEIGHT + 3;
|
|
|
|
checkboxWidget->text = ndef->caption;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
const bool* configValue = GetNotificationValuePtr(ndef);
|
|
|
|
SetCheckboxValue(checkboxWidgetIndex, *configValue);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
checkboxWidgetIndex++;
|
|
|
|
checkboxWidget++;
|
|
|
|
y += LIST_ROW_HEIGHT + 3;
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
// Remove unused checkboxes
|
|
|
|
while (checkboxWidget->type != WindowWidgetType::Last)
|
|
|
|
{
|
|
|
|
checkboxWidget->type = WindowWidgetType::Empty;
|
|
|
|
checkboxWidgetIndex++;
|
|
|
|
checkboxWidget++;
|
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
// Resize window to fit checkboxes exactly
|
|
|
|
y += 3;
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
if (height != y)
|
|
|
|
{
|
|
|
|
Invalidate();
|
|
|
|
height = y;
|
|
|
|
widgets[WIDX_BACKGROUND].bottom = y - 1;
|
|
|
|
widgets[WIDX_TAB_CONTENT_PANEL].bottom = y - 1;
|
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnDraw(rct_drawpixelinfo& dpi) override
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
DrawWidgets(dpi);
|
|
|
|
DrawTabImages(&dpi);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-12-28 20:44:20 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
private:
|
|
|
|
void SetPage(int32_t p)
|
|
|
|
{
|
|
|
|
if (page != p)
|
|
|
|
{
|
|
|
|
page = p;
|
|
|
|
frame_no = 0;
|
|
|
|
Invalidate();
|
|
|
|
}
|
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void DrawTabImages(rct_drawpixelinfo* dpi)
|
|
|
|
{
|
|
|
|
DrawTabImage(dpi, NOTIFICATION_CATEGORY_PARK, SPR_TAB_PARK);
|
|
|
|
DrawTabImage(dpi, NOTIFICATION_CATEGORY_RIDE, SPR_TAB_RIDE_0);
|
|
|
|
DrawTabImage(dpi, NOTIFICATION_CATEGORY_GUEST, SPR_TAB_GUESTS_0);
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void DrawTabImage(rct_drawpixelinfo* dpi, int32_t p, int32_t spriteIndex)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
rct_widgetindex widgetIndex = WIDX_FIRST_TAB + p;
|
|
|
|
|
2022-07-30 22:21:51 +02:00
|
|
|
if (!WidgetIsDisabled(*this, widgetIndex))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
if (page == p)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2022-01-24 15:48:43 +01:00
|
|
|
int32_t numFrames = TabAnimationFrames[page];
|
|
|
|
if (numFrames > 1)
|
|
|
|
{
|
|
|
|
int32_t frame = frame_no / TabAnimationDivisor[page];
|
|
|
|
spriteIndex += (frame % numFrames);
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2022-01-24 15:48:43 +01:00
|
|
|
|
|
|
|
const auto& widget = widgets[widgetIndex];
|
|
|
|
gfx_draw_sprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget.left, widget.top });
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2022-01-24 15:48:43 +01:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
void SetPressedTab()
|
|
|
|
{
|
|
|
|
for (int32_t i = 0; i < NOTIFICATION_CATEGORY_COUNT; i++)
|
|
|
|
pressed_widgets &= ~(1 << (WIDX_FIRST_TAB + i));
|
|
|
|
pressed_widgets |= 1LL << (WIDX_FIRST_TAB + page);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
bool* GetNotificationValuePtr(const NotificationDef* ndef)
|
|
|
|
{
|
|
|
|
bool* configValue = reinterpret_cast<bool*>(reinterpret_cast<size_t>(&gConfigNotifications) + ndef->config_offset);
|
|
|
|
return configValue;
|
|
|
|
}
|
2015-12-24 14:16:39 +01:00
|
|
|
|
2022-01-24 15:48:43 +01:00
|
|
|
static constexpr int32_t TabAnimationDivisor[3] = {
|
|
|
|
1, // Park
|
|
|
|
4, // Ride
|
|
|
|
4, // Guest
|
|
|
|
};
|
|
|
|
static constexpr int32_t TabAnimationFrames[3] = {
|
|
|
|
1, // Park
|
|
|
|
16, // Ride
|
|
|
|
8, // Guest
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
rct_window* WindowNewsOptionsOpen()
|
2015-12-24 14:16:39 +01:00
|
|
|
{
|
2022-08-21 18:38:25 +02:00
|
|
|
return WindowFocusOrCreate<NewsOptionsWindow>(WindowClass::NotificationOptions, WW, WH, WF_CENTRE_SCREEN);
|
2015-12-24 14:16:39 +01:00
|
|
|
}
|