[Game] Refactor: rename hovered to restore previous semantics (#7816)

This commit is contained in:
RickyRister 2026-11-09 04:54:10 -07:00 • committed by GitHub
parent 9793a0df4a
commit 3f3aff9408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 92 additions and 94 deletions

View file

@ -57,7 +57,7 @@ static constexpr int FADE_DURATION_MS = 140;
AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id) AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef, PlayerLogic *_owner, int _id)
: ArrowTarget(_owner, parent), state(new CardState(this, nullptr, cardRef, _id)), tapAngle(0), : ArrowTarget(_owner, parent), state(new CardState(this, nullptr, cardRef, _id)), tapAngle(0),
bgColor(Qt::transparent), isHovered(false), isHoverHighlighted(false), realZValue(0) bgColor(Qt::transparent), isHovered(false), isHoverZoomed(false), realZValue(0)
{ {
setCursor(Qt::OpenHandCursor); setCursor(Qt::OpenHandCursor);
setFlag(ItemIsSelectable); setFlag(ItemIsSelectable);
@ -82,10 +82,10 @@ AbstractCardItem::AbstractCardItem(QGraphicsItem *parent, const CardRef &cardRef
// the clip escape and the ancestor lift all stay put while the card is still large, // the clip escape and the ancestor lift all stay put while the card is still large,
// so siblings and the clip container cannot cut through the shrinking card. // so siblings and the clip container cannot cut through the shrinking card.
connect(hoverZoom, &QPropertyAnimation::finished, this, [this] { connect(hoverZoom, &QPropertyAnimation::finished, this, [this] {
if (!isHovered) { if (!isHoverZoomed) {
// The cursor may still rest on the card (e.g. wheel-up reverts the zoom), // The cursor may still rest on the card (e.g. wheel-up reverts the zoom),
// in which case the highlight keeps it raised. // in which case the highlight keeps it raised.
setZValue(isHoverHighlighted ? ZValues::HOVERED_CARD : realZValue); setZValue(isHovered ? ZValues::HOVERED_CARD : realZValue);
// Final repaint at the settled footprint: with no scale delta the animation // Final repaint at the settled footprint: with no scale delta the animation
// emits no per-frame updates, and zones would keep a stale clip hole behind. // emits no per-frame updates, and zones would keep a stale clip hole behind.
if (scene()) { if (scene()) {
@ -170,7 +170,7 @@ void AbstractCardItem::setRealZValue(qreal _zValue)
// During hover, zValue is overridden to HOVERED_CARD. Layout operations // During hover, zValue is overridden to HOVERED_CARD. Layout operations
// like reorganizeCards() call setRealZValue() on all cards including the // like reorganizeCards() call setRealZValue() on all cards including the
// hovered one — skip setZValue() here to avoid clobbering the override. // hovered one — skip setZValue() here to avoid clobbering the override.
if (!isHovered && !isHoverHighlighted) { if (!isHovered && !isHoverZoomed) {
setZValue(_zValue); setZValue(_zValue);
} }
} }
@ -268,9 +268,9 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
painter->setRenderHint(QPainter::Antialiasing, false); painter->setRenderHint(QPainter::Antialiasing, false);
if (isSelected() || isHovered || isHoverHighlighted) { if (isSelected() || isHovered || isHoverZoomed) {
QPen pen; QPen pen;
if (isHovered || isHoverHighlighted) { if (isHovered || isHoverZoomed) {
pen.setColor(Qt::yellow); pen.setColor(Qt::yellow);
} }
if (isSelected()) { if (isSelected()) {
@ -284,13 +284,13 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
painter->restore(); painter->restore();
} }
void AbstractCardItem::setHovered(bool _hovered) void AbstractCardItem::setHoverZoomed(bool _hoverZoomed)
{ {
if (isHovered == _hovered) { if (isHoverZoomed == _hoverZoomed) {
return; return;
} }
if (_hovered) { if (_hoverZoomed) {
processHoverEvent(); processHoverEvent();
} else { } else {
// Mark the hovered card's current scene footprint dirty so overlapped // Mark the hovered card's current scene footprint dirty so overlapped
@ -304,11 +304,11 @@ void AbstractCardItem::setHovered(bool _hovered)
} }
} }
isHovered = _hovered; isHoverZoomed = _hoverZoomed;
// The stacking override is one-directional: it applies the moment the hover starts // The stacking override is one-directional: it applies the moment the hover starts
// and only drops once the shrink-out finishes (see the hoverZoom finished handler). // and only drops once the shrink-out finishes (see the hoverZoom finished handler).
// Restoring it here would let siblings paint over the still-enlarged card. // Restoring it here would let siblings paint over the still-enlarged card.
if (_hovered) { if (_hoverZoomed) {
setZValue(ZValues::HOVERED_CARD); setZValue(ZValues::HOVERED_CARD);
} }
// Scale about the center in both directions: at scale 1 the origin is moot, // Scale about the center in both directions: at scale 1 the origin is moot,
@ -320,7 +320,7 @@ void AbstractCardItem::setHovered(bool _hovered)
// The target is constant ON-SCREEN pixels: divide out the board view zoom so // The target is constant ON-SCREEN pixels: divide out the board view zoom so
// fullscreen (or zoomed) boards don't overshoot while the fixed-size panel matches. // fullscreen (or zoomed) boards don't overshoot while the fixed-size panel matches.
qreal target = 1.0; qreal target = 1.0;
if (_hovered && SettingsCache::instance().cardsDisplay().getScaleCards()) { if (_hoverZoomed && SettingsCache::instance().cardsDisplay().getScaleCards()) {
const qreal w = boundingRect().width(); const qreal w = boundingRect().width();
qreal viewScale = 1.0; qreal viewScale = 1.0;
if (scene() && !scene()->views().isEmpty()) { if (scene() && !scene()->views().isEmpty()) {
@ -335,24 +335,24 @@ void AbstractCardItem::setHovered(bool _hovered)
hoverZoom->stop(); hoverZoom->stop();
hoverZoom->setStartValue(scale()); hoverZoom->setStartValue(scale());
hoverZoom->setEndValue(target); hoverZoom->setEndValue(target);
hoverZoom->setDuration(_hovered ? HOVER_ZOOM_IN_MS : HOVER_ZOOM_OUT_MS); hoverZoom->setDuration(_hoverZoomed ? HOVER_ZOOM_IN_MS : HOVER_ZOOM_OUT_MS);
hoverZoom->start(); hoverZoom->start();
update(); update();
} }
void AbstractCardItem::setHoverHighlighted(bool highlighted) void AbstractCardItem::setHovered(bool _hovered)
{ {
if (isHoverHighlighted == highlighted) { if (isHovered == _hovered) {
return; return;
} }
if (highlighted) { if (_hovered) {
// The card-info widget listens for this: hovering still updates it right away. // The card-info widget listens for this: hovering still updates it right away.
processHoverEvent(); processHoverEvent();
} }
isHoverHighlighted = highlighted; isHovered = _hovered;
if (highlighted) { if (_hovered) {
setZValue(ZValues::HOVERED_CARD); setZValue(ZValues::HOVERED_CARD);
} }
@ -368,10 +368,10 @@ void AbstractCardItem::setHoverHighlighted(bool highlighted)
setTransformOriginPoint(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F); setTransformOriginPoint(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F);
hoverZoom->stop(); hoverZoom->stop();
hoverZoom->setStartValue(scale()); hoverZoom->setStartValue(scale());
hoverZoom->setEndValue(highlighted ? LEGACY_HOVER_SCALE : 1.0); hoverZoom->setEndValue(_hovered ? LEGACY_HOVER_SCALE : 1.0);
hoverZoom->setDuration(highlighted ? HOVER_ZOOM_IN_MS : HOVER_ZOOM_OUT_MS); hoverZoom->setDuration(_hovered ? HOVER_ZOOM_IN_MS : HOVER_ZOOM_OUT_MS);
hoverZoom->start(); hoverZoom->start();
} else if (!highlighted && !isHovered && hoverZoom->state() != QAbstractAnimation::Running) { } else if (!_hovered && !isHoverZoomed && hoverZoom->state() != QAbstractAnimation::Running) {
// A zoomed card keeps its raised z until the shrink-out finishes (its finished // A zoomed card keeps its raised z until the shrink-out finishes (its finished
// handler restores it); a highlight-only card has nothing to unwind. // handler restores it); a highlight-only card has nothing to unwind.
setZValue(realZValue); setZValue(realZValue);

View file

@ -37,7 +37,7 @@ protected:
private: private:
bool isHovered; bool isHovered;
bool isHoverHighlighted; bool isHoverZoomed;
qreal realZValue; qreal realZValue;
bool pendingSelectionCollapse; bool pendingSelectionCollapse;
int selectionCollapseGeneration = 0; ///< Guards the deferred collapse timer against stale firings int selectionCollapseGeneration = 0; ///< Guards the deferred collapse timer against stale firings
@ -134,7 +134,6 @@ public:
return realZValue; return realZValue;
} }
void setRealZValue(qreal _zValue); void setRealZValue(qreal _zValue);
void setHovered(bool _hovered);
/** /**
* @brief Shows the hover outline and stacking lift, plus the historical 1.1x hover * @brief Shows the hover outline and stacking lift, plus the historical 1.1x hover
* scale whenever no zoom trigger is configured. * scale whenever no zoom trigger is configured.
@ -144,7 +143,8 @@ public:
* off and the panel not on hover, the old 1.1x enlargement (gated by scaleCards) * off and the panel not on hover, the old 1.1x enlargement (gated by scaleCards)
* stays in effect so upgrading does not silently drop it. * stays in effect so upgrading does not silently drop it.
*/ */
void setHoverHighlighted(bool highlighted); void setHovered(bool _hovered);
void setHoverZoomed(bool _hoverZoomed);
qreal getCardScale() const; qreal getCardScale() const;
void setCardScale(qreal scale); void setCardScale(qreal scale);
qreal getCardOpacity() const; qreal getCardOpacity() const;
@ -152,9 +152,9 @@ public:
/** @brief Fades the card out under the hover panel, or back in when it closes. */ /** @brief Fades the card out under the hover panel, or back in when it closes. */
void fadeCardOut(); void fadeCardOut();
void fadeCardIn(); void fadeCardIn();
bool getIsHovered() const bool getIsHoverZoomed() const
{ {
return isHovered; return isHoverZoomed;
} }
[[nodiscard]] QString getColor() const [[nodiscard]] QString getColor() const
{ {

View file

@ -533,7 +533,7 @@ bool CardItem::animationEvent()
.translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F) .translate(CardDimensions::WIDTH_HALF_F, CardDimensions::HEIGHT_HALF_F)
.rotate(tapAngle) .rotate(tapAngle)
.translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F)); .translate(-CardDimensions::WIDTH_HALF_F, -CardDimensions::HEIGHT_HALF_F));
setHovered(false); setHoverZoomed(false);
update(); update();
return animationIncomplete; return animationIncomplete;

View file

@ -773,7 +773,7 @@ void GameScene::onCardViewRefreshRequested(CardState *card, bool zoneChanged, Pl
item->deleteDragItem(); item->deleteDragItem();
if (zoneChanged) { if (zoneChanged) {
item->setBeingPointedAt(false); item->setBeingPointedAt(false);
item->setHovered(false); item->setHoverZoomed(false);
} }
if (newOwner) { if (newOwner) {
item->setOwner(newOwner); item->setOwner(newOwner);
@ -797,9 +797,9 @@ void GameScene::clearArrowsForPlayerLocally(int playerId)
} }
// ---------- Hover Handling ---------- // ---------- Hover Handling ----------
CardItem *GameScene::getHoveredCard() const CardItem *GameScene::getHoverZoomedCard() const
{ {
return hoveredCard; return hoverZoomedCard;
} }
void GameScene::updateHover(const QPointF &scenePos) void GameScene::updateHover(const QPointF &scenePos)
@ -812,14 +812,14 @@ CardItem *GameScene::pickCardAt(const QPointF &scenePos)
auto itemList = items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform()); auto itemList = items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform());
CardZone *zone = findTopmostZone(itemList); CardZone *zone = findTopmostZone(itemList);
CardItem *topCard = zone ? findTopmostCardInZone(itemList, zone) : nullptr; CardItem *topCard = zone ? findTopmostCardInZone(itemList, zone) : nullptr;
if (!topCard && hoveredCard) { if (!topCard && hoverZoomedCard) {
const QRectF guard = hoveredCard->sceneBoundingRect().adjusted(-8, -8, 8, 8); const QRectF guard = hoverZoomedCard->sceneBoundingRect().adjusted(-8, -8, 8, 8);
if (guard.contains(scenePos)) { if (guard.contains(scenePos)) {
// The zoomed card overflows onto neighboring zones, where naive topmost-zone // The zoomed card overflows onto neighboring zones, where naive topmost-zone
// picking attributes the cursor to the zone underneath. While the cursor is // picking attributes the cursor to the zone underneath. While the cursor is
// still over the zoomed footprint (with hysteresis for edge jiggle), keep it. // still over the zoomed footprint (with hysteresis for edge jiggle), keep it.
// A genuinely different topmost card still takes over. // A genuinely different topmost card still takes over.
return hoveredCard; return hoverZoomedCard;
} }
} }
return topCard; return topCard;
@ -833,27 +833,27 @@ void GameScene::updateHoveredCard(CardItem *newCard)
} }
// The hovered card may have been destroyed without ending the hover: its QPointer // The hovered card may have been destroyed without ending the hover: its QPointer
// nulled itself, but the ancestor lift is still outstanding. Restore it now. // nulled itself, but the ancestor lift is still outstanding. Restore it now.
if (!hoveredCard && !hoverLiftedAncestors.isEmpty()) { if (!hoverZoomedCard && !hoverLiftedAncestors.isEmpty()) {
restoreHoverLift(); restoreHoverLift();
} }
// Hovering alone never starts anything anymore: the trigger (dwell, click, wheel, // Hovering alone never starts anything anymore: the trigger (dwell, click, wheel,
// shortcut) resolves first, then the zoom follows. This keeps the feature calm. // shortcut) resolves first, then the zoom follows. This keeps the feature calm.
bool wasHoveringCard = (hoveredCard != nullptr); bool wasHoveringCard = (hoverZoomedCard != nullptr);
if (hoveredCard && (newCard != hoveredCard)) { if (hoverZoomedCard && (newCard != hoverZoomedCard)) {
endCardHover(hoveredCard); endHoverZoom(hoverZoomedCard);
hoveredCard = nullptr; hoverZoomedCard = nullptr;
} }
// The hover outline and the card info follow the cursor on contact: only the board // The hover outline and the card info follow the cursor on contact: only the board
// zoom and the panel wait for their trigger. A highlight-only card has no zoom to // zoom and the panel wait for their trigger. A highlight-only card has no zoom to
// unwind, so it is dropped directly instead of through endCardHover(). // unwind, so it is dropped directly instead of through endCardHover().
if (hoverHighlightCard && hoverHighlightCard != newCard) { if (hoveredCard && hoveredCard != newCard) {
hoverHighlightCard->setHoverHighlighted(false); hoveredCard->setHovered(false);
} }
hoverHighlightCard = newCard; hoveredCard = newCard;
if (newCard) { if (newCard) {
newCard->setHoverHighlighted(true); newCard->setHovered(true);
} }
auto &display = SettingsCache::instance().cardsDisplay(); auto &display = SettingsCache::instance().cardsDisplay();
@ -866,7 +866,7 @@ void GameScene::updateHoveredCard(CardItem *newCard)
hoverGracePending = false; hoverGracePending = false;
hoverGraceTimer->stop(); hoverGraceTimer->stop();
if (newCard == hoveredCard) { if (newCard == hoverZoomedCard) {
// Steady state: zoom already up. Refresh an open panel, otherwise nothing — // Steady state: zoom already up. Refresh an open panel, otherwise nothing —
// in particular this must not re-fire an armed double-confirm. // in particular this must not re-fire an armed double-confirm.
if (cardHoverWidget && cardHoverWidget->isVisible() && cardHoverWidget->getCardItem() == newCard) { if (cardHoverWidget && cardHoverWidget->isVisible() && cardHoverWidget->getCardItem() == newCard) {
@ -877,8 +877,8 @@ void GameScene::updateHoveredCard(CardItem *newCard)
if (cardHoverWidget && cardHoverWidget->isVisible() && !cardHoverWidget->isClosing() && if (cardHoverWidget && cardHoverWidget->isVisible() && !cardHoverWidget->isClosing() &&
cardHoverWidget->getCardItem() == newCard) { cardHoverWidget->getCardItem() == newCard) {
// Panel open but zoom dropped (e.g. survived a Leave) — zoom back and refresh. // Panel open but zoom dropped (e.g. survived a Leave) — zoom back and refresh.
beginCardHover(newCard); beginHoverZoom(newCard);
hoveredCard = newCard; hoverZoomedCard = newCard;
cardHoverWidget->refreshDisplay(); cardHoverWidget->refreshDisplay();
return; return;
} }
@ -896,8 +896,8 @@ void GameScene::updateHoveredCard(CardItem *newCard)
} }
if (doubleConfirm && confirmArmedCard == newCard) { if (doubleConfirm && confirmArmedCard == newCard) {
// Repeat hover on an armed card: zoom and show at once, no second dwell. // Repeat hover on an armed card: zoom and show at once, no second dwell.
beginCardHover(newCard); beginHoverZoom(newCard);
hoveredCard = newCard; hoverZoomedCard = newCard;
confirmArmedCard.clear(); confirmArmedCard.clear();
showCardHoverPopup(newCard); showCardHoverPopup(newCard);
return; return;
@ -928,9 +928,9 @@ void GameScene::updateHoveredCard(CardItem *newCard)
} }
} }
void GameScene::beginCardHover(CardItem *card) void GameScene::beginHoverZoom(CardItem *card)
{ {
card->setHovered(true); card->setHoverZoomed(true);
if (auto *zone = SelectZone::findOwningSelectZone(card)) { if (auto *zone = SelectZone::findOwningSelectZone(card)) {
zone->escapeClipForHover(card); zone->escapeClipForHover(card);
} }
@ -953,21 +953,21 @@ void GameScene::beginCardHover(CardItem *card)
ancestor = ancestor->parentItem(); ancestor = ancestor->parentItem();
} }
liftOwner = card; liftOwner = card;
connect(card, &AbstractCardItem::hoverShrinkFinished, this, &GameScene::onHoverShrinkFinished, connect(card, &AbstractCardItem::hoverShrinkFinished, this, &GameScene::onHoverZoomShrinkFinished,
Qt::UniqueConnection); Qt::UniqueConnection);
connect(card, &AbstractCardItem::hoverFootprintChanged, this, &GameScene::onHoverFootprintChanged, connect(card, &AbstractCardItem::hoverFootprintChanged, this, &GameScene::onHoverZoomFootprintChanged,
Qt::UniqueConnection); Qt::UniqueConnection);
} }
void GameScene::endCardHover(CardItem *card) void GameScene::endHoverZoom(CardItem *card)
{ {
// Only the zoom-out starts here: the z-value, the clip escape and the ancestor // Only the zoom-out starts here: the z-value, the clip escape and the ancestor
// lift stay put until the shrink finishes (onHoverShrinkFinished), so siblings and // lift stay put until the shrink finishes (onHoverShrinkFinished), so siblings and
// the clip container cannot cut through the still-enlarged card. // the clip container cannot cut through the still-enlarged card.
card->setHovered(false); card->setHoverZoomed(false);
} }
void GameScene::onHoverShrinkFinished(AbstractCardItem *card) void GameScene::onHoverZoomShrinkFinished(AbstractCardItem *card)
{ {
auto *cardItem = qobject_cast<CardItem *>(card); auto *cardItem = qobject_cast<CardItem *>(card);
if (!cardItem) { if (!cardItem) {
@ -984,7 +984,7 @@ void GameScene::onHoverShrinkFinished(AbstractCardItem *card)
restoreHoverLift(); restoreHoverLift();
} }
void GameScene::onHoverFootprintChanged(const QRectF &oldFootprint, const QRectF &newFootprint) void GameScene::onHoverZoomFootprintChanged(const QRectF &oldFootprint, const QRectF &newFootprint)
{ {
const QRectF dirty = oldFootprint.united(newFootprint); const QRectF dirty = oldFootprint.united(newFootprint);
if (dirty.isEmpty()) { if (dirty.isEmpty()) {
@ -1126,13 +1126,13 @@ void GameScene::onHoverActivateTimeout()
const bool panelPhase = display.getHoverPanelTrigger() == CardsDisplaySettings::HoverPanelTriggerHover; const bool panelPhase = display.getHoverPanelTrigger() == CardsDisplaySettings::HoverPanelTriggerHover;
const bool effectiveDouble = const bool effectiveDouble =
display.getHoverPanelDoubleConfirm() && display.getHoverZoomTrigger() == display.getHoverPanelTrigger(); display.getHoverPanelDoubleConfirm() && display.getHoverZoomTrigger() == display.getHoverPanelTrigger();
if (hoveredCard && hoveredCard != target) { if (hoverZoomedCard && hoverZoomedCard != target) {
endCardHover(hoveredCard); endHoverZoom(hoverZoomedCard);
} }
if (zoomPhase) { if (zoomPhase) {
if (hoveredCard != target) { if (hoverZoomedCard != target) {
beginCardHover(target); beginHoverZoom(target);
hoveredCard = target; hoverZoomedCard = target;
} }
if (effectiveDouble) { if (effectiveDouble) {
confirmArmedCard = target; confirmArmedCard = target;
@ -1158,7 +1158,7 @@ void GameScene::onHoverPanelTimeout()
if (!target->sceneBoundingRect().contains(cursorScene)) { if (!target->sceneBoundingRect().contains(cursorScene)) {
return; return;
} }
ensureZoomed(target); ensureHoverZoomed(target);
showCardHoverPopup(target); showCardHoverPopup(target);
} }
@ -1186,14 +1186,14 @@ void GameScene::summonHoverPanel()
} }
} }
void GameScene::ensureZoomed(CardItem *card) void GameScene::ensureHoverZoomed(CardItem *card)
{ {
if (hoveredCard != card) { if (hoverZoomedCard != card) {
if (hoveredCard) { if (hoverZoomedCard) {
endCardHover(hoveredCard); endHoverZoom(hoverZoomedCard);
} }
beginCardHover(card); beginHoverZoom(card);
hoveredCard = card; hoverZoomedCard = card;
} }
} }
@ -1225,23 +1225,23 @@ void GameScene::fireTriggers(CardItem *card, bool zoomFired, bool panelFired)
if (effectiveDouble) { if (effectiveDouble) {
if (confirmArmedCard == card) { if (confirmArmedCard == card) {
confirmArmedCard.clear(); confirmArmedCard.clear();
ensureZoomed(card); ensureHoverZoomed(card);
showCardHoverPopup(card); showCardHoverPopup(card);
} else { } else {
confirmArmedCard = card; confirmArmedCard = card;
ensureZoomed(card); ensureHoverZoomed(card);
} }
} else { } else {
ensureZoomed(card); ensureHoverZoomed(card);
showCardHoverPopup(card); showCardHoverPopup(card);
} }
return; return;
} }
if (zoomFired) { if (zoomFired) {
ensureZoomed(card); ensureHoverZoomed(card);
} }
if (panelFired) { if (panelFired) {
ensureZoomed(card); ensureHoverZoomed(card);
showCardHoverPopup(card); showCardHoverPopup(card);
} }
} }
@ -1254,7 +1254,7 @@ void GameScene::onHoverWidgetEntered()
void GameScene::onHoverWidgetLeft() void GameScene::onHoverWidgetLeft()
{ {
if (!hoveredCard && cardHoverWidget && cardHoverWidget->isVisible() && !hoverGracePending) { if (!hoverZoomedCard && cardHoverWidget && cardHoverWidget->isVisible() && !hoverGracePending) {
hoverGracePending = true; hoverGracePending = true;
hoverGraceTimer->start(); hoverGraceTimer->start();
} }
@ -1440,14 +1440,14 @@ bool GameScene::event(QEvent *event)
? wheelEvent->pixelDelta().y() ? wheelEvent->pixelDelta().y()
: (wheelEvent->orientation() == Qt::Vertical ? wheelEvent->delta() : 0); : (wheelEvent->orientation() == Qt::Vertical ? wheelEvent->delta() : 0);
if (wheelUp > 0) { if (wheelUp > 0) {
if ((cardHoverWidget && cardHoverWidget->isVisible()) || hoveredCard) { if ((cardHoverWidget && cardHoverWidget->isVisible()) || hoverZoomedCard) {
hoverPopupTarget = nullptr; hoverPopupTarget = nullptr;
hoverPanelTarget = nullptr; hoverPanelTarget = nullptr;
confirmArmedCard.clear(); confirmArmedCard.clear();
hideCardHoverPopup(); hideCardHoverPopup();
if (hoveredCard) { if (hoverZoomedCard) {
endCardHover(hoveredCard); endHoverZoom(hoverZoomedCard);
hoveredCard = nullptr; hoverZoomedCard = nullptr;
} }
event->accept(); event->accept();
return true; return true;

View file

@ -78,11 +78,9 @@ private:
ArrowRegistry arrowRegistry; ///< ID registry for arrow graphics items ArrowRegistry arrowRegistry; ///< ID registry for arrow graphics items
QList<ZoneViewWidget *> zoneViews; ///< Active zone view widgets QList<ZoneViewWidget *> zoneViews; ///< Active zone view widgets
QSize viewSize; ///< Current view size QSize viewSize; ///< Current view size
QPointer<CardItem> hoveredCard; ///< Currently hovered card (zoomed) QPointer<CardItem> hoveredCard; ///< Card the cursor is resting on
/// Card the cursor is resting on. It carries the hover outline and the card-info QPointer<CardItem> hoverZoomedCard; ///< Card that is currently being hover zoomed
/// update immediately, independently of the zoom/panel triggers. QPointer<CardItem> activeCard; ///< Card the currently open context menu targets
QPointer<CardItem> hoverHighlightCard;
QPointer<CardItem> activeCard; ///< Card the currently open context menu targets
/// Card armed for double-confirm panel summon (first trigger zooms, repeat shows). /// Card armed for double-confirm panel summon (first trigger zooms, repeat shows).
QPointer<CardItem> confirmArmedCard; QPointer<CardItem> confirmArmedCard;
/// Ancestor chain of the hovered card with pre-hover Z-values. Lifted while hovering /// Ancestor chain of the hovered card with pre-hover Z-values. Lifted while hovering
@ -120,16 +118,16 @@ private:
void updateHover(const QPointF &scenePos); void updateHover(const QPointF &scenePos);
/** /**
* @brief Activates hover state and escapes the card from its clip container * @brief Activates hover zoom state and escapes the card from its clip container
* so hover scaling is visible beyond zone bounds. * so hover scaling is visible beyond zone bounds.
*/ */
void beginCardHover(CardItem *card); void beginHoverZoom(CardItem *card);
/** @brief Deactivates hover state and restores the card to its clip container. */ /** @brief Deactivates hover zoom state and restores the card to its clip container. */
void endCardHover(CardItem *card); void endHoverZoom(CardItem *card);
/** @brief Restores every lifted ancestor to its pre-hover Z-value and drops the chain. */ /** @brief Restores every lifted ancestor to its pre-hover Z-value and drops the chain. */
void restoreHoverLift(); void restoreHoverLift();
/** @brief Settles a finished shrink-out: clip container and ancestor lift restore. */ /** @brief Settles a finished shrink-out: clip container and ancestor lift restore. */
void onHoverShrinkFinished(AbstractCardItem *card); void onHoverZoomShrinkFinished(AbstractCardItem *card);
/** /**
* @brief Repaints the zones that dodge the zoomed card when its footprint moves. * @brief Repaints the zones that dodge the zoomed card when its footprint moves.
* *
@ -137,7 +135,7 @@ private:
* item's geometry change does not dirty them, so without this the previous hole stays * item's geometry change does not dirty them, so without this the previous hole stays
* transparent in the cache and a black rectangle shows under the zoom. * transparent in the cache and a black rectangle shows under the zoom.
*/ */
void onHoverFootprintChanged(const QRectF &oldFootprint, const QRectF &newFootprint); void onHoverZoomFootprintChanged(const QRectF &oldFootprint, const QRectF &newFootprint);
// Card hover popup methods // Card hover popup methods
void showCardHoverPopup(CardItem *card); void showCardHoverPopup(CardItem *card);
@ -284,10 +282,10 @@ public:
void fireTriggers(CardItem *card, bool zoomFired, bool panelFired); void fireTriggers(CardItem *card, bool zoomFired, bool panelFired);
/** @brief Starts the hover zoom for a card without touching panel state. */ /** @brief Starts the hover zoom for a card without touching panel state. */
void ensureZoomed(CardItem *card); void ensureHoverZoomed(CardItem *card);
/** @brief The currently hovered card, if any (used by zones to dodge it while painting). */ /** @brief The currently hover zoomed card, if any (used by zones to dodge it while painting). */
CardItem *getHoveredCard() const; CardItem *getHoverZoomedCard() const;
/** /**
* @brief Registers an item for animation updates with the shared scene timer. * @brief Registers an item for animation updates with the shared scene timer.

View file

@ -119,7 +119,7 @@ void SelectZone::restoreStaleEscapedCards()
// A card parented to the zone (instead of the clip container) should // A card parented to the zone (instead of the clip container) should
// only occur while it is actively hovered. If hover cleanup was // only occur while it is actively hovered. If hover cleanup was
// missed, reparent it back so clipping resumes. // missed, reparent it back so clipping resumes.
if (card && card->parentItem() == this && !card->getIsHovered()) { if (card && card->parentItem() == this && !card->getIsHoverZoomed()) {
card->setParentItem(cardClipContainer); card->setParentItem(cardClipContainer);
} }
} }

View file

@ -176,7 +176,7 @@ std::optional<QPainterPath> TableZone::hoveredCardHole() const
if (!scene) { if (!scene) {
return std::nullopt; return std::nullopt;
} }
CardItem *hovered = scene->getHoveredCard(); CardItem *hovered = scene->getHoverZoomedCard();
if (!hovered) { if (!hovered) {
return std::nullopt; return std::nullopt;
} }

View file

@ -460,7 +460,7 @@ void CardHoverWidget::createPTOverlay()
ptPillLabel->clear(); ptPillLabel->clear();
ptOverlay->resize(ptCompactSize); ptOverlay->resize(ptCompactSize);
// The whole subtree feeds the hover state: moving onto a button must not read as a leave. // The whole subtree feeds the hover zoom state: moving onto a button must not read as a leave.
ptOverlay->installEventFilter(this); ptOverlay->installEventFilter(this);
const QList<QWidget *> ptChildren = ptOverlay->findChildren<QWidget *>(); const QList<QWidget *> ptChildren = ptOverlay->findChildren<QWidget *>();
for (QWidget *child : ptChildren) { for (QWidget *child : ptChildren) {