Simplify Models panel and dialog layout

Models panel: replace the manual resizeEvent column-sizing hack with
QHeaderView Stretch/Fixed modes, re-applied via sectionCountChanged so
they survive the model rebuilds that QHeaderView resets them on.

Dialog: only wrap the body in a QScrollArea when scrollable, mirroring
Panel. The scroll area caps its sizeHint at 36x24 cells, which turned
wide fixed-size dialog content into spurious scrollbars.

Add Model dialog: reserve a stable, font-metrics-measured height for the
hover description so longer text never reflows the buttons; regroup the
buttons into LOCAL / CLOUD / TOOLS.

Buttons: move the trailing-separator decision out of makeButtonGroup
into a new addButtonGroups row builder, so the last group in a row
never draws a dangling divider.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-20 20:56:19 +10:00
parent 19bff92a47
commit 96941463c0
9 changed files with 155 additions and 118 deletions
+10 -2
View File
@@ -22,6 +22,7 @@
#include "SvgIcon.h"
#include <QBoxLayout>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
@@ -47,11 +48,9 @@ QToolButton* makeButton(const QString& text,
QWidget* makeButtonGroup(const QString& title,
const QList<QToolButton*>& buttons,
QWidget* parent,
bool trailing_separator,
int vertical_spacing) {
auto* group = new QFrame(parent);
group->setObjectName("ribbonGroup");
group->setProperty("separator", trailing_separator);
auto* group_layout = new QVBoxLayout(group);
group_layout->setContentsMargins(8, 6, 8, 4);
@@ -74,4 +73,13 @@ QWidget* makeButtonGroup(const QString& title,
return group;
}
void addButtonGroups(QBoxLayout* row, const QList<QWidget*>& groups) {
for (int i = 0; i < groups.size(); ++i) {
// The divider belongs *between* groups; the last group never draws a
// trailing one. The stylesheet keys off this dynamic property.
groups[i]->setProperty("separator", i + 1 < groups.size());
row->addWidget(groups[i]);
}
}
} // namespace bonsaiviewer::components::buttons
+6 -1
View File
@@ -23,6 +23,7 @@
#include <QList>
class QBoxLayout;
class QToolButton;
class QWidget;
@@ -35,9 +36,13 @@ QToolButton* makeButton(const QString& text,
QWidget* makeButtonGroup(const QString& title,
const QList<QToolButton*>& buttons,
QWidget* parent,
bool trailing_separator = true,
int vertical_spacing = 4);
// Adds button groups to a ribbon row, drawing a vertical divider between
// adjacent groups but never after the last one. Centralising the decision
// here means a row can't end up with a dangling trailing separator.
void addButtonGroups(QBoxLayout* row, const QList<QWidget*>& groups);
} // namespace bonsaiviewer::components::buttons
#endif
+17 -9
View File
@@ -49,19 +49,27 @@ Dialog::Dialog(QWidget* parent, bool scrollable)
style::metrics::section_body_padding);
frame_layout->setSpacing(0);
auto* scroll = new QScrollArea(frame);
scroll->setWidgetResizable(true);
scroll->setFrameShape(QFrame::NoFrame);
auto* scroll_body = new QWidget(scroll);
scroll_body->setObjectName("panelScrollBody");
body_layout_ = new QVBoxLayout(scroll_body);
// A non-scrollable dialog must not be wrapped in a QScrollArea. The scroll
// area caps its own sizeHint at 36x24 character cells, and dialogs size
// themselves with QLayout::SetFixedSize — so any content wider/taller than
// that cap is turned into scrollbars instead of growing the dialog. Only
// use a scroll area when scrolling is actually wanted (mirrors Panel).
auto* body = new QWidget(frame);
body->setObjectName("panelScrollBody");
body_layout_ = new QVBoxLayout(body);
body_layout_->setContentsMargins(0, 0, 0, 0);
body_layout_->setSpacing(style::metrics::section_body_padding);
body_layout_->setAlignment(Qt::AlignTop);
scroll->setWidget(scroll_body);
frame_layout->addWidget(scroll, scrollable ? 1 : 0);
if (scrollable) {
auto* scroll = new QScrollArea(frame);
scroll->setWidgetResizable(true);
scroll->setFrameShape(QFrame::NoFrame);
scroll->setWidget(body);
frame_layout->addWidget(scroll, 1);
} else {
frame_layout->addWidget(body);
}
auto* footer = new QWidget(frame);
footer_layout_ = new QVBoxLayout(footer);