From f74f83c5ec18bab25606ff40e264cc2217ec5128 Mon Sep 17 00:00:00 2001 From: DawnFire42 Date: Fri, 19 Jun 2026 11:40:46 -0400 Subject: [PATCH] Sync command zone visibility on construction and reflow stack on height change - Sync command zone visibility in the PlayerGraphicsItem constructor in case processPlayerInfo runs before the signal is connected. - Emit CommandZone::effectiveHeightChanged() when a minimized zone's height changes so the stack zone repositions. --- .../game_graphics/player/player_graphics_item.cpp | 3 +++ cockatrice/src/game_graphics/zones/command_zone.cpp | 13 +++++++++---- cockatrice/src/game_graphics/zones/command_zone.h | 4 +++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cockatrice/src/game_graphics/player/player_graphics_item.cpp b/cockatrice/src/game_graphics/player/player_graphics_item.cpp index 4ab14fc4e..274815be8 100644 --- a/cockatrice/src/game_graphics/player/player_graphics_item.cpp +++ b/cockatrice/src/game_graphics/player/player_graphics_item.cpp @@ -66,6 +66,8 @@ PlayerGraphicsItem::PlayerGraphicsItem(PlayerLogic *_player) : player(_player) connect(player, &PlayerLogic::addViewCustomZoneActionToCustomZoneMenu, this, &PlayerGraphicsItem::onCustomZoneAdded); connect(player, &PlayerLogic::commandZoneSupportChanged, this, &PlayerGraphicsItem::setCommandZoneVisible); + // Sync initial state in case processPlayerInfo already ran before this connection. + setCommandZoneVisible(player->hasServerCommandZone()); playerMenu->setMenusForGraphicItems(); @@ -131,6 +133,7 @@ void PlayerGraphicsItem::initializeZones() commandZoneGraphicsItem->setZValue(ZValues::COMMAND_ZONE); commandZoneGraphicsItem->setVisible(false); connect(commandZoneGraphicsItem, &CommandZone::minimizedChanged, this, &PlayerGraphicsItem::rearrangeZones); + connect(commandZoneGraphicsItem, &CommandZone::effectiveHeightChanged, this, &PlayerGraphicsItem::rearrangeZones); connect(handZoneGraphicsItem->getLogic(), &HandZoneLogic::cardCountChanged, handCounter, &HandCounter::updateNumber); diff --git a/cockatrice/src/game_graphics/zones/command_zone.cpp b/cockatrice/src/game_graphics/zones/command_zone.cpp index d703f1c29..198a0ac82 100644 --- a/cockatrice/src/game_graphics/zones/command_zone.cpp +++ b/cockatrice/src/game_graphics/zones/command_zone.cpp @@ -44,15 +44,20 @@ void CommandZone::setMinimumHeight(int height) if (minimumHeight == height) { return; } + // Only meaningful while minimized, where currentHeight() depends on minimumHeight. + const qreal oldEffectiveHeight = currentHeight(); minimumHeight = height; prepareGeometryChange(); updateClipRect(); reorganizeCards(); update(); - // NOTE: Do NOT emit minimizedChanged here. The minimized STATE has not changed, - // only the minimum height constraint. Emitting here causes an infinite loop: - // rearrangeZones -> rearrangeCounters -> rearrangeTaxCounters -> setMinimumHeight - // -> minimizedChanged -> rearrangeZones (loop!) + // Do NOT emit minimizedChanged: the minimized STATE is unchanged, and that signal + // feeds rearrangeZones -> rearrangeCounters -> setMinimumHeight (infinite loop). + // effectiveHeightChanged repositions neighbouring zones and converges instead: the + // rearrange re-enters setMinimumHeight with the same height and early-returns above. + if (!qFuzzyCompare(currentHeight(), oldEffectiveHeight)) { + emit effectiveHeightChanged(); + } } bool CommandZone::isMinimized() const diff --git a/cockatrice/src/game_graphics/zones/command_zone.h b/cockatrice/src/game_graphics/zones/command_zone.h index 52d4f79a6..12d604b17 100644 --- a/cockatrice/src/game_graphics/zones/command_zone.h +++ b/cockatrice/src/game_graphics/zones/command_zone.h @@ -95,8 +95,10 @@ public: void rearrangeTaxCounters(); signals: - /** @brief Emitted when the zone toggles between minimized and expanded states. */ void minimizedChanged(bool isMinimized); + // Displayed height changed without a minimized-state change (e.g. tax counter toggled + // while minimized); lets neighbouring zones reposition. + void effectiveHeightChanged(); protected: void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;