feat/vtk-3d-view #7
|
|
@ -22,12 +22,16 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
||||||
|
|
||||||
auto* content = new QWidget(scroll);
|
auto* content = new QWidget(scroll);
|
||||||
auto* col = new QVBoxLayout(content);
|
auto* col = new QVBoxLayout(content);
|
||||||
|
col_ = col;
|
||||||
col->setContentsMargins(0, space::kSm, 0, space::kSm); // 顶部留白:首段段头不贴顶
|
col->setContentsMargins(0, space::kSm, 0, space::kSm); // 顶部留白:首段段头不贴顶
|
||||||
col->setSpacing(space::kSm);
|
col->setSpacing(space::kSm);
|
||||||
|
|
||||||
for (const CategorySpec& spec : categoryConfigs()) {
|
for (const CategorySpec& spec : categoryConfigs()) {
|
||||||
auto* sec = new CategorySection(spec, dict, content);
|
auto* sec = new CategorySection(spec, dict, content);
|
||||||
sections_[spec.id] = sec;
|
sections_[spec.id] = sec;
|
||||||
|
ordered_.push_back(sec);
|
||||||
|
connect(sec, &CategorySection::collapsedChanged, this,
|
||||||
|
&CategoryAnalysisTab::relayoutSections); // 折叠/展开 → 重排 stretch(向上收)
|
||||||
const std::string segId = spec.id;
|
const std::string segId = spec.id;
|
||||||
connect(sec, &CategorySection::checkedDatasetsChanged, this,
|
connect(sec, &CategorySection::checkedDatasetsChanged, this,
|
||||||
[this, segId](const QStringList& ids) {
|
[this, segId](const QStringList& ids) {
|
||||||
|
|
@ -54,9 +58,22 @@ CategoryAnalysisTab::CategoryAnalysisTab(geopro::data::DatasetFieldDictionary* d
|
||||||
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
// 某段内容增多时其最小高度(=内容总高)撑大,超出视口则由外层 QScrollArea 统一出纵向滚动条。
|
||||||
col->addWidget(sec, 1);
|
col->addWidget(sec, 1);
|
||||||
}
|
}
|
||||||
|
// 尾部弹簧(末项):默认 0;全部段折叠时由 relayoutSections 置 1,吸收余量把段头顶到顶部。
|
||||||
|
col->addStretch(0);
|
||||||
scroll->setWidget(content);
|
scroll->setWidget(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CategoryAnalysisTab::relayoutSections() {
|
||||||
|
if (!col_) return;
|
||||||
|
int expanded = 0;
|
||||||
|
for (auto* sec : ordered_)
|
||||||
|
if (sec->isExpanded()) ++expanded;
|
||||||
|
// 展开段 stretch=1(吸收余量、铺满);折叠段 stretch=0(只占段头高,下方不再留空)。
|
||||||
|
for (auto* sec : ordered_) col_->setStretchFactor(sec, sec->isExpanded() ? 1 : 0);
|
||||||
|
// 尾部弹簧:仅当全部折叠时=1(把所有段头顶到顶部);有任一展开段时=0(由展开段吸收余量)。
|
||||||
|
col_->setStretch(col_->count() - 1, expanded == 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
void CategoryAnalysisTab::setBuckets(const CategoryBuckets& b) {
|
void CategoryAnalysisTab::setBuckets(const CategoryBuckets& b) {
|
||||||
const auto& cfg = categoryConfigs();
|
const auto& cfg = categoryConfigs();
|
||||||
for (std::size_t i = 0; i < cfg.size() && i < b.segments.size(); ++i) {
|
for (std::size_t i = 0; i < cfg.size() && i < b.segments.size(); ++i) {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class QVBoxLayout;
|
||||||
#include "DatasetCategory.hpp" // CategoryBuckets
|
#include "DatasetCategory.hpp" // CategoryBuckets
|
||||||
#include "interact/SlicePlaneMath.hpp" // geopro::render::interact::SliceAxis
|
#include "interact/SlicePlaneMath.hpp" // geopro::render::interact::SliceAxis
|
||||||
#include "repo/RepoTypes.hpp"
|
#include "repo/RepoTypes.hpp"
|
||||||
|
|
@ -45,8 +47,13 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void recomputeCheckedUnion();
|
void recomputeCheckedUnion();
|
||||||
|
// 据各段折叠态重排 stretch:折叠段=0(仅段头高)、展开段=1(吸收余量);全折叠时尾部弹簧吸收→段头顶到顶部。
|
||||||
|
// 仅在面板不产生滚动条(内容short于视口)时有可见效果——正是用户反馈的"折叠后停在原位中间"场景。
|
||||||
|
void relayoutSections();
|
||||||
|
|
||||||
std::map<std::string, CategorySection*> sections_;
|
std::map<std::string, CategorySection*> sections_;
|
||||||
|
std::vector<CategorySection*> ordered_; // 按 categoryConfigs 顺序(relayout 遍历用)
|
||||||
|
QVBoxLayout* col_ = nullptr; // 段堆叠布局(末项=尾部弹簧)
|
||||||
std::map<std::string, QStringList> checkedBySeg_; // 各段当前勾选(合并成并集)
|
std::map<std::string, QStringList> checkedBySeg_; // 各段当前勾选(合并成并集)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -145,9 +145,12 @@ CategorySection::CategorySection(const CategorySpec& spec, geopro::data::Dataset
|
||||||
connect(header_, &QToolButton::toggled, this, [this, syncHeader](bool on) {
|
connect(header_, &QToolButton::toggled, this, [this, syncHeader](bool on) {
|
||||||
body_->setVisible(on);
|
body_->setVisible(on);
|
||||||
syncHeader(); // ▾(展开)/▸(折叠) 切换
|
syncHeader(); // ▾(展开)/▸(折叠) 切换
|
||||||
|
emit collapsedChanged(); // 外层据此把折叠段 stretch 归 0、展开段吸收余量 → 折叠向上收
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CategorySection::isExpanded() const { return header_ && header_->isChecked(); }
|
||||||
|
|
||||||
void CategorySection::setStructure(const std::vector<geopro::data::StructNode>& nodes) {
|
void CategorySection::setStructure(const std::vector<geopro::data::StructNode>& nodes) {
|
||||||
structure_ = nodes; // 容器分层(项目根/GS/TM→ds)在 Task 12 接入真实结构后据此构建。
|
structure_ = nodes; // 容器分层(项目根/GS/TM→ds)在 Task 12 接入真实结构后据此构建。
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,11 @@ public:
|
||||||
QStringList checkedIds() const { return checkedDsIds(); } // 当前勾选 ds(异常显隐同步用)
|
QStringList checkedIds() const { return checkedDsIds(); } // 当前勾选 ds(异常显隐同步用)
|
||||||
void refreshArrayFilter() { refreshArrayCombo(); } // 装置枚举异步加载后重填下拉
|
void refreshArrayFilter() { refreshArrayCombo(); } // 装置枚举异步加载后重填下拉
|
||||||
const CategorySpec& spec() const { return spec_; }
|
const CategorySpec& spec() const { return spec_; }
|
||||||
|
bool isExpanded() const; // 段头展开态(供外层按折叠状态重分配 stretch,实现"折叠向上收")
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void checkedDatasetsChanged(const QStringList& dsIds); // 数据行勾选=渲染
|
void checkedDatasetsChanged(const QStringList& dsIds); // 数据行勾选=渲染
|
||||||
|
void collapsedChanged(); // 折叠/展开切换 → 外层 CategoryAnalysisTab 重排各段 stretch
|
||||||
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」
|
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」
|
||||||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情
|
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 双击/右键=详情
|
||||||
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue