From a7e8b06d58799ac6d40584cce9b90ef0009eec0b Mon Sep 17 00:00:00 2001 From: Dale Eason Date: Mon, 24 Aug 2026 16:43:21 -0500 Subject: [PATCH 1/6] modified how 3D mouse buttons work --- DFTFringe_Dale.pro | 4 ++- custom3dinputhandler.cpp | 73 ++++++++++++++++++++++++++++++++++++++++ custom3dinputhandler.h | 27 +++++++++++++++ surfacegraph.cpp | 12 +++++-- 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 custom3dinputhandler.cpp create mode 100644 custom3dinputhandler.h diff --git a/DFTFringe_Dale.pro b/DFTFringe_Dale.pro index 76fd813f..082bf3b9 100644 --- a/DFTFringe_Dale.pro +++ b/DFTFringe_Dale.pro @@ -33,6 +33,7 @@ SOURCES += main.cpp \ astigpolargraph.cpp \ autoinvertdlg.cpp \ cpoint.cpp \ + custom3dinputhandler.cpp \ defocusdlg.cpp \ edgeplot.cpp \ hotkeysdlg.cpp \ @@ -153,6 +154,7 @@ HEADERS += mainwindow.h \ astigpolargraph.h \ autoinvertdlg.h \ cpoint.h \ + custom3dinputhandler.h \ defocusdlg.h \ edgeplot.h \ IgramArea.h \ @@ -411,7 +413,7 @@ RC_FILE = DFTFringe.rc QMAKE_CXXFLAGS += -std=c++11 # The application version -VERSION = Dale7.3.2 +VERSION = 3Dmouse_08/24/26 # Define the preprocessor macro to get the application version in our application. DEFINES += APP_VERSION=\\\"$$VERSION\\\" diff --git a/custom3dinputhandler.cpp b/custom3dinputhandler.cpp new file mode 100644 index 00000000..999c873a --- /dev/null +++ b/custom3dinputhandler.cpp @@ -0,0 +1,73 @@ +#include "custom3dinputhandler.h" + +Custom3DInputHandler::Custom3DInputHandler(QAbstract3DGraph *graph) + : Q3DInputHandler(graph), m_isRightDragging(false), m_graphRef(graph) { + setZoomAtTargetEnabled(true); +} + +void Custom3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos) { + if (event->button() == Qt::RightButton) { + m_isRightDragging = true; + m_lastMousePos = event->pos(); + event->accept(); + return; // Consume event so base handler doesn't interfere + } + + // Map Left-Click to Right-Click for standard rotation in base handler + Qt::MouseButton mappedButton = (event->button() == Qt::LeftButton) ? Qt::RightButton : event->button(); + Qt::MouseButtons mappedButtons = event->buttons(); + if (mappedButtons & Qt::LeftButton) { + mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; + } + + QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), + mappedButton, mappedButtons, event->modifiers()); + Q3DInputHandler::mousePressEvent(&customEvent, mousePos); +} + +void Custom3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) { + if (event->button() == Qt::RightButton) { + m_isRightDragging = false; + event->accept(); + return; + } + + Qt::MouseButton mappedButton = (event->button() == Qt::LeftButton) ? Qt::RightButton : event->button(); + Qt::MouseButtons mappedButtons = event->buttons(); + if (mappedButtons & Qt::LeftButton) { + mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; + } + + QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), + mappedButton, mappedButtons, event->modifiers()); + Q3DInputHandler::mouseReleaseEvent(&customEvent, mousePos); +} + +void Custom3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) { + if (m_isRightDragging && m_graphRef) { + QPoint delta = event->pos() - m_lastMousePos; + m_lastMousePos = event->pos(); + + // Adjust camera target to pan the view + Q3DCamera *camera = m_graphRef->scene()->activeCamera(); + if (camera) { + QVector3D target = camera->target(); + // Scale panning speed based on zoom distance or fixed factor + float panScale = 0.003f; + target.setX(target.x() - delta.x() * panScale); + target.setZ(target.z() + delta.y() * panScale); // Invert Y delta for natural feel + camera->setTarget(target); + } + event->accept(); + return; + } + + Qt::MouseButtons mappedButtons = event->buttons(); + if (mappedButtons & Qt::LeftButton) { + mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; + } + + QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), + event->button(), mappedButtons, event->modifiers()); + Q3DInputHandler::mouseMoveEvent(&customEvent, mousePos); +} diff --git a/custom3dinputhandler.h b/custom3dinputhandler.h new file mode 100644 index 00000000..e3eccb3e --- /dev/null +++ b/custom3dinputhandler.h @@ -0,0 +1,27 @@ +#ifndef CUSTOM3DINPUTHANDLER_H +#define CUSTOM3DINPUTHANDLER_H + +#include +#include +#include +#include + +using namespace QtDataVisualization; + +class Custom3DInputHandler : public Q3DInputHandler { + Q_OBJECT +public: + Custom3DInputHandler(QAbstract3DGraph *graph = nullptr); + +protected: + void mousePressEvent(QMouseEvent *event, const QPoint &mousePos) override; + void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos) override; + void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) override; + +private: + bool m_isRightDragging; + QPoint m_lastMousePos; + QAbstract3DGraph *m_graphRef; +}; + +#endif // CUSTOM3DINPUTHANDLER_H diff --git a/surfacegraph.cpp b/surfacegraph.cpp index 432e7e41..2bbc5a2b 100644 --- a/surfacegraph.cpp +++ b/surfacegraph.cpp @@ -36,17 +36,26 @@ #include #include #include - +#include "custom3dinputhandler.h" int sampleCountX = 50; int sampleCountZ = 50; const float sampleMin = -8.0f; const float sampleMax = 8.0f; #include + +#include +#include + + + SurfaceGraph::SurfaceGraph(Q3DSurface *surface) : m_graph(surface),m_axisMaxSliderXValue(100),m_axisMinSliderXValue(0), m_wf(0), m_colorRange(.56) { m_xGridMin = 0; + // Replace default input handler with your custom one + Custom3DInputHandler *customInputHandler = new Custom3DInputHandler(m_graph); + m_graph->setActiveInputHandler(customInputHandler); m_graph->setAxisX(new QValue3DAxis); m_graph->setAxisY(new QValue3DAxis); m_graph->setAxisZ(new QValue3DAxis); @@ -478,7 +487,6 @@ QSize SurfaceGraph::Size(){ QImage SurfaceGraph::render(int width, int height){ QSize orgsize = m_graph->size(); if (orgsize.width() < width){ - qDebug() << "m_graph size" << orgsize << width << height; m_graph->resize(width, height); } QImage result = m_graph->renderToImage(0, QSize(width,height)); From 1ac8e11662eaa386430eda52befed901166e34ee Mon Sep 17 00:00:00 2001 From: Julien STAUB Date: Tue, 25 Aug 2026 08:03:56 +0200 Subject: [PATCH 2/6] fixing all .pro files --- DFTFringe.pro | 4 +++- DFTFringe_QT5.pro | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DFTFringe.pro b/DFTFringe.pro index 8b1d528f..07b86821 100644 --- a/DFTFringe.pro +++ b/DFTFringe.pro @@ -151,7 +151,7 @@ SOURCES += SingleApplication/singleapplication.cpp \ astigpolargraph.cpp \ astigscatterplot.cpp \ astigstatsdlg.cpp \ - autoinvertdlg.cpp \ + autoinvertdlg.cpp \ averagewavefrontfilesdlg.cpp \ batchigramwizard.cpp \ bathastigdlg.cpp \ @@ -171,6 +171,7 @@ SOURCES += SingleApplication/singleapplication.cpp \ contourview.cpp \ counterrotationdlg.cpp \ cpoint.cpp \ + custom3dinputhandler.cpp \ defocusdlg.cpp \ dftarea.cpp \ dftcolormap.cpp \ @@ -293,6 +294,7 @@ HEADERS += bezier/bezier.h \ contourview.h \ counterrotationdlg.h \ cpoint.h \ + custom3dinputhandler.h \ defocusdlg.h \ dftarea.h \ dftcolormap.h \ diff --git a/DFTFringe_QT5.pro b/DFTFringe_QT5.pro index 65573323..f14f748c 100644 --- a/DFTFringe_QT5.pro +++ b/DFTFringe_QT5.pro @@ -175,6 +175,7 @@ SOURCES += SingleApplication/singleapplication.cpp \ contourview.cpp \ counterrotationdlg.cpp \ cpoint.cpp \ + custom3dinputhandler.cpp \ defocusdlg.cpp \ dftarea.cpp \ dftcolormap.cpp \ @@ -297,6 +298,7 @@ HEADERS += bezier/bezier.h \ contourview.h \ counterrotationdlg.h \ cpoint.h \ + custom3dinputhandler.h \ defocusdlg.h \ dftarea.h \ dftcolormap.h \ From f1375c4d317aa827062c461311e6964fe2478838 Mon Sep 17 00:00:00 2001 From: Julien Staub Date: Tue, 25 Aug 2026 08:11:45 +0200 Subject: [PATCH 3/6] QT5/QT6 compatibility issue --- custom3dinputhandler.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/custom3dinputhandler.h b/custom3dinputhandler.h index e3eccb3e..41014383 100644 --- a/custom3dinputhandler.h +++ b/custom3dinputhandler.h @@ -6,7 +6,10 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +//keep compatiblity with Qt5 using namespace QtDataVisualization; +#endif class Custom3DInputHandler : public Q3DInputHandler { Q_OBJECT From a530b82eb5c2379cd95374cd06df817ad484d50a Mon Sep 17 00:00:00 2001 From: Dale Eason Date: Tue, 25 Aug 2026 03:32:13 -0500 Subject: [PATCH 4/6] fixed pan when scene is rotated. More or less --- custom3dinputhandler.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/custom3dinputhandler.cpp b/custom3dinputhandler.cpp index 999c873a..39433fa3 100644 --- a/custom3dinputhandler.cpp +++ b/custom3dinputhandler.cpp @@ -1,5 +1,5 @@ #include "custom3dinputhandler.h" - +#include Custom3DInputHandler::Custom3DInputHandler(QAbstract3DGraph *graph) : Q3DInputHandler(graph), m_isRightDragging(false), m_graphRef(graph) { setZoomAtTargetEnabled(true); @@ -43,6 +43,8 @@ void Custom3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &m Q3DInputHandler::mouseReleaseEvent(&customEvent, mousePos); } + + void Custom3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos) { if (m_isRightDragging && m_graphRef) { QPoint delta = event->pos() - m_lastMousePos; @@ -52,10 +54,28 @@ void Custom3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mous Q3DCamera *camera = m_graphRef->scene()->activeCamera(); if (camera) { QVector3D target = camera->target(); - // Scale panning speed based on zoom distance or fixed factor float panScale = 0.003f; - target.setX(target.x() - delta.x() * panScale); - target.setZ(target.z() + delta.y() * panScale); // Invert Y delta for natural feel + + // Extract both rotations in radians + float xRotRad = qDegreesToRadians(camera->xRotation()); // Yaw (horizontal orbit) + float yRotRad = qDegreesToRadians(camera->yRotation()); // Pitch (vertical tilt) + + float cosX = qCos(xRotRad); + float sinX = qSin(xRotRad); + float cosY = qCos(yRotRad); + float sinY = qSin(yRotRad); + + // Invert Y delta (flipped back so dragging down moves the scene down) + float invertedDeltaY = -delta.y(); + + float dx = (-delta.x() * cosX - invertedDeltaY * sinX * cosY) * panScale; + float dy = (invertedDeltaY * sinY) * panScale; + float dz = (delta.x() * sinX - invertedDeltaY * cosX * cosY) * panScale; + + target.setX(target.x() + dx); + target.setY(target.y() + dy); + target.setZ(target.z() + dz); + camera->setTarget(target); } event->accept(); From bd9360c9d2251fbd01f1bc449cd654e1e171a94f Mon Sep 17 00:00:00 2001 From: Dale Eason Date: Tue, 25 Aug 2026 12:44:19 -0500 Subject: [PATCH 5/6] added QT5 and Qt 6 flags for event types --- custom3dinputhandler.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/custom3dinputhandler.cpp b/custom3dinputhandler.cpp index 39433fa3..04e5a269 100644 --- a/custom3dinputhandler.cpp +++ b/custom3dinputhandler.cpp @@ -20,8 +20,14 @@ void Custom3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mou mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QMouseEvent customEvent(event->type(), event->position(), event->globalPosition(), + mappedButton, mappedButtons, event->modifiers()); +#else QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), mappedButton, mappedButtons, event->modifiers()); +#endif + Q3DInputHandler::mousePressEvent(&customEvent, mousePos); Q3DInputHandler::mousePressEvent(&customEvent, mousePos); } @@ -38,8 +44,14 @@ void Custom3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &m mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QMouseEvent customEvent(event->type(), event->position(), event->globalPosition(), + mappedButton, mappedButtons, event->modifiers()); +#else QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), mappedButton, mappedButtons, event->modifiers()); +#endif + Q3DInputHandler::mousePressEvent(&customEvent, mousePos); Q3DInputHandler::mouseReleaseEvent(&customEvent, mousePos); } @@ -87,7 +99,12 @@ void Custom3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mous mappedButtons = (mappedButtons & ~Qt::LeftButton) | Qt::RightButton; } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QMouseEvent customEvent(event->type(), event->position(), event->globalPosition(), + event->button(), mappedButtons, event->modifiers()); +#else QMouseEvent customEvent(event->type(), event->localPos(), event->globalPos(), event->button(), mappedButtons, event->modifiers()); +#endif Q3DInputHandler::mouseMoveEvent(&customEvent, mousePos); } From e4e44be6cd6d858e283a01e4584ab6916fe1ac4c Mon Sep 17 00:00:00 2001 From: gr5 Date: Tue, 25 Aug 2026 14:18:26 -0400 Subject: [PATCH 6/6] Apply suggestion from @atsju these 2 lines of code not needed. Co-authored-by: Julien Staub --- surfacegraph.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/surfacegraph.cpp b/surfacegraph.cpp index 2bbc5a2b..076e4819 100644 --- a/surfacegraph.cpp +++ b/surfacegraph.cpp @@ -44,8 +44,6 @@ const float sampleMin = -8.0f; const float sampleMax = 8.0f; #include -#include -#include