From 0cfa1ad35231fd9edfc4d5ba507d0d56d8711310 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Thu, 25 Jun 2026 14:01:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=94=B9=E6=8A=BD=E5=B1=89=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?(=E5=B7=A5=E5=85=B7=E6=9D=A1=E5=8F=B3=E4=BE=A7=E6=BB=91?= =?UTF-8?q?=E5=87=BA)+=E8=A1=A5=E5=9D=90=E6=A0=87=E8=BD=B4=E5=8D=95?= =?UTF-8?q?=E4=BD=8D/=E6=94=BE=E5=A4=A7=E7=B3=BB=E6=95=B0(=E6=8C=89?= =?UTF-8?q?=E5=8E=9F=E5=9E=8B=E5=9B=BE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/AxesSettingsPanel.cpp | 134 ++++++++++++++++++++++++++++++++++ src/app/AxesSettingsPanel.hpp | 40 ++++++++++ src/app/CMakeLists.txt | 1 + src/app/main.cpp | 37 ++++++++-- 4 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 src/app/AxesSettingsPanel.cpp create mode 100644 src/app/AxesSettingsPanel.hpp diff --git a/src/app/AxesSettingsPanel.cpp b/src/app/AxesSettingsPanel.cpp new file mode 100644 index 0000000..dc1a2d8 --- /dev/null +++ b/src/app/AxesSettingsPanel.cpp @@ -0,0 +1,134 @@ +#include "AxesSettingsPanel.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include "Theme.hpp" + +namespace geopro::app { + +AxesSettingsPanel::AxesSettingsPanel(QWidget* parent) : QFrame(parent) { + setFrameShape(QFrame::StyledPanel); + applyTokenizedStyleSheet( + this, QStringLiteral("QFrame{background:{{bg/panel}};border:1px solid {{border/default}};" + "border-radius:10px;}")); + setFixedWidth(320); + + auto* v = new QVBoxLayout(this); + v->setContentsMargins(space::kMd, space::kMd, space::kMd, space::kMd); + v->setSpacing(space::kSm); + + // 标题行:坐标轴设置 + × 关闭。 + auto* titleRow = new QHBoxLayout(); + auto* title = new QLabel(QStringLiteral("坐标轴设置"), this); + title->setStyleSheet(QStringLiteral("font-weight:600;font-size:15px;border:none;")); + auto* close = new QPushButton(QStringLiteral("✕"), this); + close->setFlat(true); + close->setFixedSize(24, 24); + connect(close, &QPushButton::clicked, this, &AxesSettingsPanel::closed); + titleRow->addWidget(title); + titleRow->addStretch(1); + titleRow->addWidget(close); + v->addLayout(titleRow); + + // 坐标轴单位。 + auto* unitLbl = new QLabel(QStringLiteral("坐标轴单位"), this); + unitLbl->setStyleSheet(QStringLiteral("border:none;")); + v->addWidget(unitLbl); + unit_ = new QComboBox(this); + unit_->addItems({QStringLiteral("米"), QStringLiteral("英尺")}); + v->addWidget(unit_); + + // X / Y / Z 三轴(各:显示开关 + 最小值/最大值)。 + x_ = addAxisRow(v, QStringLiteral("X轴"), {true, -500, 500}); + y_ = addAxisRow(v, QStringLiteral("Y轴"), {true, -500, 500}); + z_ = addAxisRow(v, QStringLiteral("Z轴"), {true, 0, 200}); + + // 放大系数(=垂直夸张)。 + auto* scaleLbl = new QLabel(QStringLiteral("放大系数"), this); + scaleLbl->setStyleSheet(QStringLiteral("border:none;")); + v->addWidget(scaleLbl); + scale_ = new QComboBox(this); + scale_->addItems({QStringLiteral("0.1"), QStringLiteral("0.5"), QStringLiteral("1"), + QStringLiteral("2"), QStringLiteral("5")}); + scale_->setCurrentText(QStringLiteral("1")); + v->addWidget(scale_); + + // 取消 / 应用。 + auto* btns = new QHBoxLayout(); + auto* cancel = new QPushButton(QStringLiteral("取消"), this); + auto* apply = new QPushButton(QStringLiteral("应用"), this); + apply->setStyleSheet(QStringLiteral( + "QPushButton{background:#2f6fed;color:white;border:none;border-radius:6px;padding:6px 18px;}" + "QPushButton:hover{background:#2a63d4;}")); + connect(cancel, &QPushButton::clicked, this, &AxesSettingsPanel::closed); + connect(apply, &QPushButton::clicked, this, [this] { + auto rd = [](const Row& r) { + return AxisRange{r.show->isChecked(), r.lo->value(), r.hi->value()}; + }; + emit applied(rd(x_), rd(y_), rd(z_), unit_->currentIndex(), scale_->currentText().toDouble()); + }); + btns->addStretch(1); + btns->addWidget(cancel); + btns->addWidget(apply); + v->addLayout(btns); +} + +AxesSettingsPanel::Row AxesSettingsPanel::addAxisRow(QVBoxLayout* col, const QString& title, + const AxisRange& def) { + Row r; + auto* head = new QHBoxLayout(); + auto* lbl = new QLabel(title, this); + lbl->setStyleSheet(QStringLiteral("font-weight:600;border:none;")); + head->addWidget(lbl); + head->addStretch(1); + auto* showLbl = new QLabel(QStringLiteral("显示"), this); + showLbl->setStyleSheet(QStringLiteral("border:none;")); + head->addWidget(showLbl); + r.show = new QCheckBox(this); + r.show->setChecked(def.show); + head->addWidget(r.show); + col->addLayout(head); + + auto* range = new QHBoxLayout(); + auto* loCol = new QVBoxLayout(); + auto* loLbl = new QLabel(QStringLiteral("最小值"), this); + loLbl->setStyleSheet(QStringLiteral("border:none;color:#888;")); + loCol->addWidget(loLbl); + r.lo = new QDoubleSpinBox(this); + r.lo->setRange(-1e6, 1e6); + r.lo->setValue(def.min); + loCol->addWidget(r.lo); + range->addLayout(loCol); + auto* hiCol = new QVBoxLayout(); + auto* hiLbl = new QLabel(QStringLiteral("最大值"), this); + hiLbl->setStyleSheet(QStringLiteral("border:none;color:#888;")); + hiCol->addWidget(hiLbl); + r.hi = new QDoubleSpinBox(this); + r.hi->setRange(-1e6, 1e6); + r.hi->setValue(def.max); + hiCol->addWidget(r.hi); + range->addLayout(hiCol); + col->addLayout(range); + return r; +} + +void AxesSettingsPanel::setValues(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale) { + auto wr = [](const Row& r, const AxisRange& a) { + r.show->setChecked(a.show); + r.lo->setValue(a.min); + r.hi->setValue(a.max); + }; + wr(x_, x); + wr(y_, y); + wr(z_, z); + unit_->setCurrentIndex(unitIdx); + scale_->setCurrentText(QString::number(scale)); // 命中预设项则选中,否则保持 +} + +} // namespace geopro::app diff --git a/src/app/AxesSettingsPanel.hpp b/src/app/AxesSettingsPanel.hpp new file mode 100644 index 0000000..9c40ba7 --- /dev/null +++ b/src/app/AxesSettingsPanel.hpp @@ -0,0 +1,40 @@ +#pragma once +#include + +#include "AxesSettingsDialog.hpp" // AxisRange + +class QCheckBox; +class QComboBox; +class QDoubleSpinBox; +class QVBoxLayout; + +namespace geopro::app { + +// 坐标轴设置抽屉面板(原型):工具条右侧滑出、非模态。 +// 内容:坐标轴单位(米/英尺) → X/Y/Z 三轴(显示开关 + 最小值/最大值) → 放大系数(0.1/0.5/1/2/5) → 取消/应用。 +class AxesSettingsPanel : public QFrame { + Q_OBJECT +public: + explicit AxesSettingsPanel(QWidget* parent = nullptr); + + // 打开前回灌当前值(单位 0=米/1=英尺;scale=放大系数=垂直夸张)。 + void setValues(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale); + +signals: + void applied(AxisRange x, AxisRange y, AxisRange z, int unitIdx, double scale); + void closed(); // × 或 取消 + +private: + struct Row { + QCheckBox* show = nullptr; + QDoubleSpinBox* lo = nullptr; + QDoubleSpinBox* hi = nullptr; + }; + Row addAxisRow(QVBoxLayout* col, const QString& title, const AxisRange& def); + + QComboBox* unit_ = nullptr; // 坐标轴单位:米 / 英尺 + QComboBox* scale_ = nullptr; // 放大系数:0.1 / 0.5 / 1 / 2 / 5 + Row x_, y_, z_; +}; + +} // namespace geopro::app diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 5d4f914..6a640e5 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -113,6 +113,7 @@ add_executable(geopro_desktop WIN32 DatasetCategory.cpp VtkViewToolbar.cpp AxesSettingsDialog.cpp + AxesSettingsPanel.cpp TileBasemap.cpp) target_include_directories(geopro_desktop PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/app/main.cpp b/src/app/main.cpp index d28aa83..677dba5 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -141,6 +141,7 @@ #include "panels/columns/CategorySection.hpp" #include "VtkViewToolbar.hpp" #include "AxesSettingsDialog.hpp" +#include "AxesSettingsPanel.hpp" #include "repo/DatasetFieldDictionary.hpp" #include "panels/columns/Column3DDataset.hpp" #include "panels/columns/Column2DDataset.hpp" @@ -395,6 +396,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re viewToolbar->move(12, 12); viewToolbar->raise(); viewToolbar->show(); + // 坐标轴设置抽屉面板:叠加 vtkWidget、工具条右侧滑出,默认隐藏(点设置 toggle)。 + auto* axesPanel = new geopro::app::AxesSettingsPanel(vtkWidget); + axesPanel->hide(); // 3b:三维分析栏勾选的已保存切片(dd_slice) id 集合 + 调和函数。 // syncSlices:按"当前活动体 dsId"调和 InteractionManager 上显示的已保存切片—— @@ -713,15 +717,20 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re &geopro::controller::VtkSceneController::zoomOut); QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::fitRequested, sceneCtrl, &geopro::controller::VtkSceneController::fit); + // 设置(⚙)→ 工具条右侧 toggle 抽屉面板(非模态弹窗)。 QObject::connect(viewToolbar, &geopro::app::VtkViewToolbar::axesSettingsRequested, &window, - [&window, sceneCtrl]() { - geopro::app::AxesSettingsDialog dlg({}, {}, {}, &window); - if (dlg.exec() != QDialog::Accepted) return; - const bool anyShow = dlg.x().show || dlg.y().show || dlg.z().show; - sceneCtrl->setAxesMode(anyShow ? geopro::controller::AxesMode::Standard - : geopro::controller::AxesMode::None); - // per-axis min/max 范围待 VtkSceneController 加坐标轴范围 API 后接入。 + [axesPanel, viewToolbar]() { + if (axesPanel->isVisible()) { + axesPanel->hide(); + return; + } + axesPanel->adjustSize(); + axesPanel->move(viewToolbar->x() + viewToolbar->width() + 8, viewToolbar->y()); + axesPanel->raise(); + axesPanel->show(); }); + QObject::connect(axesPanel, &geopro::app::AxesSettingsPanel::closed, &window, + [axesPanel]() { axesPanel->hide(); }); // 三维数据集栏勾选(反演剖面)→ 并入渲染勾选集(剖面走帘面路径)。 QObject::connect(c3, &geopro::app::Column3DDataset::checkedDatasetsChanged, sceneCtrl, [checkedProfiles, pushChecked](const QStringList& ids) { @@ -1071,6 +1080,20 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re // 单一来源:kVerticalExaggeration 一处定义,组合根下发到 控制器(上方259) / 底图 / UI 显示。 basemap->setVerticalExaggeration(kVerticalExaggeration); drawer->col3D()->setVerticalExaggeration(kVerticalExaggeration); + // 坐标轴设置抽屉「应用」:轴显示开关 + 放大系数(=垂直夸张,下发控制器+底图);范围/单位待控制器 API。 + QObject::connect(axesPanel, &geopro::app::AxesSettingsPanel::applied, &window, + [axesPanel, sceneCtrl, basemap](geopro::app::AxisRange x, geopro::app::AxisRange y, + geopro::app::AxisRange z, int /*unitIdx*/, + double scale) { + const bool anyShow = x.show || y.show || z.show; + sceneCtrl->setAxesMode(anyShow ? geopro::controller::AxesMode::Standard + : geopro::controller::AxesMode::None); + if (scale > 0) { + sceneCtrl->setVerticalExaggeration(scale); + basemap->setVerticalExaggeration(scale); + } + axesPanel->hide(); + }); // ── 中央“空状态”引导浮层:未接入真实 sections 时,引导首次使用者从左侧入手。── // 透明背景 + 鼠标穿透(不挡 QVTK 交互);CenterOverlay 随视口尺寸保持居中;