#pragma once #include #include "entt/entity/entity.hpp" #include "BuildingId.h" #include "SelectionContext.h" class QWidget; class SelectionContent; class Simulation; // What is currently selected, in the selection panel's terms. The two categories are // mutually exclusive (REQ-UI-SELECTION-CATEGORIES): either buildings is non-empty, or // actors and/or debris are, never both. struct SelectionRequest { std::vector buildings; std::vector actors; std::vector debris; bool isEmpty() const { return buildings.empty() && actors.empty() && debris.empty(); } }; // One entry of the content catalog (REQ-UI-SELECTION-CONTENT). Selections that share an // entry get the same content and differ only in the name and symbol in the header. enum class SelectionContentKind { None, // nothing selected: the panel hides itself entirely RecipeProduction, // Miner, Assembler, Smelter, Reprocessing Plant Shipyard, Storage, // Salvage Bay Hq, Belt, // Belt, Tunnel Entry, Tunnel Exit Splitter, MultiBuilding, Ship, Station, Debris, FieldMulti, }; // Identifies the card on screen. The panel rebuilds when this changes and only refreshes // otherwise, so a construction site finishing swaps the card while a progress counter // running does not. struct ContentKey { SelectionContentKind kind = SelectionContentKind::None; bool isSite = false; bool operator==(const ContentKey& other) const { return kind == other.kind && isSite == other.isSite; } bool operator!=(const ContentKey& other) const { return !(*this == other); } }; // The card this selection calls for. This is where REQ-UI-SELECTION-AGGREGATE is // decided: a multi-selection that aggregates resolves to the single-object kind, and // everything else to one of the two count summaries. ContentKey chooseContent(const SelectionRequest& request, Simulation& sim); // Builds the card. Returns nullptr for SelectionContentKind::None. SelectionContent* createContent(const ContentKey& key, const SelectionRequest& request, const SelectionContext& context, QWidget* parent);