mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2026-05-06 07:56:46 -04:00
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:
@@ -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 g’s stat requirements for Flying Roller Coaster don’t 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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)];
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user