120 lines
8.6 KiB
C++
120 lines
8.6 KiB
C++
#pragma once
|
||
#include <QStringList>
|
||
#include <QWidget>
|
||
#include <vector>
|
||
#include "interact/SlicePlaneMath.hpp" // geopro::render::interact::SliceAxis
|
||
#include "repo/CategoryDescriptor.hpp" // geopro::data::CategoryDescriptor / OpKind / FilterKind
|
||
#include "repo/RepoTypes.hpp"
|
||
|
||
class QTreeWidget;
|
||
class QTreeWidgetItem;
|
||
class QComboBox;
|
||
class QDateEdit;
|
||
class QLabel;
|
||
class QToolButton;
|
||
class QTimer;
|
||
class QWidget;
|
||
|
||
namespace geopro::data {
|
||
class DatasetFieldDictionary;
|
||
}
|
||
|
||
namespace geopro::app {
|
||
|
||
class DateRangeEdit;
|
||
class SectionIconBar;
|
||
|
||
// 单个数据类型大类段(spec §7):段头(标题/折叠 + 段头图标条)+ 段体(折叠筛选行 + 可勾选数据树)。
|
||
// 段头图标条由 descriptor.operations(OpKind) 驱动;筛选行由 descriptor.filters(FilterKind) 驱动、默认折叠。
|
||
// 勾选数据行 = 渲染(帘面/体素/切片/二维面);GenerateVolume 图标据当前勾选源发 generateVolumeRequested。
|
||
class CategorySection : public QWidget {
|
||
Q_OBJECT
|
||
public:
|
||
CategorySection(const geopro::data::CategoryDescriptor& desc,
|
||
geopro::data::DatasetFieldDictionary* dict, QWidget* parent = nullptr);
|
||
|
||
// 对象树同源的扁平 GS/TM 节点(段体容器分层用;Task 12 接入真实结构,当前仅存储)。
|
||
void setStructure(const std::vector<geopro::data::StructNode>& nodes);
|
||
void setDatasets(const std::vector<geopro::data::DsRow>& rows);
|
||
void setChecked(const QString& dsId, bool on); // 按 dsId 勾选/取消(新建切片自动勾选等场景)
|
||
// 渲染中:该行复选框替换为等待 spinner(busy=true)/复原(false)。busy 期间保持勾选、动画由定时器驱动。
|
||
void setBusy(const QString& dsId, bool busy);
|
||
void clearAllBusy(); // 撤回本段所有 spinner(失败兜底)
|
||
void selectItem(const QString& dsId); // 程序化选中某行(VTK→list 反向联动);空/未找到=清选中
|
||
void clearSelection(); // 清本段树选中(信号阻断,不回发 datasetSelected);供跨段全列互斥用
|
||
QStringList checkedIds() const { return checkedDsIds(); } // 当前勾选 ds(异常显隐同步用)
|
||
void refreshArrayFilter() { refreshArrayCombo(); } // 装置枚举异步加载后重填下拉
|
||
bool isExpanded() const; // 段头展开态(供外层按折叠状态重分配 stretch,实现"折叠向上收")
|
||
void ensureExpanded(); // 展开本段(折叠则展开):滚动定位前确保目标行可见
|
||
QTreeWidget* listWidget() const { return list_; } // 段体树(外层滚动定位用)
|
||
QTreeWidgetItem* itemFor(const QString& dsId) const; // 按 dsId 取行(无则 nullptr)
|
||
// 该 ds 所在层级子树的全部 dsId(贴合坐标轴子树盒,spec §2/§3.2 决策 3):先归一到子树根
|
||
// (向上找最高非容器祖先=三维体行),再自根向下收集整棵子树(体+切片+异常)的非空 dsId。
|
||
// 故选中体/切片/异常都归到同一个「该体子树」盒。dsId 不在本段则返回空。
|
||
QStringList subtreeDsIds(const QString& dsId) const;
|
||
bool hasRenderableRows() const; // 段体是否含可渲染数据行(非 container 容器节点),供单列动态显隐
|
||
|
||
protected:
|
||
// 段体树 viewport 事件过滤:在默认处理改选之前记录「按下瞬间该行是否已选中」,供单击已选行的 toggle 取消判定。
|
||
bool eventFilter(QObject* obj, QEvent* ev) override;
|
||
|
||
signals:
|
||
void checkedDatasetsChanged(const QStringList& dsIds); // 数据行勾选=渲染
|
||
void collapsedChanged(); // 折叠/展开切换 → 外层 CategoryAnalysisTab 重排各段 stretch
|
||
void generateVolumeRequested(const QString& dsTypeCode, const QStringList& sourceDsIds); // 段头「+新增三维体」(接收方按 sourceIds 解析类型)
|
||
void planeZChanged(const QString& typeId, double z); // PlaneZ 滑块:整体升降该 2D 类型平面(z=绝对高程,米)
|
||
void basemapKindChanged(const QString& typeId, int kind); // 底图弹窗:矢量平面(0)/无(1)
|
||
void basemapOpacityChanged(const QString& typeId, double o); // 底图弹窗透明度滑块[0,1](防抖发射)
|
||
void detailRequested(const QString& dsId, const QString& ddCode, const QString& name); // 右键「详情」=属性弹窗
|
||
// 双击某行(决策6/T4):适配相机到该 ds 子树空间范围 + 联动中下方详情面板(无详情页类型静默)。
|
||
// 与 detailRequested(右键属性弹窗)分开,使双击「只适配 + 图表联动」,三维体等无图表页时静默。
|
||
void datasetActivated(const QString& dsId, const QString& ddCode, const QString& name);
|
||
void deleteDatasetRequested(const QString& dsId, const QString& ddCode); // 右键删除(切片/异常)
|
||
// ── 三维体段右键操作(迁自旧 Column3DAnalysis,全接)──
|
||
void sliceRequested(geopro::render::interact::SliceAxis axis, const QString& volumeDsId); // 体→生成切片(轴+目标体)
|
||
void colorScaleRequested(const QString& dsId); // 体/切片→色阶
|
||
void radarGainModeRequested(const QString& dsId, int mode); // 雷达体→显示增益模式(0关/1AGC/2保幅tpow)
|
||
void sliceSaveRequested(const QString& dsId); // 切片→保存位姿
|
||
void sliceSaveAsRequested(const QString& dsId); // 切片→另存
|
||
void sliceExportImageRequested(const QString& dsId); // 切片→导出图片
|
||
void sliceExportDatRequested(const QString& dsId); // 切片→导出 dat
|
||
void anomalyVisibilityChanged(const QString& dsId, bool vis); // 异常→显示/隐藏
|
||
void datasetSelected(const QString& dsId, const QString& ddCode); // 树选中行→VTK 高亮联动(切片/异常)
|
||
|
||
private:
|
||
void showContextMenu(const QPoint& pos); // 段体树右键菜单(详情 + 删除)
|
||
void showPlaneZPopup(QToolButton* host); // PlaneZ 图标:弹 z 值滑块 popup → planeZChanged
|
||
void showBasemapPopup(QToolButton* host); // Basemap 图标:弹 矢量平面/无 + 透明度滑块 popup
|
||
void rebuildList(); // 据 rows_(经装置/日期筛选)重建段体树并复原勾选
|
||
void refreshArrayCombo(); // 据当前 rows_ 重填装置类型下拉项(经字典 value→中文)
|
||
void emitChecked(); // 收集勾选 → checkedDatasetsChanged
|
||
QStringList checkedDsIds() const;
|
||
bool passesFilters(const geopro::data::DsRow& row) const; // 装置类型 + 采集时间范围
|
||
|
||
geopro::data::CategoryDescriptor desc_;
|
||
geopro::data::DatasetFieldDictionary* dict_ = nullptr;
|
||
std::vector<geopro::data::DsRow> rows_;
|
||
std::vector<geopro::data::StructNode> structure_;
|
||
|
||
QToolButton* header_ = nullptr; // 折叠头(标题 + 箭头)
|
||
SectionIconBar* iconBar_ = nullptr; // 段头响应式图标条(由 desc_.operations 装配)
|
||
QWidget* body_ = nullptr; // 段体容器(折叠时隐藏)
|
||
QWidget* filterRow_ = nullptr; // 筛选行容器(默认折叠,由 Filter 图标 toggle)
|
||
QComboBox* arrayCombo_ = nullptr; // 装置类型筛选(仅 desc_.filters 含 ArrayType)
|
||
DateRangeEdit* dateRange_ = nullptr; // 采集时间范围筛选(起止双日历,可清空)
|
||
QTreeWidget* list_ = nullptr;
|
||
QTimer* spinTimer_ = nullptr; // 驱动 busy 行 spinner 旋转(有 busy 行时运行)
|
||
int spinAngle_ = 0; // 当前 spinner 角度(度)
|
||
double lastPlaneZ_ = 0.0; // 上次 z 值滑块设定的平面高程(重开 popup 时回显,无则 0;直接平移故无防抖)
|
||
int lastBasemapKind_ = 0; // 上次底图选择(0=矢量平面/1=无),重开 popup 时回显
|
||
int lastBasemapOpacity_ = 50; // 上次底图透明度(0–100,重开 popup 回显;默认 50)
|
||
QTimer* basemapOpacityTimer_ = nullptr; // 底图透明度滑块发射防抖(透明度改动会触发瓦片重铺,仍需防抖)
|
||
double pendingBasemapOpacity_ = 0.5; // 防抖待发的底图透明度[0,1](定时器到点发射 basemapOpacityChanged)
|
||
// 单击已选行取消选中(toggle-off):eventFilter 于按下瞬间(默认改选前)记录被按行及其选中态;itemClicked 据此取消。
|
||
QTreeWidgetItem* pressedItem_ = nullptr; // 本次左键按下的行(itemAt(press),与 itemClicked 的行比对)
|
||
bool pressedSelected_ = false; // 按下瞬间该行是否已选中(true 且非勾选框点击时,单击取消选中)
|
||
bool checkToggledThisPress_ = false; // 本次按下是否切换了勾选框(点勾选框只改渲染,不取消选中)
|
||
};
|
||
|
||
} // namespace geopro::app
|