diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 0438f61..350ab65 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -8,6 +8,9 @@ #include "HPPA.h" #include "RasterLayer.h" #include "LayerTreeLayerNode.h" +#include "MapTool.h" +#include "MapToolPan.h" +#include "MapToolSpectral.h" HPPA* HPPA::s_instance = nullptr; @@ -89,9 +92,7 @@ HPPA::HPPA(QWidget* parent) initMenubarToolbar(); - - - + initMapTools(); //光谱仪操作 m_Imager = nullptr; m_RecordState = 0; @@ -122,6 +123,7 @@ HPPA::HPPA(QWidget* parent) //connect(ui.graphicsView->imager, SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onimagerSimulatorMove(int, int))); initPanelToolbar(); + initMapTools(); setDockNestingEnabled(true); connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout())); connect(this->ui.mActionOneMotorScenario, SIGNAL(triggered()), this, SLOT(createOneMotorScenario())); @@ -142,7 +144,6 @@ HPPA::HPPA(QWidget* parent) border-bottom-right-radius: 10px; )"; - //TOC CustomDockWidgetBase* dock_layers = new CustomDockWidgetBase(QString::fromLocal8Bit("layers"), this); dock_layers->setObjectName("mDockLayers"); @@ -819,7 +820,7 @@ void HPPA::createActionGroups() } else if (lastSelectedAction == "mActionCorning_410") { - ui.mActionCorning_410->setChecked(true); + ui.mActionCorning_410->setChecked(true); } } @@ -1006,6 +1007,73 @@ void HPPA::initPanelToolbar() mToolbarMenu->addAction(ui.mainToolBar->toggleViewAction()); } +void HPPA::initMapTools() +{ + // Make the actions checkable + ui.mActionPan->setCheckable(true); + ui.mActionSpectral->setCheckable(true); + + // Create tools (canvas will be set per-tab, tools are re-applied on tab switch) + // We don't create per-canvas tools here; instead we create shared tool instances + // and re-apply them when the tab changes. + m_mapToolPan = nullptr; + m_mapToolSpectral = nullptr; + + connect(ui.mActionPan, SIGNAL(triggered()), this, SLOT(onMapToolPanTriggered())); + connect(ui.mActionSpectral, SIGNAL(triggered()), this, SLOT(onMapToolSpectralTriggered())); + + // Default tool: pan + ui.mActionPan->trigger(); +} + +void HPPA::onMapToolPanTriggered() +{ + // Find the current Mapcavas + QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); + if (!currentWidget) return; + + QList canvases = currentWidget->findChildren(); + if (canvases.isEmpty()) return; + + Mapcavas* canvas = canvases[0]; + + // Clean up old tool + delete m_mapToolPan; + m_mapToolPan = new MapToolPan(canvas, this); + m_mapToolPan->setAction(ui.mActionPan); + + // Uncheck the other action + ui.mActionSpectral->setChecked(false); + + canvas->setMapTool(m_mapToolPan); +} + +void HPPA::onMapToolSpectralTriggered() +{ + // Find the current Mapcavas + QWidget* currentWidget = m_imageViewerTabWidget->currentWidget(); + if (!currentWidget) return; + + QList canvases = currentWidget->findChildren(); + if (canvases.isEmpty()) return; + + Mapcavas* canvas = canvases[0]; + + // Clean up old tool + delete m_mapToolSpectral; + m_mapToolSpectral = new MapToolSpectral(canvas, this); + m_mapToolSpectral->setAction(ui.mActionSpectral); + + // Uncheck the other action + ui.mActionPan->setChecked(false); + + // Connect spectral signal to existing slot + connect(m_mapToolSpectral, SIGNAL(spectralClicked(int,int,QVector,QVector)), + this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); + + canvas->setMapTool(m_mapToolSpectral); +} + //---------------------------------------------------- void HPPA::createScenarioActionGroup() { @@ -1282,6 +1350,25 @@ void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab,会调 //先disconnect然后再connect,否则每次切换一次都会connect一次,会累积connect很多次! disconnect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector,QVector)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); connect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int,int,QVector,QVector)), this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); + + // Re-apply the current map tool to the new canvas + Mapcavas* canvas = currentImageViewer[0]; + if (ui.mActionPan->isChecked()) + { + delete m_mapToolPan; + m_mapToolPan = new MapToolPan(canvas, this); + m_mapToolPan->setAction(ui.mActionPan); + canvas->setMapTool(m_mapToolPan); + } + else if (ui.mActionSpectral->isChecked()) + { + delete m_mapToolSpectral; + m_mapToolSpectral = new MapToolSpectral(canvas, this); + m_mapToolSpectral->setAction(ui.mActionSpectral); + connect(m_mapToolSpectral, SIGNAL(spectralClicked(int,int,QVector,QVector)), + this, SLOT(onLeftMouseButtonPressed(int,int,QVector,QVector))); + canvas->setMapTool(m_mapToolSpectral); + } } void HPPA::onActionOpenDirectory() @@ -1564,10 +1651,10 @@ void HPPA::onconnect() else { QMessageBox msgBox; - msgBox.setText(QString::fromLocal8Bit("请选择相机!")); - msgBox.exec(); + msgBox.setText(QString::fromLocal8Bit("请选择相机!")); + msgBox.exec(); - return; + return; } m_Imager->moveToThread(m_RecordThread); @@ -1758,7 +1845,7 @@ void HPPA::onDark() QString checkedName = checked->objectName(); if (checkedName == "mAction_is_no_motor" || checkedName == "mAction_RobotArm") { - emit RecordDarlSignal(); + emit RecordDarlSignal(); } else if (checkedName == "mAction_1AxisMotor") { diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h index 03f983f..434206f 100644 --- a/HPPA/HPPA.h +++ b/HPPA/HPPA.h @@ -62,6 +62,10 @@ #include "LayerTreeView.h" #include "LayerTreeViewMenuProvider.h" +#include "MapTool.h" +#include "MapToolPan.h" +#include "MapToolSpectral.h" + #define PI 3.1415926 QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用 @@ -274,6 +278,11 @@ private: MapLayerStore* m_MapLayerStore = nullptr; + // Map tools + MapToolPan* m_mapToolPan = nullptr; + MapToolSpectral* m_mapToolSpectral = nullptr; + void initMapTools(); + public Q_SLOTS: void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath); void PlotSpectral(int state); @@ -338,6 +347,9 @@ public Q_SLOTS: void onLayerTreeSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); void onBandSelectionChanged(double rWave, double gWave, double bWave); + + void onMapToolPanTriggered(); + void onMapToolSpectralTriggered(); signals: void StartFocusSignal(); void StartRecordSignal(); diff --git a/HPPA/HPPA.vcxproj b/HPPA/HPPA.vcxproj index 81fa7c0..572a9cd 100644 --- a/HPPA/HPPA.vcxproj +++ b/HPPA/HPPA.vcxproj @@ -124,6 +124,9 @@ + + + @@ -205,6 +208,9 @@ + + + diff --git a/HPPA/HPPA.vcxproj.filters b/HPPA/HPPA.vcxproj.filters index 8450c33..864f33a 100644 --- a/HPPA/HPPA.vcxproj.filters +++ b/HPPA/HPPA.vcxproj.filters @@ -178,6 +178,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -323,6 +332,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + diff --git a/HPPA/ImageViewer.cpp b/HPPA/ImageViewer.cpp index 794f221..2c8a27d 100644 --- a/HPPA/ImageViewer.cpp +++ b/HPPA/ImageViewer.cpp @@ -7,6 +7,7 @@ #include "ImageViewer.h" #include "RasterLayer.h" +#include "MapTool.h" #define VIEW_CENTER viewport()->rect().center() @@ -105,6 +106,12 @@ bool Mapcavas::HasImage() void Mapcavas::wheelEvent(QWheelEvent *event) { + // Always let the tool have a chance first + if (m_mapTool) + { + m_mapTool->canvasWheelEvent(event); + } + if (HasImage()) { QPointF oldPos = mapToScene(event->pos()); @@ -126,6 +133,13 @@ void Mapcavas::scaling(qreal scaleFactor) void Mapcavas::mousePressEvent(QMouseEvent *event) { + if (m_mapTool) + { + m_mapTool->canvasMousePressEvent(event); + return; + } + + // Legacy fallback when no tool is set if (event->button()==Qt::LeftButton) { m_bMouseTranslate = true; @@ -150,6 +164,13 @@ void Mapcavas::mousePressEvent(QMouseEvent *event) void Mapcavas::mouseMoveEvent(QMouseEvent *event) { + if (m_mapTool) + { + m_mapTool->canvasMouseMoveEvent(event); + return; + } + + // Legacy fallback if (m_bMouseTranslate){ QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(m_lastMousePos); translate(mouseDelta.x(),mouseDelta.y()); @@ -161,12 +182,25 @@ void Mapcavas::mouseMoveEvent(QMouseEvent *event) void Mapcavas::mouseReleaseEvent(QMouseEvent *event) { + if (m_mapTool) + { + m_mapTool->canvasMouseReleaseEvent(event); + return; + } + + // Legacy fallback m_bMouseTranslate = false; QGraphicsView::mouseReleaseEvent(event); } void Mapcavas::mouseDoubleClickEvent(QMouseEvent *event) { + if (m_mapTool) + { + m_mapTool->canvasMouseDoubleClickEvent(event); + return; + } + QGraphicsView::mouseDoubleClickEvent(event); } @@ -248,3 +282,41 @@ void Mapcavas::freshmap(const RasterLayer::RenderParams& params) QPixmap pm = QPixmap::fromImage(img); SetImage(&pm); } + +// MapTool management +void Mapcavas::setMapTool(MapTool* tool) +{ + if (m_mapTool) + { + m_mapTool->deactivate(); + } + + m_mapTool = tool; + + if (m_mapTool) + { + // Disable built-in drag mode so the tool controls everything + setDragMode(QGraphicsView::NoDrag); + m_mapTool->activate(); + } + else + { + // Restore legacy drag mode when no tool + setDragMode(QGraphicsView::ScrollHandDrag); + } +} + +void Mapcavas::unsetMapTool(MapTool* tool) +{ + if (m_mapTool && m_mapTool == tool) + { + m_mapTool->deactivate(); + m_mapTool = nullptr; + setDragMode(QGraphicsView::ScrollHandDrag); + } +} + +MapTool* Mapcavas::mapTool() const +{ + return m_mapTool; +} diff --git a/HPPA/ImageViewer.h b/HPPA/ImageViewer.h index bc1df68..d312951 100644 --- a/HPPA/ImageViewer.h +++ b/HPPA/ImageViewer.h @@ -6,6 +6,8 @@ #include #include "RasterLayer.h" +class MapTool; + class Mapcavas : public QGraphicsView { Q_OBJECT @@ -49,6 +51,11 @@ public: RasterLayer* rasterLayer() const; + // MapTool management + void setMapTool(MapTool* tool); + void unsetMapTool(MapTool* tool); + MapTool* mapTool() const; + protected: QGraphicsScene *m_qtGraphicsScene; private: @@ -56,6 +63,7 @@ private: QLabel *m_framNumberLabel;//ʾʵʱɼ֡ RasterLayer* m_rasterLayer = nullptr; // associated raster layer + MapTool* m_mapTool = nullptr; // current active map tool qreal m_translateSpeed; // ƽٶ qreal m_zoomDelta; // ŵ diff --git a/HPPA/MapTool.cpp b/HPPA/MapTool.cpp new file mode 100644 index 0000000..5fc618f --- /dev/null +++ b/HPPA/MapTool.cpp @@ -0,0 +1,98 @@ +#include "stdafx.h" +#include "MapTool.h" +#include "ImageViewer.h" +#include + +MapTool::MapTool(Mapcavas* canvas, QObject* parent) + : QObject(parent) + , m_canvas(canvas) + , m_cursor(Qt::ArrowCursor) +{ +} + +MapTool::~MapTool() +{ + if (m_canvas && m_canvas->mapTool() == this) + { + m_canvas->unsetMapTool(this); + } +} + +QAction* MapTool::action() const +{ + return m_action; +} + +void MapTool::setAction(QAction* action) +{ + m_action = action; +} + +Mapcavas* MapTool::canvas() const +{ + return m_canvas; +} + +void MapTool::setCursor(const QCursor& cursor) +{ + m_cursor = cursor; +} + +QCursor MapTool::cursor() const +{ + return m_cursor; +} + +void MapTool::activate() +{ + if (m_canvas) + { + m_canvas->viewport()->setCursor(m_cursor); + } + if (m_action) + { + m_action->setChecked(true); + } + m_isActive = true; + emit activated(); +} + +void MapTool::deactivate() +{ + if (m_action) + { + m_action->setChecked(false); + } + m_isActive = false; + emit deactivated(); +} + +bool MapTool::isActive() const +{ + return m_isActive; +} + +void MapTool::canvasMousePressEvent(QMouseEvent* e) +{ + Q_UNUSED(e); +} + +void MapTool::canvasMouseReleaseEvent(QMouseEvent* e) +{ + Q_UNUSED(e); +} + +void MapTool::canvasMouseMoveEvent(QMouseEvent* e) +{ + Q_UNUSED(e); +} + +void MapTool::canvasMouseDoubleClickEvent(QMouseEvent* e) +{ + Q_UNUSED(e); +} + +void MapTool::canvasWheelEvent(QWheelEvent* e) +{ + Q_UNUSED(e); +} diff --git a/HPPA/MapTool.h b/HPPA/MapTool.h new file mode 100644 index 0000000..5a28402 --- /dev/null +++ b/HPPA/MapTool.h @@ -0,0 +1,64 @@ +#ifndef MAPTOOL_H +#define MAPTOOL_H + +#include +#include +#include + +class Mapcavas; +class QAction; + +class MapTool : public QObject +{ + Q_OBJECT + +public: + enum Flag + { + NoFlags = 0, + Transient = 1 << 1, + }; + Q_DECLARE_FLAGS(Flags, Flag) + + MapTool(Mapcavas* canvas, QObject* parent = nullptr); + virtual ~MapTool(); + + virtual Flags flags() const { return NoFlags; } + + // Associated action C used to auto-check / uncheck when tool is activated / deactivated + QAction* action() const; + void setAction(QAction* action); + + // Canvas this tool operates on + Mapcavas* canvas() const; + + // Cursor shown when tool is active + virtual void setCursor(const QCursor& cursor); + QCursor cursor() const; + + // Lifecycle + virtual void activate(); + virtual void deactivate(); + bool isActive() const; + + // Mouse event handlers C return true if event was handled + virtual void canvasMousePressEvent(QMouseEvent* e); + virtual void canvasMouseReleaseEvent(QMouseEvent* e); + virtual void canvasMouseMoveEvent(QMouseEvent* e); + virtual void canvasMouseDoubleClickEvent(QMouseEvent* e); + virtual void canvasWheelEvent(QWheelEvent* e); + +signals: + void activated(); + void deactivated(); + +private: + Mapcavas* m_canvas = nullptr; + QAction* m_action = nullptr; + QCursor m_cursor; + bool m_isActive = false; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(MapTool::Flags) + +#endif // MAPTOOL_H diff --git a/HPPA/MapToolPan.cpp b/HPPA/MapToolPan.cpp new file mode 100644 index 0000000..8ab0aab --- /dev/null +++ b/HPPA/MapToolPan.cpp @@ -0,0 +1,61 @@ +#include "stdafx.h" +#include "MapToolPan.h" +#include "ImageViewer.h" +#include +#include + +MapToolPan::MapToolPan(Mapcavas* canvas, QObject* parent) + : MapTool(canvas, parent) +{ + setCursor(Qt::OpenHandCursor); +} + +void MapToolPan::activate() +{ + MapTool::activate(); + if (canvas()) + { + canvas()->setDragMode(QGraphicsView::NoDrag); + } +} + +void MapToolPan::deactivate() +{ + m_dragging = false; + MapTool::deactivate(); +} + +void MapToolPan::canvasMousePressEvent(QMouseEvent* e) +{ + if (e->button() == Qt::LeftButton) + { + m_dragging = true; + m_lastPos = e->pos(); + if (canvas()) + { + canvas()->viewport()->setCursor(Qt::ClosedHandCursor); + } + } +} + +void MapToolPan::canvasMouseMoveEvent(QMouseEvent* e) +{ + if (m_dragging && canvas()) + { + QPointF delta = canvas()->mapToScene(e->pos()) - canvas()->mapToScene(m_lastPos); + canvas()->translate(delta.x(), delta.y()); + m_lastPos = e->pos(); + } +} + +void MapToolPan::canvasMouseReleaseEvent(QMouseEvent* e) +{ + if (e->button() == Qt::LeftButton) + { + m_dragging = false; + if (canvas()) + { + canvas()->viewport()->setCursor(Qt::OpenHandCursor); + } + } +} diff --git a/HPPA/MapToolPan.h b/HPPA/MapToolPan.h new file mode 100644 index 0000000..a777083 --- /dev/null +++ b/HPPA/MapToolPan.h @@ -0,0 +1,26 @@ +#ifndef MAPTOOLPAN_H +#define MAPTOOLPAN_H + +#include "MapTool.h" +#include + +class MapToolPan : public MapTool +{ + Q_OBJECT + +public: + MapToolPan(Mapcavas* canvas, QObject* parent = nullptr); + + void activate() override; + void deactivate() override; + + void canvasMousePressEvent(QMouseEvent* e) override; + void canvasMouseMoveEvent(QMouseEvent* e) override; + void canvasMouseReleaseEvent(QMouseEvent* e) override; + +private: + bool m_dragging = false; + QPoint m_lastPos; +}; + +#endif // MAPTOOLPAN_H diff --git a/HPPA/MapToolSpectral.cpp b/HPPA/MapToolSpectral.cpp new file mode 100644 index 0000000..42b716b --- /dev/null +++ b/HPPA/MapToolSpectral.cpp @@ -0,0 +1,36 @@ +#include "stdafx.h" +#include "MapToolSpectral.h" +#include "ImageViewer.h" +#include "RasterLayer.h" +#include +#include + +MapToolSpectral::MapToolSpectral(Mapcavas* canvas, QObject* parent) + : MapTool(canvas, parent) +{ + setCursor(Qt::CrossCursor); +} + +void MapToolSpectral::canvasMousePressEvent(QMouseEvent* e) +{ + if (e->button() != Qt::LeftButton) + return; + + if (!canvas()) + return; + + const QPointF scenePt = canvas()->mapToScene(e->pos()); + const int x = static_cast(std::floor(scenePt.x())); + const int y = static_cast(std::floor(scenePt.y())); + + RasterLayer* rl = canvas()->rasterLayer(); + if (rl && rl->isValidPixel(x, y)) + { + QVector wavelengths; + QVector spectrum; + if (rl->readPixelSpectrum(x, y, wavelengths, spectrum)) + { + emit spectralClicked(x, y, wavelengths, spectrum); + } + } +} diff --git a/HPPA/MapToolSpectral.h b/HPPA/MapToolSpectral.h new file mode 100644 index 0000000..60a70bc --- /dev/null +++ b/HPPA/MapToolSpectral.h @@ -0,0 +1,20 @@ +#ifndef MAPTOOLSPECTRAL_H +#define MAPTOOLSPECTRAL_H + +#include "MapTool.h" +#include + +class MapToolSpectral : public MapTool +{ + Q_OBJECT + +public: + MapToolSpectral(Mapcavas* canvas, QObject* parent = nullptr); + + void canvasMousePressEvent(QMouseEvent* e) override; + +signals: + void spectralClicked(int x, int y, QVector wavelengths, QVector spectrum); +}; + +#endif // MAPTOOLSPECTRAL_H