show the controls panel's rows before measuring them
A widget created under an already-visible parent starts hidden, and a layout counts a hidden item as empty -- it adds nothing to the size hint. Nothing showed the freshly built rows until the event loop next ran, long after the panel had measured itself, so every rebuild measured an empty card. That one fact explains both symptoms. Originally refit() read a stale cached hint, which described the previous context and so drew the card one rebuild behind. Invalidating that cache to fix it replaced a plausible wrong answer with the true one for a card whose rows were all still hidden, which is why the panel then collapsed to its heading on every mode change. Measured on a forced rebuild, with the rows shown and without: shown: rowItems=10 hidden=0 rowsHint=188 needed=140x221 hidden: rowItems=10 hidden=10 rowsHint=6 needed=72x39 39px being heading plus margins -- the collapsed card exactly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
@@ -65,6 +65,18 @@ QWidget* makeRow(ControlAction action, const ControlContext& context, QWidget* p
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adds a freshly built widget to the rows and shows it.
|
||||||
|
//
|
||||||
|
// The show is what makes it count. A widget created under an already-visible parent
|
||||||
|
// starts hidden, and a layout treats a hidden item as empty -- it contributes nothing
|
||||||
|
// to the size hint until something shows it, which otherwise does not happen until the
|
||||||
|
// event loop next runs, long after the panel has measured itself.
|
||||||
|
void addAndShow(QVBoxLayout* layout, QWidget* widget)
|
||||||
|
{
|
||||||
|
layout->addWidget(widget);
|
||||||
|
widget->show();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ControlsPanel::ControlsPanel(const GameWorldView* view, QWidget* parent)
|
ControlsPanel::ControlsPanel(const GameWorldView* view, QWidget* parent)
|
||||||
@@ -173,7 +185,7 @@ void ControlsPanel::rebuild(const ControlContext& context)
|
|||||||
|
|
||||||
for (ControlAction action : m_shownContextActions)
|
for (ControlAction action : m_shownContextActions)
|
||||||
{
|
{
|
||||||
m_rowsLayout->addWidget(makeRow(action, context, m_rows));
|
addAndShow(m_rowsLayout, makeRow(action, context, m_rows));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The always-available block sits under a divider in every context, the General one
|
// The always-available block sits under a divider in every context, the General one
|
||||||
@@ -185,17 +197,17 @@ void ControlsPanel::rebuild(const ControlContext& context)
|
|||||||
divider->setFrameShape(QFrame::HLine);
|
divider->setFrameShape(QFrame::HLine);
|
||||||
divider->setFrameShadow(QFrame::Plain);
|
divider->setFrameShadow(QFrame::Plain);
|
||||||
m_rowsLayout->addSpacing(6);
|
m_rowsLayout->addSpacing(6);
|
||||||
m_rowsLayout->addWidget(divider);
|
addAndShow(m_rowsLayout, divider);
|
||||||
|
|
||||||
QLabel* caption = new QLabel(tr("ALWAYS AVAILABLE"), m_rows);
|
QLabel* caption = new QLabel(tr("ALWAYS AVAILABLE"), m_rows);
|
||||||
caption->setObjectName(QStringLiteral("controlCaption"));
|
caption->setObjectName(QStringLiteral("controlCaption"));
|
||||||
caption->setFont(makeSpacedFont(font(), /*bold*/ false, /*pointSizeDelta*/ -1));
|
caption->setFont(makeSpacedFont(font(), /*bold*/ false, /*pointSizeDelta*/ -1));
|
||||||
m_rowsLayout->addWidget(caption);
|
addAndShow(m_rowsLayout, caption);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ControlAction action : m_shownAlwaysActions)
|
for (ControlAction action : m_shownAlwaysActions)
|
||||||
{
|
{
|
||||||
m_rowsLayout->addWidget(makeRow(action, context, m_rows));
|
addAndShow(m_rowsLayout, makeRow(action, context, m_rows));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rows->setVisible(!m_collapsed);
|
m_rows->setVisible(!m_collapsed);
|
||||||
|
|||||||
Reference in New Issue
Block a user