fix(view): 2D/3D 统一面板表头(分段页签) + 画布空状态提示用 canvas 令牌融入深底(规范§5/§6.5)

This commit is contained in:
gaozheng 2026-06-10 15:52:45 +08:00
parent b242240df6
commit 58cabc6350
3 changed files with 68 additions and 28 deletions

View File

@ -165,4 +165,41 @@ TabbedPanel buildTabbedPanel(const QVector<PanelTab>& tabs, const QVector<Header
return result;
}
SegmentedHeader buildSegmentedHeader(const QVector<QString>& segments,
const QVector<HeaderAction>& actions)
{
auto* header = new QWidget();
header->setObjectName(QStringLiteral("panelHeader"));
header->setFixedHeight(kHeaderHeight);
geopro::app::applyThemedStyleSheet(header, headerQss());
auto* hlay = new QHBoxLayout(header);
hlay->setContentsMargins(10, 0, 8, 0);
hlay->setSpacing(2);
auto* group = new QButtonGroup(header);
group->setExclusive(true);
SegmentedHeader result;
result.header = header;
for (int i = 0; i < segments.size(); ++i) {
auto* btn = new QToolButton(header); // 与异常/属性页签统一: tabBtn 样式 + 强调色下划线
btn->setObjectName(QStringLiteral("tabBtn"));
btn->setText(segments[i]);
btn->setCheckable(true);
btn->setCursor(Qt::PointingHandCursor);
group->addButton(btn, i);
hlay->addWidget(btn);
hlay->addSpacing(10);
result.buttons.append(btn);
}
hlay->addStretch();
for (const auto& a : actions) hlay->addWidget(makeActionButton(header, a));
if (!result.buttons.isEmpty()) result.buttons[0]->setChecked(true);
return result;
}
} // namespace geopro::app

View File

@ -14,6 +14,7 @@
class QWidget;
class QLabel;
class QToolButton;
namespace geopro::app {
@ -43,4 +44,16 @@ struct TabbedPanel {
TabbedPanel buildTabbedPanel(const QVector<PanelTab>& tabs,
const QVector<HeaderAction>& actions = {});
// 分段切换表头构建结果:表头容器 + 各分段按钮(互斥,首个默认激活,供调用方接 clicked
struct SegmentedHeader {
QWidget* header;
QVector<QToolButton*> buttons;
};
// 构建「分段切换表头」:一行 Tab 风格互斥按钮(与异常/属性页签同款:选中=强调色文字 + 2px
// 强调色下划线)+ 右侧操作按钮。表头底/高度/边框与 buildTabbedPanel 完全一致;内容由调用方
// 自行 addWidget 到表头下方(不建堆叠,因 2D/3D 共用同一画布部件)。
SegmentedHeader buildSegmentedHeader(const QVector<QString>& segments,
const QVector<HeaderAction>& actions = {});
} // namespace geopro::app

View File

@ -334,27 +334,15 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
.arg(geopro::app::scaledPx(geopro::app::type::kBody))
.arg(geopro::app::type::kWeightSemibold);
// 工具条:「二维地图/三维视图」两个互斥可勾选按钮。默认二维地图。
auto* viewToolBar = new QWidget();
auto* viewBarLay = new QHBoxLayout(viewToolBar);
viewBarLay->setContentsMargins(8, 6, 8, 6);
viewBarLay->setSpacing(6);
auto* viewGroup = new QButtonGroup(viewToolBar);
viewGroup->setExclusive(true);
auto* act2D = new QToolButton(viewToolBar);
act2D->setText(QStringLiteral("二维地图"));
act2D->setCheckable(true);
auto* act3D = new QToolButton(viewToolBar);
act3D->setText(QStringLiteral("三维视图"));
act3D->setCheckable(true);
viewGroup->addButton(act2D);
viewGroup->addButton(act3D);
viewBarLay->addWidget(act2D);
viewBarLay->addWidget(act3D);
viewBarLay->addStretch();
act2D->setChecked(true); // 默认二维地图
geopro::app::applyThemedStyleSheet(viewToolBar, kBarBtnQss);
centerLayout->addWidget(viewToolBar);
// 「二维地图/三维视图」分段切换表头:与「异常/属性」面板表头同款42px 表头底 + 强调色下划线页签)。
auto seg = geopro::app::buildSegmentedHeader(
{QStringLiteral("二维地图"), QStringLiteral("三维视图")},
{{geopro::app::Glyph::Collapse, QStringLiteral("折叠")},
{geopro::app::Glyph::Download, QStringLiteral("导出")}});
auto* viewHeader = seg.header;
auto* act2D = seg.buttons[0];
auto* act3D = seg.buttons[1];
centerLayout->addWidget(viewHeader);
centerLayout->addWidget(vtkWidget, 1);
// ──「视图详情」图层浮层(对齐原型 3D 视图左上):浮在 QVTK 之上,控制三维图层显隐。
@ -420,13 +408,15 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
auto* esIcon = new QLabel(emptyState);
esIcon->setPixmap(
geopro::app::makeGlyph(geopro::app::Glyph::Dataset, QColor("#C2CCDA"), 56).pixmap(56, 56));
geopro::app::makeGlyph(geopro::app::Glyph::Dataset,
geopro::app::tokenColor("canvas/text-dim"), 56)
.pixmap(56, 56));
esIcon->setAlignment(Qt::AlignCenter);
auto* esTitle = new QLabel(QStringLiteral("选择左侧数据集开始分析"), emptyState);
esTitle->setAlignment(Qt::AlignCenter);
geopro::app::applyThemedStyleSheet(
esTitle, QStringLiteral("color:#5A6B85; font-size:%1px; font-weight:%2;")
geopro::app::applyTokenizedStyleSheet(
esTitle, QStringLiteral("color:{{canvas/text}}; font-size:%1px; font-weight:%2;")
.arg(geopro::app::scaledPx(geopro::app::type::kHeading))
.arg(geopro::app::type::kWeightSemibold));
@ -434,9 +424,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
"切到「三维视图」可叠加帘面、体素与地形图层"),
emptyState);
esHint->setAlignment(Qt::AlignCenter);
geopro::app::applyThemedStyleSheet(
geopro::app::applyTokenizedStyleSheet(
esHint,
QStringLiteral("color:#8A93A3; font-size:%1px;").arg(geopro::app::scaledPx(geopro::app::type::kBody)));
QStringLiteral("color:{{canvas/text-dim}}; font-size:%1px;").arg(geopro::app::scaledPx(geopro::app::type::kBody)));
esLay->addWidget(esIcon);
esLay->addWidget(esTitle);
@ -827,9 +817,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
});
// 「视图详情」浮层显隐:仅三维显示,置于 QVTK 左上(工具条下方)并置顶。
auto showLayerPanel = [layerPanel, viewToolBar](bool show3D) {
auto showLayerPanel = [layerPanel, viewHeader](bool show3D) {
if (show3D) {
layerPanel->move(14, viewToolBar->height() + 12);
layerPanel->move(14, viewHeader->height() + 12);
layerPanel->adjustSize();
layerPanel->setVisible(true);
layerPanel->raise();