The three restart paths each repeated the same config + visuals reload with its own try/catch and error dialog. Only that shared part is extracted; each site keeps its own follow-up (ResetCommand vs. direct Simulation::reset) and its own error-path cleanup. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
94 lines
3.5 KiB
C++
94 lines
3.5 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QWidget>
|
|
|
|
#include "BuildingId.h"
|
|
#include "EscapeMenuRequestedEvent.h"
|
|
#include "EventHandler.h"
|
|
#include "GameConfig.h"
|
|
#include "GameOverEvent.h"
|
|
#include "LayoutDialogRequestedEvent.h"
|
|
#include "ModalDimOverlay.h"
|
|
#include "WinEvent.h"
|
|
#include "RecipeSelectionRequestedEvent.h"
|
|
#include "SchematicChoicesAvailableEvent.h"
|
|
#include "ShipLayout.h"
|
|
#include "ShipLayoutBlueprint.h"
|
|
#include "Tick.h"
|
|
#include "VisualsConfig.h"
|
|
|
|
struct ParsedReplay;
|
|
class Simulation;
|
|
class GameWorldView;
|
|
class HeaderBar;
|
|
class SelectedBuildingPanel;
|
|
class BuildButtonGrid;
|
|
class BlueprintPanel;
|
|
class ItemIconCache;
|
|
class QCloseEvent;
|
|
class QResizeEvent;
|
|
|
|
class MainWindow : public QWidget,
|
|
public CombinedEventHandler<SchematicChoicesAvailableEvent,
|
|
GameOverEvent,
|
|
WinEvent,
|
|
EscapeMenuRequestedEvent,
|
|
LayoutDialogRequestedEvent,
|
|
RecipeSelectionRequestedEvent>
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
MainWindow(Simulation* sim, const std::string& configDir,
|
|
std::shared_ptr<ParsedReplay> replay = nullptr, QWidget* parent = nullptr);
|
|
~MainWindow() override;
|
|
|
|
protected:
|
|
void resizeEvent(QResizeEvent* event) override;
|
|
void closeEvent(QCloseEvent* event) override;
|
|
|
|
private:
|
|
void handleEvent(std::shared_ptr<const SchematicChoicesAvailableEvent> event) override;
|
|
void handleEvent(std::shared_ptr<const GameOverEvent> event) override;
|
|
void handleEvent(std::shared_ptr<const WinEvent> event) override;
|
|
void handleEvent(std::shared_ptr<const EscapeMenuRequestedEvent> event) override;
|
|
void handleEvent(std::shared_ptr<const LayoutDialogRequestedEvent> event) override;
|
|
void handleEvent(std::shared_ptr<const RecipeSelectionRequestedEvent> event) override;
|
|
|
|
// Reloads the game config and visuals.toml from disk (REQ-CFG-RELOAD), shared
|
|
// by every restart path. On success the reloaded visuals are applied to this
|
|
// window and the fresh GameConfig is returned; on failure a modal error dialog
|
|
// is shown and std::nullopt is returned, leaving the window state untouched.
|
|
std::optional<GameConfig> reloadConfig();
|
|
|
|
// Opens the shipyard layout configuration dialog for the given schematic and
|
|
// current layout, applying the result via SetShipLayoutCommand (REQ-MOD-UI-DIALOG).
|
|
void openShipLayoutDialog(BuildingId shipyardId,
|
|
const std::string& schematicId,
|
|
const ShipLayoutConfig& currentLayout);
|
|
void layoutPanels();
|
|
|
|
private:
|
|
std::string m_configDir;
|
|
VisualsConfig m_visuals;
|
|
Simulation* m_sim;
|
|
// One per-item icon cache for the whole window (REQ-UI-ITEM-ICON): the header,
|
|
// build grid, world view, and recipe dialog all rasterize the same SVGs.
|
|
std::unique_ptr<ItemIconCache> m_itemIcons;
|
|
GameWorldView* m_gameWorldView;
|
|
HeaderBar* m_headerBar;
|
|
SelectedBuildingPanel* m_selectedBuildingPanel;
|
|
BuildButtonGrid* m_buildButtonGrid;
|
|
BlueprintPanel* m_blueprintPanel;
|
|
QWidget* m_sidePanel;
|
|
ModalDimOverlay* m_dimOverlay = nullptr;
|
|
|
|
std::vector<ShipLayoutBlueprint> m_layoutBlueprints;
|
|
std::shared_ptr<ParsedReplay> m_replay; // non-null => view-only playback
|
|
};
|