#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 "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; its owner hands it the // world view's rect through anchorTo() and it centers itself along that rect's // bottom edge. class BuildButtonBar : public QWidget, 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). The rect is remembered, so a // re-center later driven by an unlock needs no second call from the owner. void anchorTo(const QRect& worldViewRect); // Height of the strip the bar occupies along the bottom of the world view: its own // height plus the margin below it. The selection panel keeps out of this strip, and // the bar never moves for the panel in return (REQ-UI-BUILD-BAR). int getStripHeightPx() const; 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(); // Shrinks the bar to its currently shown buttons and re-centers it in the // anchored rect (REQ-UI-BUILD-BAR). Does nothing until anchorTo() supplied that // rect, so the construction-time call is harmless. void recenter(); 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; QRect m_viewRect; };