From c2042d541a6c04ee62d703d3f2e8c03f1748e86c Mon Sep 17 00:00:00 2001
From: Tom
Date: Sat, 29 Apr 2023 03:54:02 +0100
Subject: [PATCH] Refactor window to class: Research (#19910)
* Refactor window to class: Research (#13794)
- Update Research window to new window class
- Refactor dependant windows (Finances and NewRides)
* Refactor window to class: Research (#13794)
- Refactor all shared logic for both pages in research window. Reused by Finances and NewRides windows.
* Refactor window to class: Research (#13794)
- Fix style issues
* Refactor window to class: Research
- Fix style issues, again
* Refactor window to class: Research
- Override Window class methods
* Refactor window to class: Research
- Remove old method comments
* Refactor window to class: Research
- Addresses code review comments
* Refactor window to class: Research
- Adds ResearchWindow ctor
* Refactor window to class: Research
- Hide funding dropdown in no money scenarios
- Addresses code review comments
---
src/openrct2-ui/windows/Finances.cpp | 105 +----
src/openrct2-ui/windows/NewRide.cpp | 13 +-
src/openrct2-ui/windows/Research.cpp | 556 +++++++++++++--------------
src/openrct2-ui/windows/Window.h | 10 +-
4 files changed, 278 insertions(+), 406 deletions(-)
diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp
index a8a5207441..0c548da76b 100644
--- a/src/openrct2-ui/windows/Finances.cpp
+++ b/src/openrct2-ui/windows/Finances.cpp
@@ -253,7 +253,7 @@ public:
OnMouseDownSummary(widgetIndex);
break;
case WINDOW_FINANCES_PAGE_RESEARCH:
- OnMouseDownResearch(widgetIndex);
+ WindowResearchFundingMouseDown(this, widgetIndex, WIDX_RESEARCH_FUNDING);
break;
}
}
@@ -280,7 +280,7 @@ public:
OnMouseUpMarketing(widgetIndex);
break;
case WINDOW_FINANCES_PAGE_RESEARCH:
- OnMouseUpResearch(widgetIndex);
+ WindowResearchFundingMouseUp(widgetIndex, WIDX_RESEARCH_FUNDING);
}
break;
}
@@ -290,7 +290,7 @@ public:
{
if (page == WINDOW_FINANCES_PAGE_RESEARCH)
{
- OnDropdownResearch(widgetIndex, selectedIndex);
+ WindowResearchFundingDropdown(widgetIndex, selectedIndex, WIDX_RESEARCH_FUNDING);
}
}
@@ -318,7 +318,7 @@ public:
OnPrepareDrawMarketing();
break;
case WINDOW_FINANCES_PAGE_RESEARCH:
- OnPrepareDrawResearch();
+ WindowResearchFundingPrepareDraw(this, WIDX_RESEARCH_FUNDING);
break;
}
}
@@ -346,7 +346,7 @@ public:
OnDrawMarketing(dpi);
break;
case WINDOW_FINANCES_PAGE_RESEARCH:
- OnDrawResearch(dpi);
+ WindowResearchFundingDraw(this, dpi);
break;
}
}
@@ -901,101 +901,6 @@ public:
}
}
-#pragma endregion
-
-#pragma region Research Events
-
- void OnMouseUpResearch(WidgetIndex widgetIndex)
- {
- if (widgetIndex >= WIDX_TRANSPORT_RIDES && widgetIndex <= WIDX_SCENERY_AND_THEMING)
- {
- auto activeResearchTypes = gResearchPriorities;
- activeResearchTypes ^= 1uLL << (widgetIndex - WIDX_TRANSPORT_RIDES);
-
- auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
- GameActions::Execute(&gameAction);
- }
- }
-
- void OnMouseDownResearch(WidgetIndex widgetIndex)
- {
- if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON)
- return;
-
- Widget* dropdownWidget = &widgets[widgetIndex - 1];
-
- for (std::size_t i = 0; i < std::size(ResearchFundingLevelNames); i++)
- {
- gDropdownItems[i].Format = STR_DROPDOWN_MENU_LABEL;
- gDropdownItems[i].Args = ResearchFundingLevelNames[i];
- }
-
- WindowDropdownShowTextCustomWidth(
- { windowPos.x + dropdownWidget->left, windowPos.y + dropdownWidget->top }, dropdownWidget->height() + 1, colours[1],
- 0, Dropdown::Flag::StayOpen, 4, dropdownWidget->width() - 3);
-
- int32_t currentResearchLevel = gResearchFundingLevel;
- Dropdown::SetChecked(currentResearchLevel, true);
- }
-
- void OnDropdownResearch(WidgetIndex widgetIndex, int32_t selectedIndex)
- {
- if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON || selectedIndex == -1)
- return;
-
- auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, selectedIndex);
- GameActions::Execute(&gameAction);
- }
-
- void OnPrepareDrawResearch()
- {
- if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
- {
- _windowFinancesResearchWidgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::Empty;
- _windowFinancesResearchWidgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Empty;
- }
- else
- {
- _windowFinancesResearchWidgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::DropdownMenu;
- _windowFinancesResearchWidgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
- }
- int32_t currentResearchLevel = gResearchFundingLevel;
-
- // Current funding
- _windowFinancesResearchWidgets[WIDX_RESEARCH_FUNDING].text = ResearchFundingLevelNames[currentResearchLevel];
-
- // Checkboxes
- uint8_t activeResearchTypes = gResearchPriorities;
- int32_t uncompletedResearchTypes = gResearchUncompletedCategories;
- for (int32_t i = 0; i < 7; i++)
- {
- int32_t mask = 1 << i;
- int32_t widgetMask = 1uLL << (i + WIDX_TRANSPORT_RIDES);
-
- // Set checkbox disabled if research type is complete
- if (uncompletedResearchTypes & mask)
- {
- disabled_widgets &= ~widgetMask;
-
- // Set checkbox ticked if research type is active
- if (activeResearchTypes & mask)
- pressed_widgets |= widgetMask;
- else
- pressed_widgets &= ~widgetMask;
- }
- else
- {
- disabled_widgets |= widgetMask;
- pressed_widgets &= ~widgetMask;
- }
- }
- }
-
- void OnDrawResearch(DrawPixelInfo& dpi)
- {
- WindowResearchFundingPagePaint(this, dpi, WIDX_RESEARCH_FUNDING);
- }
-
#pragma endregion
void InitialiseScrollPosition(WidgetIndex widgetIndex, int32_t scrollId)
diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp
index 4eaf63a9ec..ab252e608a 100644
--- a/src/openrct2-ui/windows/NewRide.cpp
+++ b/src/openrct2-ui/windows/NewRide.cpp
@@ -350,7 +350,7 @@ public:
Close();
break;
case WIDX_LAST_DEVELOPMENT_BUTTON:
- News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
+ WindowResearchDevelopmentMouseUp(widgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
break;
case WIDX_RESEARCH_FUNDING_BUTTON:
ContextOpenWindowView(WV_FINANCES_RESEARCH);
@@ -397,14 +397,7 @@ public:
if (_currentTab == RESEARCH_TAB)
{
- widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::Empty;
- if (gResearchLastItem.has_value())
- {
- auto type = gResearchLastItem->type;
- widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn;
- const auto index = (type == Research::EntryType::Ride) ? SPR_NEW_RIDE : SPR_NEW_SCENERY;
- widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = ImageId(index);
- }
+ WindowResearchDevelopmentPrepareDraw(this, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
}
const auto& ls = OpenRCT2::GetContext()->GetLocalisationService();
@@ -427,7 +420,7 @@ public:
}
else
{
- WindowResearchDevelopmentPagePaint(this, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+ WindowResearchDevelopmentDraw(this, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
}
}
diff --git a/src/openrct2-ui/windows/Research.cpp b/src/openrct2-ui/windows/Research.cpp
index 0bfc1c404d..dbed33e9aa 100644
--- a/src/openrct2-ui/windows/Research.cpp
+++ b/src/openrct2-ui/windows/Research.cpp
@@ -99,47 +99,6 @@ static Widget *window_research_page_widgets[] = {
#pragma endregion
-#pragma region Events
-
-static void WindowResearchDevelopmentMouseup(WindowBase *w, WidgetIndex widgetIndex);
-static void WindowResearchDevelopmentUpdate(WindowBase *w);
-static void WindowResearchDevelopmentInvalidate(WindowBase *w);
-static void WindowResearchDevelopmentPaint(WindowBase *w, DrawPixelInfo& dpi);
-
-static void WindowResearchFundingMouseup(WindowBase *w, WidgetIndex widgetIndex);
-static void WindowResearchFundingMousedown(WindowBase *w, WidgetIndex widgetIndex, Widget* widget);
-static void WindowResearchFundingDropdown(WindowBase *w, WidgetIndex widgetIndex, int32_t dropdownIndex);
-static void WindowResearchFundingUpdate(WindowBase *w);
-static void WindowResearchFundingInvalidate(WindowBase *w);
-static void WindowResearchFundingPaint(WindowBase *w, DrawPixelInfo& dpi);
-
-//
-static WindowEventList window_research_development_events([](auto& events)
-{
- events.mouse_up = &WindowResearchDevelopmentMouseup;
- events.update = &WindowResearchDevelopmentUpdate;
- events.invalidate = &WindowResearchDevelopmentInvalidate;
- events.paint = &WindowResearchDevelopmentPaint;
-});
-
-// 0x009890E8
-static WindowEventList window_research_funding_events([](auto& events)
-{
- events.mouse_up = &WindowResearchFundingMouseup;
- events.mouse_down = &WindowResearchFundingMousedown;
- events.dropdown = &WindowResearchFundingDropdown;
- events.update = &WindowResearchFundingUpdate;
- events.invalidate = &WindowResearchFundingInvalidate;
- events.paint = &WindowResearchFundingPaint;
-});
-
-static WindowEventList *window_research_page_events[] = {
- &window_research_development_events,
- &window_research_funding_events,
-};
-
-#pragma endregion
-
// clang-format on
const int32_t window_research_tab_animation_loops[] = {
@@ -154,119 +113,247 @@ static constexpr const StringId ResearchStageNames[] = {
STR_RESEARCH_STAGE_UNKNOWN,
};
-static void WindowResearchSetPage(WindowBase* w, int32_t page);
-static void WindowResearchSetPressedTab(WindowBase* w);
-static void WindowResearchDrawTabImages(DrawPixelInfo& dpi, WindowBase* w);
-
-WindowBase* WindowResearchOpen()
+class ResearchWindow final : public Window
{
- WindowBase* w;
-
- w = WindowBringToFrontByClass(WindowClass::Research);
- if (w == nullptr)
+public:
+ ResearchWindow()
+ {
+ widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT];
+ width = WW_DEVELOPMENT;
+ height = WH_DEVELOPMENT;
+ }
+
+ void SetPage(int32_t newPageIndex)
+ {
+ page = newPageIndex;
+ frame_no = 0;
+ RemoveViewport();
+
+ hold_down_widgets = 0;
+ widgets = window_research_page_widgets[newPageIndex];
+ disabled_widgets = 0;
+ pressed_widgets = 0;
+
+ Invalidate();
+ if (newPageIndex == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
+ {
+ width = WW_DEVELOPMENT;
+ height = WH_DEVELOPMENT;
+ }
+ else
+ {
+ width = WW_FUNDING;
+ height = WH_FUNDING;
+ }
+ OnResize();
+
+ InitScrollWidgets();
+ Invalidate();
+ }
+
+private:
+ void OnOpen() override
{
- w = WindowCreateAutoPos(WW_FUNDING, WH_FUNDING, window_research_page_events[0], WindowClass::Research, WF_10);
- w->widgets = window_research_page_widgets[0];
- w->number = 0;
- w->page = 0;
- w->frame_no = 0;
- w->disabled_widgets = 0;
ResearchUpdateUncompletedTypes();
}
- w->page = 0;
- w->Invalidate();
- w->width = WW_DEVELOPMENT;
- w->height = WH_DEVELOPMENT;
- w->Invalidate();
+ void OnUpdate() override
+ {
+ // Tab animation
+ if (++frame_no >= window_research_tab_animation_loops[page])
+ frame_no = 0;
- w->widgets = window_research_page_widgets[0];
- w->hold_down_widgets = 0;
- w->event_handlers = window_research_page_events[0];
- w->pressed_widgets = 0;
- w->disabled_widgets = 0;
- WindowInitScrollWidgets(*w);
+ switch (page)
+ {
+ case WINDOW_RESEARCH_PAGE_DEVELOPMENT:
+ {
+ InvalidateWidget(WIDX_TAB_1);
+ break;
+ }
+ case WINDOW_RESEARCH_PAGE_FUNDING:
+ {
+ InvalidateWidget(WIDX_TAB_2);
+ break;
+ }
+ }
+ }
- return w;
+ void OnMouseDown(WidgetIndex widgetIndex) override
+ {
+ if (page == WINDOW_RESEARCH_PAGE_FUNDING)
+ {
+ WindowResearchFundingMouseDown(this, widgetIndex, WIDX_RESEARCH_FUNDING);
+ }
+ }
+
+ void OnMouseUp(WidgetIndex widgetIndex) override
+ {
+ // Switch tab or close
+ switch (widgetIndex)
+ {
+ case WIDX_CLOSE:
+ {
+ Close();
+ break;
+ }
+ case WIDX_TAB_1:
+ case WIDX_TAB_2:
+ {
+ SetPage(widgetIndex - WIDX_TAB_1);
+ break;
+ }
+ }
+
+ // Process mouse up for specific tab
+ switch (page)
+ {
+ case WINDOW_RESEARCH_PAGE_DEVELOPMENT:
+ {
+ WindowResearchDevelopmentMouseUp(widgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+ break;
+ }
+ case WINDOW_RESEARCH_PAGE_FUNDING:
+ {
+ WindowResearchFundingMouseUp(widgetIndex, WIDX_RESEARCH_FUNDING);
+ break;
+ }
+ }
+ }
+
+ void OnDropdown(WidgetIndex widgetIndex, int32_t selectedIndex) override
+ {
+ if (page == WINDOW_RESEARCH_PAGE_FUNDING)
+ {
+ WindowResearchFundingDropdown(widgetIndex, selectedIndex, WIDX_RESEARCH_FUNDING);
+ }
+ }
+
+ void OnPrepareDraw() override
+ {
+ auto* targetWidgets = window_research_page_widgets[page];
+
+ if (widgets != targetWidgets)
+ {
+ widgets = targetWidgets;
+ InitScrollWidgets();
+ }
+
+ for (auto i = 0; i < WINDOW_RESEARCH_PAGE_COUNT; i++)
+ {
+ SetWidgetPressed(WIDX_TAB_1 + i, false);
+ }
+
+ SetWidgetPressed(WIDX_TAB_1 + page, true);
+
+ switch (page)
+ {
+ case WINDOW_RESEARCH_PAGE_DEVELOPMENT:
+ {
+ WindowResearchDevelopmentPrepareDraw(this, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+ break;
+ }
+ case WINDOW_RESEARCH_PAGE_FUNDING:
+ {
+ WindowResearchFundingPrepareDraw(this, WIDX_RESEARCH_FUNDING);
+ break;
+ }
+ }
+ }
+
+ void OnDraw(DrawPixelInfo& dpi) override
+ {
+ DrawWidgets(dpi);
+ DrawTabImages(dpi);
+
+ switch (page)
+ {
+ case WINDOW_RESEARCH_PAGE_DEVELOPMENT:
+ {
+ WindowResearchDevelopmentDraw(this, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+ break;
+ }
+ case WINDOW_RESEARCH_PAGE_FUNDING:
+ {
+ WindowResearchFundingDraw(this, dpi);
+ break;
+ }
+ }
+ }
+
+ void DrawTabImage(DrawPixelInfo& dpi, int32_t tabPage, int32_t spriteIndex)
+ {
+ WidgetIndex widgetIndex = WIDX_TAB_1 + tabPage;
+
+ if (!IsWidgetDisabled(widgetIndex))
+ {
+ if (page == tabPage)
+ {
+ int32_t frame = frame_no / 2;
+ if (tabPage == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
+ frame %= 8;
+ spriteIndex += frame;
+ }
+
+ GfxDrawSprite(
+ dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widgets[widgetIndex].left, widgets[widgetIndex].top });
+ }
+ }
+
+ void DrawTabImages(DrawPixelInfo& dpi)
+ {
+ DrawTabImage(dpi, WINDOW_RESEARCH_PAGE_DEVELOPMENT, SPR_TAB_FINANCES_RESEARCH_0);
+ DrawTabImage(dpi, WINDOW_RESEARCH_PAGE_FUNDING, SPR_TAB_FINANCES_SUMMARY_0);
+ }
+};
+
+WindowBase* WindowResearchOpen()
+{
+ ResearchWindow* window = WindowFocusOrCreate(WindowClass::Research, WW_FUNDING, WH_FUNDING, WF_10);
+ window->SetPage(WINDOW_RESEARCH_PAGE_DEVELOPMENT);
+ return window;
+}
+
+static WidgetIndex GetWidgetIndexOffset(WidgetIndex baseWidgetIndex, WidgetIndex currentPageWidgetIndex)
+{
+ // Other windows that reuse the logic here will have different values for the widget enums, but they otherwise align to
+ // those in this class. Therefore, they can be referenced relative to the widget index for the page in this class, using
+ // the difference between them as an offset.
+ return baseWidgetIndex - currentPageWidgetIndex;
}
#pragma region Development page
-/**
- *
- * rct2: 0x006B6B38
- */
-static void WindowResearchDevelopmentMouseup(WindowBase* w, WidgetIndex widgetIndex)
+void WindowResearchDevelopmentMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
{
- switch (widgetIndex)
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+
+ if (widgetIndex == (WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset))
{
- case WIDX_CLOSE:
- WindowClose(*w);
- break;
- case WIDX_TAB_1:
- case WIDX_TAB_2:
- WindowResearchSetPage(w, widgetIndex - WIDX_TAB_1);
- break;
- case WIDX_LAST_DEVELOPMENT_BUTTON:
- News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
- break;
+ News::OpenSubject(News::ItemType::Research, gResearchLastItem->rawValue);
}
}
-/**
- *
- * rct2: 0x0069CBA6
- */
-static void WindowResearchDevelopmentUpdate(WindowBase* w)
+void WindowResearchDevelopmentPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex)
{
- // Tab animation
- if (++w->frame_no >= window_research_tab_animation_loops[w->page])
- w->frame_no = 0;
- WidgetInvalidate(*w, WIDX_TAB_1);
-}
+ // Offset the widget index to allow reuse from other windows
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
+ w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].type = WindowWidgetType::Empty;
-/**
- *
- * rct2: 0x006B6819
- */
-static void WindowResearchDevelopmentInvalidate(WindowBase* w)
-{
- if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT])
- {
- w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT];
- WindowInitScrollWidgets(*w);
- }
-
- WindowResearchSetPressedTab(w);
-
- window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::Empty;
+ // Display button to link to the last development, if there is one
if (gResearchLastItem.has_value())
{
auto type = gResearchLastItem->type;
- window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WindowWidgetType::FlatBtn;
+ w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].type = WindowWidgetType::FlatBtn;
const auto image = type == Research::EntryType::Ride ? SPR_NEW_RIDE : SPR_NEW_SCENERY;
- window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = ImageId(image);
+ w->widgets[WIDX_LAST_DEVELOPMENT_BUTTON + widgetOffset].image = ImageId(image);
}
}
-/**
- *
- * rct2: 0x006B689B
- */
-static void WindowResearchDevelopmentPaint(WindowBase* w, DrawPixelInfo& dpi)
+void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex)
{
- WindowDrawWidgets(*w, dpi);
- WindowResearchDrawTabImages(dpi, w);
-
- WindowResearchDevelopmentPagePaint(w, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
-}
-
-void WindowResearchDevelopmentPagePaint(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex)
-{
- baseWidgetIndex = baseWidgetIndex - WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP;
-
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
auto screenCoords = w->windowPos
- + ScreenCoordsXY{ 10, w->widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12 };
+ + ScreenCoordsXY{ 10, w->widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP + widgetOffset].top + 12 };
if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
{
@@ -348,7 +435,7 @@ void WindowResearchDevelopmentPagePaint(WindowBase* w, DrawPixelInfo& dpi, Widge
}
// Last development
- screenCoords = w->windowPos + ScreenCoordsXY{ 10, w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12 };
+ screenCoords = w->windowPos + ScreenCoordsXY{ 10, w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + widgetOffset].top + 12 };
if (gResearchLastItem.has_value())
{
@@ -387,48 +474,14 @@ void WindowResearchDevelopmentPagePaint(WindowBase* w, DrawPixelInfo& dpi, Widge
#pragma region Funding page
-/**
- *
- * rct2: 0x0069DB3F
- */
-static void WindowResearchFundingMouseup(WindowBase* w, WidgetIndex widgetIndex)
+void WindowResearchFundingMouseDown(WindowBase* w, WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
{
- switch (widgetIndex)
- {
- case WIDX_CLOSE:
- WindowClose(*w);
- break;
- case WIDX_TAB_1:
- case WIDX_TAB_2:
- WindowResearchSetPage(w, widgetIndex - WIDX_TAB_1);
- break;
- case WIDX_TRANSPORT_RIDES:
- case WIDX_GENTLE_RIDES:
- case WIDX_ROLLER_COASTERS:
- case WIDX_THRILL_RIDES:
- case WIDX_WATER_RIDES:
- case WIDX_SHOPS_AND_STALLS:
- case WIDX_SCENERY_AND_THEMING:
- {
- auto activeResearchTypes = gResearchPriorities;
- activeResearchTypes ^= 1 << (widgetIndex - WIDX_TRANSPORT_RIDES);
- auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
- GameActions::Execute(&gameAction);
- break;
- }
- }
-}
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
-/**
- *
- * rct2: 0x0069DB66
- */
-static void WindowResearchFundingMousedown(WindowBase* w, WidgetIndex widgetIndex, Widget* widget)
-{
- if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON)
+ if (widgetIndex != (WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset))
return;
- Widget* dropdownWidget = widget - 1;
+ Widget* dropdownWidget = &w->widgets[widgetIndex - 1];
for (std::size_t i = 0; i < std::size(ResearchFundingLevelNames); i++)
{
@@ -443,70 +496,69 @@ static void WindowResearchFundingMousedown(WindowBase* w, WidgetIndex widgetInde
Dropdown::SetChecked(currentResearchLevel, true);
}
-/**
- *
- * rct2: 0x0069DB6D
- */
-static void WindowResearchFundingDropdown(WindowBase* w, WidgetIndex widgetIndex, int32_t dropdownIndex)
+void WindowResearchFundingMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex)
{
- if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON || dropdownIndex == -1)
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
+
+ switch (widgetIndex - widgetOffset)
+ {
+ case WIDX_TRANSPORT_RIDES:
+ case WIDX_GENTLE_RIDES:
+ case WIDX_ROLLER_COASTERS:
+ case WIDX_THRILL_RIDES:
+ case WIDX_WATER_RIDES:
+ case WIDX_SHOPS_AND_STALLS:
+ case WIDX_SCENERY_AND_THEMING:
+ {
+ auto activeResearchTypes = gResearchPriorities;
+ activeResearchTypes ^= 1uLL << (widgetIndex - (WIDX_TRANSPORT_RIDES + widgetOffset));
+ auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
+ GameActions::Execute(&gameAction);
+ break;
+ }
+ }
+}
+
+void WindowResearchFundingDropdown(WidgetIndex widgetIndex, int32_t selectedIndex, WidgetIndex baseWidgetIndex)
+{
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
+
+ if (widgetIndex != (WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset) || selectedIndex == -1)
return;
- auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, dropdownIndex);
+ auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, selectedIndex);
GameActions::Execute(&gameAction);
}
-/**
- *
- * rct2: 0x0069DC23
- */
-static void WindowResearchFundingUpdate(WindowBase* w)
+void WindowResearchFundingPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex)
{
- // Tab animation
- if (++w->frame_no >= window_research_tab_animation_loops[w->page])
- w->frame_no = 0;
- WidgetInvalidate(*w, WIDX_TAB_2);
-}
+ auto widgetOffset = GetWidgetIndexOffset(baseWidgetIndex, WIDX_RESEARCH_FUNDING);
-/**
- *
- * rct2: 0x0069DA64
- */
-static void WindowResearchFundingInvalidate(WindowBase* w)
-{
- if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING])
+ if ((gParkFlags & PARK_FLAGS_NO_MONEY) || gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
{
- w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING];
- WindowInitScrollWidgets(*w);
- }
-
- WindowResearchSetPressedTab(w);
-
- if ((gParkFlags & PARK_FLAGS_NO_MONEY) || (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL))
- {
- window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::Empty;
- window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Empty;
+ w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].type = WindowWidgetType::Empty;
+ w->widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset].type = WindowWidgetType::Empty;
}
else
{
- window_research_funding_widgets[WIDX_FUNDING_GROUP].type = WindowWidgetType::Groupbox;
- window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WindowWidgetType::DropdownMenu;
- window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WindowWidgetType::Button;
-
- // Current funding
- int32_t currentResearchLevel = gResearchFundingLevel;
- window_research_funding_widgets[WIDX_RESEARCH_FUNDING].text = ResearchFundingLevelNames[currentResearchLevel];
+ w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].type = WindowWidgetType::DropdownMenu;
+ w->widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON + widgetOffset].type = WindowWidgetType::Button;
}
+ // Current funding
+ int32_t currentResearchLevel = gResearchFundingLevel;
+ w->widgets[WIDX_RESEARCH_FUNDING + widgetOffset].text = ResearchFundingLevelNames[currentResearchLevel];
+
// Checkboxes
uint8_t activeResearchTypes = gResearchPriorities;
+ int32_t uncompletedResearchTypes = gResearchUncompletedCategories;
for (int32_t i = 0; i < 7; i++)
{
int32_t mask = 1 << i;
- int32_t widgetMask = 1 << (i + WIDX_TRANSPORT_RIDES);
+ int32_t widgetMask = 1uLL << (i + WIDX_TRANSPORT_RIDES + widgetOffset);
// Set checkbox disabled if research type is complete
- if (gResearchUncompletedCategories & mask)
+ if (uncompletedResearchTypes & mask)
{
w->disabled_widgets &= ~widgetMask;
@@ -524,19 +576,7 @@ static void WindowResearchFundingInvalidate(WindowBase* w)
}
}
-/**
- *
- * rct2: 0x0069DAF0
- */
-static void WindowResearchFundingPaint(WindowBase* w, DrawPixelInfo& dpi)
-{
- WindowDrawWidgets(*w, dpi);
- WindowResearchDrawTabImages(dpi, w);
-
- WindowResearchFundingPagePaint(w, dpi, WIDX_RESEARCH_FUNDING);
-}
-
-void WindowResearchFundingPagePaint(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex)
+void WindowResearchFundingDraw(WindowBase* w, DrawPixelInfo& dpi)
{
if (gParkFlags & PARK_FLAGS_NO_MONEY)
return;
@@ -548,75 +588,3 @@ void WindowResearchFundingPagePaint(WindowBase* w, DrawPixelInfo& dpi, WidgetInd
}
#pragma endregion
-
-#pragma region Common
-
-/**
- *
- * rct2: 0x0069CAC5
- */
-static void WindowResearchSetPage(WindowBase* w, int32_t page)
-{
- w->page = page;
- w->frame_no = 0;
- w->RemoveViewport();
-
- w->hold_down_widgets = 0;
- w->event_handlers = window_research_page_events[page];
- w->widgets = window_research_page_widgets[page];
- w->disabled_widgets = 0;
- w->pressed_widgets = 0;
-
- w->Invalidate();
- if (w->page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
- {
- w->width = WW_DEVELOPMENT;
- w->height = WH_DEVELOPMENT;
- }
- else
- {
- w->width = WW_FUNDING;
- w->height = WH_FUNDING;
- }
- WindowEventResizeCall(w);
- WindowEventInvalidateCall(w);
-
- WindowInitScrollWidgets(*w);
- w->Invalidate();
-}
-
-static void WindowResearchSetPressedTab(WindowBase* w)
-{
- int32_t i;
- for (i = 0; i < WINDOW_RESEARCH_PAGE_COUNT; i++)
- w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
- w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
-}
-
-static void WindowResearchDrawTabImage(DrawPixelInfo& dpi, WindowBase* w, int32_t page, int32_t spriteIndex)
-{
- WidgetIndex widgetIndex = WIDX_TAB_1 + page;
-
- if (!WidgetIsDisabled(*w, widgetIndex))
- {
- if (w->page == page)
- {
- int32_t frame = w->frame_no / 2;
- if (page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
- frame %= 8;
- spriteIndex += frame;
- }
-
- GfxDrawSprite(
- dpi, ImageId(spriteIndex),
- w->windowPos + ScreenCoordsXY{ w->widgets[widgetIndex].left, w->widgets[widgetIndex].top });
- }
-}
-
-static void WindowResearchDrawTabImages(DrawPixelInfo& dpi, WindowBase* w)
-{
- WindowResearchDrawTabImage(dpi, w, WINDOW_RESEARCH_PAGE_DEVELOPMENT, SPR_TAB_FINANCES_RESEARCH_0);
- WindowResearchDrawTabImage(dpi, w, WINDOW_RESEARCH_PAGE_FUNDING, SPR_TAB_FINANCES_SUMMARY_0);
-}
-
-#pragma endregion
diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h
index 5c09586b45..fbca14f94b 100644
--- a/src/openrct2-ui/windows/Window.h
+++ b/src/openrct2-ui/windows/Window.h
@@ -120,8 +120,14 @@ WindowBase* WindowMapOpen();
void WindowMapReset();
WindowBase* WindowResearchOpen();
-void WindowResearchDevelopmentPagePaint(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex);
-void WindowResearchFundingPagePaint(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex);
+void WindowResearchDevelopmentMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex);
+void WindowResearchDevelopmentPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex);
+void WindowResearchDevelopmentDraw(WindowBase* w, DrawPixelInfo& dpi, WidgetIndex baseWidgetIndex);
+void WindowResearchFundingMouseDown(WindowBase* w, WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex);
+void WindowResearchFundingMouseUp(WidgetIndex widgetIndex, WidgetIndex baseWidgetIndex);
+void WindowResearchFundingDropdown(WidgetIndex widgetIndex, int32_t selectedIndex, WidgetIndex baseWidgetIndex);
+void WindowResearchFundingPrepareDraw(WindowBase* w, WidgetIndex baseWidgetIndex);
+void WindowResearchFundingDraw(WindowBase* w, DrawPixelInfo& dpi);
WindowBase* WindowNewRideOpen();
WindowBase* WindowNewRideOpenResearch();