Every display naming an item now shows that item's production tooltip, not only the selection panel's chips: the header block stock, the total cost of a building multi-selection, the remaining scrap of a debris selection, the icons of every recipe summary, and a blueprint card's cost. ItemTooltip moves out of the selection panel and takes an ItemTooltipContext of its own -- an item is named all over the UI, and the panel's context carries visuals and a debug flag no tooltip reads. A recipe line wraps each icon with its amount so the pair can be pointed at as one statement, and attaches tooltips only where asked: a module button and the item tooltip itself draw the same line and stay silent. Hover only wherever the display sits on something the player clicks, whose click is not free to explain. Note that a recipe line on an option button can no longer be transparent to the mouse -- Qt never looks inside a transparent widget for the cursor -- so it relies on press propagation to keep picking the option. The header block stock loses world.building_blocks_tooltip, showing what every other block icon shows instead. The Expand button keeps no tooltip: its cost is painted into its face with nowhere to hang one, and the button is due to be removed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
113 lines
3.4 KiB
C++
113 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QPoint>
|
|
|
|
#include "GameConfig.h"
|
|
#include "ItemTooltipContext.h"
|
|
#include "ModalDialog.h"
|
|
#include "Rotation.h"
|
|
#include "ShipLayout.h"
|
|
#include "ShipLayoutBlueprint.h"
|
|
|
|
class ItemIconCache;
|
|
class QPushButton;
|
|
class RecipeLineRow;
|
|
class SectionBox;
|
|
class ShipStatsPanel;
|
|
|
|
class ShipLayoutDialog : public ModalDialog
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
// The context's item cache draws what each module costs and what the layout costs in
|
|
// total (REQ-MOD-UI-DIALOG, REQ-MOD-UI-STATS-PANEL), and the rest of it lets the
|
|
// build cost explain the items it names (REQ-UI-ITEM-VALUE-TOOLTIP). Nothing in it is
|
|
// owned.
|
|
ShipLayoutDialog(const std::string& shipId,
|
|
const ShipLayoutConfig& currentLayout,
|
|
std::vector<ShipLayoutBlueprint>& allBlueprints,
|
|
std::set<std::string> unlockedModuleIds,
|
|
bool debugDraw,
|
|
const ItemTooltipContext& context,
|
|
QWidget* parent = nullptr);
|
|
|
|
std::optional<ShipLayoutConfig> getResult() const;
|
|
|
|
bool isDismissible() const override;
|
|
|
|
public slots:
|
|
// Backs out one level per dismissal, as Q does in the game world: the module being
|
|
// placed, then remove mode, then the dialog itself, which discards the session
|
|
// (REQ-UI-DIALOG-DISMISS). So a single press or click never both leaves a mode and
|
|
// throws the session away.
|
|
void requestDismiss() override;
|
|
|
|
protected:
|
|
void keyPressEvent(QKeyEvent* event) override;
|
|
|
|
signals:
|
|
void gridCellClicked(QPoint cell);
|
|
|
|
private slots:
|
|
void onModuleButtonClicked(int index);
|
|
// Enters remove mode, or leaves it when it is already active (REQ-MOD-REMOVE).
|
|
// Reached by the Remove button and by a dismissal, which leaves the mode on its way
|
|
// out of the dialog (REQ-UI-DIALOG-DISMISS).
|
|
void onRemoveButtonClicked();
|
|
void onConfirm();
|
|
void onCancel();
|
|
|
|
public:
|
|
struct CellInfo
|
|
{
|
|
bool buildable;
|
|
std::optional<int> moduleIndex; // nullopt if empty
|
|
};
|
|
|
|
private:
|
|
|
|
void rebuildOccupancy();
|
|
void updateGridWidget();
|
|
void updateStats();
|
|
bool canPlaceModule(const ModuleDef& def, QPoint position, Rotation rotation) const;
|
|
std::vector<std::string> rotatedMask(const ModuleDef& def, Rotation rotation) const;
|
|
void loadLayoutBlueprint(const std::vector<PlacedModule>& modules);
|
|
|
|
ItemTooltipContext m_context;
|
|
const GameConfig* m_config;
|
|
ItemIconCache* m_itemIcons;
|
|
std::string m_shipId;
|
|
std::set<std::string> m_unlockedModuleIds;
|
|
std::vector<std::string> m_shipLayout;
|
|
int m_rows;
|
|
int m_cols;
|
|
|
|
std::vector<PlacedModule> m_placedModules;
|
|
std::vector<std::vector<CellInfo>> 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<int> m_activeModuleIndex;
|
|
bool m_removeMode = false;
|
|
Rotation m_currentRotation;
|
|
|
|
std::vector<QPushButton*> m_moduleButtons;
|
|
QPushButton* m_removeButton;
|
|
QWidget* m_gridWidget;
|
|
ShipStatsPanel* m_statsPanel;
|
|
SectionBox* m_buildCostSection;
|
|
RecipeLineRow* m_buildCostLine;
|
|
bool m_debugDraw;
|
|
|
|
std::optional<ShipLayoutConfig> m_result;
|
|
};
|