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();