feat(ui): CategoryAnalysisTab(QScrollArea 5段)+ColumnDrawer 两tab(旧栏隐藏过渡)
This commit is contained in:
parent
30e990d967
commit
98114a36e0
|
|
@ -82,6 +82,7 @@ add_executable(geopro_desktop WIN32
|
||||||
panels/columns/Column3DDataset.cpp
|
panels/columns/Column3DDataset.cpp
|
||||||
panels/columns/Column3DAnalysis.cpp
|
panels/columns/Column3DAnalysis.cpp
|
||||||
panels/columns/CategorySection.cpp
|
panels/columns/CategorySection.cpp
|
||||||
|
panels/columns/CategoryAnalysisTab.cpp
|
||||||
panels/columns/ColumnDrawer.cpp
|
panels/columns/ColumnDrawer.cpp
|
||||||
panels/AnomalyTablePanel.cpp
|
panels/AnomalyTablePanel.cpp
|
||||||
panels/LoadingOverlay.cpp
|
panels/LoadingOverlay.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include "panels/columns/CategoryAnalysisTab.hpp"
|
||||||
|
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "Theme.hpp"
|
||||||
|
#include "panels/columns/CategorySection.hpp"
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* dict, QWidget* parent)
|
||||||
|
: QWidget(parent) {
|
||||||
|
auto* outer = new QVBoxLayout(this);
|
||||||
|
outer->setContentsMargins(0, 0, 0, 0);
|
||||||
|
outer->setSpacing(0);
|
||||||
|
|
||||||
|
auto* scroll = new QScrollArea(this);
|
||||||
|
scroll->setWidgetResizable(true);
|
||||||
|
scroll->setFrameShape(QFrame::NoFrame);
|
||||||
|
outer->addWidget(scroll, 1);
|
||||||
|
|
||||||
|
auto* content = new QWidget(scroll);
|
||||||
|
auto* col = new QVBoxLayout(content);
|
||||||
|
col->setContentsMargins(0, 0, 0, 0);
|
||||||
|
col->setSpacing(space::kSm);
|
||||||
|
|
||||||
|
for (const CategorySpec& spec : categoryConfigs()) {
|
||||||
|
auto* sec = new CategorySection(spec, dict, content);
|
||||||
|
sections_[spec.id] = sec;
|
||||||
|
const std::string segId = spec.id;
|
||||||
|
connect(sec, &CategorySection::checkedDatasetsChanged, this,
|
||||||
|
[this, segId](const QStringList& ids) {
|
||||||
|
checkedBySeg_[segId] = ids;
|
||||||
|
recomputeCheckedUnion();
|
||||||
|
});
|
||||||
|
connect(sec, &CategorySection::generateVolumeRequested, this,
|
||||||
|
&CategoryAnalysisTab::generateVolumeRequested);
|
||||||
|
connect(sec, &CategorySection::detailRequested, this, &CategoryAnalysisTab::detailRequested);
|
||||||
|
col->addWidget(sec);
|
||||||
|
}
|
||||||
|
col->addStretch(1);
|
||||||
|
scroll->setWidget(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CategoryAnalysisTab::setBuckets(const CategoryBuckets& b) {
|
||||||
|
const auto& cfg = categoryConfigs();
|
||||||
|
for (std::size_t i = 0; i < cfg.size() && i < b.segments.size(); ++i) {
|
||||||
|
if (auto* sec = section(cfg[i].id)) sec->setDatasets(b.segments[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CategoryAnalysisTab::setStructure(const std::vector<geopro::data::StructNode>& nodes) {
|
||||||
|
for (auto& [id, sec] : sections_) sec->setStructure(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
CategorySection* CategoryAnalysisTab::section(const std::string& id) const {
|
||||||
|
const auto it = sections_.find(id);
|
||||||
|
return it != sections_.end() ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CategoryAnalysisTab::recomputeCheckedUnion() {
|
||||||
|
QStringList all; // ds 归属唯一段,跨段不重复,直接拼接
|
||||||
|
for (const auto& [id, ids] : checkedBySeg_) all += ids;
|
||||||
|
emit checkedDatasetsChanged(all);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "DatasetCategory.hpp" // CategoryBuckets
|
||||||
|
#include "repo/RepoTypes.hpp"
|
||||||
|
|
||||||
|
namespace geopro::data {
|
||||||
|
class DatasetFieldDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace geopro::app {
|
||||||
|
|
||||||
|
class CategorySection;
|
||||||
|
|
||||||
|
// 「三维分析」tab:QScrollArea 竖向堆叠 5 个数据类型大类段(spec §4)。
|
||||||
|
// 各段勾选合并为并集上抛;生成/详情请求透传。
|
||||||
|
class CategoryAnalysisTab : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* dict, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void setBuckets(const CategoryBuckets& b); // 分发到 5 段(与 categoryConfigs 同序)
|
||||||
|
void setStructure(const std::vector<geopro::data::StructNode>& nodes); // 转发各段
|
||||||
|
CategorySection* section(const std::string& id) const; // 按 CategorySpec.id 取段
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void checkedDatasetsChanged(const QStringList& dsIds); // 5 段勾选并集
|
||||||
|
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds);
|
||||||
|
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void recomputeCheckedUnion();
|
||||||
|
|
||||||
|
std::map<std::string, CategorySection*> sections_;
|
||||||
|
std::map<std::string, QStringList> checkedBySeg_; // 各段当前勾选(合并成并集)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace geopro::app
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include "panels/columns/Column3DDataset.hpp"
|
#include "panels/columns/Column3DDataset.hpp"
|
||||||
#include "panels/columns/Column2DDataset.hpp"
|
#include "panels/columns/Column2DDataset.hpp"
|
||||||
#include "panels/columns/Column3DAnalysis.hpp"
|
#include "panels/columns/Column3DAnalysis.hpp"
|
||||||
|
#include "panels/columns/CategoryAnalysisTab.hpp"
|
||||||
#include "Glyphs.hpp"
|
#include "Glyphs.hpp"
|
||||||
#include "Theme.hpp"
|
#include "Theme.hpp"
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
@ -10,20 +11,22 @@
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
||||||
ColumnDrawer::ColumnDrawer(QWidget* parent)
|
ColumnDrawer::ColumnDrawer(QWidget* parent, geopro::data::DatasetFieldDictionary* dict)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
// 创建三个栏
|
col2D_ = new Column2DDataset(this);
|
||||||
col3D_ = new Column3DDataset(this);
|
analysisTab_ = new CategoryAnalysisTab(dict, this);
|
||||||
col2D_ = new Column2DDataset(this);
|
// 过渡:旧三维数据集/三维分析栏仍实例化以兼容 main 现有接线,但隐藏、不入 tab(Task 12 退役)。
|
||||||
|
col3D_ = new Column3DDataset(this);
|
||||||
colAnalysis_ = new Column3DAnalysis(this);
|
colAnalysis_ = new Column3DAnalysis(this);
|
||||||
|
col3D_->hide();
|
||||||
|
colAnalysis_->hide();
|
||||||
|
|
||||||
// Tab 容器(body_)
|
// Tab 容器(body_):两 tab(三维分析[分段] / 二维分析)。
|
||||||
auto* tabs = new QTabWidget(this);
|
auto* tabs = new QTabWidget(this);
|
||||||
body_ = tabs;
|
body_ = tabs;
|
||||||
tabs->addTab(col3D_, QStringLiteral("三维数据集"));
|
tabs->addTab(analysisTab_, QStringLiteral("三维分析"));
|
||||||
tabs->addTab(col2D_, QStringLiteral("二维数据集"));
|
tabs->addTab(col2D_, QStringLiteral("二维分析"));
|
||||||
tabs->addTab(colAnalysis_, QStringLiteral("三维分析"));
|
|
||||||
|
|
||||||
// 折叠按钮:固定宽 18px,垂直拉伸。
|
// 折叠按钮:固定宽 18px,垂直拉伸。
|
||||||
// 用 SVG 图标(makeGlyph)而非 ◀/▶ 文字——三角符(U+25C0/25B6)不在 YaHei,作按钮文字会触发
|
// 用 SVG 图标(makeGlyph)而非 ◀/▶ 文字——三角符(U+25C0/25B6)不在 YaHei,作按钮文字会触发
|
||||||
|
|
|
||||||
|
|
@ -3,30 +3,39 @@
|
||||||
|
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace geopro::data {
|
||||||
|
class DatasetFieldDictionary;
|
||||||
|
}
|
||||||
|
|
||||||
namespace geopro::app {
|
namespace geopro::app {
|
||||||
|
|
||||||
class Column3DDataset;
|
class Column3DDataset;
|
||||||
class Column2DDataset;
|
class Column2DDataset;
|
||||||
class Column3DAnalysis;
|
class Column3DAnalysis;
|
||||||
|
class CategoryAnalysisTab;
|
||||||
|
|
||||||
// VTK视图左侧内嵌抽屉:三 tab(三维数据集/二维数据集/三维分析) + 折叠开关。
|
// VTK视图左侧内嵌抽屉:两 tab(三维分析[按数据类型分段]/二维分析) + 折叠开关。
|
||||||
|
// 旧 col3D_/colAnalysis_ 仍实例化但隐藏(不入 tab),保留访问器供 main 现有接线过渡,Task 12 退役。
|
||||||
class ColumnDrawer : public QWidget {
|
class ColumnDrawer : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ColumnDrawer(QWidget* parent = nullptr);
|
explicit ColumnDrawer(QWidget* parent = nullptr,
|
||||||
|
geopro::data::DatasetFieldDictionary* dict = nullptr);
|
||||||
|
|
||||||
Column3DDataset* col3D() const { return col3D_; }
|
Column3DDataset* col3D() const { return col3D_; } // 【过渡,Task 12 删】
|
||||||
Column2DDataset* col2D() const { return col2D_; }
|
Column2DDataset* col2D() const { return col2D_; }
|
||||||
Column3DAnalysis* colAnalysis() const { return colAnalysis_; }
|
Column3DAnalysis* colAnalysis() const { return colAnalysis_; } // 【过渡,Task 12 删】
|
||||||
|
CategoryAnalysisTab* analysisTab() const { return analysisTab_; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleCollapsed();
|
void toggleCollapsed();
|
||||||
void expand(); // 强制展开(进入全屏时确保三栏可见)
|
void expand(); // 强制展开(进入全屏时确保三栏可见)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Column3DDataset* col3D_ = nullptr;
|
Column3DDataset* col3D_ = nullptr; // 【过渡,隐藏不入 tab,Task 12 删】
|
||||||
Column2DDataset* col2D_ = nullptr;
|
Column2DDataset* col2D_ = nullptr;
|
||||||
Column3DAnalysis* colAnalysis_ = nullptr;
|
Column3DAnalysis* colAnalysis_ = nullptr; // 【过渡,隐藏不入 tab,Task 12 删】
|
||||||
|
CategoryAnalysisTab* analysisTab_ = nullptr;
|
||||||
QWidget* body_ = nullptr; // QTabWidget,折叠时隐藏
|
QWidget* body_ = nullptr; // QTabWidget,折叠时隐藏
|
||||||
QPushButton* toggleBtn_ = nullptr;
|
QPushButton* toggleBtn_ = nullptr;
|
||||||
bool collapsed_ = false;
|
bool collapsed_ = false;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue