[PATCH 3/3] Profile: attempt on better zoom and pan logic

Lubomir I. Ivanov neolit123 at gmail.com
Thu Jul 4 13:55:27 PDT 2013


From: "Lubomir I. Ivanov" <neolit123 at gmail.com>

QGraphicsView::AnchorUnderMouse does not work for
Qt 4.8.1 on Ubuntu 12.04 and if the mouseMoveEvent
overload is disabled it practically can be seen that
the anchor point is [0, 0] instead of the mouse location.

After a suggestion found on the web this patch attempts
to use the hidden scroll bars to calculate reposition
on pan and zoom *near the mouse cursor.

On the other hand QAbstactSlider (QScrollBar) class
strangly uses negative offsets for minimum scroll
position, which makes the implementation even more
ugly.

[*near] because it's not that accurate!

Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---

QGraphicView::translate() is technically a NOP
as there is no way to disable the scene alignment
in Qt 4.8.x. actually, there are bug reports on the
web for that and the recommendation is to add a root
item on the scene (?) and use transformation
matrix on that. centerOn() is another option i didn't try.

there is another bug where if switching views (ctrl+1...n)
the profile zooming becomes broken, but also the text looks
kinda out of position, so i think it's related to another
issue.

please consider testing...
---
 qt-ui/profilegraphics.cpp | 29 ++++++++++++++++++++++++-----
 qt-ui/profilegraphics.h   |  1 +
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp
index cfc1cf6..1cdd2d6 100644
--- a/qt-ui/profilegraphics.cpp
+++ b/qt-ui/profilegraphics.cpp
@@ -6,6 +6,7 @@
 #include <QGraphicsScene>
 #include <QResizeEvent>
 #include <QGraphicsLineItem>
+#include <QScrollBar>
 #include <QPen>
 #include <QBrush>
 #include <QDebug>
@@ -67,12 +68,32 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent
 
 }
 
+/* since we cannot use translate() directly on the scene we hack on
+ * the scroll bars (hidden) functionality */
+void ProfileGraphicsView::scrollViewTo(const QPoint pos)
+{
+	if (!zoomLevel)
+		return;
+	QScrollBar *vs = verticalScrollBar();
+	QScrollBar *hs = horizontalScrollBar();
+	const qreal yRat = pos.y() / sceneRect().height();
+	const qreal xRat = pos.x() / sceneRect().width();
+	const int vMax = vs->maximum();
+	const int hMax = hs->maximum();
+	const int vMin = vs->minimum();
+	const int hMin = hs->minimum();
+	/* QScrollBar receives crazy negative values for minimum */
+	vs->setValue(yRat * (vMax - vMin) + vMin * 0.9);
+	hs->setValue(xRat * (hMax - hMin) + hMin * 0.9);
+}
+
 void ProfileGraphicsView::wheelEvent(QWheelEvent* event)
 {
 	if (!toolTip)
 		return;
 
-	setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+	// doesn't seem to work for Qt 4.8.1
+	// setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
 
 	// Scale the view / do the zoom
 	QPoint toolTipPos = mapFromScene(toolTip->pos());
@@ -86,6 +107,7 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event)
 		scale(1.0 / scaleFactor, 1.0 / scaleFactor);
 		zoomLevel--;
 	}
+	scrollViewTo(event->pos());
 	toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y());
 }
 
@@ -98,10 +120,7 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event)
 
 	QPoint toolTipPos = mapFromScene(toolTip->pos());
 
-	double dx = sceneRect().x();
-	double dy = sceneRect().y();
-
-	ensureVisible(event->pos().x() + dx, event->pos().y() + dy, 1, 1);
+	scrollViewTo(event->pos());
 
 	if (zoomLevel == 0)
 		QGraphicsView::mouseMoveEvent(event);
diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h
index c3cb4ef..48c88aa 100644
--- a/qt-ui/profilegraphics.h
+++ b/qt-ui/profilegraphics.h
@@ -124,6 +124,7 @@ private:
 	void plot_depth_scale();
 
 	QColor get_sac_color(int sac, int avg_sac);
+	void scrollViewTo(const QPoint pos);
 
 	QPen defaultPen;
 	QBrush defaultBrush;
-- 
1.7.11.msysgit.0



More information about the subsurface mailing list