#pragma once #include #include #include #include #include #include #include #include "GameConfig.h" #include "Rotation.h" #include "ShipLayout.h" #include "ShipLayoutBlueprint.h" class QPushButton; class ShipStatsPanel; class ShipLayoutDialog : public QDialog { Q_OBJECT public: ShipLayoutDialog(const GameConfig* config, const std::string& shipId, const ShipLayoutConfig& currentLayout, std::vector& allBlueprints, std::set unlockedModuleIds, bool debugDraw, QWidget* parent = nullptr); std::optional getResult() const; protected: void keyPressEvent(QKeyEvent* event) override; signals: void gridCellClicked(QPoint cell); private slots: void onModuleButtonClicked(int index); void onConfirm(); void onCancel(); public: struct CellInfo { bool buildable; std::optional moduleIndex; // nullopt if empty }; private: void rebuildOccupancy(); void updateGridWidget(); void updateStats(); bool canPlaceModule(const ModuleDef& def, QPoint position, Rotation rotation) const; std::vector rotatedMask(const ModuleDef& def, Rotation rotation) const; void loadLayoutBlueprint(const std::vector& modules); const GameConfig* m_config; std::string m_shipId; std::set m_unlockedModuleIds; std::vector m_shipLayout; int m_rows; int m_cols; std::vector m_placedModules; std::vector> m_grid; // The module to place, as an index into config modules; nullopt when no // module is selected for placement. m_removeMode is a separate mode in which // clicking a cell removes the module there (mutually exclusive with a // selected module). std::optional m_activeModuleIndex; bool m_removeMode = false; Rotation m_currentRotation; std::vector m_moduleButtons; QPushButton* m_removeButton; QWidget* m_gridWidget; ShipStatsPanel* m_statsPanel; bool m_debugDraw; std::optional m_result; };