Refactor widget state to single storage model (#26443)

* Allow flag/bitmask coexistence in readers

* Add factory helpers and bulk setters for per-widget flags

* Switch coexistence from OR-both to per-window opt-in

* Migrate seven small windows to per-widget flags

* Migrate seven more windows to per-widget flags

* Migrate Cheats, MapGen and Footpath to per-widget flags

* Fix #26421: scenery tab highlight wraps when there are 64+ groups

* Migrate Ride window to per-widget flags

* Migrate ride and maze construction windows to per-widget flags

* Migrate six more windows to per-widget flags

* Migrate Banner, EditorScenarioOptions and RideList to per-widget flags

* Migrate SceneryScatter and LoadSave to per-widget flags

* Migrate EditorObjectSelection, GameBottomToolbar, Guest, Map, NewRide and Park to per-widget flags

* Migrate TopToolbar, TrackList, Research, Player and Options to per-widget flags

* Opt in remaining windows to per-widget flags

* Narrow getters and setters to per-widget flags

* Remove bitmask fields and useWidgetFlags switch

* Restore switch statements for tab/density pressed state

* Add makeHoldableSpinnerWidgets to drop per-page loops

* Update tests for per-widget flag storage

* Add changelog entry for #26421

* Reword narrative-tense comments from the migration

* Fix clang-format violations

* Remove dead holdable-widget tables from Park and Finances
This commit is contained in:
Marino Rottier
2026-04-28 09:26:02 +02:00
committed by GitHub
parent a939eccc14
commit 45ff80d890
50 changed files with 683 additions and 906 deletions
+1
View File
@@ -13,6 +13,7 @@
- Fix: [#26374] Add higher resolution app icons for Android.
- Fix: [#26410] Tiles with water can draw incorrectly when there is something underwater and nothing above water.
- Fix: [#26419] Drop count & negative gs stat requirements for Flying Roller Coaster dont get nullified by having an inversion.
- Fix: [#26421] Wrong scenery tab highlighted when more than 64 scenery groups are selected.
- Fix: [#26425] Benches don't reduce watching spots from 4 to 2 while other path additions do (should be reversed).
- Fix: [#26432] Guests choose to head for rides they have already ridden if they don't have a map.
+22 -40
View File
@@ -904,16 +904,12 @@ namespace OpenRCT2::Ui
bool widgetIsDisabled(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::custom)
return w.widgets[widgetIndex].flags.has(WidgetFlag::isDisabled);
return (w.disabledWidgets & (1LL << widgetIndex)) != 0;
return w.widgets[widgetIndex].flags.has(WidgetFlag::isDisabled);
}
bool widgetIsHoldable(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::custom)
return w.widgets[widgetIndex].flags.has(WidgetFlag::isHoldable);
return (w.holdDownWidgets & (1LL << widgetIndex)) != 0;
return w.widgets[widgetIndex].flags.has(WidgetFlag::isHoldable);
}
bool widgetIsVisible(const WindowBase& w, WidgetIndex widgetIndex)
@@ -923,20 +919,8 @@ namespace OpenRCT2::Ui
bool widgetIsPressed(const WindowBase& w, WidgetIndex widgetIndex)
{
if (w.classification == WindowClass::custom)
{
if (w.widgets[widgetIndex].flags.has(WidgetFlag::isPressed))
{
return true;
}
}
else
{
if (w.pressedWidgets & (1LL << widgetIndex))
{
return true;
}
}
if (w.widgets[widgetIndex].flags.has(WidgetFlag::isPressed))
return true;
if (InputGetState() == InputState::WidgetPressed || InputGetState() == InputState::DropdownActive)
{
@@ -1113,27 +1097,11 @@ namespace OpenRCT2::Ui
void widgetSetDisabled(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WidgetFlag::isDisabled, value);
if (value)
{
w.disabledWidgets |= (1uLL << widgetIndex);
}
else
{
w.disabledWidgets &= ~(1uLL << widgetIndex);
}
}
void widgetSetHoldable(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WidgetFlag::isHoldable, value);
if (value)
{
w.holdDownWidgets |= (1uLL << widgetIndex);
}
else
{
w.holdDownWidgets &= ~(1uLL << widgetIndex);
}
}
void widgetSetVisible(WindowBase& w, WidgetIndex widgetIndex, bool value)
@@ -1144,10 +1112,6 @@ namespace OpenRCT2::Ui
void widgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value)
{
SafeSetWidgetFlag(w, widgetIndex, WidgetFlag::isPressed, value);
if (value)
w.pressedWidgets |= (1uLL << widgetIndex);
else
w.pressedWidgets &= ~(1uLL << widgetIndex);
}
void widgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value)
@@ -1155,6 +1119,24 @@ namespace OpenRCT2::Ui
widgetSetPressed(w, widgetIndex, value);
}
void widgetsClearPressed(WindowBase& w, std::initializer_list<WidgetIndex> indices)
{
for (auto i : indices)
widgetSetPressed(w, i, false);
}
void widgetSetPressedExclusive(WindowBase& w, std::initializer_list<WidgetIndex> group, WidgetIndex pressed)
{
for (auto i : group)
widgetSetPressed(w, i, i == pressed);
}
void widgetsSetHoldable(WindowBase& w, std::initializer_list<WidgetIndex> indices)
{
for (auto i : indices)
widgetSetHoldable(w, i, true);
}
static void WidgetTextBoxDraw(RenderTarget& rt, WindowBase& w, WidgetIndex widgetIndex)
{
// Get the widget
+28
View File
@@ -11,6 +11,7 @@
#include "Window.h"
#include <initializer_list>
#include <openrct2-ui/UiStringIds.h>
#include <openrct2/drawing/FilterPaletteIds.h>
#include <openrct2/interface/Widget.h>
@@ -91,6 +92,19 @@ namespace OpenRCT2::Ui
return makeWidget(origin, size, type, colour, content, tooltip);
}
constexpr Widget withFlag(Widget w, WidgetFlag flag)
{
w.flags.set(flag);
return w;
}
constexpr Widget makeHoldableWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, WidgetType type, WindowColour colour,
uint32_t content = kWidgetContentEmpty, StringId tooltip = kStringIdNone)
{
return withFlag(makeWidget(origin, size, type, colour, content, tooltip), WidgetFlag::isHoldable);
}
constexpr Widget makeProgressBar(
const ScreenCoordsXY& origin, const ScreenSize& size, Drawing::Colour colour, uint8_t lowerBlinkBound = 0,
uint8_t upperBlinkBound = 0)
@@ -220,6 +234,16 @@ namespace OpenRCT2::Ui
makeSpinnerDecreaseWidget(origin, size, type, colour, content, tooltip));
};
constexpr std::array<Widget, 3> makeHoldableSpinnerWidgets(
const ScreenCoordsXY& origin, const ScreenSize& size, WidgetType type, WindowColour colour,
uint32_t content = kWidgetContentEmpty, StringId tooltip = kStringIdNone)
{
return makeWidgets(
makeWidget(origin, size, type, colour, content, tooltip),
withFlag(makeSpinnerIncreaseWidget(origin, size, type, colour, content, tooltip), WidgetFlag::isHoldable),
withFlag(makeSpinnerDecreaseWidget(origin, size, type, colour, content, tooltip), WidgetFlag::isHoldable));
};
constexpr Widget makeDropdownBoxWidget(
const ScreenCoordsXY& origin, const ScreenSize& size, [[maybe_unused]] WidgetType type, WindowColour colour,
[[maybe_unused]] uint32_t content = kWidgetContentEmpty, StringId tooltip = kStringIdNone)
@@ -266,6 +290,10 @@ namespace OpenRCT2::Ui
void widgetSetPressed(WindowBase& w, WidgetIndex widgetIndex, bool value);
void widgetSetCheckboxValue(WindowBase& w, WidgetIndex widgetIndex, bool value);
void widgetsClearPressed(WindowBase& w, std::initializer_list<WidgetIndex> indices);
void widgetSetPressedExclusive(WindowBase& w, std::initializer_list<WidgetIndex> group, WidgetIndex pressed);
void widgetsSetHoldable(WindowBase& w, std::initializer_list<WidgetIndex> indices);
void widgetProgressBarSetNewPercentage(Widget& widget, uint8_t newPercentage);
void widgetScrollUpdateThumbs(WindowBase& w, WidgetIndex widget_index);
+4 -3
View File
@@ -205,20 +205,21 @@ namespace OpenRCT2::Ui::Windows
page = p;
currentFrame = 0;
pressedWidgets = 0;
WindowSetResize(*this, kWindowSize, kWindowSize);
setWidgets(_windowAboutPageWidgets[p]);
WidgetIndex pressedTab = WIDX_TAB_ABOUT_OPENRCT2;
switch (p)
{
case WINDOW_ABOUT_PAGE_OPENRCT2:
pressedWidgets |= (1uLL << WIDX_TAB_ABOUT_OPENRCT2);
pressedTab = WIDX_TAB_ABOUT_OPENRCT2;
break;
case WINDOW_ABOUT_PAGE_RCT2:
pressedWidgets |= (1uLL << WIDX_TAB_ABOUT_RCT2);
pressedTab = WIDX_TAB_ABOUT_RCT2;
break;
}
widgetSetPressedExclusive(*this, { WIDX_TAB_ABOUT_OPENRCT2, WIDX_TAB_ABOUT_RCT2 }, pressedTab);
}
int32_t DrawOpenRCT2Info(Drawing::RenderTarget& rt)
+5 -9
View File
@@ -296,15 +296,11 @@ namespace OpenRCT2::Ui::Windows
{
colourBtn.type = WidgetType::colourBtn;
}
pressedWidgets &= ~(1uLL << WIDX_BANNER_NO_ENTRY);
disabledWidgets &= ~(
(1uLL << WIDX_BANNER_TEXT) | (1uLL << WIDX_TEXT_COLOUR_DROPDOWN) | (1uLL << WIDX_TEXT_COLOUR_DROPDOWN_BUTTON));
if (banner->flags.has(BannerFlag::noEntry))
{
pressedWidgets |= (1uLL << WIDX_BANNER_NO_ENTRY);
disabledWidgets |= (1uLL << WIDX_BANNER_TEXT) | (1uLL << WIDX_TEXT_COLOUR_DROPDOWN)
| (1uLL << WIDX_TEXT_COLOUR_DROPDOWN_BUTTON);
}
const bool noEntry = banner->flags.has(BannerFlag::noEntry);
setWidgetPressed(WIDX_BANNER_NO_ENTRY, noEntry);
setWidgetDisabled(WIDX_BANNER_TEXT, noEntry);
setWidgetDisabled(WIDX_TEXT_COLOUR_DROPDOWN, noEntry);
setWidgetDisabled(WIDX_TEXT_COLOUR_DROPDOWN_BUTTON, noEntry);
colourBtn.image = getColourButtonImage(banner->colour);
Widget& dropDownWidget = widgets[WIDX_TEXT_COLOUR_DROPDOWN];
dropDownWidget.text = kBannerColouredTextFormats[EnumValue(banner->textColour)];
+22 -39
View File
@@ -371,29 +371,22 @@ static constexpr std::span<const Widget> window_cheats_page_widgets[] =
window_cheats_weather_widgets,
};
static uint64_t window_cheats_page_holdDownWidgets[] = {
(1uLL << WIDX_MONEY_SPINNER_INCREMENT) |
(1uLL << WIDX_MONEY_SPINNER_DECREMENT) |
(1uLL << WIDX_ADD_MONEY),
(1uLL << WIDX_YEAR_UP) |
(1uLL << WIDX_YEAR_DOWN) |
(1uLL << WIDX_MONTH_UP) |
(1uLL << WIDX_MONTH_DOWN) |
(1uLL << WIDX_DAY_UP) |
(1uLL << WIDX_DAY_DOWN),
0,
0,
(1uLL << WIDX_INCREASE_PARK_RATING) |
(1uLL << WIDX_DECREASE_PARK_RATING),
0,
0,
};
static void setPageHoldableWidgets(WindowBase& w, int32_t page)
{
switch (page)
{
case WINDOW_CHEATS_PAGE_MONEY:
widgetsSetHoldable(w, { WIDX_MONEY_SPINNER_INCREMENT, WIDX_MONEY_SPINNER_DECREMENT, WIDX_ADD_MONEY });
break;
case WINDOW_CHEATS_PAGE_DATE:
widgetsSetHoldable(
w, { WIDX_YEAR_UP, WIDX_YEAR_DOWN, WIDX_MONTH_UP, WIDX_MONTH_DOWN, WIDX_DAY_UP, WIDX_DAY_DOWN });
break;
case WINDOW_CHEATS_PAGE_PARK:
widgetsSetHoldable(w, { WIDX_INCREASE_PARK_RATING, WIDX_DECREASE_PARK_RATING });
break;
}
}
static StringId window_cheats_page_titles[] = {
STR_CHEAT_TITLE_FINANCIAL,
@@ -509,14 +502,6 @@ static StringId window_cheats_page_titles[] = {
void onPrepareDraw() override
{
pressedWidgets = 0;
disabledWidgets = 0;
// Set correct active tab
for (auto i = 0; i < WINDOW_CHEATS_PAGE_COUNT; i++)
setWidgetPressed(WIDX_TAB_1 + i, false);
setWidgetPressed(WIDX_TAB_1 + page, true);
// Set title
widgets[WIDX_TITLE].text = window_cheats_page_titles[page];
@@ -525,10 +510,7 @@ static StringId window_cheats_page_titles[] = {
{
case WINDOW_CHEATS_PAGE_MONEY:
{
if (isInEditorMode())
{
setWidgetDisabled(WIDX_NO_MONEY, true);
}
setWidgetDisabled(WIDX_NO_MONEY, isInEditorMode());
auto moneyDisabled = (gameState.park.flags & PARK_FLAGS_NO_MONEY) != 0;
setCheckboxValue(WIDX_NO_MONEY, moneyDisabled);
@@ -598,10 +580,10 @@ static StringId window_cheats_page_titles[] = {
widgets[WIDX_STAFF_SPEED].text = _staffSpeedNames[EnumValue(gameState.cheats.selectedStaffSpeed)];
}
setWidgetDisabled(WIDX_TAB_2, isInEditorMode());
setWidgetDisabled(WIDX_TAB_3, isInEditorMode());
if (isInEditorMode())
{
setWidgetDisabled(WIDX_TAB_2, true);
setWidgetDisabled(WIDX_TAB_3, true);
UpdateTabPositions();
}
}
@@ -748,9 +730,10 @@ static StringId window_cheats_page_titles[] = {
page = p;
currentFrame = 0;
holdDownWidgets = window_cheats_page_holdDownWidgets[p];
pressedWidgets = 0;
setWidgets(window_cheats_page_widgets[p]);
setPageHoldableWidgets(*this, p);
widgetSetPressedExclusive(
*this, { WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4, WIDX_TAB_5, WIDX_TAB_6, WIDX_TAB_7 }, WIDX_TAB_1 + p);
auto maxY = 0;
for (WidgetIndex widgetIdx = WIDX_TAB_CONTENT; widgetIdx < widgets.size(); widgetIdx++)
+9 -5
View File
@@ -71,7 +71,12 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(window_clear_scenery_widgets);
holdDownWidgets = (1uLL << WIDX_INCREMENT) | (1uLL << WIDX_DECREMENT);
widgetsSetHoldable(*this, { WIDX_INCREMENT, WIDX_DECREMENT });
widgetSetPressed(*this, WIDX_PREVIEW, true);
widgetSetPressed(*this, WIDX_SMALL_SCENERY, _clearSmallScenery);
widgetSetPressed(*this, WIDX_LARGE_SCENERY, _clearLargeScenery);
widgetSetPressed(*this, WIDX_FOOTPATH, _clearFootpath);
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
@@ -104,14 +109,17 @@ namespace OpenRCT2::Ui::Windows
}
case WIDX_SMALL_SCENERY:
_clearSmallScenery ^= 1;
widgetSetPressed(*this, WIDX_SMALL_SCENERY, _clearSmallScenery);
invalidate();
break;
case WIDX_LARGE_SCENERY:
_clearLargeScenery ^= 1;
widgetSetPressed(*this, WIDX_LARGE_SCENERY, _clearLargeScenery);
invalidate();
break;
case WIDX_FOOTPATH:
_clearFootpath ^= 1;
widgetSetPressed(*this, WIDX_FOOTPATH, _clearFootpath);
invalidate();
break;
}
@@ -166,10 +174,6 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
// Set the preview image button to be pressed down
pressedWidgets = (1uLL << WIDX_PREVIEW) | (_clearSmallScenery ? (1uLL << WIDX_SMALL_SCENERY) : 0)
| (_clearLargeScenery ? (1uLL << WIDX_LARGE_SCENERY) : 0) | (_clearFootpath ? (1uLL << WIDX_FOOTPATH) : 0);
// Update the preview image (for tool sizes up to 7)
widgets[WIDX_PREVIEW].image = ImageId(LandTool::SizeToSpriteIndex(gLandToolSize));
}
+1 -1
View File
@@ -56,7 +56,7 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(window_custom_currency_widgets);
holdDownWidgets = (1uLL << WIDX_RATE_UP) | (1uLL << WIDX_RATE_DOWN);
widgetsSetHoldable(*this, { WIDX_RATE_UP, WIDX_RATE_DOWN });
WindowInitScrollWidgets(*this);
colours[0] = Drawing::Colour::lightBrown;
colours[1] = Drawing::Colour::lightBrown;
@@ -157,6 +157,8 @@ namespace OpenRCT2::Ui::Windows
ResearchRidesSetup();
setWidgets(_inventionListWidgets);
widgetSetPressed(*this, WIDX_PREVIEW, true);
widgetSetPressed(*this, WIDX_TAB_1, true);
initScrollWidgets();
selectedTab = 0;
_selectedResearchItem = nullptr;
@@ -447,9 +449,6 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
pressedWidgets |= 1uLL << WIDX_PREVIEW;
pressedWidgets |= 1uLL << WIDX_TAB_1;
widgets[WIDX_CLOSE].type = gLegacyScene == LegacyScene::scenarioEditor ? WidgetType::empty : WidgetType::closeBox;
int16_t scrollListHeight = (height - 88) / 2;
@@ -299,7 +299,7 @@ namespace OpenRCT2::Ui::Windows
_listSortType = RIDE_SORT_TYPE;
_listSortDescending = false;
disabledWidgets |= 1u << WIDX_FILTER_RIDE_TAB_FRAME;
setWidgetDisabled(WIDX_FILTER_RIDE_TAB_FRAME, true);
VisibleListRefresh();
}
@@ -857,7 +857,7 @@ namespace OpenRCT2::Ui::Windows
installTrackWidget.moveToX(dropdownWidget.left - installTrackWidget.width() - 11);
// Set pressed widgets
pressedWidgets |= 1uLL << WIDX_PREVIEW;
setWidgetPressed(WIDX_PREVIEW, true);
SetPressedTab();
// Set window title and buttons
@@ -962,13 +962,13 @@ namespace OpenRCT2::Ui::Windows
{
widgets[WIDX_SUB_TAB_0 + i].tooltip = i < numSubTabs ? currentPage.subTabs[i].tooltip : kStringIdNone;
widgets[WIDX_SUB_TAB_0 + i].type = i < numSubTabs ? WidgetType::tab : WidgetType::empty;
pressedWidgets &= ~(1uLL << (WIDX_SUB_TAB_0 + i));
setWidgetPressed(WIDX_SUB_TAB_0 + i, false);
}
// Mark current sub-tab as active, and toggle tab frame
if (hasSubTabs)
{
pressedWidgets |= (1uLL << (WIDX_SUB_TAB_0 + _selectedSubTab));
setWidgetPressed(WIDX_SUB_TAB_0 + _selectedSubTab, true);
widgets[WIDX_FILTER_RIDE_TAB_FRAME].type = WidgetType::imgBtn;
}
else
@@ -1597,9 +1597,8 @@ namespace OpenRCT2::Ui::Windows
{
for (size_t i = 0; i < std::size(ObjectSelectionPages); i++)
{
pressedWidgets &= ~(1ull << (WIDX_TAB_1 + i));
setWidgetPressed(WIDX_TAB_1 + static_cast<WidgetIndex>(i), static_cast<int32_t>(i) == selectedTab);
}
pressedWidgets |= 1LL << (WIDX_TAB_1 + selectedTab);
}
/**
@@ -272,7 +272,7 @@ namespace OpenRCT2::Ui::Windows
auto newMaxHeight = static_cast<int16_t>(kWindowSize.height + kImageSize * (GetNumRows() - 1));
WindowSetResize(*this, kWindowSize, { kWindowSize.width, newMaxHeight });
pressedWidgets |= 1LL << WIDX_TAB;
widgetSetPressed(*this, WIDX_TAB, true);
ToolSet(*this, WIDX_LIST, Tool::entranceDown);
gInputFlags.set(InputFlag::allowRightMouseRemoval);
@@ -222,10 +222,10 @@ namespace OpenRCT2::Ui::Windows
makeWidget ({ 8, 48}, {344, 12}, WidgetType::label, WindowColour::secondary, STR_OBJECTIVE_DROPDOWN_LABEL ),
makeWidget ({ 98, 47}, {344, 14}, WidgetType::dropdownMenu, WindowColour::secondary, kStringIdNone, STR_SELECT_OBJECTIVE_FOR_THIS_SCENARIO_TIP),
makeWidget ({430, 48}, { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH, STR_SELECT_OBJECTIVE_FOR_THIS_SCENARIO_TIP),
makeWidget ({ 28, 66}, {140, 12}, WidgetType::label, WindowColour::secondary, kStringIdEmpty ),
makeSpinnerWidgets({158, 65}, {120, 14}, WidgetType::button, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 28, 85}, {140, 12}, WidgetType::label, WindowColour::secondary, STR_WINDOW_OBJECTIVE_DATE ),
makeSpinnerWidgets({158, 84}, {120, 14}, WidgetType::button, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 28, 66}, {140, 12}, WidgetType::label, WindowColour::secondary, kStringIdEmpty ),
makeHoldableSpinnerWidgets({158, 65}, {120, 14}, WidgetType::button, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 28, 85}, {140, 12}, WidgetType::label, WindowColour::secondary, STR_WINDOW_OBJECTIVE_DATE ),
makeHoldableSpinnerWidgets({158, 84}, {120, 14}, WidgetType::button, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 14, 103}, {340, 12}, WidgetType::checkbox, WindowColour::secondary, STR_HARD_PARK_RATING, STR_HARD_PARK_RATING_TIP )
);
@@ -242,48 +242,48 @@ namespace OpenRCT2::Ui::Windows
makeOptionsWidgets(STR_SCENARIO_OPTIONS_FINANCIAL, kSizeFinancial),
makeWidget ({ 8, 48}, {kSizeFinancial.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_MAKE_PARK_NO_MONEY, STR_MAKE_PARK_NO_MONEY_TIP ),
makeWidget ({ 5, 63}, {kSizeFinancial.width - 10, 72}, WidgetType::groupbox, WindowColour::secondary, STR_GROUP_LOAN_OPTIONS ),
makeWidget ({ 9, 78}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_INIT_LOAN_LABEL ),
makeSpinnerWidgets({268, 77}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 97}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_MAX_LOAN_LABEL ),
makeSpinnerWidgets({268, 96}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 116}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_INTEREST_RATE_LABEL ),
makeSpinnerWidgets({298, 115}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 10, 115}, {kSizeFinancial.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_RCT1_INTEREST, STR_RCT1_INTEREST_TIP ),
makeWidget ({ 5, 63}, {kSizeFinancial.width - 10, 72}, WidgetType::groupbox, WindowColour::secondary, STR_GROUP_LOAN_OPTIONS ),
makeWidget ({ 9, 78}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_INIT_LOAN_LABEL ),
makeHoldableSpinnerWidgets({268, 77}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 97}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_MAX_LOAN_LABEL ),
makeHoldableSpinnerWidgets({268, 96}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 116}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_INTEREST_RATE_LABEL ),
makeHoldableSpinnerWidgets({298, 115}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 10, 115}, {kSizeFinancial.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_RCT1_INTEREST, STR_RCT1_INTEREST_TIP ),
makeWidget ({ 5, 137}, {kSizeFinancial.width - 10, 89}, WidgetType::groupbox, WindowColour::secondary, STR_GROUP_BUSINESS_MODEL ),
makeWidget ({ 9, 155}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_INIT_CASH_LABEL ),
makeSpinnerWidgets({268, 154}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 173}, { 150, 12}, WidgetType::label, WindowColour::secondary, STR_EARNINGS_LABEL ),
makeWidget ({158, 172}, { 210, 14}, WidgetType::dropdownMenu, WindowColour::secondary, kStringIdNone, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
makeWidget ({356, 173}, { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
makeWidget ({ 9, 191}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_ENTRY_PRICE_LABEL ),
makeSpinnerWidgets({298, 190}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 10, 208}, {kSizeFinancial.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_FORBID_MARKETING, STR_FORBID_MARKETING_TIP )
makeWidget ({ 5, 137}, {kSizeFinancial.width - 10, 89}, WidgetType::groupbox, WindowColour::secondary, STR_GROUP_BUSINESS_MODEL ),
makeWidget ({ 9, 155}, { 250, 12}, WidgetType::label, WindowColour::secondary, STR_INIT_CASH_LABEL ),
makeHoldableSpinnerWidgets({268, 154}, { 100, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 9, 173}, { 150, 12}, WidgetType::label, WindowColour::secondary, STR_EARNINGS_LABEL ),
makeWidget ({158, 172}, { 210, 14}, WidgetType::dropdownMenu, WindowColour::secondary, kStringIdNone, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
makeWidget ({356, 173}, { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH, STR_PAY_FOR_PARK_PAY_FOR_RIDES_TIP),
makeWidget ({ 9, 191}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_ENTRY_PRICE_LABEL ),
makeSpinnerWidgets ({298, 190}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 10, 208}, {kSizeFinancial.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_FORBID_MARKETING, STR_FORBID_MARKETING_TIP )
);
static constexpr auto window_editor_scenario_options_guests_widgets = makeWidgets(
makeOptionsWidgets(STR_SCENARIO_OPTIONS_GUESTS, kSizeGuests),
makeWidget ({ 8, 49}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_CASH_PER_GUEST_LABEL ),
makeSpinnerWidgets({298, 48}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 68}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_HAPPINESS ),
makeSpinnerWidgets({298, 67}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 87}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_HUNGER ),
makeSpinnerWidgets({298, 86}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 106}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_THIRST ),
makeSpinnerWidgets({298, 105}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 124}, { 180, 12}, WidgetType::label, WindowColour::secondary, STR_GUESTS_PREFER_INTENSITY_LABEL ),
makeWidget ({198, 123}, { 170, 14}, WidgetType::dropdownMenu, WindowColour::secondary, kStringIdNone, STR_GUESTS_PREFER_INTENSITY_TIP ),
makeWidget ({357, 124}, { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH, STR_GUESTS_PREFER_INTENSITY_TIP ),
makeWidget ({ 8, 143}, { 350, 12}, WidgetType::checkbox, WindowColour::secondary, STR_HARD_GUEST_GENERATION, STR_HARD_GUEST_GENERATION_TIP )
makeWidget ({ 8, 49}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_CASH_PER_GUEST_LABEL ),
makeHoldableSpinnerWidgets({298, 48}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 68}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_HAPPINESS ),
makeHoldableSpinnerWidgets({298, 67}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 87}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_HUNGER ),
makeHoldableSpinnerWidgets({298, 86}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 106}, { 280, 12}, WidgetType::label, WindowColour::secondary, STR_GUEST_INIT_THIRST ),
makeHoldableSpinnerWidgets({298, 105}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 124}, { 180, 12}, WidgetType::label, WindowColour::secondary, STR_GUESTS_PREFER_INTENSITY_LABEL ),
makeWidget ({198, 123}, { 170, 14}, WidgetType::dropdownMenu, WindowColour::secondary, kStringIdNone, STR_GUESTS_PREFER_INTENSITY_TIP ),
makeWidget ({357, 124}, { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH, STR_GUESTS_PREFER_INTENSITY_TIP ),
makeWidget ({ 8, 143}, { 350, 12}, WidgetType::checkbox, WindowColour::secondary, STR_HARD_GUEST_GENERATION, STR_HARD_GUEST_GENERATION_TIP )
);
static constexpr auto window_editor_scenario_options_land_widgets = makeWidgets(
makeOptionsWidgets(STR_SCENARIO_OPTIONS_LAND_RESTRICTIONS, kSizeLand),
makeWidget ({ 8, 49}, { 170, 12}, WidgetType::label, WindowColour::secondary, STR_LAND_COST_LABEL ),
makeSpinnerWidgets({188, 48}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 66}, { 170, 12}, WidgetType::label, WindowColour::secondary, STR_RIGHTS_COST_LABEL ),
makeSpinnerWidgets({188, 65}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 49}, { 170, 12}, WidgetType::label, WindowColour::secondary, STR_LAND_COST_LABEL ),
makeHoldableSpinnerWidgets({188, 48}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 66}, { 170, 12}, WidgetType::label, WindowColour::secondary, STR_RIGHTS_COST_LABEL ),
makeHoldableSpinnerWidgets({188, 65}, { 70, 14}, WidgetType::spinner, WindowColour::secondary ), // NB: 3 widgets
makeWidget ({ 8, 82}, {kSizeLand.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_FORBID_TREE_REMOVAL, STR_FORBID_TREE_REMOVAL_TIP ),
makeWidget ({ 8, 99}, {kSizeLand.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_FORBID_LANDSCAPE_CHANGES, STR_FORBID_LANDSCAPE_CHANGES_TIP ),
makeWidget ({ 8, 116}, {kSizeLand.width - 16, 12}, WidgetType::checkbox, WindowColour::secondary, STR_FORBID_HIGH_CONSTRUCTION, STR_FORBID_HIGH_CONSTRUCTION_TIP )
@@ -304,40 +304,6 @@ namespace OpenRCT2::Ui::Windows
window_editor_scenario_options_rides_widgets,
};
#pragma endregion
#pragma region Enabled widgets
static uint64_t window_editor_scenario_options_page_holdDownWidgets[] = {
(1uLL << WIDX_OBJECTIVE_ARG_1_INCREASE) |
(1uLL << WIDX_OBJECTIVE_ARG_1_DECREASE) |
(1uLL << WIDX_OBJECTIVE_ARG_2_INCREASE) |
(1uLL << WIDX_OBJECTIVE_ARG_2_DECREASE),
0,
(1uLL << WIDX_INITIAL_CASH_INCREASE) |
(1uLL << WIDX_INITIAL_CASH_DECREASE) |
(1uLL << WIDX_INITIAL_LOAN_INCREASE) |
(1uLL << WIDX_INITIAL_LOAN_DECREASE) |
(1uLL << WIDX_MAXIMUM_LOAN_INCREASE) |
(1uLL << WIDX_MAXIMUM_LOAN_DECREASE) |
(1uLL << WIDX_INTEREST_RATE_INCREASE) |
(1uLL << WIDX_INTEREST_RATE_DECREASE),
(1uLL << WIDX_CASH_PER_GUEST_INCREASE) |
(1uLL << WIDX_CASH_PER_GUEST_DECREASE) |
(1uLL << WIDX_GUEST_INITIAL_HAPPINESS_INCREASE) |
(1uLL << WIDX_GUEST_INITIAL_HAPPINESS_DECREASE) |
(1uLL << WIDX_GUEST_INITIAL_HUNGER_INCREASE) |
(1uLL << WIDX_GUEST_INITIAL_HUNGER_DECREASE) |
(1uLL << WIDX_GUEST_INITIAL_THIRST_INCREASE) |
(1uLL << WIDX_GUEST_INITIAL_THIRST_DECREASE),
(1uLL << WIDX_LAND_COST_INCREASE) |
(1uLL << WIDX_LAND_COST_DECREASE) |
(1uLL << WIDX_CONSTRUCTION_RIGHTS_COST_INCREASE) |
(1uLL << WIDX_CONSTRUCTION_RIGHTS_COST_DECREASE) |
(1uLL << WIDX_ENTRY_PRICE_INCREASE) |
(1uLL << WIDX_ENTRY_PRICE_DECREASE),
0
};
// clang-format on
#pragma endregion
@@ -669,9 +635,6 @@ namespace OpenRCT2::Ui::Windows
page = newPage;
currentFrame = 0;
disabledWidgets = 0;
holdDownWidgets = window_editor_scenario_options_page_holdDownWidgets[page];
pressedWidgets = 0;
setWidgets(window_editor_scenario_options_widgets[page]);
invalidate();
+6 -14
View File
@@ -206,17 +206,6 @@ namespace OpenRCT2::Ui::Windows
static constexpr int32_t kExpenditureColumnWidth = 80;
static constexpr uint32_t _windowFinancesPageHoldDownWidgets[] = {
(1uLL << WIDX_LOAN_INCREASE) | (1uLL << WIDX_LOAN_DECREASE), // WINDOW_FINANCES_PAGE_SUMMARY
0, // WINDOW_FINANCES_PAGE_FINANCIAL_GRAPH
0, // WINDOW_FINANCES_PAGE_VALUE_GRAPH
0, // WINDOW_FINANCES_PAGE_PROFIT_GRAPH
0, // WINDOW_FINANCES_PAGE_MARKETING
0, // WINDOW_FINANCES_PAGE_RESEARCH
};
static_assert(std::size(_windowFinancesPageHoldDownWidgets) == WINDOW_FINANCES_PAGE_COUNT);
static constexpr ScreenCoordsXY kGraphTopLeftPadding{ 88, 20 };
static constexpr ScreenCoordsXY kGraphBottomRightPadding{ 15, 18 };
static constexpr uint8_t kGraphNumYLabels = 5;
@@ -234,7 +223,7 @@ namespace OpenRCT2::Ui::Windows
void SetDisabledTabs()
{
disabledWidgets = (getGameState().park.flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) ? (1uLL << WIDX_TAB_5) : 0;
setWidgetDisabled(WIDX_TAB_5, (getGameState().park.flags & PARK_FLAGS_FORBID_MARKETING_CAMPAIGN) != 0);
}
public:
@@ -525,8 +514,11 @@ namespace OpenRCT2::Ui::Windows
setWidgets(_windowFinancesPageWidgets[p]);
SetDisabledTabs();
holdDownWidgets = _windowFinancesPageHoldDownWidgets[p];
pressedWidgets = 0;
if (p == WINDOW_FINANCES_PAGE_SUMMARY)
widgetsSetHoldable(*this, { WIDX_LOAN_INCREASE, WIDX_LOAN_DECREASE });
widgetSetPressedExclusive(
*this, { WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4, WIDX_TAB_5, WIDX_TAB_6 }, WIDX_TAB_1 + p);
resizeFrame();
onPrepareDraw();
+41 -52
View File
@@ -237,6 +237,7 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(kWindowFootpathWidgets);
widgetsSetHoldable(*this, { WIDX_CONSTRUCT, WIDX_REMOVE });
WindowInitScrollWidgets(*this);
WindowPushOthersRight(*this);
@@ -251,8 +252,6 @@ namespace OpenRCT2::Ui::Windows
_footpathPlaceCtrlState = false;
_footpathPlaceShiftState = false;
holdDownWidgets = (1u << WIDX_CONSTRUCT) | (1u << WIDX_REMOVE);
}
void onClose() override
@@ -527,9 +526,8 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
// Press / unpress footpath and queue type buttons
pressedWidgets &= ~(1uLL << WIDX_FOOTPATH_TYPE);
pressedWidgets &= ~(1uLL << WIDX_QUEUELINE_TYPE);
pressedWidgets |= gFootpathSelection.isQueueSelected ? (1uLL << WIDX_QUEUELINE_TYPE) : (1uLL << WIDX_FOOTPATH_TYPE);
setWidgetPressed(WIDX_FOOTPATH_TYPE, !gFootpathSelection.isQueueSelected);
setWidgetPressed(WIDX_QUEUELINE_TYPE, gFootpathSelection.isQueueSelected);
// Enable / disable construct button
widgets[WIDX_CONSTRUCT].type = _footpathConstructionMode == PathConstructionMode::bridgeOrTunnel
@@ -542,10 +540,7 @@ namespace OpenRCT2::Ui::Windows
{
canDrag = Network::CanPerformAction(Network::GetCurrentPlayerGroupIndex(), Network::Permission::dragPathArea);
}
if (canDrag)
disabledWidgets &= ~(1uLL << WIDX_CONSTRUCT_DRAG_AREA);
else
disabledWidgets |= (1uLL << WIDX_CONSTRUCT_DRAG_AREA);
setWidgetDisabled(WIDX_CONSTRUCT_DRAG_AREA, !canDrag);
#endif
if (gFootpathSelection.legacyPath == kObjectEntryIndexNull)
@@ -1666,53 +1661,47 @@ namespace OpenRCT2::Ui::Windows
_footpathConstructFromPosition.y + CoordsDirectionDelta[direction].y });
}
uint64_t newPressedWidgets = pressedWidgets
& ~((1LL << WIDX_DIRECTION_NW) | (1LL << WIDX_DIRECTION_NE) | (1LL << WIDX_DIRECTION_SW)
| (1LL << WIDX_DIRECTION_SE) | (1LL << WIDX_SLOPEDOWN) | (1LL << WIDX_LEVEL) | (1LL << WIDX_SLOPEUP));
uint64_t newDisabledWidgets = 0;
int32_t currentRotation = GetCurrentRotation();
if (_footpathConstructionMode == PathConstructionMode::bridgeOrTunnel)
{
// Set pressed directional widget
int32_t direction = (_footpathConstructDirection + currentRotation) & 3;
newPressedWidgets |= (1LL << (WIDX_DIRECTION_NW + direction));
const int32_t currentRotation = GetCurrentRotation();
const bool bridgeMode = _footpathConstructionMode == PathConstructionMode::bridgeOrTunnel;
// Set pressed slope widget
switch (_footpathConstructSlope)
{
case SlopePitch::flat:
newPressedWidgets |= (1uLL << WIDX_LEVEL);
break;
case SlopePitch::upwards:
newPressedWidgets |= (1uLL << WIDX_SLOPEUP);
break;
case SlopePitch::downwards:
newPressedWidgets |= (1uLL << WIDX_SLOPEDOWN);
break;
}
// Pressed directional widgets
const int32_t pressedDir = bridgeMode ? ((_footpathConstructDirection + currentRotation) & 3) : -1;
setWidgetPressed(WIDX_DIRECTION_NW, pressedDir == 0);
setWidgetPressed(WIDX_DIRECTION_NE, pressedDir == 1);
setWidgetPressed(WIDX_DIRECTION_SW, pressedDir == 2);
setWidgetPressed(WIDX_DIRECTION_SE, pressedDir == 3);
// Enable / disable directional widgets
direction = _footpathConstructValidDirections;
if (direction != kInvalidDirection)
{
newDisabledWidgets |= (1uLL << WIDX_DIRECTION_NW) | (1uLL << WIDX_DIRECTION_NE)
| (1uLL << WIDX_DIRECTION_SW) | (1uLL << WIDX_DIRECTION_SE);
// Pressed slope widget
setWidgetPressed(WIDX_LEVEL, bridgeMode && _footpathConstructSlope == SlopePitch::flat);
setWidgetPressed(WIDX_SLOPEUP, bridgeMode && _footpathConstructSlope == SlopePitch::upwards);
setWidgetPressed(WIDX_SLOPEDOWN, bridgeMode && _footpathConstructSlope == SlopePitch::downwards);
direction = (direction + currentRotation) & 3;
newDisabledWidgets &= ~(1 << (WIDX_DIRECTION_NW + direction));
}
}
else
{
// Disable all bridge mode widgets
newDisabledWidgets |= (1uLL << WIDX_DIRECTION_GROUP) | (1uLL << WIDX_DIRECTION_NW) | (1uLL << WIDX_DIRECTION_NE)
| (1uLL << WIDX_DIRECTION_SW) | (1uLL << WIDX_DIRECTION_SE) | (1uLL << WIDX_SLOPE_GROUP)
| (1uLL << WIDX_SLOPEDOWN) | (1uLL << WIDX_LEVEL) | (1uLL << WIDX_SLOPEUP) | (1uLL << WIDX_CONSTRUCT)
| (1uLL << WIDX_REMOVE);
}
// Enabled directional widgets
int32_t validDirections = bridgeMode ? _footpathConstructValidDirections : kInvalidDirection;
const int32_t onlyEnabledDir = (bridgeMode && validDirections != kInvalidDirection)
? ((validDirections + currentRotation) & 3)
: -1;
auto directionDisabled = [&](int32_t idx) {
if (!bridgeMode)
return true;
if (onlyEnabledDir < 0)
return false;
return idx != onlyEnabledDir;
};
setWidgetDisabled(WIDX_DIRECTION_NW, directionDisabled(0));
setWidgetDisabled(WIDX_DIRECTION_NE, directionDisabled(1));
setWidgetDisabled(WIDX_DIRECTION_SW, directionDisabled(2));
setWidgetDisabled(WIDX_DIRECTION_SE, directionDisabled(3));
// Bridge-mode group / slope widgets
setWidgetDisabled(WIDX_DIRECTION_GROUP, !bridgeMode);
setWidgetDisabled(WIDX_SLOPE_GROUP, !bridgeMode);
setWidgetDisabled(WIDX_SLOPEDOWN, !bridgeMode);
setWidgetDisabled(WIDX_LEVEL, !bridgeMode);
setWidgetDisabled(WIDX_SLOPEUP, !bridgeMode);
setWidgetDisabled(WIDX_CONSTRUCT, !bridgeMode);
setWidgetDisabled(WIDX_REMOVE, !bridgeMode);
pressedWidgets = newPressedWidgets;
disabledWidgets = newDisabledWidgets;
invalidate();
}
@@ -601,25 +601,25 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_NEWS_LOCATE].type = WidgetType::flatBtn;
widgets[WIDX_MIDDLE_OUTSET].colour = 2;
widgets[WIDX_MIDDLE_INSET].colour = 2;
disabledWidgets &= ~(1uLL << WIDX_NEWS_SUBJECT);
disabledWidgets &= ~(1uLL << WIDX_NEWS_LOCATE);
setWidgetDisabled(WIDX_NEWS_SUBJECT, false);
setWidgetDisabled(WIDX_NEWS_LOCATE, false);
// Find out if the news item is no longer valid
auto subjectLoc = News::GetSubjectLocation(newsItem->type, newsItem->assoc);
if (!subjectLoc.has_value())
disabledWidgets |= (1uLL << WIDX_NEWS_LOCATE);
setWidgetDisabled(WIDX_NEWS_LOCATE, true);
if (!(newsItem->typeHasSubject()))
{
disabledWidgets |= (1uLL << WIDX_NEWS_SUBJECT);
setWidgetDisabled(WIDX_NEWS_SUBJECT, true);
widgets[WIDX_NEWS_SUBJECT].type = WidgetType::empty;
}
if (newsItem->hasButton())
{
disabledWidgets |= (1uLL << WIDX_NEWS_SUBJECT);
disabledWidgets |= (1uLL << WIDX_NEWS_LOCATE);
setWidgetDisabled(WIDX_NEWS_SUBJECT, true);
setWidgetDisabled(WIDX_NEWS_LOCATE, true);
}
}
}
+8 -29
View File
@@ -465,7 +465,7 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDrawCommon()
{
pressedWidgets |= 1uLL << (page + WIDX_TAB_1);
setWidgetPressed(page + WIDX_TAB_1, true);
const auto peep = GetGuest();
if (peep == nullptr)
@@ -486,28 +486,13 @@ namespace OpenRCT2::Ui::Windows
{
return;
}
uint64_t newDisabledWidgets = 0;
if (peep->CanBePickedUp())
{
if (widgetIsDisabled(*this, WIDX_PICKUP))
invalidate();
}
else
{
newDisabledWidgets = (1uLL << WIDX_PICKUP);
if (!widgetIsDisabled(*this, WIDX_PICKUP))
invalidate();
}
if (getGameState().park.flags & PARK_FLAGS_NO_MONEY)
{
newDisabledWidgets |= (1uLL << WIDX_TAB_4); // Disable finance tab if no money
}
if (!Config::Get().general.debuggingTools)
{
newDisabledWidgets |= (1uLL << WIDX_TAB_7); // Disable debug tab when debug tools not turned on
}
disabledWidgets = newDisabledWidgets;
const bool disablePickup = !peep->CanBePickedUp();
if (disablePickup != isWidgetDisabled(WIDX_PICKUP))
invalidate();
setWidgetDisabled(WIDX_PICKUP, disablePickup);
setWidgetDisabled(WIDX_TAB_4, (getGameState().park.flags & PARK_FLAGS_NO_MONEY) != 0);
setWidgetDisabled(WIDX_TAB_7, !Config::Get().general.debuggingTools);
}
void setPage(int32_t newPage)
@@ -533,8 +518,6 @@ namespace OpenRCT2::Ui::Windows
removeViewport();
holdDownWidgets = 0;
pressedWidgets = 0;
setWidgets(_guestWindowPageWidgets[page]);
DisableWidgets();
invalidate();
@@ -870,11 +853,7 @@ namespace OpenRCT2::Ui::Windows
{
return;
}
pressedWidgets &= ~(1uLL << WIDX_TRACK);
if (peep->PeepFlags & PEEP_FLAGS_TRACKING)
{
pressedWidgets |= (1uLL << WIDX_TRACK);
}
setWidgetPressed(WIDX_TRACK, (peep->PeepFlags & PEEP_FLAGS_TRACKING) != 0);
widgets[WIDX_VIEWPORT].right = width - 26;
widgets[WIDX_VIEWPORT].bottom = height - 14;
+2 -9
View File
@@ -89,6 +89,7 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(window_install_track_widgets);
setWidgetPressed(WIDX_TRACK_PREVIEW, true);
WindowInitScrollWidgets(*this);
WindowPushOthersRight(*this);
@@ -139,15 +140,7 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
pressedWidgets |= 1uLL << WIDX_TRACK_PREVIEW;
if (!gTrackDesignSceneryToggle)
{
pressedWidgets |= (1uLL << WIDX_TOGGLE_SCENERY);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_TOGGLE_SCENERY);
}
setWidgetPressed(WIDX_TOGGLE_SCENERY, !gTrackDesignSceneryToggle);
}
void onDraw(RenderTarget& rt) override
+6 -11
View File
@@ -101,7 +101,8 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(window_land_widgets);
holdDownWidgets = (1uLL << WIDX_DECREMENT) | (1uLL << WIDX_INCREMENT);
widgetsSetHoldable(*this, { WIDX_DECREMENT, WIDX_INCREMENT });
setWidgetPressed(WIDX_PREVIEW, true);
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
@@ -246,16 +247,10 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
pressedWidgets = 0;
setWidgetPressed(WIDX_PREVIEW, true);
if (gLandToolTerrainSurface != kObjectEntryIndexNull)
setWidgetPressed(WIDX_FLOOR, true);
if (gLandToolTerrainEdge != kObjectEntryIndexNull)
setWidgetPressed(WIDX_WALL, true);
if (_landToolMountainMode)
setWidgetPressed(WIDX_MOUNTAINMODE, true);
if (_landToolPaintMode)
setWidgetPressed(WIDX_PAINTMODE, true);
setWidgetPressed(WIDX_FLOOR, gLandToolTerrainSurface != kObjectEntryIndexNull);
setWidgetPressed(WIDX_WALL, gLandToolTerrainEdge != kObjectEntryIndexNull);
setWidgetPressed(WIDX_MOUNTAINMODE, _landToolMountainMode);
setWidgetPressed(WIDX_PAINTMODE, _landToolPaintMode);
// Update the preview image (for tool sizes up to 7)
widgets[WIDX_PREVIEW].image = ImageId(LandTool::SizeToSpriteIndex(gLandToolSize));
+6 -2
View File
@@ -107,7 +107,11 @@ namespace OpenRCT2::Ui::Windows
void SwitchToMode(LandRightsMode mode)
{
auto widgetIndex = WIDX_BUY_LAND_RIGHTS + EnumValue(mode);
pressedWidgets = (1uLL << widgetIndex);
widgetSetPressedExclusive(
*this,
{ WIDX_BUY_LAND_RIGHTS, WIDX_BUY_CONSTRUCTION_RIGHTS, WIDX_LAND_OWNED_CHECKBOX, WIDX_LAND_SALE_CHECKBOX,
WIDX_CONSTRUCTION_RIGHTS_OWNED_CHECKBOX, WIDX_CONSTRUCTION_RIGHTS_SALE_CHECKBOX, WIDX_UNOWNED_LAND_CHECKBOX },
widgetIndex);
_landRightsMode = mode;
ToolSet(*this, widgetIndex, Tool::upArrow);
@@ -130,7 +134,7 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(window_land_rights_widgets);
holdDownWidgets = (1uLL << WIDX_INCREMENT) | (1uLL << WIDX_DECREMENT);
widgetsSetHoldable(*this, { WIDX_INCREMENT, WIDX_DECREMENT });
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
+5 -7
View File
@@ -178,7 +178,8 @@ namespace OpenRCT2::Ui::Windows
if (directory.empty() && drives)
{
// List Windows drives
disabledWidgets |= (1uLL << WIDX_NEW_FOLDER) | (1uLL << WIDX_PARENT_FOLDER);
setWidgetDisabled(WIDX_NEW_FOLDER, true);
setWidgetDisabled(WIDX_PARENT_FOLDER, true);
static constexpr auto NumDriveLetters = 26;
for (int32_t x = 0; x < NumDriveLetters; x++)
{
@@ -222,13 +223,10 @@ namespace OpenRCT2::Ui::Windows
}
// Disable the Up button if the current directory is the root directory
if (String::isNullOrEmpty(_parentDirectory) && !drives)
disabledWidgets |= (1uLL << WIDX_PARENT_FOLDER);
else
disabledWidgets &= ~(1uLL << WIDX_PARENT_FOLDER);
setWidgetDisabled(WIDX_PARENT_FOLDER, String::isNullOrEmpty(_parentDirectory) && !drives);
// Re-enable the "new" button if it was disabled
disabledWidgets &= ~(1uLL << WIDX_NEW_FOLDER);
setWidgetDisabled(WIDX_NEW_FOLDER, false);
// List all directories
auto subDirectories = Path::GetDirectories(absoluteDirectory);
@@ -547,7 +545,7 @@ namespace OpenRCT2::Ui::Windows
const auto& uiContext = GetContext()->GetUiContext();
if (!uiContext.HasFilePicker())
{
disabledWidgets |= (1uLL << WIDX_SYSTEM_BROWSER);
setWidgetDisabled(WIDX_SYSTEM_BROWSER, true);
widgets[WIDX_SYSTEM_BROWSER].type = WidgetType::empty;
}
+8 -13
View File
@@ -252,8 +252,10 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(window_map_widgets);
holdDownWidgets = (1uLL << WIDX_MAP_SIZE_SPINNER_Y_UP) | (1uLL << WIDX_MAP_SIZE_SPINNER_Y_DOWN)
| (1uLL << WIDX_MAP_SIZE_SPINNER_X_UP) | (1uLL << WIDX_MAP_SIZE_SPINNER_X_DOWN);
widgetsSetHoldable(
*this,
{ WIDX_MAP_SIZE_SPINNER_Y_UP, WIDX_MAP_SIZE_SPINNER_Y_DOWN, WIDX_MAP_SIZE_SPINNER_X_UP,
WIDX_MAP_SIZE_SPINNER_X_DOWN });
flags |= WindowFlag::resizable;
@@ -613,18 +615,11 @@ namespace OpenRCT2::Ui::Windows
auto* windowMgr = GetWindowManager();
// Set the pressed widgets
pressedWidgets = 0;
setWidgetPressed(WIDX_MAP_SIZE_LINK, _mapWidthAndHeightLinked);
pressedWidgets |= (1uLL << (WIDX_PEOPLE_TAB + selectedTab));
if (windowMgr->FindByClass(WindowClass::editorParkEntrance))
pressedWidgets |= (1uLL << WIDX_BUILD_PARK_ENTRANCE);
if (windowMgr->FindByClass(WindowClass::landRights))
pressedWidgets |= (1uLL << WIDX_SET_LAND_RIGHTS);
if (windowMgr->FindByClass(WindowClass::mapgen))
pressedWidgets |= (1uLL << WIDX_MAP_GENERATOR);
widgetSetPressedExclusive(*this, { WIDX_PEOPLE_TAB, WIDX_RIDES_TAB }, WIDX_PEOPLE_TAB + selectedTab);
setWidgetPressed(WIDX_BUILD_PARK_ENTRANCE, windowMgr->FindByClass(WindowClass::editorParkEntrance) != nullptr);
setWidgetPressed(WIDX_SET_LAND_RIGHTS, windowMgr->FindByClass(WindowClass::landRights) != nullptr);
setWidgetPressed(WIDX_MAP_GENERATOR, windowMgr->FindByClass(WindowClass::mapgen) != nullptr);
// Set disabled widgets
auto& gameState = getGameState();
+35 -81
View File
@@ -183,56 +183,32 @@ namespace OpenRCT2::Ui::Windows
#pragma region Widget flags
// clang-format off
static uint64_t PageDisabledWidgets[WINDOW_MAPGEN_PAGE_COUNT] = {
(1uLL << WIDX_HEIGHTMAP_SMOOTH_HEIGHTMAP) |
(1uLL << WIDX_HEIGHTMAP_STRENGTH) |
(1uLL << WIDX_HEIGHTMAP_STRENGTH_UP) |
(1uLL << WIDX_HEIGHTMAP_STRENGTH_DOWN) |
(1uLL << WIDX_HEIGHTMAP_NORMALIZE),
0,
0,
0
};
static uint64_t HoldDownWidgets[WINDOW_MAPGEN_PAGE_COUNT] = {
(1uLL << WIDX_MAP_SIZE_Y_UP) |
(1uLL << WIDX_MAP_SIZE_Y_DOWN) |
(1uLL << WIDX_MAP_SIZE_X_UP) |
(1uLL << WIDX_MAP_SIZE_X_DOWN) |
(1uLL << WIDX_SIMPLEX_BASE_FREQ_UP) |
(1uLL << WIDX_SIMPLEX_BASE_FREQ_DOWN) |
(1uLL << WIDX_SIMPLEX_OCTAVES_UP) |
(1uLL << WIDX_SIMPLEX_OCTAVES_DOWN) |
(1uLL << WIDX_HEIGHTMAP_STRENGTH_UP) |
(1uLL << WIDX_HEIGHTMAP_STRENGTH_DOWN),
(1uLL << WIDX_HEIGHTMAP_LOW_UP) |
(1uLL << WIDX_HEIGHTMAP_LOW_DOWN) |
(1uLL << WIDX_HEIGHTMAP_HIGH_UP) |
(1uLL << WIDX_HEIGHTMAP_HIGH_DOWN),
(1uLL << WIDX_WATER_LEVEL_UP) |
(1uLL << WIDX_WATER_LEVEL_DOWN),
(1uLL << WIDX_TREE_LAND_RATIO_UP) |
(1uLL << WIDX_TREE_LAND_RATIO_DOWN) |
(1uLL << WIDX_TREE_ALTITUDE_MIN_UP) |
(1uLL << WIDX_TREE_ALTITUDE_MIN_DOWN) |
(1uLL << WIDX_TREE_ALTITUDE_MAX_UP) |
(1uLL << WIDX_TREE_ALTITUDE_MAX_DOWN),
};
static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = {
0,
(1uLL << WIDX_HEIGHTMAP_SMOOTH_TILE_EDGES),
0,
0,
};
// clang-format on
static void setPageHoldableWidgets(WindowBase& w, int32_t page)
{
switch (page)
{
case WINDOW_MAPGEN_PAGE_BASE:
widgetsSetHoldable(
w,
{ WIDX_MAP_SIZE_Y_UP, WIDX_MAP_SIZE_Y_DOWN, WIDX_MAP_SIZE_X_UP, WIDX_MAP_SIZE_X_DOWN,
WIDX_SIMPLEX_BASE_FREQ_UP, WIDX_SIMPLEX_BASE_FREQ_DOWN, WIDX_SIMPLEX_OCTAVES_UP,
WIDX_SIMPLEX_OCTAVES_DOWN, WIDX_HEIGHTMAP_STRENGTH_UP, WIDX_HEIGHTMAP_STRENGTH_DOWN });
break;
case WINDOW_MAPGEN_PAGE_TERRAIN:
widgetsSetHoldable(
w, { WIDX_HEIGHTMAP_LOW_UP, WIDX_HEIGHTMAP_LOW_DOWN, WIDX_HEIGHTMAP_HIGH_UP, WIDX_HEIGHTMAP_HIGH_DOWN });
break;
case WINDOW_MAPGEN_PAGE_WATER:
widgetsSetHoldable(w, { WIDX_WATER_LEVEL_UP, WIDX_WATER_LEVEL_DOWN });
break;
case WINDOW_MAPGEN_PAGE_FORESTS:
widgetsSetHoldable(
w,
{ WIDX_TREE_LAND_RATIO_UP, WIDX_TREE_LAND_RATIO_DOWN, WIDX_TREE_ALTITUDE_MIN_UP,
WIDX_TREE_ALTITUDE_MIN_DOWN, WIDX_TREE_ALTITUDE_MAX_UP, WIDX_TREE_ALTITUDE_MAX_DOWN });
break;
}
}
#pragma endregion
@@ -290,22 +266,14 @@ namespace OpenRCT2::Ui::Windows
removeViewport();
setWidgets(PageWidgets[newPage]);
holdDownWidgets = HoldDownWidgets[newPage];
disabledWidgets = PageDisabledWidgets[newPage];
pressedWidgets = PressedWidgets[newPage];
setPageHoldableWidgets(*this, newPage);
widgetSetPressedExclusive(*this, { WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4 }, WIDX_TAB_1 + newPage);
initScrollWidgets();
invalidate();
onResize();
}
void SetPressedTab()
{
for (auto i = 0; i < WINDOW_MAPGEN_PAGE_COUNT; i++)
pressedWidgets &= ~(1 << (WIDX_TAB_1 + i));
pressedWidgets |= 1LL << (WIDX_TAB_1 + page);
}
void DrawTabImage(RenderTarget& rt, int32_t newPage, int32_t spriteIndex)
{
WidgetIndex widgetIndex = WIDX_TAB_1 + newPage;
@@ -538,16 +506,12 @@ namespace OpenRCT2::Ui::Windows
setWidgetDisabled(WIDX_MAP_SIZE_X_DOWN, isHeightMapImage);
// Enable heightmap widgets if one is loaded
if (isHeightMapImage)
{
setWidgetEnabled(WIDX_HEIGHTMAP_NORMALIZE, _heightmapLoaded);
setWidgetEnabled(WIDX_HEIGHTMAP_SMOOTH_HEIGHTMAP, _heightmapLoaded);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH, _heightmapLoaded && _settings.smooth_height_map);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH_UP, _heightmapLoaded && _settings.smooth_height_map);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH_DOWN, _heightmapLoaded && _settings.smooth_height_map);
}
SetPressedTab();
const bool heightmapEnabled = isHeightMapImage && _heightmapLoaded;
setWidgetEnabled(WIDX_HEIGHTMAP_NORMALIZE, heightmapEnabled);
setWidgetEnabled(WIDX_HEIGHTMAP_SMOOTH_HEIGHTMAP, heightmapEnabled);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH, heightmapEnabled && _settings.smooth_height_map);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH_UP, heightmapEnabled && _settings.smooth_height_map);
setWidgetEnabled(WIDX_HEIGHTMAP_STRENGTH_DOWN, heightmapEnabled && _settings.smooth_height_map);
_xSpinnerCaption = std::to_string(_settings.mapSize.x - 2);
widgets[WIDX_MAP_SIZE_X].setString(_xSpinnerCaption.c_str());
@@ -746,11 +710,7 @@ namespace OpenRCT2::Ui::Windows
void ForestsPrepareDraw()
{
pressedWidgets = 0;
if (_settings.trees)
pressedWidgets |= 1uLL << WIDX_FORESTS_PLACE_TREES;
SetPressedTab();
setWidgetPressed(WIDX_FORESTS_PLACE_TREES, _settings.trees);
const bool isFlatland = _settings.algorithm == MapGenerator::Algorithm::blank;
@@ -1226,7 +1186,6 @@ namespace OpenRCT2::Ui::Windows
// only offer terrain edge smoothing if we don't use flatland terrain
setWidgetEnabled(WIDX_HEIGHTMAP_SMOOTH_TILE_EDGES, _settings.algorithm != MapGenerator::Algorithm::blank);
SetPressedTab();
}
void TerrainDraw(RenderTarget& rt)
@@ -1336,8 +1295,6 @@ namespace OpenRCT2::Ui::Windows
void WaterPrepareDraw()
{
setCheckboxValue(WIDX_ADD_BEACHES, _settings.beaches != 0);
SetPressedTab();
}
void WaterDraw(RenderTarget& rt)
@@ -1366,9 +1323,6 @@ namespace OpenRCT2::Ui::Windows
setPage(WINDOW_MAPGEN_PAGE_BASE);
invalidate();
holdDownWidgets = HoldDownWidgets[WINDOW_MAPGEN_PAGE_BASE];
pressedWidgets = PressedWidgets[WINDOW_MAPGEN_PAGE_BASE];
disabledWidgets = PageDisabledWidgets[WINDOW_MAPGEN_PAGE_BASE];
initScrollWidgets();
_heightmapLoaded = false;
+13 -41
View File
@@ -189,19 +189,17 @@ namespace OpenRCT2::Ui::Windows
| (1uLL << WIDX_MAZE_DIRECTION_SW) | (1uLL << WIDX_MAZE_DIRECTION_SE);
}
// Set and invalidate the changed widgets
uint64_t currentDisabledWidgets = disabledWidgets;
if (currentDisabledWidgets == newDisabledWidgets)
return;
for (WidgetIndex i = 0; i < 64; i++)
// Invalidate only widgets whose disabled state changes.
const auto widgetCount = static_cast<WidgetIndex>(widgets.size());
for (WidgetIndex i = 0; i < widgetCount && i < 64; i++)
{
if ((newDisabledWidgets & (1uLL << i)) != (currentDisabledWidgets & (1uLL << i)))
const bool shouldBeDisabled = (newDisabledWidgets & (1uLL << i)) != 0;
if (isWidgetDisabled(i) != shouldBeDisabled)
{
setWidgetDisabled(i, shouldBeDisabled);
invalidateWidget(i);
}
}
disabledWidgets = newDisabledWidgets;
}
void onMouseDown(WidgetIndex widgetIndex) override
@@ -461,41 +459,15 @@ namespace OpenRCT2::Ui::Windows
if (w == nullptr)
return;
uint64_t newPressedWidgets = w->pressedWidgets;
const bool isEntranceExit = _rideConstructionState == RideConstructionState::EntranceExit;
const bool entranceToolActive = isToolActive(WindowClass::rideConstruction, WIDX_MAZE_ENTRANCE);
// Unpress all the mode buttons
newPressedWidgets &= ~EnumToFlag(WIDX_MAZE_BUILD_MODE);
newPressedWidgets &= ~EnumToFlag(WIDX_MAZE_MOVE_MODE);
newPressedWidgets &= ~EnumToFlag(WIDX_MAZE_FILL_MODE);
newPressedWidgets &= ~EnumToFlag(WIDX_MAZE_ENTRANCE);
newPressedWidgets &= ~EnumToFlag(WIDX_MAZE_EXIT);
widgetSetPressed(*w, WIDX_MAZE_BUILD_MODE, _rideConstructionState == RideConstructionState::MazeBuild);
widgetSetPressed(*w, WIDX_MAZE_MOVE_MODE, _rideConstructionState == RideConstructionState::MazeMove);
widgetSetPressed(*w, WIDX_MAZE_FILL_MODE, _rideConstructionState == RideConstructionState::MazeFill);
widgetSetPressed(*w, WIDX_MAZE_ENTRANCE, isEntranceExit && entranceToolActive);
widgetSetPressed(*w, WIDX_MAZE_EXIT, isEntranceExit && !entranceToolActive);
switch (_rideConstructionState)
{
case RideConstructionState::EntranceExit:
if (isToolActive(WindowClass::rideConstruction, WIDX_MAZE_ENTRANCE))
{
newPressedWidgets |= EnumToFlag(WIDX_MAZE_ENTRANCE);
}
else
{
newPressedWidgets |= EnumToFlag(WIDX_MAZE_EXIT);
}
break;
case RideConstructionState::MazeBuild:
newPressedWidgets |= EnumToFlag(WIDX_MAZE_BUILD_MODE);
break;
case RideConstructionState::MazeMove:
newPressedWidgets |= EnumToFlag(WIDX_MAZE_MOVE_MODE);
break;
case RideConstructionState::MazeFill:
newPressedWidgets |= EnumToFlag(WIDX_MAZE_FILL_MODE);
break;
default:
break;
}
w->pressedWidgets = newPressedWidgets;
w->invalidate();
}
} // namespace OpenRCT2::Ui::Windows
+1 -12
View File
@@ -155,14 +155,6 @@ namespace OpenRCT2::Ui::Windows
uint8_t _selectedGroup{ 0 };
private:
void resetPressedWidgets()
{
for (int32_t i = WIDX_TAB1; i <= WIDX_TAB4; i++)
{
setWidgetPressed(i, false);
}
}
void showGroupDropdown(WidgetIndex widgetIndex)
{
auto widget = &widgets[widgetIndex];
@@ -523,10 +515,9 @@ namespace OpenRCT2::Ui::Windows
numListItems = 0;
selectedListItem = -1;
holdDownWidgets = 0;
pressedWidgets = 0;
setWidgets(window_multiplayer_page_widgets[page]);
widgets[WIDX_TITLE].text = WindowMultiplayerPageTitles[page];
setWidgetPressed(WIDX_TAB1 + page, true);
onResize();
onPrepareDraw();
@@ -654,8 +645,6 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
resetPressedWidgets();
setWidgetPressed(WIDX_TAB1 + page, true);
switch (page)
{
case WINDOW_MULTIPLAYER_PAGE_INFORMATION:
+1 -1
View File
@@ -178,7 +178,7 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(window_new_campaign_widgets);
holdDownWidgets = (1uLL << WIDX_WEEKS_INCREASE_BUTTON) | (1uLL << WIDX_WEEKS_DECREASE_BUTTON);
widgetsSetHoldable(*this, { WIDX_WEEKS_INCREASE_BUTTON, WIDX_WEEKS_DECREASE_BUTTON });
WindowInitScrollWidgets(*this);
}
+4 -16
View File
@@ -411,10 +411,7 @@ namespace OpenRCT2::Ui::Windows
{
SetPressedTab();
if (!Config::Get().interface.listRideVehiclesSeparately)
pressedWidgets |= (1LL << WIDX_GROUP_BY_TRACK_TYPE);
else
pressedWidgets &= ~(1LL << WIDX_GROUP_BY_TRACK_TYPE);
setWidgetPressed(WIDX_GROUP_BY_TRACK_TYPE, !Config::Get().interface.listRideVehiclesSeparately);
widgets[WIDX_TITLE].text = RideTitles[_currentTab];
widgets[WIDX_TAB_7].type = WidgetType::tab;
@@ -815,24 +812,15 @@ namespace OpenRCT2::Ui::Windows
void SetPressedTab()
{
int32_t i{};
for (i = 0; i < TAB_COUNT; i++)
for (int32_t i = 0; i < TAB_COUNT; i++)
{
pressedWidgets &= ~(1 << (WIDX_TAB_1 + i));
setWidgetPressed(WIDX_TAB_1 + i, i == static_cast<int32_t>(_currentTab));
}
pressedWidgets |= 1LL << (WIDX_TAB_1 + static_cast<int32_t>(_currentTab));
}
void RefreshWidgetSizing()
{
if (_currentTab < SHOP_TAB)
{
disabledWidgets &= ~(1 << WIDX_GROUP_BY_TRACK_TYPE);
}
else
{
disabledWidgets |= 1LL << WIDX_GROUP_BY_TRACK_TYPE;
}
setWidgetDisabled(WIDX_GROUP_BY_TRACK_TYPE, _currentTab >= SHOP_TAB);
// Show or hide unrelated widgets
+24 -48
View File
@@ -752,12 +752,12 @@ namespace OpenRCT2::Ui::Windows
{
SetPressedTab();
disabledWidgets = 0;
auto hasFilePicker = GetContext()->GetUiContext().HasFilePicker();
const bool advancedTabSelected = (WIDX_FIRST_TAB + page) == WIDX_TAB_ADVANCED;
if (!hasFilePicker && advancedTabSelected)
const bool disableAlwaysNative = !hasFilePicker && advancedTabSelected;
setWidgetDisabled(WIDX_ALWAYS_NATIVE_LOADSAVE, disableAlwaysNative);
if (disableAlwaysNative)
{
disabledWidgets |= (1uLL << WIDX_ALWAYS_NATIVE_LOADSAVE);
widgets[WIDX_ALWAYS_NATIVE_LOADSAVE].type = WidgetType::empty;
}
}
@@ -990,18 +990,11 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_RESOLUTION].setString(_dropdownCaption.c_str());
// Disable resolution dropdown on "Windowed" and "Fullscreen (desktop)"
if (Config::Get().general.fullscreenMode != static_cast<int32_t>(FullscreenMode::fullscreen))
{
disabledWidgets |= (1uLL << WIDX_RESOLUTION_DROPDOWN);
disabledWidgets |= (1uLL << WIDX_RESOLUTION);
disabledWidgets |= (1uLL << WIDX_RESOLUTION_LABEL);
}
else
{
disabledWidgets &= ~(1uLL << WIDX_RESOLUTION_DROPDOWN);
disabledWidgets &= ~(1uLL << WIDX_RESOLUTION);
disabledWidgets &= ~(1uLL << WIDX_RESOLUTION_LABEL);
}
const bool disableResolution = Config::Get().general.fullscreenMode
!= static_cast<int32_t>(FullscreenMode::fullscreen);
setWidgetDisabled(WIDX_RESOLUTION_DROPDOWN, disableResolution);
setWidgetDisabled(WIDX_RESOLUTION, disableResolution);
setWidgetDisabled(WIDX_RESOLUTION_LABEL, disableResolution);
setCheckboxValue(WIDX_SHOW_FPS_CHECKBOX, Config::Get().general.showFPS);
setCheckboxValue(WIDX_MULTITHREADING_CHECKBOX, Config::Get().general.multiThreading);
@@ -1154,43 +1147,26 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_VIRTUAL_FLOOR].text = _virtualFloorStyleStrings[EnumValue(Config::Get().general.virtualFloorStyle)];
setCheckboxValue(WIDX_ENABLE_LIGHT_FX_CHECKBOX, Config::Get().general.enableLightFx);
if (Config::Get().general.dayNightCycle
&& Config::Get().general.drawingEngine == DrawingEngine::SoftwareWithHardwareDisplay)
{
disabledWidgets &= ~(1uLL << WIDX_ENABLE_LIGHT_FX_CHECKBOX);
}
else
{
disabledWidgets |= (1uLL << WIDX_ENABLE_LIGHT_FX_CHECKBOX);
const bool lightFxEnabled = Config::Get().general.dayNightCycle
&& Config::Get().general.drawingEngine == DrawingEngine::SoftwareWithHardwareDisplay;
setWidgetDisabled(WIDX_ENABLE_LIGHT_FX_CHECKBOX, !lightFxEnabled);
if (!lightFxEnabled)
Config::Get().general.enableLightFx = false;
}
setCheckboxValue(WIDX_ENABLE_LIGHT_FX_FOR_VEHICLES_CHECKBOX, Config::Get().general.enableLightFxForVehicles);
if (Config::Get().general.dayNightCycle
&& Config::Get().general.drawingEngine == DrawingEngine::SoftwareWithHardwareDisplay
&& Config::Get().general.enableLightFx)
{
disabledWidgets &= ~(1uLL << WIDX_ENABLE_LIGHT_FX_FOR_VEHICLES_CHECKBOX);
}
else
{
disabledWidgets |= (1uLL << WIDX_ENABLE_LIGHT_FX_FOR_VEHICLES_CHECKBOX);
const bool lightFxForVehiclesEnabled = lightFxEnabled && Config::Get().general.enableLightFx;
setWidgetDisabled(WIDX_ENABLE_LIGHT_FX_FOR_VEHICLES_CHECKBOX, !lightFxForVehiclesEnabled);
if (!lightFxForVehiclesEnabled)
Config::Get().general.enableLightFxForVehicles = false;
}
setCheckboxValue(
WIDX_RENDER_WEATHER_EFFECTS_CHECKBOX,
Config::Get().general.renderWeatherEffects || Config::Get().general.renderWeatherGloom);
setCheckboxValue(WIDX_DISABLE_LIGHTNING_EFFECT_CHECKBOX, Config::Get().general.disableLightningEffect);
if (!Config::Get().general.renderWeatherEffects && !Config::Get().general.renderWeatherGloom)
{
const bool noWeather = !Config::Get().general.renderWeatherEffects && !Config::Get().general.renderWeatherGloom;
if (noWeather)
setCheckboxValue(WIDX_DISABLE_LIGHTNING_EFFECT_CHECKBOX, true);
disabledWidgets |= (1uLL << WIDX_DISABLE_LIGHTNING_EFFECT_CHECKBOX);
}
else
{
disabledWidgets &= ~(1uLL << WIDX_DISABLE_LIGHTNING_EFFECT_CHECKBOX);
}
setWidgetDisabled(WIDX_DISABLE_LIGHTNING_EFFECT_CHECKBOX, noWeather);
}
#pragma endregion
@@ -2005,9 +1981,12 @@ namespace OpenRCT2::Ui::Windows
// The real name setting of clients is fixed to that of the server
// and the server cannot change the setting during gameplay to prevent desyncs
if (Network::GetMode() != Network::Mode::none)
const bool inNetwork = Network::GetMode() != Network::Mode::none;
setWidgetDisabled(WIDX_REAL_NAMES_GUESTS_CHECKBOX, inNetwork);
setWidgetDisabled(WIDX_REAL_NAMES_STAFF_CHECKBOX, inNetwork);
setWidgetDisabled(WIDX_ALLOW_EARLY_COMPLETION, Network::GetMode() == Network::Mode::client);
if (inNetwork)
{
disabledWidgets |= (1uLL << WIDX_REAL_NAMES_GUESTS_CHECKBOX) | (1uLL << WIDX_REAL_NAMES_STAFF_CHECKBOX);
widgets[WIDX_REAL_NAMES_GUESTS_CHECKBOX].tooltip = STR_OPTION_DISABLED_DURING_NETWORK_PLAY;
widgets[WIDX_REAL_NAMES_STAFF_CHECKBOX].tooltip = STR_OPTION_DISABLED_DURING_NETWORK_PLAY;
@@ -2016,7 +1995,6 @@ namespace OpenRCT2::Ui::Windows
// the way scenarios are completed during this network-session
if (Network::GetMode() == Network::Mode::client)
{
disabledWidgets |= (1uLL << WIDX_ALLOW_EARLY_COMPLETION);
widgets[WIDX_ALLOW_EARLY_COMPLETION].tooltip = STR_OPTION_DISABLED_DURING_NETWORK_PLAY;
}
}
@@ -2270,7 +2248,6 @@ namespace OpenRCT2::Ui::Windows
page = p;
currentFrame = 0;
pressedWidgets = 0;
setWidgets(window_options_page_widgets[page]);
invalidate();
@@ -2283,8 +2260,7 @@ namespace OpenRCT2::Ui::Windows
void SetPressedTab()
{
for (int32_t i = 0; i < WINDOW_OPTIONS_PAGE_COUNT; i++)
pressedWidgets &= ~(1 << (WIDX_FIRST_TAB + i));
pressedWidgets |= 1LL << (WIDX_FIRST_TAB + page);
setWidgetPressed(WIDX_FIRST_TAB + i, i == page);
}
void ShowDropdown(Widget* widget, int32_t num_items)
+10 -22
View File
@@ -161,19 +161,6 @@ namespace OpenRCT2::Ui::Windows
#pragma endregion
// clang-format off
static std::array<uint32_t, WINDOW_PARK_PAGE_COUNT> _pagedHoldDownWidgets = {
0,
0,
0,
(1uLL << WIDX_INCREASE_PRICE) |
(1uLL << WIDX_DECREASE_PRICE),
0,
0,
0,
};
// clang-format on
class ParkWindow final : public Window
{
int32_t _numberOfStaff = -1;
@@ -401,7 +388,7 @@ namespace OpenRCT2::Ui::Windows
void SetDisabledTabs()
{
// Disable price tab if money is disabled
disabledWidgets = (getGameState().park.flags & PARK_FLAGS_NO_MONEY) ? (1uLL << WIDX_TAB_4) : 0;
setWidgetDisabled(WIDX_TAB_4, (getGameState().park.flags & PARK_FLAGS_NO_MONEY) != 0);
}
void PrepareWindowTitleText()
@@ -518,10 +505,10 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_OPEN_LIGHT].image = ImageId(openLightImage);
// only allow closing of park for guest / rating objective
if (gameState.scenarioOptions.objective.Type == Scenario::ObjectiveType::guestsAndRating)
disabledWidgets |= (1uLL << WIDX_OPEN_OR_CLOSE) | (1uLL << WIDX_CLOSE_LIGHT) | (1uLL << WIDX_OPEN_LIGHT);
else
disabledWidgets &= ~((1uLL << WIDX_OPEN_OR_CLOSE) | (1uLL << WIDX_CLOSE_LIGHT) | (1uLL << WIDX_OPEN_LIGHT));
const bool disableOpenClose = gameState.scenarioOptions.objective.Type == Scenario::ObjectiveType::guestsAndRating;
setWidgetDisabled(WIDX_OPEN_OR_CLOSE, disableOpenClose);
setWidgetDisabled(WIDX_CLOSE_LIGHT, disableOpenClose);
setWidgetDisabled(WIDX_OPEN_LIGHT, disableOpenClose);
// only allow purchase of land when there is money
if (gameState.park.flags & PARK_FLAGS_NO_MONEY)
@@ -1181,8 +1168,9 @@ namespace OpenRCT2::Ui::Windows
_peepAnimationFrame = 0;
removeViewport();
holdDownWidgets = _pagedHoldDownWidgets[newPage];
setWidgets(_pagedWidgets[newPage]);
if (newPage == WINDOW_PARK_PAGE_PRICE)
widgetsSetHoldable(*this, { WIDX_INCREASE_PRICE, WIDX_DECREASE_PRICE });
SetDisabledTabs();
invalidate();
initScrollWidgets();
@@ -1204,9 +1192,9 @@ namespace OpenRCT2::Ui::Windows
void SetPressedTab()
{
for (int32_t i = WIDX_TAB_1; i <= WIDX_TAB_7; i++)
pressedWidgets &= ~(1 << i);
pressedWidgets |= 1LL << (WIDX_TAB_1 + page);
widgetSetPressedExclusive(
*this, { WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4, WIDX_TAB_5, WIDX_TAB_6, WIDX_TAB_7 },
WIDX_TAB_1 + page);
}
void DrawTabImages(RenderTarget& rt)
+1 -1
View File
@@ -62,7 +62,7 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(PatrolAreaWidgets);
holdDownWidgets = (1uLL << WIDX_INCREMENT) | (1uLL << WIDX_DECREMENT);
widgetsSetHoldable(*this, { WIDX_INCREMENT, WIDX_DECREMENT });
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
gLandToolSize = 4;
+2 -10
View File
@@ -106,8 +106,6 @@ namespace OpenRCT2::Ui::Windows
WindowSetResize(*this, { 210, 134 }, { 500, 450 });
holdDownWidgets = 0;
pressedWidgets = 0;
setPage(WINDOW_PLAYER_PAGE_OVERVIEW);
}
@@ -222,8 +220,6 @@ namespace OpenRCT2::Ui::Windows
page = newPage;
currentFrame = 0;
holdDownWidgets = 0;
pressedWidgets = 0;
setWidgets(window_player_page_widgets[newPage]);
invalidate();
onResize();
@@ -378,9 +374,7 @@ namespace OpenRCT2::Ui::Windows
return;
}
pressedWidgets &= ~(WIDX_TAB_1);
pressedWidgets &= ~(WIDX_TAB_2);
pressedWidgets |= 1uLL << (page + WIDX_TAB_1);
widgetSetPressedExclusive(*this, { WIDX_TAB_1, WIDX_TAB_2 }, page + WIDX_TAB_1);
UpdateTitle();
@@ -589,9 +583,7 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDrawStatistics()
{
pressedWidgets &= ~(WIDX_TAB_1);
pressedWidgets &= ~(WIDX_TAB_2);
pressedWidgets |= 1uLL << (page + WIDX_TAB_1);
widgetSetPressedExclusive(*this, { WIDX_TAB_1, WIDX_TAB_2 }, page + WIDX_TAB_1);
UpdateTitle();
+4 -21
View File
@@ -148,9 +148,6 @@ namespace OpenRCT2::Ui::Windows
invalidate();
setWidgets(window_research_page_widgets[newPageIndex]);
holdDownWidgets = 0;
disabledWidgets = 0;
pressedWidgets = 0;
}
private:
@@ -555,24 +552,10 @@ namespace OpenRCT2::Ui::Windows
for (int32_t i = 0; i < 7; i++)
{
int32_t mask = 1 << i;
int32_t widgetMask = 1uLL << (i + WIDX_TRANSPORT_RIDES + widgetOffset);
// Set checkbox disabled if research type is complete
if (uncompletedResearchTypes & mask)
{
w->disabledWidgets &= ~widgetMask;
// Set checkbox ticked if research type is active
if (activeResearchTypes & mask)
w->pressedWidgets |= widgetMask;
else
w->pressedWidgets &= ~widgetMask;
}
else
{
w->disabledWidgets |= widgetMask;
w->pressedWidgets &= ~widgetMask;
}
const WidgetIndex widgetIdx = static_cast<WidgetIndex>(i + WIDX_TRANSPORT_RIDES + widgetOffset);
const bool uncompleted = (uncompletedResearchTypes & mask) != 0;
widgetSetDisabled(*w, widgetIdx, !uncompleted);
widgetSetPressed(*w, widgetIdx, uncompleted && (activeResearchTypes & mask) != 0);
}
}
+106 -160
View File
@@ -428,36 +428,35 @@ namespace OpenRCT2::Ui::Windows
};
static_assert(std::size(PageWidgets) == WINDOW_RIDE_PAGE_COUNT);
static constexpr std::array PageHoldDownWidgets = {
0uLL,
(1uLL << WIDX_VEHICLE_TRAINS_INCREASE) |
(1uLL << WIDX_VEHICLE_TRAINS_DECREASE) |
(1uLL << WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE) |
(1uLL << WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE),
(1uLL << WIDX_MODE_TWEAK_INCREASE) |
(1uLL << WIDX_MODE_TWEAK_DECREASE) |
(1uLL << WIDX_LIFT_HILL_SPEED_INCREASE) |
(1uLL << WIDX_LIFT_HILL_SPEED_DECREASE) |
(1uLL << WIDX_MINIMUM_LENGTH_INCREASE) |
(1uLL << WIDX_MINIMUM_LENGTH_DECREASE) |
(1uLL << WIDX_MAXIMUM_LENGTH_INCREASE) |
(1uLL << WIDX_MAXIMUM_LENGTH_DECREASE) |
(1uLL << WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE) |
(1uLL << WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE),
0uLL,
0uLL,
0uLL,
0uLL,
0uLL,
(1uLL << WIDX_PRIMARY_PRICE_INCREASE) |
(1uLL << WIDX_PRIMARY_PRICE_DECREASE) |
(1uLL << WIDX_SECONDARY_PRICE_INCREASE) |
(1uLL << WIDX_SECONDARY_PRICE_DECREASE),
0uLL,
};
static_assert(std::size(PageHoldDownWidgets) == WINDOW_RIDE_PAGE_COUNT);
// clang-format on
static void setPageHoldableWidgets(WindowBase& w, int32_t page)
{
switch (page)
{
case WINDOW_RIDE_PAGE_VEHICLE:
widgetsSetHoldable(
w,
{ WIDX_VEHICLE_TRAINS_INCREASE, WIDX_VEHICLE_TRAINS_DECREASE, WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE,
WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE });
break;
case WINDOW_RIDE_PAGE_OPERATING:
widgetsSetHoldable(
w,
{ WIDX_MODE_TWEAK_INCREASE, WIDX_MODE_TWEAK_DECREASE, WIDX_LIFT_HILL_SPEED_INCREASE,
WIDX_LIFT_HILL_SPEED_DECREASE, WIDX_MINIMUM_LENGTH_INCREASE, WIDX_MINIMUM_LENGTH_DECREASE,
WIDX_MAXIMUM_LENGTH_INCREASE, WIDX_MAXIMUM_LENGTH_DECREASE, WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE,
WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE });
break;
case WINDOW_RIDE_PAGE_INCOME:
widgetsSetHoldable(
w,
{ WIDX_PRIMARY_PRICE_INCREASE, WIDX_PRIMARY_PRICE_DECREASE, WIDX_SECONDARY_PRICE_INCREASE,
WIDX_SECONDARY_PRICE_DECREASE });
break;
}
}
#pragma endregion
static void CancelScenerySelection();
@@ -778,7 +777,6 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(PageWidgets[WINDOW_RIDE_PAGE_MAIN]);
holdDownWidgets = PageHoldDownWidgets[WINDOW_RIDE_PAGE_MAIN];
setPage(WINDOW_RIDE_PAGE_MAIN);
listInformationType = 0;
@@ -1212,9 +1210,13 @@ namespace OpenRCT2::Ui::Windows
removeViewport();
holdDownWidgets = PageHoldDownWidgets[page];
pressedWidgets = 0;
setWidgets(PageWidgets[page]);
setPageHoldableWidgets(*this, page);
widgetSetPressedExclusive(
*this,
{ WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4, WIDX_TAB_5, WIDX_TAB_6, WIDX_TAB_7, WIDX_TAB_8, WIDX_TAB_9,
WIDX_TAB_10 },
WIDX_TAB_1 + page);
DisableTabs();
invalidate();
@@ -1393,57 +1395,43 @@ namespace OpenRCT2::Ui::Windows
void DisableTabs()
{
uint32_t disabledTabs = 0;
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
const auto& rtd = ride->getRideTypeDescriptor();
if (!rtd.flags.has(RtdFlag::hasDataLogging))
disabledTabs |= (1uLL << WIDX_TAB_8); // 0x800
if (rtd.specialType == RtdSpecialType::miniGolf)
disabledTabs |= (1uLL << WIDX_TAB_2 | 1uLL << WIDX_TAB_3 | 1uLL << WIDX_TAB_4); // 0xE0
if (rtd.flags.has(RtdFlag::noVehicles))
disabledTabs |= (1uLL << WIDX_TAB_2); // 0x20
if (!rtd.flags.hasAny(
RtdFlag::hasTrackColourMain, RtdFlag::hasTrackColourAdditional, RtdFlag::hasTrackColourSupports,
RtdFlag::hasVehicleColours, RtdFlag::hasEntranceAndExit))
{
disabledTabs |= (1uLL << WIDX_TAB_5); // 0x100
}
if (rtd.flags.has(RtdFlag::isShopOrFacility))
disabledTabs |= (1uLL << WIDX_TAB_3 | 1uLL << WIDX_TAB_4 | 1uLL << WIDX_TAB_7); // 0x4C0
if (!rtd.flags.has(RtdFlag::allowMusic))
{
disabledTabs |= (1uLL << WIDX_TAB_6); // 0x200
}
if (rtd.specialType == RtdSpecialType::cashMachine || rtd.specialType == RtdSpecialType::firstAid
|| (getGameState().park.flags & PARK_FLAGS_NO_MONEY) != 0)
disabledTabs |= (1uLL << WIDX_TAB_9); // 0x1000
if (gLegacyScene == LegacyScene::trackDesigner)
disabledTabs |= (1uLL << WIDX_TAB_4 | 1uLL << WIDX_TAB_6 | 1uLL << WIDX_TAB_9 | 1uLL << WIDX_TAB_10); // 0x3280
const auto* rideEntry = GetRideEntryByIndex(ride->subtype);
const bool noRideEntry = rideEntry == nullptr;
if (rideEntry == nullptr)
{
disabledTabs |= 1uLL << WIDX_TAB_2 | 1uLL << WIDX_TAB_3 | 1uLL << WIDX_TAB_4 | 1uLL << WIDX_TAB_5
| 1uLL << WIDX_TAB_6 | 1uLL << WIDX_TAB_7 | 1uLL << WIDX_TAB_8 | 1uLL << WIDX_TAB_9 | 1uLL << WIDX_TAB_10;
}
else if (rideEntry->flags.has(RideEntryFlag::disableColourTab))
{
disabledTabs |= (1uLL << WIDX_TAB_5);
}
const bool disableTab2 = noRideEntry || rtd.specialType == RtdSpecialType::miniGolf
|| rtd.flags.has(RtdFlag::noVehicles);
const bool disableTab3 = noRideEntry || rtd.specialType == RtdSpecialType::miniGolf
|| rtd.flags.has(RtdFlag::isShopOrFacility);
const bool disableTab4 = noRideEntry || rtd.specialType == RtdSpecialType::miniGolf
|| rtd.flags.has(RtdFlag::isShopOrFacility) || gLegacyScene == LegacyScene::trackDesigner;
const bool disableTab5 = noRideEntry
|| !rtd.flags.hasAny(
RtdFlag::hasTrackColourMain, RtdFlag::hasTrackColourAdditional, RtdFlag::hasTrackColourSupports,
RtdFlag::hasVehicleColours, RtdFlag::hasEntranceAndExit)
|| (!noRideEntry && rideEntry->flags.has(RideEntryFlag::disableColourTab));
const bool disableTab6 = noRideEntry || !rtd.flags.has(RtdFlag::allowMusic)
|| gLegacyScene == LegacyScene::trackDesigner;
const bool disableTab7 = noRideEntry || rtd.flags.has(RtdFlag::isShopOrFacility);
const bool disableTab8 = noRideEntry || !rtd.flags.has(RtdFlag::hasDataLogging);
const bool disableTab9 = noRideEntry || rtd.specialType == RtdSpecialType::cashMachine
|| rtd.specialType == RtdSpecialType::firstAid || (getGameState().park.flags & PARK_FLAGS_NO_MONEY) != 0
|| gLegacyScene == LegacyScene::trackDesigner;
const bool disableTab10 = noRideEntry || gLegacyScene == LegacyScene::trackDesigner;
disabledWidgets = disabledTabs;
setWidgetDisabled(WIDX_TAB_2, disableTab2);
setWidgetDisabled(WIDX_TAB_3, disableTab3);
setWidgetDisabled(WIDX_TAB_4, disableTab4);
setWidgetDisabled(WIDX_TAB_5, disableTab5);
setWidgetDisabled(WIDX_TAB_6, disableTab6);
setWidgetDisabled(WIDX_TAB_7, disableTab7);
setWidgetDisabled(WIDX_TAB_8, disableTab8);
setWidgetDisabled(WIDX_TAB_9, disableTab9);
setWidgetDisabled(WIDX_TAB_10, disableTab10);
}
void UpdateOverallView(const Ride& ride) const
@@ -1507,13 +1495,6 @@ namespace OpenRCT2::Ui::Windows
}
}
void SetPressedTab()
{
for (int32_t i = 0; i < WINDOW_RIDE_PAGE_COUNT; i++)
pressedWidgets &= ~(1 << (WIDX_TAB_1 + i));
pressedWidgets |= 1LL << (WIDX_TAB_1 + page);
}
#pragma region Main
std::optional<StationIndex> GetStationIndexFromViewSelection() const
@@ -2424,17 +2405,16 @@ namespace OpenRCT2::Ui::Windows
{
int32_t i, widgetHeight;
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
const auto& gameState = getGameState();
disabledWidgets &= ~((1uLL << WIDX_DEMOLISH) | (1uLL << WIDX_CONSTRUCTION));
if (ride->flags.hasAny(RideFlag::indestructible, RideFlag::indestructibleTrack)
&& !gameState.cheats.makeAllDestructible)
disabledWidgets |= (1uLL << WIDX_DEMOLISH);
setWidgetDisabled(WIDX_CONSTRUCTION, false);
setWidgetDisabled(
WIDX_DEMOLISH,
ride->flags.hasAny(RideFlag::indestructible, RideFlag::indestructibleTrack)
&& !gameState.cheats.makeAllDestructible);
uint32_t spriteIds[] = {
SPR_CLOSED,
@@ -2874,8 +2854,6 @@ namespace OpenRCT2::Ui::Windows
void VehicleOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
@@ -2922,14 +2900,7 @@ namespace OpenRCT2::Ui::Windows
|| (gameState.cheats.disableTrainLengthLimit && !ride->getRideTypeDescriptor().flags.has(RtdFlag::isFlatRide)))
{
widgets[WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX].type = WidgetType::checkbox;
if (ride->flags.has(RideFlag::reversedTrains))
{
pressedWidgets |= (1uLL << WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX);
}
setWidgetPressed(WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX, ride->flags.has(RideFlag::reversedTrains));
}
else
{
@@ -3555,17 +3526,16 @@ namespace OpenRCT2::Ui::Windows
{
StringId format, caption, tooltip;
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
// Widget setup
pressedWidgets &= ~(
(1uLL << WIDX_LOAD_CHECKBOX) | (1uLL << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX)
| (1uLL << WIDX_MINIMUM_LENGTH_CHECKBOX) | (1uLL << WIDX_MAXIMUM_LENGTH_CHECKBOX)
| (1uLL << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX));
setWidgetPressed(WIDX_LOAD_CHECKBOX, false);
setWidgetPressed(WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX, false);
setWidgetPressed(WIDX_MINIMUM_LENGTH_CHECKBOX, false);
setWidgetPressed(WIDX_MAXIMUM_LENGTH_CHECKBOX, false);
setWidgetPressed(WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX, false);
// Sometimes, only one of the alternatives support lift hill pieces. Make sure to check both.
const auto& rtd = ride->getRideTypeDescriptor();
@@ -3661,7 +3631,7 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_MAXIMUM_LENGTH].setString(_spinnerCaption4.c_str());
if (ride->departFlags & RIDE_DEPART_WAIT_FOR_LOAD)
pressedWidgets |= (1uLL << WIDX_LOAD_CHECKBOX);
setWidgetPressed(WIDX_LOAD_CHECKBOX, true);
}
else
{
@@ -3681,13 +3651,13 @@ namespace OpenRCT2::Ui::Windows
}
if (ride->departFlags & RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES)
pressedWidgets |= (1uLL << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX);
setWidgetPressed(WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX, true);
if (ride->departFlags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)
pressedWidgets |= (1uLL << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX);
setWidgetPressed(WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX, true);
if (ride->departFlags & RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH)
pressedWidgets |= (1uLL << WIDX_MINIMUM_LENGTH_CHECKBOX);
setWidgetPressed(WIDX_MINIMUM_LENGTH_CHECKBOX, true);
if (ride->departFlags & RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH)
pressedWidgets |= (1uLL << WIDX_MAXIMUM_LENGTH_CHECKBOX);
setWidgetPressed(WIDX_MAXIMUM_LENGTH_CHECKBOX, true);
// Mode specific functionality
auto multiplier = ride->getRideTypeDescriptor().OperatingSettings.OperatingSettingMultiplier;
@@ -3752,7 +3722,7 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_MODE_TWEAK].setString(_spinnerCaption0.c_str());
widgets[WIDX_MODE_TWEAK_INCREASE].type = WidgetType::button;
widgets[WIDX_MODE_TWEAK_DECREASE].type = WidgetType::button;
pressedWidgets &= ~(1uLL << WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX);
setWidgetPressed(WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX, false);
}
else
{
@@ -4070,8 +4040,6 @@ namespace OpenRCT2::Ui::Windows
void MaintenanceOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
@@ -4091,12 +4059,12 @@ namespace OpenRCT2::Ui::Windows
if (ride->getRideTypeDescriptor().availableBreakdowns.isEmpty() || !ride->flags.has(RideFlag::everBeenOpened))
{
disabledWidgets |= (1uLL << WIDX_REFURBISH_RIDE);
setWidgetDisabled(WIDX_REFURBISH_RIDE, true);
widgets[WIDX_REFURBISH_RIDE].tooltip = STR_CANT_REFURBISH_NOT_NEEDED;
}
else
{
disabledWidgets &= ~(1uLL << WIDX_REFURBISH_RIDE);
setWidgetDisabled(WIDX_REFURBISH_RIDE, false);
widgets[WIDX_REFURBISH_RIDE].tooltip = STR_REFURBISH_RIDE_TIP;
}
}
@@ -4651,7 +4619,6 @@ namespace OpenRCT2::Ui::Windows
void ColourOnPrepareDraw()
{
SetPressedTab();
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_10);
auto ride = GetRide(rideId);
@@ -4736,14 +4703,7 @@ namespace OpenRCT2::Ui::Windows
if (ride->hasRecolourableShopItems())
{
widgets[WIDX_SELL_ITEM_RANDOM_COLOUR_CHECKBOX].type = WidgetType::checkbox;
if (ride->flags.has(RideFlag::randomShopColours))
{
pressedWidgets |= (1uLL << WIDX_SELL_ITEM_RANDOM_COLOUR_CHECKBOX);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_SELL_ITEM_RANDOM_COLOUR_CHECKBOX);
}
setWidgetPressed(WIDX_SELL_ITEM_RANDOM_COLOUR_CHECKBOX, ride->flags.has(RideFlag::randomShopColours));
}
else
{
@@ -5386,8 +5346,6 @@ namespace OpenRCT2::Ui::Windows
void MusicOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
@@ -5427,14 +5385,19 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_MUSIC_DATA].right = width - 8;
}
pressedWidgets |= (1uLL << WIDX_PLAY_MUSIC) | (1uLL << WIDX_MUSIC_IMAGE);
disabledWidgets &= ~((1uLL << WIDX_MUSIC) | (1uLL << WIDX_MUSIC_DROPDOWN) | (1uLL << WIDX_MUSIC_DATA));
setWidgetPressed(WIDX_PLAY_MUSIC, true);
setWidgetPressed(WIDX_MUSIC_IMAGE, true);
setWidgetDisabled(WIDX_MUSIC, false);
setWidgetDisabled(WIDX_MUSIC_DROPDOWN, false);
setWidgetDisabled(WIDX_MUSIC_DATA, false);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_PLAY_MUSIC);
pressedWidgets |= (1uLL << WIDX_MUSIC_IMAGE);
disabledWidgets |= (1uLL << WIDX_MUSIC) | (1uLL << WIDX_MUSIC_DROPDOWN) | (1uLL << WIDX_MUSIC_DATA);
setWidgetPressed(WIDX_PLAY_MUSIC, false);
setWidgetPressed(WIDX_MUSIC_IMAGE, true);
setWidgetDisabled(WIDX_MUSIC, true);
setWidgetDisabled(WIDX_MUSIC_DROPDOWN, true);
setWidgetDisabled(WIDX_MUSIC_DATA, true);
}
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_10);
@@ -5779,8 +5742,6 @@ namespace OpenRCT2::Ui::Windows
void MeasurementsOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
@@ -5802,15 +5763,10 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_CANCEL_DESIGN].type = WidgetType::empty;
widgets[WIDX_SAVE_TRACK_DESIGN].type = WidgetType::flatBtn;
disabledWidgets |= (1uLL << WIDX_SAVE_TRACK_DESIGN);
if (ride->flags.has(RideFlag::tested))
{
if (!ride->ratings.isNull())
{
disabledWidgets &= ~(1uLL << WIDX_SAVE_TRACK_DESIGN);
widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN;
}
}
const bool canSaveTrackDesign = ride->flags.has(RideFlag::tested) && !ride->ratings.isNull();
setWidgetDisabled(WIDX_SAVE_TRACK_DESIGN, !canSaveTrackDesign);
if (canSaveTrackDesign)
widgets[WIDX_SAVE_TRACK_DESIGN].tooltip = STR_SAVE_TRACK_DESIGN;
}
WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_10);
@@ -6211,18 +6167,14 @@ namespace OpenRCT2::Ui::Windows
void GraphsOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
// Set pressed graph button type
pressedWidgets &= ~(1uLL << WIDX_GRAPH_VELOCITY);
pressedWidgets &= ~(1uLL << WIDX_GRAPH_ALTITUDE);
pressedWidgets &= ~(1uLL << WIDX_GRAPH_VERTICAL);
pressedWidgets &= ~(1uLL << WIDX_GRAPH_LATERAL);
pressedWidgets |= (1LL << (WIDX_GRAPH_VELOCITY + listInformationType));
widgetSetPressedExclusive(
*this, { WIDX_GRAPH_VELOCITY, WIDX_GRAPH_ALTITUDE, WIDX_GRAPH_VERTICAL, WIDX_GRAPH_LATERAL },
WIDX_GRAPH_VELOCITY + listInformationType);
// Hide graph buttons that are not applicable
if (ride->getRideTypeDescriptor().flags.has(RtdFlag::hasGForces))
@@ -6720,8 +6672,6 @@ namespace OpenRCT2::Ui::Windows
void IncomeOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride == nullptr)
return;
@@ -6731,8 +6681,7 @@ namespace OpenRCT2::Ui::Windows
return;
// Primary item
pressedWidgets &= ~(1uLL << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK);
disabledWidgets &= ~(1uLL << WIDX_PRIMARY_PRICE);
setWidgetPressed(WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK, false);
widgets[WIDX_PRIMARY_PRICE_LABEL].tooltip = kStringIdNone;
widgets[WIDX_PRIMARY_PRICE].tooltip = kStringIdNone;
@@ -6741,10 +6690,11 @@ namespace OpenRCT2::Ui::Windows
// If ride prices are locked, do not allow setting the price, unless we're dealing with a shop or toilet.
const auto& rtd = ride->getRideTypeDescriptor();
if (!Park::RidePricesUnlocked(park) && rideEntry->shop_item[0] == ShopItem::none
&& rtd.specialType != RtdSpecialType::toilet)
const bool primaryPriceLocked = !Park::RidePricesUnlocked(park) && rideEntry->shop_item[0] == ShopItem::none
&& rtd.specialType != RtdSpecialType::toilet;
setWidgetDisabled(WIDX_PRIMARY_PRICE, primaryPriceLocked);
if (primaryPriceLocked)
{
disabledWidgets |= (1uLL << WIDX_PRIMARY_PRICE);
widgets[WIDX_PRIMARY_PRICE_LABEL].tooltip = STR_RIDE_INCOME_ADMISSION_PAY_FOR_ENTRY_TIP;
widgets[WIDX_PRIMARY_PRICE].tooltip = STR_RIDE_INCOME_ADMISSION_PAY_FOR_ENTRY_TIP;
}
@@ -6770,7 +6720,7 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK].type = WidgetType::checkbox;
if (ShopItemHasCommonPrice(primaryItem))
pressedWidgets |= (1uLL << WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK);
setWidgetPressed(WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK, true);
widgets[WIDX_PRIMARY_PRICE_LABEL].text = GetShopItemDescriptor(primaryItem).Naming.PriceLabel;
}
@@ -6797,9 +6747,7 @@ namespace OpenRCT2::Ui::Windows
else
{
// Set same price throughout park checkbox
pressedWidgets &= ~(1uLL << WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK);
if (ShopItemHasCommonPrice(secondaryItem))
pressedWidgets |= (1uLL << WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK);
setWidgetPressed(WIDX_SECONDARY_PRICE_SAME_THROUGHOUT_PARK, ShopItemHasCommonPrice(secondaryItem));
// Show widgets
widgets[WIDX_SECONDARY_PRICE_LABEL].type = WidgetType::label;
@@ -6998,8 +6946,6 @@ namespace OpenRCT2::Ui::Windows
void CustomerOnPrepareDraw()
{
SetPressedTab();
auto ride = GetRide(rideId);
if (ride != nullptr)
{
+26 -26
View File
@@ -1009,19 +1009,17 @@ namespace OpenRCT2::Ui::Windows
newDisabledWidgets &= ~(1uLL << WIDX_CHAIN_LIFT);
}
// Set and invalidate the changed widgets
uint64_t currentDisabledWidgets = disabledWidgets;
if (currentDisabledWidgets == newDisabledWidgets)
return;
for (WidgetIndex i = 0; i < 64; i++)
// Invalidate only widgets whose disabled state changes.
const auto widgetCount = static_cast<WidgetIndex>(widgets.size());
for (WidgetIndex i = 0; i < widgetCount && i < 64; i++)
{
if ((newDisabledWidgets & (1uLL << i)) != (currentDisabledWidgets & (1uLL << i)))
const bool shouldBeDisabled = (newDisabledWidgets & (1uLL << i)) != 0;
if (isWidgetDisabled(i) != shouldBeDisabled)
{
setWidgetDisabled(i, shouldBeDisabled);
invalidateWidget(i);
}
}
disabledWidgets = newDisabledWidgets;
}
void onUpdate() override
@@ -1647,14 +1645,7 @@ namespace OpenRCT2::Ui::Windows
if (currentRide->supportsStatus(RideStatus::simulating))
{
simulateWidget.type = WidgetType::flatBtn;
if (currentRide->status == RideStatus::simulating)
{
pressedWidgets |= (1uLL << WIDX_SIMULATE);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_SIMULATE);
}
setWidgetPressed(WIDX_SIMULATE, currentRide->status == RideStatus::simulating);
}
_windowTitle = FormatStringID(STR_RIDE_CONSTRUCTION_WINDOW_TITLE, currentRide->getName().c_str());
widgets[WIDX_TITLE].setString(_windowTitle.c_str());
@@ -1744,8 +1735,7 @@ namespace OpenRCT2::Ui::Windows
const auto& rtd = GetRideTypeDescriptor(currentRide->type);
auto trackDrawerDescriptor = getCurrentTrackDrawerDescriptor(rtd);
holdDownWidgets = (1u << WIDX_CONSTRUCT) | (1u << WIDX_DEMOLISH) | (1u << WIDX_NEXT_SECTION)
| (1u << WIDX_PREVIOUS_SECTION);
widgetsSetHoldable(*this, { WIDX_CONSTRUCT, WIDX_DEMOLISH, WIDX_NEXT_SECTION, WIDX_PREVIOUS_SECTION });
if (rtd.flags.has(RtdFlag::isShopOrFacility) || !currentRide->hasStation())
{
widgets[WIDX_ENTRANCE_EXIT_GROUPBOX].type = WidgetType::empty;
@@ -2041,7 +2031,7 @@ namespace OpenRCT2::Ui::Windows
auto spinnerStart = 124 + widgets[WIDX_TITLE].bottom;
resizeSpinner(WIDX_SPEED_SETTING_SPINNER, { 12, spinnerStart }, { 85, kSpinnerHeight });
holdDownWidgets |= (1uLL << WIDX_SPEED_SETTING_SPINNER_UP) | (1uLL << WIDX_SPEED_SETTING_SPINNER_DOWN);
widgetsSetHoldable(*this, { WIDX_SPEED_SETTING_SPINNER_UP, WIDX_SPEED_SETTING_SPINNER_DOWN });
}
static constexpr int16_t bankingGroupboxRightNoSeatRotation = kGroupWidth;
@@ -2084,11 +2074,14 @@ namespace OpenRCT2::Ui::Windows
}
}
uint64_t newPressedWidgets = pressedWidgets
& ((1uLL << WIDX_BACKGROUND) | (1uLL << WIDX_TITLE) | (1uLL << WIDX_CLOSE) | (1uLL << WIDX_DIRECTION_GROUPBOX)
| (1uLL << WIDX_SLOPE_GROUPBOX) | (1uLL << WIDX_BANKING_GROUPBOX) | (1uLL << WIDX_CONSTRUCT)
| (1uLL << WIDX_DEMOLISH) | (1uLL << WIDX_PREVIOUS_SECTION) | (1uLL << WIDX_NEXT_SECTION)
| (1uLL << WIDX_ENTRANCE_EXIT_GROUPBOX) | (1uLL << WIDX_ENTRANCE) | (1uLL << WIDX_EXIT));
uint64_t newPressedWidgets = 0;
for (auto preservedIndex : { WIDX_BACKGROUND, WIDX_TITLE, WIDX_CLOSE, WIDX_DIRECTION_GROUPBOX, WIDX_SLOPE_GROUPBOX,
WIDX_BANKING_GROUPBOX, WIDX_CONSTRUCT, WIDX_DEMOLISH, WIDX_PREVIOUS_SECTION,
WIDX_NEXT_SECTION, WIDX_ENTRANCE_EXIT_GROUPBOX, WIDX_ENTRANCE, WIDX_EXIT })
{
if (isWidgetPressed(preservedIndex))
newPressedWidgets |= (1uLL << preservedIndex);
}
widgets[WIDX_CONSTRUCT].type = WidgetType::empty;
widgets[WIDX_DEMOLISH].type = WidgetType::flatBtn;
@@ -2127,7 +2120,7 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_PREVIOUS_SECTION].type = WidgetType::empty;
break;
default:
pressedWidgets = newPressedWidgets;
applyPressedBits(newPressedWidgets);
invalidate();
return;
}
@@ -2226,10 +2219,17 @@ namespace OpenRCT2::Ui::Windows
if (_currentTrackHasLiftHill)
newPressedWidgets |= (1uLL << WIDX_CHAIN_LIFT);
pressedWidgets = newPressedWidgets;
applyPressedBits(newPressedWidgets);
invalidate();
}
void applyPressedBits(uint64_t bits)
{
const auto widgetCount = static_cast<WidgetIndex>(widgets.size());
for (WidgetIndex i = 0; i < widgetCount && i < 64; i++)
setWidgetPressed(i, (bits & (1uLL << i)) != 0);
}
void updatePossibleRideConfigurations()
{
auto currentRide = GetRide(_currentRideIndex);
+2 -7
View File
@@ -506,16 +506,11 @@ namespace OpenRCT2::Ui::Windows
ft.Add<StringId>(STR_UP);
// Set correct active tab
for (int32_t i = 0; i < 3; i++)
pressedWidgets &= ~(1 << (WIDX_TAB_1 + i));
pressedWidgets |= 1LL << (WIDX_TAB_1 + page);
widgetSetPressedExclusive(*this, { WIDX_TAB_1, WIDX_TAB_2, WIDX_TAB_3 }, WIDX_TAB_1 + page);
widgets[WIDX_TITLE].text = page_names[page];
if (_quickDemolishMode)
pressedWidgets |= (1uLL << WIDX_QUICK_DEMOLISH);
else
pressedWidgets &= ~(1uLL << WIDX_QUICK_DEMOLISH);
setWidgetPressed(WIDX_QUICK_DEMOLISH, _quickDemolishMode);
widgets[WIDX_LIST].right = width - 26;
widgets[WIDX_LIST].bottom = height - 15;
+11 -7
View File
@@ -149,6 +149,7 @@ namespace OpenRCT2::Ui::Windows
_highlightedScenario = nullptr;
initTabs();
updatePressedTab();
initialiseListItems();
initScrollWidgets();
}
@@ -179,6 +180,7 @@ namespace OpenRCT2::Ui::Windows
_highlightedScenario = nullptr;
_preview = {};
updatePressedTab();
initialiseListItems();
invalidate();
onResize();
@@ -429,13 +431,6 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
pressedWidgets &= ~(
(1uLL << WIDX_CLOSE) | (1uLL << WIDX_TAB1) | (1uLL << WIDX_TAB2) | (1uLL << WIDX_TAB3) | (1uLL << WIDX_TAB4)
| (1uLL << WIDX_TAB5) | (1uLL << WIDX_TAB6) | (1uLL << WIDX_TAB7) | (1uLL << WIDX_TAB8) | (1uLL << WIDX_TAB9)
| (1uLL << WIDX_TAB10));
pressedWidgets |= 1LL << (selectedTab + WIDX_TAB1);
const int32_t bottomMargin = Config::Get().general.debuggingTools ? 17 : 5;
widgets[WIDX_SCENARIOLIST].right = width - GetPreviewPaneWidth() - 2 * kPadding;
widgets[WIDX_SCENARIOLIST].bottom = height - bottomMargin;
@@ -637,6 +632,15 @@ namespace OpenRCT2::Ui::Windows
}
private:
void updatePressedTab()
{
widgetSetPressedExclusive(
*this,
{ WIDX_TAB1, WIDX_TAB2, WIDX_TAB3, WIDX_TAB4, WIDX_TAB5, WIDX_TAB6, WIDX_TAB7, WIDX_TAB8, WIDX_TAB9,
WIDX_TAB10 },
selectedTab + WIDX_TAB1);
}
void DrawCategoryHeading(RenderTarget& rt, int32_t left, int32_t right, int32_t y, StringId stringId) const
{
auto baseColour = colours[1];
+14 -12
View File
@@ -271,11 +271,18 @@ namespace OpenRCT2::Ui::Windows
{
_activeTabIndex = 0;
}
updatePressedTab();
WindowMovePosition(*this, { ContextGetWidth() - GetRequiredWidth(), 0x1D });
WindowPushOthersBelow(*this);
}
void updatePressedTab()
{
for (size_t i = 0; i < _tabEntries.size(); i++)
widgetSetPressed(*this, static_cast<WidgetIndex>(WIDX_SCENERY_TAB_1 + i), i == _activeTabIndex);
}
void onClose() override
{
SceneryRemoveGhostToolPlacement();
@@ -423,6 +430,7 @@ namespace OpenRCT2::Ui::Windows
if (widgetIndex >= WIDX_SCENERY_TAB_1)
{
_activeTabIndex = widgetIndex - WIDX_SCENERY_TAB_1;
updatePressedTab();
invalidate();
gSceneryPlaceCost = kMoney64Undefined;
@@ -711,14 +719,9 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_SCENERY_TITLE].text = titleStringId;
widgets[WIDX_FILTER_TEXT_BOX].string = _filteredSceneryTab.Filter.data();
pressedWidgets = 0;
pressedWidgets |= 1uLL << (tabIndex + WIDX_SCENERY_TAB_1);
if (_sceneryPaintEnabled)
pressedWidgets |= (1uLL << WIDX_SCENERY_REPAINT_SCENERY_BUTTON);
if (gWindowSceneryEyedropperEnabled)
pressedWidgets |= (1uLL << WIDX_SCENERY_EYEDROPPER_BUTTON);
if (gWindowSceneryScatterEnabled)
pressedWidgets |= (1uLL << WIDX_SCENERY_BUILD_CLUSTER_BUTTON);
setWidgetPressed(WIDX_SCENERY_REPAINT_SCENERY_BUTTON, _sceneryPaintEnabled);
setWidgetPressed(WIDX_SCENERY_EYEDROPPER_BUTTON, gWindowSceneryEyedropperEnabled);
setWidgetPressed(WIDX_SCENERY_BUILD_CLUSTER_BUTTON, gWindowSceneryScatterEnabled);
widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WidgetType::empty;
widgets[WIDX_SCENERY_BUILD_CLUSTER_BUTTON].type = WidgetType::empty;
@@ -745,10 +748,7 @@ namespace OpenRCT2::Ui::Windows
if (gLegacyScene == LegacyScene::scenarioEditor || getGameState().cheats.sandboxMode)
{
widgets[WIDX_RESTRICT_SCENERY].type = WidgetType::button;
if (IsSceneryItemRestricted(tabSelectedScenery))
pressedWidgets |= (1uLL << WIDX_RESTRICT_SCENERY);
else
pressedWidgets &= ~(1uLL << WIDX_RESTRICT_SCENERY);
setWidgetPressed(WIDX_RESTRICT_SCENERY, IsSceneryItemRestricted(tabSelectedScenery));
}
}
@@ -956,6 +956,7 @@ namespace OpenRCT2::Ui::Windows
}
_activeTabIndex = tabIndex.value();
updatePressedTab();
SetSelectedScenery(tabIndex.value(), scenery);
if (primary.has_value())
{
@@ -1089,6 +1090,7 @@ namespace OpenRCT2::Ui::Windows
_requiredWidth = std::min(static_cast<int32_t>(_tabEntries.size()), kMaxTabsPerRow) * kTabWidth + 5;
PrepareWidgets();
updatePressedTab();
auto* windowMgr = GetWindowManager();
windowMgr->InvalidateByClass(WindowClass::scenery);
+7 -9
View File
@@ -62,8 +62,9 @@ namespace OpenRCT2::Ui::Windows
void onOpen() override
{
setWidgets(_sceneryScatterWidgets);
setWidgetPressed(WIDX_PREVIEW, true);
holdDownWidgets = (1uLL << WIDX_INCREMENT) | (1uLL << WIDX_DECREMENT);
widgetsSetHoldable(*this, { WIDX_INCREMENT, WIDX_DECREMENT });
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
@@ -160,24 +161,21 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
// Set the preview image button to be pressed down
pressedWidgets = (1uLL << WIDX_PREVIEW);
// Set density buttons' pressed state.
WidgetIndex pressedDensity = WIDX_DENSITY_HIGH;
switch (gWindowSceneryScatterDensity)
{
case ScatterToolDensity::LowDensity:
pressedWidgets |= (1uLL << WIDX_DENSITY_LOW);
pressedDensity = WIDX_DENSITY_LOW;
break;
case ScatterToolDensity::MediumDensity:
pressedWidgets |= (1uLL << WIDX_DENSITY_MEDIUM);
pressedDensity = WIDX_DENSITY_MEDIUM;
break;
case ScatterToolDensity::HighDensity:
pressedWidgets |= (1uLL << WIDX_DENSITY_HIGH);
pressedDensity = WIDX_DENSITY_HIGH;
break;
}
widgetSetPressedExclusive(*this, { WIDX_DENSITY_LOW, WIDX_DENSITY_MEDIUM, WIDX_DENSITY_HIGH }, pressedDensity);
// Update the preview image (for tool sizes up to 7)
widgets[WIDX_PREVIEW].image = ImageId(LandTool::SizeToSpriteIndex(gWindowSceneryScatterSize));
+1 -3
View File
@@ -349,7 +349,6 @@ namespace OpenRCT2::Ui::Windows
{
ColourSchemeUpdateByClass(this, static_cast<WindowClass>(WindowClass::staff));
SetPressedTab();
DisableWidgets();
auto staff = GetStaff();
@@ -1073,9 +1072,8 @@ namespace OpenRCT2::Ui::Windows
page = newPage;
currentFrame = 0;
pressedWidgets = 0;
holdDownWidgets = 0;
setWidgets(window_staff_page_widgets[page]);
SetPressedTab();
removeViewport();
+12 -8
View File
@@ -275,12 +275,23 @@ namespace OpenRCT2::Ui::Windows
WindowThemesInitVars();
WindowInitScrollWidgets(*this);
WindowSetResize(*this, kWindowSize, kWindowSize);
updatePressedTab();
listInformationType = 0;
_classIndex = -1;
_buttonIndex = -1;
}
void updatePressedTab()
{
widgetSetPressedExclusive(
*this,
{ WIDX_THEMES_SETTINGS_TAB, WIDX_THEMES_MAIN_UI_TAB, WIDX_THEMES_PARK_TAB, WIDX_THEMES_TOOLS_TAB,
WIDX_THEMES_RIDE_PEEPS_TAB, WIDX_THEMES_EDITORS_TAB, WIDX_THEMES_MISC_TAB, WIDX_THEMES_PROMPTS_TAB,
WIDX_THEMES_FEATURES_TAB },
_selectedTab + WIDX_THEMES_SETTINGS_TAB);
}
void onResize() override
{
if (_selectedTab == WINDOW_THEMES_TAB_SETTINGS)
@@ -310,14 +321,6 @@ namespace OpenRCT2::Ui::Windows
void onPrepareDraw() override
{
int32_t newPressedWidgets = pressedWidgets
& ~((1LL << WIDX_THEMES_SETTINGS_TAB) | (1LL << WIDX_THEMES_MAIN_UI_TAB) | (1LL << WIDX_THEMES_PARK_TAB)
| (1LL << WIDX_THEMES_TOOLS_TAB) | (1LL << WIDX_THEMES_RIDE_PEEPS_TAB) | (1LL << WIDX_THEMES_EDITORS_TAB)
| (1LL << WIDX_THEMES_MISC_TAB) | (1LL << WIDX_THEMES_PROMPTS_TAB) | (1LL << WIDX_THEMES_FEATURES_TAB));
WidgetIndex widgetIndex = _selectedTab + WIDX_THEMES_SETTINGS_TAB;
pressedWidgets = newPressedWidgets | (1 << widgetIndex);
auto* windowMgr = GetWindowManager();
if (windowMgr->FindByClass(WindowClass::dropdown) == nullptr)
{
@@ -438,6 +441,7 @@ namespace OpenRCT2::Ui::Windows
_selectedTab = static_cast<uint8_t>(newSelectedTab);
scrolls[0].contentOffsetY = 0;
currentFrame = 0;
updatePressedTab();
onResize();
invalidate();
break;
+25 -38
View File
@@ -283,10 +283,10 @@ namespace OpenRCT2::Ui::Windows
makeWindowShim(kWindowTitle, kWindowSize),
makeWidget({3, 57}, {kWindowSize.width - 6, kWindowSize.height - kBottomPadding - 58}, WidgetType::scroll, WindowColour::secondary, SCROLL_VERTICAL), /* Element list */
/* X and Y spinners */
makeWidget ({ 4, 24}, {38, 12}, WidgetType::label, WindowColour::secondary, STR_TILE_INSPECTOR_X_LABEL),
makeSpinnerWidgets({20, 23}, {51, 14}, WidgetType::spinner, WindowColour::secondary), /* Spinner X (3 widgets) */
makeWidget ({74, 24}, {38, 12}, WidgetType::label, WindowColour::secondary, STR_TILE_INSPECTOR_Y_LABEL),
makeSpinnerWidgets({90, 23}, {51, 14}, WidgetType::spinner, WindowColour::secondary), /* Spinner Y (3 widgets) */
makeWidget ({ 4, 24}, {38, 12}, WidgetType::label, WindowColour::secondary, STR_TILE_INSPECTOR_X_LABEL),
makeHoldableSpinnerWidgets({20, 23}, {51, 14}, WidgetType::spinner, WindowColour::secondary), /* Spinner X (3 widgets) */
makeWidget ({74, 24}, {38, 12}, WidgetType::label, WindowColour::secondary, STR_TILE_INSPECTOR_Y_LABEL),
makeHoldableSpinnerWidgets({90, 23}, {51, 14}, WidgetType::spinner, WindowColour::secondary), /* Spinner Y (3 widgets) */
/* Top buttons */
makeWidget(kToolbarButtonAnchor + kToolbarButtonOffsetX * 0, kToolbarButtonSize, WidgetType::flatBtn, WindowColour::secondary, ImageId(SPR_DEMOLISH), STR_REMOVE_SELECTED_ELEMENT_TIP ), /* Remove button */
makeWidget(kToolbarButtonAnchor + kToolbarButtonOffsetX * 1, kToolbarButtonHalfSize, WidgetType::button, WindowColour::secondary, STR_UP, STR_MOVE_SELECTED_ELEMENT_UP_TIP), /* Move up */
@@ -318,7 +318,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kSurfaceDetailsHeight = 20 + kNumSurfaceDetails * 11;
static constexpr auto kSurfaceWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_SURFACE_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_SURFACE_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0 }, 1, 0), kPropertyButtonSize, WidgetType::button, WindowColour::secondary, STR_TILE_INSPECTOR_SURFACE_REMOVE_FENCES), // WIDX_SURFACE_BUTTON_REMOVE_FENCES
makeWidget(PropertyRowCol({ 12, 0 }, 1, 1), kPropertyButtonSize, WidgetType::button, WindowColour::secondary, STR_TILE_INSPECTOR_SURFACE_RESTORE_FENCES), // WIDX_SURFACE_BUTTON_RESTORE_FENCES
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 2, 1), 1, 0), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_SURFACE_CHECK_CORNER_N
@@ -334,7 +334,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kPathDetailsHeight = 20 + kNumPathDetails * 11;
static constexpr auto kPathWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_PATH_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_PATH_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0 }, 1, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_PATH_BROKEN), // WIDX_PATH_CHECK_BROKEN
makeWidget(PropertyRowCol({ 12, 0 }, 2, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_PATH_SLOPED), // WIDX_PATH_CHECK_SLOPED
makeWidget(PropertyRowCol({ 12, 0 }, 3, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_PATH_JUNCTION_RAILINGS), // WIDX_PATH_CHECK_JUNCTION_RAILINGS
@@ -355,7 +355,7 @@ namespace OpenRCT2::Ui::Windows
static constexpr auto kTrackWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeWidget(PropertyRowCol({ 12, 0}, 0, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_TRACK_ENTIRE_TRACK_PIECE), // WIDX_TRACK_CHECK_APPLY_TO_ALL
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 1, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_TRACK_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 1, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_TRACK_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0}, 2, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_TRACK_CHAIN_LIFT), // WIDX_TRACK_CHECK_CHAIN_LIFT
makeWidget(PropertyRowCol({ 12, 0}, 3, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_TRACK_BRAKE_CLOSED), // WIDX_TRACK_CHECK_BRAKE_CLOSED
makeWidget(PropertyRowCol({ 12, 0}, 4, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_TRACK_IS_INDESTRUCTIBLE) // WIDX_TRACK_CHECK_IS_INDESTRUCTIBLE
@@ -367,7 +367,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kSceneryDetailsHeight = 20 + kNumSceneryDetails * 11;
static constexpr auto kSceneryWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_SCENERY_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_SCENERY_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 1, 0 + 0), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_SCENERY_CHECK_QUARTER_N
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 2, 0 + 1), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_SCENERY_CHECK_QUARTER_E
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 1, 0 + 2), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_SCENERY_CHECK_QUARTER_S
@@ -384,7 +384,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kEntranceDetailsHeight = 20 + kNumEntranceDetails * 11;
static constexpr auto kEntranceWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_ENTRANCE_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_ENTRANCE_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0 }, 1, 0), kPropertyButtonSize, WidgetType::button, WindowColour::secondary, STR_TILE_INSPECTOR_ENTRANCE_MAKE_USABLE, STR_TILE_INSPECTOR_ENTRANCE_MAKE_USABLE_TIP) // WIDX_ENTRANCE_BUTTON_MAKE_USABLE
);
@@ -394,10 +394,10 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kWallDetailsHeight = 20 + kNumWallDetails * 11;
static constexpr auto kWallWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_WALL_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_WALL_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0 }, 1, 1), kPropertyButtonSize, WidgetType::dropdownMenu, WindowColour::secondary), // WIDX_WALL_DROPDOWN_SLOPE
makeWidget(PropertyRowCol({ 12 + kPropertyButtonSize.width - 12, 0 }, 1, 1), { 11, 12}, WidgetType::button, WindowColour::secondary, STR_DROPDOWN_GLYPH), // WIDX_WALL_DROPDOWN_SLOPE_BUTTON
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 2, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_WALL_SPINNER_ANIMATION_FRAME{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 2, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_WALL_SPINNER_ANIMATION_FRAME{,_INCREASE,_DECREASE}
makeWidget(PropertyRowCol({ 12, 0 }, 3, 0), kPropertyFullWidth, WidgetType::checkbox, WindowColour::secondary, STR_TILE_INSPECTOR_WALL_ANIMATION_IS_BACKWARDS) // WIDX_WALL_ANIMATION_IS_BACKWARDS
);
@@ -407,7 +407,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kLargeSceneryDetailsHeight = 20 + kNumLargeSceneryDetails * 11;
static constexpr auto kLargeSceneryWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary) // WIDX_LARGE_SCENERY_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary) // WIDX_LARGE_SCENERY_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
);
constexpr int32_t kNumBannerProperties = 3;
@@ -416,7 +416,7 @@ namespace OpenRCT2::Ui::Windows
constexpr int32_t kBannerDetailsHeight = 20 + kNumBannerDetails * 11;
static constexpr auto kBannerWidgets = makeWidgets(
kMainTileInspectorWidgets,
makeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_BANNER_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeHoldableSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), kPropertySpinnerSize, WidgetType::spinner, WindowColour::secondary), // WIDX_BANNER_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 3, 1), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_BANNER_CHECK_BLOCK_NE
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 3, 3), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_BANNER_CHECK_BLOCK_SE
makeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 1, 1), 1, 3), { 12, 12 }, WidgetType::checkbox, WindowColour::secondary), // WIDX_BANNER_CHECK_BLOCK_SW
@@ -475,28 +475,16 @@ namespace OpenRCT2::Ui::Windows
ViewportInteractionItem::wall, ViewportInteractionItem::largeScenery, ViewportInteractionItem::banner);
// clang-format off
static uint64_t kHoldableWidgetsByPage[] = {
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_SURFACE_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_SURFACE_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_PATH_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_PATH_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_TRACK_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_TRACK_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_SCENERY_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_SCENERY_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_ENTRANCE_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_ENTRANCE_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_WALL_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_WALL_SPINNER_HEIGHT_DECREASE) | (1uLL << WIDX_WALL_SPINNER_ANIMATION_FRAME_INCREASE) | (1uLL << WIDX_WALL_SPINNER_ANIMATION_FRAME_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_LARGE_SCENERY_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_LARGE_SCENERY_SPINNER_HEIGHT_DECREASE),
(1uLL << WIDX_SPINNER_X_INCREASE) | (1uLL << WIDX_SPINNER_X_DECREASE) | (1uLL << WIDX_SPINNER_Y_INCREASE) | (1uLL << WIDX_SPINNER_Y_DECREASE) | (1uLL << WIDX_BANNER_SPINNER_HEIGHT_INCREASE) | (1uLL << WIDX_BANNER_SPINNER_HEIGHT_DECREASE),
};
static uint64_t kDisabledWidgetsByPage[] = {
(1uLL << WIDX_BUTTON_MOVE_UP) | (1uLL << WIDX_BUTTON_MOVE_DOWN) | (1uLL << WIDX_BUTTON_REMOVE) | (1uLL << WIDX_BUTTON_ROTATE) | (1uLL << WIDX_BUTTON_COPY),
0,
0,
0,
0,
0,
0,
(1uLL << WIDX_BUTTON_ROTATE),
0,
static constexpr std::initializer_list<WidgetIndex> kDisabledWidgetsByPage[] = {
{ WIDX_BUTTON_MOVE_UP, WIDX_BUTTON_MOVE_DOWN, WIDX_BUTTON_REMOVE, WIDX_BUTTON_ROTATE, WIDX_BUTTON_COPY },
{},
{},
{},
{},
{},
{},
{ WIDX_BUTTON_ROTATE },
{},
};
// clang-format on
@@ -1799,9 +1787,8 @@ namespace OpenRCT2::Ui::Windows
tileInspectorPage = p;
auto pageIndex = EnumValue(p);
setWidgets(kWidgetsByPage[pageIndex]);
holdDownWidgets = kHoldableWidgetsByPage[pageIndex];
disabledWidgets = kDisabledWidgetsByPage[pageIndex];
pressedWidgets = 0;
for (auto widgetIndex : kDisabledWidgetsByPage[pageIndex])
setWidgetDisabled(widgetIndex, true);
invalidate();
}
+6 -24
View File
@@ -1224,31 +1224,16 @@ namespace OpenRCT2::Ui::Windows
return;
}
if (mainWindow->viewport->zoom == ZoomLevel::min())
{
disabledWidgets |= (1uLL << WIDX_ZOOM_IN);
}
else if (mainWindow->viewport->zoom >= ZoomLevel::max())
{
disabledWidgets |= (1uLL << WIDX_ZOOM_OUT);
}
else
{
disabledWidgets &= ~((1uLL << WIDX_ZOOM_IN) | (1uLL << WIDX_ZOOM_OUT));
}
setWidgetDisabled(WIDX_ZOOM_IN, mainWindow->viewport->zoom == ZoomLevel::min());
setWidgetDisabled(WIDX_ZOOM_OUT, mainWindow->viewport->zoom >= ZoomLevel::max());
}
void ApplyPausedState()
{
bool paused = (gGamePaused & GAME_PAUSED_NORMAL);
if (paused || _waitingForPause)
{
pressedWidgets |= (1uLL << WIDX_PAUSE);
if (paused)
_waitingForPause = false;
}
else
pressedWidgets &= ~(1uLL << WIDX_PAUSE);
if (paused)
_waitingForPause = false;
setWidgetPressed(WIDX_PAUSE, paused || _waitingForPause);
}
void ApplyMapRotation()
@@ -1280,10 +1265,7 @@ namespace OpenRCT2::Ui::Windows
{
// Footpath button pressed down
auto* windowMgr = GetWindowManager();
if (windowMgr->FindByClass(WindowClass::footpath) == nullptr)
pressedWidgets &= ~(1uLL << WIDX_PATH);
else
pressedWidgets |= (1uLL << WIDX_PATH);
setWidgetPressed(WIDX_PATH, windowMgr->FindByClass(WindowClass::footpath) != nullptr);
}
// TODO: look into using std::span
+5 -13
View File
@@ -407,25 +407,17 @@ namespace OpenRCT2::Ui::Windows
_windowTitle = FormatStringID(titleFormat, stringId);
widgets[WIDX_TITLE].setString(_windowTitle.c_str());
if ((gLegacyScene == LegacyScene::trackDesignsManager) || selectedListItem != 0)
const bool showPreview = (gLegacyScene == LegacyScene::trackDesignsManager) || selectedListItem != 0;
setWidgetPressed(WIDX_TRACK_PREVIEW, showPreview);
setWidgetDisabled(WIDX_TRACK_PREVIEW, !showPreview);
if (showPreview)
{
pressedWidgets |= 1uLL << WIDX_TRACK_PREVIEW;
disabledWidgets &= ~(1uLL << WIDX_TRACK_PREVIEW);
widgets[WIDX_ROTATE].type = WidgetType::flatBtn;
widgets[WIDX_TOGGLE_SCENERY].type = WidgetType::flatBtn;
if (gTrackDesignSceneryToggle)
{
pressedWidgets &= ~(1uLL << WIDX_TOGGLE_SCENERY);
}
else
{
pressedWidgets |= (1uLL << WIDX_TOGGLE_SCENERY);
}
setWidgetPressed(WIDX_TOGGLE_SCENERY, !gTrackDesignSceneryToggle);
}
else
{
pressedWidgets &= ~(1uLL << WIDX_TRACK_PREVIEW);
disabledWidgets |= (1uLL << WIDX_TRACK_PREVIEW);
widgets[WIDX_ROTATE].type = WidgetType::empty;
widgets[WIDX_TOGGLE_SCENERY].type = WidgetType::empty;
}
-3
View File
@@ -115,9 +115,6 @@ namespace OpenRCT2::Ui::Windows
uint32_t wflags = 0;
WindowBase* w = WindowGetMain();
pressedWidgets = 0;
disabledWidgets = 0;
if (w != nullptr)
wflags = w->viewport->flags;
+2 -9
View File
@@ -279,14 +279,7 @@ namespace OpenRCT2::Ui::Windows
WIDX_CLIP_SEE_THROUGH_CHECKBOX_ENABLE, mainWindow->viewport->flags & VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH);
}
if (IsActive())
{
this->pressedWidgets |= 1uLL << WIDX_CLIP_SELECTOR;
}
else
{
this->pressedWidgets &= ~(1uLL << WIDX_CLIP_SELECTOR);
}
setWidgetPressed(WIDX_CLIP_SELECTOR, IsActive());
}
void onDraw(Drawing::RenderTarget& rt) override
@@ -362,7 +355,7 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(_viewClippingWidgets);
this->holdDownWidgets = (1uLL << WIDX_CLIP_HEIGHT_INCREASE) | (1uL << WIDX_CLIP_HEIGHT_DECREASE);
widgetsSetHoldable(*this, { WIDX_CLIP_HEIGHT_INCREASE, WIDX_CLIP_HEIGHT_DECREASE });
WindowInitScrollWidgets(*this);
_clipHeightDisplayType = DisplayType::DisplayUnits;
+2 -5
View File
@@ -192,11 +192,8 @@ namespace OpenRCT2::Ui::Windows
widgets[WIDX_TITLE].setString(_windowTitle.c_str());
// Set disabled widgets
disabledWidgets = 0;
if (viewport != nullptr && viewport->zoom == ZoomLevel::min())
disabledWidgets |= 1uLL << WIDX_ZOOM_IN;
if (viewport != nullptr && viewport->zoom >= ZoomLevel::max())
disabledWidgets |= 1uLL << WIDX_ZOOM_OUT;
setWidgetDisabled(WIDX_ZOOM_IN, viewport != nullptr && viewport->zoom == ZoomLevel::min());
setWidgetDisabled(WIDX_ZOOM_OUT, viewport != nullptr && viewport->zoom >= ZoomLevel::max());
if (viewport != nullptr)
{
+1 -1
View File
@@ -61,7 +61,7 @@ namespace OpenRCT2::Ui::Windows
{
setWidgets(_waterWidgets);
holdDownWidgets = (1uLL << WIDX_INCREMENT) | (1uLL << WIDX_DECREMENT);
widgetsSetHoldable(*this, { WIDX_INCREMENT, WIDX_DECREMENT });
WindowInitScrollWidgets(*this);
WindowPushOthersBelow(*this);
-3
View File
@@ -77,9 +77,6 @@ namespace OpenRCT2
struct WindowBase
{
Viewport* viewport{};
uint64_t disabledWidgets{};
uint64_t pressedWidgets{};
uint64_t holdDownWidgets{};
std::vector<Widget> widgets{};
ScreenCoordsXY windowPos;
int16_t width{};
+2 -1
View File
@@ -36,7 +36,8 @@ set(test_files
"${CMAKE_CURRENT_SOURCE_DIR}/TestData.h"
"${CMAKE_CURRENT_SOURCE_DIR}/tests.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TileElements.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/TileElementsView.cpp")
"${CMAKE_CURRENT_SOURCE_DIR}/TileElementsView.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/WidgetStateTests.cpp")
add_executable(OpenRCT2Tests ${test_files})
add_executable(OpenRCT2::OpenRCT2Tests ALIAS OpenRCT2Tests)
+140
View File
@@ -0,0 +1,140 @@
/*****************************************************************************
* Copyright (c) 2014-2026 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 <gtest/gtest.h>
#include <openrct2-ui/interface/Widget.h>
#include <openrct2/core/FlagHolder.hpp>
#include <openrct2/interface/Widget.h>
#include <openrct2/interface/WindowBase.h>
#include <span>
using namespace OpenRCT2;
TEST(WidgetStateTest, WidgetDefaultConstructedHasNoFlags)
{
Widget widget{};
ASSERT_TRUE(widget.flags.isEmpty());
ASSERT_FALSE(widget.flags.has(WidgetFlag::isPressed));
ASSERT_FALSE(widget.flags.has(WidgetFlag::isDisabled));
ASSERT_FALSE(widget.flags.has(WidgetFlag::isHoldable));
}
TEST(WidgetStateTest, FlagHolderSetConditional)
{
WidgetFlags flags;
flags.set(WidgetFlag::isPressed, true);
ASSERT_TRUE(flags.has(WidgetFlag::isPressed));
flags.set(WidgetFlag::isPressed, false);
ASSERT_FALSE(flags.has(WidgetFlag::isPressed));
}
TEST(WidgetStateTest, FlagsAreIndependent)
{
WidgetFlags flags;
flags.set(WidgetFlag::isPressed);
flags.set(WidgetFlag::isHoldable);
ASSERT_TRUE(flags.has(WidgetFlag::isPressed));
ASSERT_TRUE(flags.has(WidgetFlag::isHoldable));
ASSERT_FALSE(flags.has(WidgetFlag::isDisabled));
flags.unset(WidgetFlag::isPressed);
ASSERT_FALSE(flags.has(WidgetFlag::isPressed));
ASSERT_TRUE(flags.has(WidgetFlag::isHoldable));
}
// Regression guard for #26421: widgets at index >= 64 must round-trip cleanly.
// The scenery window's 65th tab has widget index 79. A uint64 bitmask indexed
// by widget index would wrap (1uLL << 79 == 1uLL << 15) and cause the first
// tab to falsely report as pressed. Per-widget flags have no such cap.
TEST(WidgetStateTest, HighIndexRoundTripsWithoutShiftWrap)
{
WindowBase w;
w.widgets.resize(300);
w.widgets[79].flags.set(WidgetFlag::isPressed);
ASSERT_TRUE(w.widgets[79].flags.has(WidgetFlag::isPressed));
// Must not false-positive at any prior shift-wrap alias.
ASSERT_FALSE(w.widgets[15].flags.has(WidgetFlag::isPressed)); // 79 % 64
ASSERT_FALSE(w.widgets[143].flags.has(WidgetFlag::isPressed)); // 143 % 64 == 15
ASSERT_FALSE(w.widgets[271].flags.has(WidgetFlag::isPressed));
}
TEST(WidgetStateTest, SetWidgetsPreservesFlags)
{
Widget mutableSource[3] = { Widget{}, Widget{}, Widget{} };
mutableSource[1].flags.set(WidgetFlag::isPressed);
mutableSource[1].flags.set(WidgetFlag::isHoldable);
WindowBase w;
w.setWidgets(std::span<const Widget>(mutableSource, 3));
ASSERT_EQ(w.widgets.size(), 3u);
ASSERT_TRUE(w.widgets[1].flags.has(WidgetFlag::isPressed));
ASSERT_TRUE(w.widgets[1].flags.has(WidgetFlag::isHoldable));
ASSERT_FALSE(w.widgets[0].flags.has(WidgetFlag::isPressed));
ASSERT_FALSE(w.widgets[2].flags.has(WidgetFlag::isPressed));
}
TEST(WidgetStateTest, WithFlagSetsFlagWithoutDisturbingOthers)
{
using Ui::withFlag;
Widget base{};
base.flags.set(WidgetFlag::isPressed);
auto holdable = withFlag(base, WidgetFlag::isHoldable);
ASSERT_TRUE(holdable.flags.has(WidgetFlag::isPressed));
ASSERT_TRUE(holdable.flags.has(WidgetFlag::isHoldable));
ASSERT_FALSE(holdable.flags.has(WidgetFlag::isDisabled));
}
TEST(WidgetStateTest, MakeHoldableWidgetHasHoldableFlag)
{
using Ui::makeHoldableWidget;
using Ui::WindowColour;
constexpr auto w = makeHoldableWidget({ 0, 0 }, { 10, 10 }, WidgetType::button, WindowColour::primary);
static_assert(w.flags.has(WidgetFlag::isHoldable));
static_assert(!w.flags.has(WidgetFlag::isPressed));
static_assert(!w.flags.has(WidgetFlag::isDisabled));
ASSERT_TRUE(w.flags.has(WidgetFlag::isHoldable));
}
TEST(WidgetStateTest, MakeWidgetDefaultHasNoFlags)
{
using Ui::makeWidget;
using Ui::WindowColour;
constexpr auto w = makeWidget({ 0, 0 }, { 10, 10 }, WidgetType::button, WindowColour::primary);
static_assert(w.flags.isEmpty());
ASSERT_TRUE(w.flags.isEmpty());
}
TEST(WidgetStateTest, MakeSpinnerWidgetsHasNoHoldableFlag)
{
using Ui::makeSpinnerWidgets;
using Ui::WindowColour;
constexpr auto widgets = makeSpinnerWidgets({ 0, 0 }, { 100, 14 }, WidgetType::spinner, WindowColour::primary);
static_assert(!widgets[0].flags.has(WidgetFlag::isHoldable));
static_assert(!widgets[1].flags.has(WidgetFlag::isHoldable));
static_assert(!widgets[2].flags.has(WidgetFlag::isHoldable));
}
TEST(WidgetStateTest, MakeHoldableSpinnerWidgetsHasHoldableOnIncrementButtons)
{
using Ui::makeHoldableSpinnerWidgets;
using Ui::WindowColour;
constexpr auto widgets = makeHoldableSpinnerWidgets({ 0, 0 }, { 100, 14 }, WidgetType::spinner, WindowColour::primary);
// Element [0] is the spinner input field; increment/decrement buttons are
// [1] and [2] and must be holdable for press-and-hold repeat.
static_assert(!widgets[0].flags.has(WidgetFlag::isHoldable));
static_assert(widgets[1].flags.has(WidgetFlag::isHoldable));
static_assert(widgets[2].flags.has(WidgetFlag::isHoldable));
}
+1
View File
@@ -112,6 +112,7 @@
</ClCompile>
<ClCompile Include="TileElements.cpp" />
<ClCompile Include="TileElementsView.cpp" />
<ClCompile Include="WidgetStateTests.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="testdata\sprites\badManifest.json" />