#pragma once #include #include #include "DebrisSelectionChangedEvent.h" #include "DebugDrawToggledEvent.h" #include "EntitySelectionChangedEvent.h" #include "EventHandler.h" #include "PlayerCommandsAppliedEvent.h" #include "SelectionChangedEvent.h" #include "TickAdvancedEvent.h" #include "selection/SelectionContentFactory.h" #include "selection/SelectionContext.h" struct GameConfig; struct VisualsConfig; class BuildingIconCache; class ItemIconCache; class SelectionContent; class Simulation; class QScrollArea; class QVBoxLayout; // Shows the current selection. The panel itself renders nothing: it arbitrates between // the two selection categories (REQ-UI-SELECTION-CATEGORIES), picks the card that fits // what is selected (REQ-UI-SELECTION-CONTENT), and hosts exactly one of them at a time. // What each card looks like lives in src/ui/selection/. // // The panel floats over the game world view rather than occupying a column of its own // (REQ-UI-SELECTION-PANEL): it sizes itself to its card, anchors to the right edge of // the band its owner hands it, and hides itself entirely while nothing is selected // (REQ-UI-EMPTY-SELECTION). class SelectionPanel : public QWidget, public CombinedEventHandler { Q_OBJECT public: // visuals, itemIcons and buildingIcons are window-wide rendering resources the cards // draw from; none is owned and all must outlive this widget. SelectionPanel(Simulation* sim, const GameConfig* config, const VisualsConfig* visuals, ItemIconCache* itemIcons, BuildingIconCache* buildingIcons, QWidget* parent = nullptr); ~SelectionPanel() override; // Confines the panel to the given band of the game world view: it right-aligns // within it and centers vertically in it. The band is the world view less the strip // the build button bar occupies, so the two never overlap and the bar never has to // move (REQ-UI-SELECTION-PANEL, REQ-UI-BUILD-BAR). void anchorTo(const QRect& bandRect); private: 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; void handleEvent(std::shared_ptr event) override; // Re-reads the live values of the card on screen. When the selection now calls for a // different card -- a construction site finishing is the case that matters -- it // rebuilds instead, because a card never changes its own shape. void refreshContent(); // Replaces the card with the one the current selection calls for. void rebuildContent(); // Shows the panel while a card exists and hides it otherwise // (REQ-UI-EMPTY-SELECTION), re-fitting it to the card while it is shown. void updateVisibility(); // Re-fits the panel to its card within the anchored band. void refit(); SelectionContext m_context; // Read through m_context by the cards that need it, so a toggle reaches the card on // screen without it having to subscribe to the event itself. bool m_debugDrawEnabled = false; SelectionRequest m_request; ContentKey m_contentKey; SelectionContent* m_content = nullptr; // The band the panel confines itself to, in the coordinates of its parent; null // until the owner has anchored it for the first time. QRect m_bandRect; // Scrolls the card once it outgrows the band (REQ-UI-SELECTION-PANEL). The card is a // child of m_body, not of the panel itself. QScrollArea* m_scrollArea; QWidget* m_body; QVBoxLayout* m_bodyLayout; };