From 99ff39a3d62d778117c161ce50e36a61460973af Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Thu, 21 Dec 2023 15:10:20 +0100 Subject: [PATCH] FIXED issue mentioned in https://github.com/jkriege2/JKQtPlotter/pull/110: Lock the panning action to certain values: View zooms in, when panning close to AbosluteXY (thanks to https://github.com/sim186 for reporting) --- doc/dox/whatsnew.dox | 1 + lib/jkqtplotter/jkqtplotter.cpp | 33 ++++++++++++++++++++++++++++++++- lib/jkqtplotter/jkqtplotter.h | 3 +++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 91f4b2b5a9..9ced50c674 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -45,6 +45,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
  • FIXED: fixed impleentations of JKQTPlotter::beginGraphs(), which actually returned the end-iterator (COPY-PASTE-ERROR!!!)
  • FIXED issue #99: Clipping of Tick Labels: for horizontal axes, additional space at the left and/or right of the plot is allowed so labels are no longer clipped (thanks to user:allenbarnett5/a> for reporting)
  • FIXED issue #99: Height of one-column key/legend was too large (thanks to user:allenbarnett5/a> for reporting)
  • +
  • FIXED issue mentioned in #110: Lock the panning action to certain values: View zooms in, when panning close to AbosluteXY (thanks to user:sim186 for reporting)
  • FIXED/IMPROVED issue #100: Add option to disable resize delay feature by setting the delay to zero (thanks to user:fpalazzolo for reporting)
  • FIXED/NEW: placement of plot-title (was not centerd in its box, but glued to the bottom) by adding a plotstyle parameter JKQTBasePlotterStyle::plotLabelOffset
  • FIXED/REWORKED issue #111: Can't write to PDF files with JKQTPlotter::saveImage() when passing a filename ending in ".pdf" (thanks to user:fpalazzolo/a> for reporting):
    While fixing this issue, the functions JKQTBasePlotter::saveImage() etc. gained a bool return value to indicate whether sacing was successful.
  • diff --git a/lib/jkqtplotter/jkqtplotter.cpp b/lib/jkqtplotter/jkqtplotter.cpp index a363dfbcac..4e3cb11353 100644 --- a/lib/jkqtplotter/jkqtplotter.cpp +++ b/lib/jkqtplotter/jkqtplotter.cpp @@ -747,6 +747,33 @@ void JKQTPlotter::paintUserAction() { } } +void JKQTPlotter::correctZoomRectForPanning(QRectF &zoomRect) const +{ + zoomRect=zoomRect.normalized(); + + // this code corrects for cases, where you pan over getAbsoluteXY(). + // without this correction, the zoom rectangle size will be changed, instead of jus stopping at the absolute size + auto correctForAbsoluteLeft=[](double pos, double absPos) { + if (!JKQTPIsOKFloat(absPos)) return pos; + if (posabsPos) return absPos; + return pos; + }; + const double absXMin=plotter->x2p(plotter->getAbsoluteXMin()); + const double absYMin=plotter->y2p(plotter->getAbsoluteYMin()); + const double absXMax=plotter->x2p(plotter->getAbsoluteXMax()); + const double absYMax=plotter->y2p(plotter->getAbsoluteYMax()); + if (JKQTPIsOKFloat(absXMin)&&JKQTPIsOKFloat(absXMax)) zoomRect.moveLeft(correctForAbsoluteLeft(zoomRect.left(), std::min(absXMin, absXMax))); + if (JKQTPIsOKFloat(absYMin)&&JKQTPIsOKFloat(absYMax)) zoomRect.moveTop(correctForAbsoluteLeft(zoomRect.top(), std::min(absYMin, absYMax))); + if (JKQTPIsOKFloat(absXMin)&&JKQTPIsOKFloat(absXMax)) zoomRect.moveRight(correctForAbsoluteRight(zoomRect.right(), std::max(absXMin, absXMax))); + if (JKQTPIsOKFloat(absYMin)&&JKQTPIsOKFloat(absYMax)) zoomRect.moveBottom(correctForAbsoluteRight(zoomRect.bottom(), std::max(absYMin, absYMax))); + +} + void JKQTPlotter::mouseMoveEvent ( QMouseEvent * event ) { if (plotterStyle.displayMousePosition) { @@ -825,6 +852,7 @@ void JKQTPlotter::mouseMoveEvent ( QMouseEvent * event ) { } else { zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel); } + correctZoomRectForPanning(zoomRect); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true); } @@ -939,6 +967,7 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){ } else { zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel); } + correctZoomRectForPanning(zoomRect); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true); } else if (currentMouseDragAction.mode==jkqtpmdaDrawRectangleForEvent) { emit userRectangleFinished(x1, y1, x2-x1, y2-y1, event->modifiers()); @@ -1094,7 +1123,7 @@ void JKQTPlotter::wheelEvent ( QWheelEvent * event ) { acTodo=WheelActionType::Pan; d=QPointF(angleDelta.x()/120.0*zoomRect.width()/10.0, angleDelta.y()/120.0*zoomRect.height()/10.0); - // maximum shoft is 100 Pixels in either direction + // maximum shift is 100 Pixels in either direction d.setX(jkqtp_bounded(-100, d.x(), 100)); d.setY(jkqtp_bounded(-100, d.y(), 100)); // minimmum shift is 10 pixels, unles |shift|<1 @@ -1130,6 +1159,8 @@ void JKQTPlotter::wheelEvent ( QWheelEvent * event ) { } else { zoomRect.translate(d.x(), d.y()); } + correctZoomRectForPanning(zoomRect); + // now apply the new range setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true); } diff --git a/lib/jkqtplotter/jkqtplotter.h b/lib/jkqtplotter/jkqtplotter.h index 64df241809..c6500f45c8 100644 --- a/lib/jkqtplotter/jkqtplotter.h +++ b/lib/jkqtplotter/jkqtplotter.h @@ -1496,6 +1496,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget { /** \brief paint the user action (rectangle, ellipse, ... */ void paintUserAction(); + /** \brief tool function, which corrects the given rectangle (in pixels!) during a panning action. The correction is necesary towards getAbsoluteXY() to prevent an unwanted zooming in. */ + void correctZoomRectForPanning(QRectF& rect) const; + /** \brief event handler for a double click *