feat/object-selection-panels #4
116
src/app/main.cpp
116
src/app/main.cpp
|
|
@ -44,7 +44,6 @@
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QSignalBlocker>
|
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include <QVariantAnimation>
|
#include <QVariantAnimation>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
@ -84,8 +83,9 @@
|
||||||
#include "api/ApiProjectRepository.hpp"
|
#include "api/ApiProjectRepository.hpp"
|
||||||
#include "panels/ObjectTreePanel.hpp"
|
#include "panels/ObjectTreePanel.hpp"
|
||||||
#include "login/LoginWindow.hpp"
|
#include "login/LoginWindow.hpp"
|
||||||
#include "panels/AnomalyListPanel.hpp"
|
|
||||||
#include "panels/DatasetListPanel.hpp"
|
#include "panels/DatasetListPanel.hpp"
|
||||||
|
#include "panels/DynamicFormView.hpp"
|
||||||
|
#include "panels/ObjectExceptionPanel.hpp"
|
||||||
|
|
||||||
#include "CameraPreset.hpp"
|
#include "CameraPreset.hpp"
|
||||||
#include "ColorLutBuilder.hpp"
|
#include "ColorLutBuilder.hpp"
|
||||||
|
|
@ -549,23 +549,18 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
dockManager->addDockWidget(ads::BottomDockWidgetArea, datasetDock, leftArea);
|
dockManager->addDockWidget(ads::BottomDockWidgetArea, datasetDock, leftArea);
|
||||||
|
|
||||||
// 右上 dock:异常列表 / 对象属性 合并为带 Tab 表头的面板(对齐原型上半)。
|
// 右上 dock:异常列表 / 对象属性 合并为带 Tab 表头的面板(对齐原型上半)。
|
||||||
auto* anomalyList = new QListWidget();
|
auto* exceptionPanel = new geopro::app::ObjectExceptionPanel();
|
||||||
geopro::app::applyAnomalyCardDelegate(anomalyList);
|
auto* objAttrView = new geopro::app::DynamicFormView();
|
||||||
auto* objAttrLabel = new QLabel(QStringLiteral("(选中对象后显示其属性)"));
|
|
||||||
objAttrLabel->setWordWrap(true);
|
|
||||||
objAttrLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
|
||||||
objAttrLabel->setMargin(8);
|
|
||||||
|
|
||||||
auto anomalyPanel = geopro::app::buildTabbedPanel(
|
auto anomalyPanel = geopro::app::buildTabbedPanel(
|
||||||
{{geopro::app::Glyph::Anomaly, QStringLiteral("异常"), anomalyList, true},
|
{{geopro::app::Glyph::Anomaly, QStringLiteral("对象异常"), exceptionPanel, true},
|
||||||
{geopro::app::Glyph::Property, QStringLiteral("对象属性"), objAttrLabel, false}},
|
{geopro::app::Glyph::Property, QStringLiteral("对象属性"), objAttrView, false}},
|
||||||
{{geopro::app::Glyph::Filter, QStringLiteral("筛选")},
|
{{geopro::app::Glyph::Filter, QStringLiteral("筛选")},
|
||||||
{geopro::app::Glyph::Plus, QStringLiteral("添加异常")}});
|
{geopro::app::Glyph::Plus, QStringLiteral("添加异常")}});
|
||||||
auto* anomalyBadge = anomalyPanel.badges.value(0); // 异常列表 Tab 的数量徽标
|
auto* anomalyBadge = anomalyPanel.badges.value(0); // 异常列表 Tab 的数量徽标
|
||||||
// colorize(C):异常计数用语义 warning“需注意”变体(区别于普通中性计数徽标),
|
// colorize(C):异常计数用语义 warning“需注意”变体(区别于普通中性计数徽标),
|
||||||
// 提示“这些异常点待复查”。改 objectName 后重新 polish 以应用 #panelBadgeWarn 样式。
|
// 提示“这些异常点待复查”。改 objectName 后重新 polish 以应用 #panelBadgeWarn 样式。
|
||||||
// 注:徽标的填充/显隐在 loadDataset 内(当前被 park),故此色与徽标本身同属休眠态,
|
// 注:徽标的填充/显隐由 exceptionTreeLoaded 连接驱动(勾选对象后按异常计数更新)。
|
||||||
// 接 dd 详情渲染那轮一并可见。
|
|
||||||
if (anomalyBadge) {
|
if (anomalyBadge) {
|
||||||
anomalyBadge->setObjectName(QStringLiteral("panelBadgeWarn"));
|
anomalyBadge->setObjectName(QStringLiteral("panelBadgeWarn"));
|
||||||
anomalyBadge->style()->unpolish(anomalyBadge);
|
anomalyBadge->style()->unpolish(anomalyBadge);
|
||||||
|
|
@ -577,13 +572,10 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
auto* rightArea = dockManager->addDockWidget(ads::RightDockWidgetArea, rightDock);
|
auto* rightArea = dockManager->addDockWidget(ads::RightDockWidgetArea, rightDock);
|
||||||
|
|
||||||
// 右下 dock:属性(数据集属性,键值;对齐原型下半,独立面板)。
|
// 右下 dock:属性(数据集属性,键值;对齐原型下半,独立面板)。
|
||||||
auto* propLabel = new QLabel(QStringLiteral("(单击左侧数据集查看属性与平面剖面)"));
|
auto* propView = new geopro::app::DynamicFormView();
|
||||||
propLabel->setWordWrap(true);
|
|
||||||
propLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
|
||||||
propLabel->setMargin(8);
|
|
||||||
auto* propDock = new ads::CDockWidget(QStringLiteral("数据集属性"));
|
auto* propDock = new ads::CDockWidget(QStringLiteral("数据集属性"));
|
||||||
propDock->setWidget(
|
propDock->setWidget(
|
||||||
wrapWithHeader(geopro::app::Glyph::Property, QStringLiteral("数据集属性"), propLabel));
|
wrapWithHeader(geopro::app::Glyph::Property, QStringLiteral("数据集属性"), propView));
|
||||||
dockManager->addDockWidget(ads::BottomDockWidgetArea, propDock, rightArea);
|
dockManager->addDockWidget(ads::BottomDockWidgetArea, propDock, rightArea);
|
||||||
|
|
||||||
// 固定全部面板(对齐原型):移除 关闭/浮动/拖动/钉住 等子窗口操作,仅保留分隔条调整边界。
|
// 固定全部面板(对齐原型):移除 关闭/浮动/拖动/钉住 等子窗口操作,仅保留分隔条调整边界。
|
||||||
|
|
@ -709,66 +701,15 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 加载某数据集到「数据详情 + 异常列表 + 属性」(数据列表单击与启动默认共用)。
|
// ── 单击左下数据列表的采集批次(DS) → 加载数据集动态表单(数据集属性面板)──
|
||||||
auto loadDataset = [&repo, propLabel, currentDsId, rebuildDetail, anomalyList, hiddenAnoms,
|
|
||||||
anomalyBadge](const QString& dsId, const QString& name) {
|
|
||||||
if (dsId.isEmpty()) return;
|
|
||||||
*currentDsId = dsId;
|
|
||||||
|
|
||||||
// 右上异常列表:按该数据集异常重填(默认全显);先清隐藏集再填,避免重建时阻塞信号回灌。
|
|
||||||
const auto anomalies = repo.loadAnomalies(dsId.toStdString());
|
|
||||||
hiddenAnoms->clear();
|
|
||||||
{
|
|
||||||
const QSignalBlocker block(anomalyList); // 重填触发 itemChanged,先屏蔽
|
|
||||||
geopro::app::populateAnomalyList(anomalyList, anomalies);
|
|
||||||
}
|
|
||||||
// 异常列表 Tab 数量徽标。
|
|
||||||
if (anomalyBadge) {
|
|
||||||
anomalyBadge->setText(QString::number(anomalies.size()));
|
|
||||||
anomalyBadge->setVisible(!anomalies.empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
rebuildDetail();
|
|
||||||
|
|
||||||
// 右下属性(数据集级,与详情模式无关)。
|
|
||||||
const auto g = repo.loadGrid(dsId.toStdString());
|
|
||||||
propLabel->setText(
|
|
||||||
QStringLiteral("数据集: %1\n类型: 剖面网格 (dd_section)\n网格: %2 x %3\n"
|
|
||||||
"vmin / vmax: %4 / %5\n异常: %6 个")
|
|
||||||
.arg(name).arg(g.nx()).arg(g.ny()).arg(g.vmin).arg(g.vmax)
|
|
||||||
.arg(anomalies.size()));
|
|
||||||
};
|
|
||||||
// 暂未触发:保留待下一轮真实 DS 详情渲染复用。
|
|
||||||
// TODO(overdrive-A 依赖):把下面数据集单击处理改调 loadDataset(dsId, name) 接通真实详情
|
|
||||||
// 渲染后,rebuildDetail 里已就绪的“相机补间 + actor 淡入”揭示动画会在切换数据集时自动激活
|
|
||||||
// (见 rebuildDetail 的 animate 分支与 animateReveal)。在此之前该动画为休眠态、不可见。
|
|
||||||
(void)loadDataset;
|
|
||||||
|
|
||||||
// ── 单击左下数据列表的采集批次(DS) → 占位(真实剖面/反演渲染下一阶段接 dd 接口)──
|
|
||||||
// 接 dd 那轮:把本处占位改为 loadDataset(id, name) 即接通详情渲染,并自动激活 overdrive-A 揭示动画。
|
|
||||||
QObject::connect(datasetList, &QListWidget::itemClicked, datasetList,
|
QObject::connect(datasetList, &QListWidget::itemClicked, datasetList,
|
||||||
[propLabel, detailRendererPtr, detailRenderWindowPtr, &nav](QListWidgetItem* item) {
|
[&nav](QListWidgetItem* item) {
|
||||||
if (item->data(geopro::app::kDsLoadMoreRole).toBool()) {
|
if (item->data(geopro::app::kDsLoadMoreRole).toBool()) {
|
||||||
nav.loadMoreData();
|
nav.loadMoreData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QString name =
|
const QString dsId = item->data(geopro::app::kDsIdRole).toString();
|
||||||
item->data(Qt::DisplayRole).toString().section('\n', 0, 0);
|
if (!dsId.isEmpty()) nav.selectDataset(dsId);
|
||||||
detailRendererPtr->RemoveAllViewProps();
|
|
||||||
detailRenderWindowPtr->Render();
|
|
||||||
propLabel->setText(QStringLiteral(
|
|
||||||
"数据集: %1\n(该数据集的剖面/反演渲染将在下一阶段接入 dd 接口)").arg(name));
|
|
||||||
});
|
|
||||||
|
|
||||||
// ── 异常列表勾选(显隐) → 更新隐藏集 → 重建数据详情 ──
|
|
||||||
QObject::connect(anomalyList, &QListWidget::itemChanged, anomalyList,
|
|
||||||
[hiddenAnoms, rebuildDetail](QListWidgetItem* item) {
|
|
||||||
const int idx = item->data(geopro::app::kAnomalyIndexRole).toInt();
|
|
||||||
if (item->checkState() == Qt::Checked)
|
|
||||||
hiddenAnoms->erase(idx);
|
|
||||||
else
|
|
||||||
hiddenAnoms->insert(idx);
|
|
||||||
rebuildDetail();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── 数据详情工具条「反演剖面/原数据」:切模式 → 重建数据详情 ──
|
// ── 数据详情工具条「反演剖面/原数据」:切模式 → 重建数据详情 ──
|
||||||
|
|
@ -916,8 +857,28 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
});
|
});
|
||||||
dlg->exec();
|
dlg->exec();
|
||||||
});
|
});
|
||||||
QObject::connect(objectTree, &geopro::app::ObjectTreePanel::tmClicked, &nav,
|
QObject::connect(objectTree, &geopro::app::ObjectTreePanel::objectClicked, &nav,
|
||||||
&geopro::controller::WorkbenchNavController::selectTm);
|
&geopro::controller::WorkbenchNavController::selectObject);
|
||||||
|
QObject::connect(objectTree, &geopro::app::ObjectTreePanel::checkedTmsChanged, &nav,
|
||||||
|
&geopro::controller::WorkbenchNavController::setCheckedTms);
|
||||||
|
|
||||||
|
// 控制器详情/异常/数据集表单 → 三个被动面板。
|
||||||
|
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::objectDetailLoaded, objAttrView,
|
||||||
|
[objAttrView](const QString&, const geopro::data::DynamicForm& form) {
|
||||||
|
objAttrView->setForm(form);
|
||||||
|
});
|
||||||
|
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::exceptionTreeLoaded,
|
||||||
|
exceptionPanel,
|
||||||
|
[exceptionPanel, anomalyBadge](
|
||||||
|
const std::vector<geopro::data::ObjectExceptionGroup>& groups, int total) {
|
||||||
|
exceptionPanel->setGroups(groups);
|
||||||
|
if (anomalyBadge) {
|
||||||
|
anomalyBadge->setText(QString::number(total));
|
||||||
|
anomalyBadge->setVisible(total > 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::datasetDetailLoaded, propView,
|
||||||
|
[propView](const geopro::data::DynamicForm& form) { propView->setForm(form); });
|
||||||
|
|
||||||
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::workspacesLoaded, topBar,
|
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::workspacesLoaded, topBar,
|
||||||
[topBar](const std::vector<geopro::data::Workspace>& list, const QString& cur) {
|
[topBar](const std::vector<geopro::data::Workspace>& list, const QString& cur) {
|
||||||
|
|
@ -929,12 +890,17 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
topBar->setProjects(list, cur, total > static_cast<int>(list.size()));
|
topBar->setProjects(list, cur, total > static_cast<int>(list.size()));
|
||||||
});
|
});
|
||||||
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::structureLoaded, objectTree,
|
QObject::connect(&nav, &geopro::controller::WorkbenchNavController::structureLoaded, objectTree,
|
||||||
[objectTree, datasetList, fileList, datasetTitle, datasetTabs](
|
[objectTree, datasetList, fileList, datasetTitle, datasetTabs, exceptionPanel,
|
||||||
|
objAttrView, propView, anomalyBadge](
|
||||||
const QString& projectName,
|
const QString& projectName,
|
||||||
const std::vector<geopro::data::StructNode>& nodes) {
|
const std::vector<geopro::data::StructNode>& nodes) {
|
||||||
objectTree->setStructure(projectName, nodes);
|
objectTree->setStructure(projectName, nodes);
|
||||||
datasetList->clear();
|
datasetList->clear();
|
||||||
fileList->clear();
|
fileList->clear();
|
||||||
|
exceptionPanel->showMessage(QStringLiteral("(勾选对象后显示其异常 / 异常体)"));
|
||||||
|
objAttrView->showMessage(QStringLiteral("(选中对象后显示其属性)"));
|
||||||
|
propView->showMessage(QStringLiteral("(单击数据集查看属性)"));
|
||||||
|
if (anomalyBadge) anomalyBadge->setVisible(false);
|
||||||
if (datasetTitle) datasetTitle->setText(QStringLiteral("数据集"));
|
if (datasetTitle) datasetTitle->setText(QStringLiteral("数据集"));
|
||||||
datasetTabs->setTabText(0, QStringLiteral("数据"));
|
datasetTabs->setTabText(0, QStringLiteral("数据"));
|
||||||
datasetTabs->setTabText(1, QStringLiteral("文件"));
|
datasetTabs->setTabText(1, QStringLiteral("文件"));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue