diff --git a/src/app/AxesSettingsDialog.cpp b/src/app/AxesSettingsDialog.cpp new file mode 100644 index 0000000..74001bb --- /dev/null +++ b/src/app/AxesSettingsDialog.cpp @@ -0,0 +1,59 @@ +#include "AxesSettingsDialog.hpp" + +#include +#include +#include +#include +#include +#include + +namespace geopro::app { + +namespace { +constexpr double kSpinAbsLimit = 1e6; +} + +AxesSettingsDialog::AxesSettingsDialog(AxisRange x, AxisRange y, AxisRange z, QWidget* parent) + : QDialog(parent) { + setWindowTitle(QStringLiteral("坐标轴设置")); + auto* grid = new QGridLayout(this); + grid->addWidget(new QLabel(QStringLiteral("轴")), 0, 0); + grid->addWidget(new QLabel(QStringLiteral("显示")), 0, 1); + grid->addWidget(new QLabel(QStringLiteral("最小")), 0, 2); + grid->addWidget(new QLabel(QStringLiteral("最大")), 0, 3); + + auto build = [&](int gridRow, const QString& label, const AxisRange& r, Row& out) { + grid->addWidget(new QLabel(label), gridRow, 0); + out.show = new QCheckBox(this); + out.show->setChecked(r.show); + grid->addWidget(out.show, gridRow, 1); + out.lo = new QDoubleSpinBox(this); + out.lo->setRange(-kSpinAbsLimit, kSpinAbsLimit); + out.lo->setValue(r.min); + grid->addWidget(out.lo, gridRow, 2); + out.hi = new QDoubleSpinBox(this); + out.hi->setRange(-kSpinAbsLimit, kSpinAbsLimit); + out.hi->setValue(r.max); + grid->addWidget(out.hi, gridRow, 3); + }; + build(1, QStringLiteral("X"), x, x_); + build(2, QStringLiteral("Y"), y, y_); + build(3, QStringLiteral("深度"), z, z_); + + auto* btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + btns->button(QDialogButtonBox::Ok)->setText(QStringLiteral("应用")); + btns->button(QDialogButtonBox::Cancel)->setText(QStringLiteral("取消")); + connect(btns, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(btns, &QDialogButtonBox::rejected, this, &QDialog::reject); + grid->addWidget(btns, 4, 0, 1, 4); +} + +static AxisRange readRow(QCheckBox* show, QDoubleSpinBox* lo, QDoubleSpinBox* hi) { + return {show->isChecked(), lo->value(), hi->value()}; +} + +AxisRange AxesSettingsDialog::x() const { return readRow(x_.show, x_.lo, x_.hi); } +AxisRange AxesSettingsDialog::y() const { return readRow(y_.show, y_.lo, y_.hi); } +AxisRange AxesSettingsDialog::z() const { return readRow(z_.show, z_.lo, z_.hi); } + +} // namespace geopro::app diff --git a/src/app/AxesSettingsDialog.hpp b/src/app/AxesSettingsDialog.hpp new file mode 100644 index 0000000..aa1ea36 --- /dev/null +++ b/src/app/AxesSettingsDialog.hpp @@ -0,0 +1,34 @@ +#pragma once +#include + +class QCheckBox; +class QDoubleSpinBox; + +namespace geopro::app { + +// 单轴显示设置:是否显示 + 取值范围(spec §9)。 +struct AxisRange { + bool show = true; + double min = -500; + double max = 500; +}; + +// 坐标轴设置对话框(spec §9):X / Y / 深度 三轴各「显示 + min/max」,应用后读取。 +class AxesSettingsDialog : public QDialog { + Q_OBJECT +public: + AxesSettingsDialog(AxisRange x, AxisRange y, AxisRange z, QWidget* parent = nullptr); + AxisRange x() const; + AxisRange y() const; + AxisRange z() const; + +private: + struct Row { + QCheckBox* show = nullptr; + QDoubleSpinBox* lo = nullptr; + QDoubleSpinBox* hi = nullptr; + }; + Row x_, y_, z_; +}; + +} // namespace geopro::app diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index bbe0e46..d56b9d5 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -110,6 +110,8 @@ add_executable(geopro_desktop WIN32 Logging.cpp DatasetDimension.cpp DatasetCategory.cpp + VtkViewToolbar.cpp + AxesSettingsDialog.cpp TileBasemap.cpp) target_include_directories(geopro_desktop PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/app/VtkViewToolbar.cpp b/src/app/VtkViewToolbar.cpp new file mode 100644 index 0000000..5715f5c --- /dev/null +++ b/src/app/VtkViewToolbar.cpp @@ -0,0 +1,45 @@ +#include "VtkViewToolbar.hpp" + +#include +#include + +using geopro::controller::ViewDir; + +namespace geopro::app { + +VtkViewToolbar::VtkViewToolbar(QWidget* parent) : QWidget(parent) { + auto* col = new QVBoxLayout(this); + col->setContentsMargins(2, 2, 2, 2); + col->setSpacing(2); + + auto addBtn = [&](const QString& text) { + auto* b = new QToolButton(this); + b->setText(text); + b->setAutoRaise(true); + b->setFixedWidth(34); + col->addWidget(b); + return b; + }; + + connect(addBtn(QStringLiteral("设置")), &QToolButton::clicked, this, + &VtkViewToolbar::axesSettingsRequested); + + struct V { + const char* t; + ViewDir d; + }; + const V views[] = {{"前", ViewDir::Front}, {"后", ViewDir::Back}, {"上", ViewDir::Top}, + {"下", ViewDir::Bottom}, {"左", ViewDir::Left}, {"右", ViewDir::Right}}; + for (const V& v : views) { + const ViewDir d = v.d; + connect(addBtn(QString::fromUtf8(v.t)), &QToolButton::clicked, this, + [this, d] { emit viewRequested(d); }); + } + + connect(addBtn(QStringLiteral("放大")), &QToolButton::clicked, this, &VtkViewToolbar::zoomInRequested); + connect(addBtn(QStringLiteral("缩小")), &QToolButton::clicked, this, &VtkViewToolbar::zoomOutRequested); + connect(addBtn(QStringLiteral("复位")), &QToolButton::clicked, this, &VtkViewToolbar::fitRequested); + col->addStretch(1); +} + +} // namespace geopro::app diff --git a/src/app/VtkViewToolbar.hpp b/src/app/VtkViewToolbar.hpp new file mode 100644 index 0000000..271c000 --- /dev/null +++ b/src/app/VtkViewToolbar.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "I3dSceneView.hpp" // geopro::controller::ViewDir + +namespace geopro::app { + +// VTK 画布竖排工具条(spec §9):全局视图控制——设置(坐标轴)/前后上下左右/放大缩小复位。 +// 仅发信号,不认 VTK;由 main 接到场景控制器。 +class VtkViewToolbar : public QWidget { + Q_OBJECT +public: + explicit VtkViewToolbar(QWidget* parent = nullptr); + +signals: + void axesSettingsRequested(); // 设置 → 弹 AxesSettingsDialog + void viewRequested(geopro::controller::ViewDir dir); // 前/后/上/下/左/右 + void zoomInRequested(); + void zoomOutRequested(); + void fitRequested(); // 复位=适配 +}; + +} // namespace geopro::app