stop hovering when the cursor points at no tile

A cursor resting on a panel or outside the window kept whatever it last
pointed at: the ghost, the tunnel preview, the deconstruct tint all stayed
put, because "not hovering" was not a state the build mode could hold. Make
both ghost tiles optional, clear the hover with them, and re-derive it when
the cursor comes back or a mode is entered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
This commit is contained in:
2026-08-17 15:19:22 +02:00
parent 9490a96e12
commit b2148f00ac
7 changed files with 167 additions and 31 deletions

View File

@@ -54,6 +54,15 @@ public:
// Backs out of whichever mode is active, if any (the Q key and right-click).
void exitCurrentMode();
// --- hover ----------------------------------------------------------------
// Drops everything that follows from a cursor pointing at the world — both
// ghost tiles, placement validity, the resolved tunnel end, the transfer flag,
// the deconstruct hover — for a cursor that points at no tile at all, because it
// rests on a panel or has left the window (REQ-BLD-GHOST). The active mode is
// untouched: the player is still building, just not over anything. A belt drag's
// path is untouched too, since a drag keeps hovering while the button is held.
void clearHover();
// --- builder mode ---------------------------------------------------------
// Only meaningful while isBuilderMode().
BuildingType getBuilderType() const;
@@ -64,7 +73,9 @@ public:
// tunnel mode, the plain builder type otherwise.
BuildingType getEffectiveBuilderType() const;
QPoint getGhostTile() const;
// Unset while the cursor points at no tile (clearHover), which is the one case
// where builder mode draws no ghost at all.
const std::optional<QPoint>& getGhostTile() const;
Rotation getGhostRotation() const;
bool isGhostValid() const;
void setGhostTile(QPoint tile);
@@ -92,7 +103,8 @@ public:
// Mutable so the caller can rotate the layout in place; rotating a blueprint
// needs building footprints from the config, which does not belong here.
Blueprint& getMutableBlueprint();
QPoint getBlueprintGhostTile() const;
// Unset for a cursor pointing at no tile, as for the builder ghost above.
const std::optional<QPoint>& getBlueprintGhostTile() const;
void setBlueprintGhostTile(QPoint tile);
// Whether the ghost under the cursor would hand its settings to the building
@@ -115,7 +127,7 @@ private:
BuildMode m_mode = BuildMode::None;
BuildingType m_builderType = BuildingType::Belt;
QPoint m_ghostTile;
std::optional<QPoint> m_ghostTile;
Rotation m_ghostRotation = Rotation::East;
bool m_ghostValid = false;
BuildingType m_tunnelGhostType = BuildingType::TunnelEntry;
@@ -125,9 +137,9 @@ private:
QPoint m_beltDragAnchor;
std::vector<BeltPathTile> m_beltDragPath;
Blueprint m_blueprint;
QPoint m_blueprintGhostTile;
bool m_hoveredGhostIsTransfer = false;
Blueprint m_blueprint;
std::optional<QPoint> m_blueprintGhostTile;
bool m_hoveredGhostIsTransfer = false;
std::optional<BuildingId> m_deconstructHoverBuildingId;
};