#pragma once #include #include #include #include #include #include #include #include "BuilderModeExitedEvent.h" #include "BuildHotkeyPressedEvent.h" #include "BuildingBlocksChangedEvent.h" #include "BuildingType.h" #include "DeconstructModeChangedEvent.h" #include "EventHandler.h" #include "FloatingPanel.h" #include "GameConfig.h" #include "UnlockedBuildingsChangedEvent.h" class QPushButton; class Simulation; class BuildingIconCache; class ItemIconCache; // The build menu: one horizontal row of build buttons floating over the game world // view (REQ-UI-BUILD-BAR). The bar is sized to its buttons and centers itself along the // bottom edge of the rect its owner places it in. It is placed first of the floating // widgets and so takes the space it wants outright: nothing ever moves it aside, and the // widgets placed after it keep out of its way instead. class BuildButtonBar : public QWidget, public FloatingPanel, public CombinedEventHandler { Q_OBJECT public: // buildingIcons supplies each button's chip icon (REQ-UI-BUILD-ICON) and itemIcons // the building_block icon shown in each button's cost (REQ-UI-BUILD-COST). Both are // window-wide caches; neither is owned, and both must outlive this widget. BuildButtonBar(Simulation* sim, const GameConfig* config, BuildingIconCache* buildingIcons, ItemIconCache* itemIcons, QWidget* parent = nullptr); ~BuildButtonBar() override; // Centers the bar along the bottom edge of the game world view's rect, given in the // bar's parent coordinates (REQ-UI-BUILD-BAR). Nothing is occupied yet when the bar // is placed, so it ignores what it is handed there. void placeIn(const QRect& viewRect, const std::vector& occupiedRects) override; void clearActiveButton(); private: // Re-evaluates which build buttons are enabled from the current building block // stock (read from the simulation). If the currently selected tool can no longer // be afforded, it exits builder mode so the button does not stay selected. void updateAffordability(); // Re-evaluates which build buttons are visible from the current per-building // unlock state (REQ-LOCK-BUILDING); a locked building type's button is hidden. void updateVisibility(); void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; private slots: void onBuildButton(int index); private: Simulation* m_sim; const GameConfig* m_config; BuildingIconCache* m_buildingIcons; // Not owned; lives in MainWindow. ItemIconCache* m_itemIcons; // Not owned; lives in MainWindow. std::vector m_types; std::vector m_buttons; std::map m_costs; std::optional m_activeIndex; QPushButton* m_deconstructButton; };