measure the controls panel against its content, not its old geometry
The previous fix went too far: it activated the panel's own layout before resizing, which lays the heading and the rows out inside the geometry left over from the previous context. The panel then took that stale frame as its answer and collapsed to almost nothing whenever the mode changed. Only the rows layout is activated now -- that part was right, and is what makes freshly added rows visible and so measurable. The size comes from layout()->totalSizeHint(), which says how big the content needs to be without reference to how big the panel currently is; setGeometry re-runs the outer layout afterwards on its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
@@ -239,27 +239,28 @@ void ControlsPanel::refit()
|
||||
{
|
||||
if (m_bandRect.isNull()) { return; }
|
||||
|
||||
// Both layouts, innermost first, and both invalidated before being re-run. Rows are
|
||||
// created and destroyed wholesale, so the rows layout's cached size hint describes
|
||||
// the previous context until it is discarded; asking the panel for its hint without
|
||||
// this returns the size the last context needed, which is why a first selection
|
||||
// used to draw a card one rebuild behind.
|
||||
//
|
||||
// The polish is part of the same problem: a freshly created label reports an
|
||||
// unstyled size hint until the stylesheet has been applied to it, and the badge
|
||||
// chips carry border and padding that change their width.
|
||||
// Rows are torn down and rebuilt wholesale, and a widget added to a layout is only
|
||||
// shown once that layout runs -- without this the new rows count for nothing and
|
||||
// the card is measured for the context before it. The polish belongs to the same
|
||||
// step: a freshly created label reports an unstyled size hint until the stylesheet
|
||||
// has reached it, and the badge chips carry border and padding that change it.
|
||||
m_rows->ensurePolished();
|
||||
m_rowsLayout->invalidate();
|
||||
m_rowsLayout->activate();
|
||||
|
||||
// Deliberately not activating the panel's own layout here. That lays the heading
|
||||
// and the rows out inside the geometry the panel still has from the previous
|
||||
// context, which is the wrong frame of reference for choosing the new one.
|
||||
// totalSizeHint answers "how big does this need to be" without reference to how big
|
||||
// it currently is; setGeometry below then re-runs the outer layout on its own.
|
||||
layout()->invalidate();
|
||||
layout()->activate();
|
||||
const QSize needed = layout()->totalSizeHint();
|
||||
|
||||
const QRect band = m_bandRect.adjusted(kMarginPx, kMarginPx, -kMarginPx, -kMarginPx);
|
||||
if (band.width() <= 0 || band.height() <= 0) { return; }
|
||||
|
||||
const QSize hint = sizeHint();
|
||||
const int widthPx = qMin(hint.width(), band.width());
|
||||
const int heightPx = qMin(hint.height(), band.height());
|
||||
const int widthPx = qMin(needed.width(), band.width());
|
||||
const int heightPx = qMin(needed.height(), band.height());
|
||||
|
||||
// Left edge of the band, sitting on its bottom edge, so the panel grows upward as
|
||||
// rows are added (REQ-UI-CONTROLS-PANEL).
|
||||
|
||||
Reference in New Issue
Block a user