[kmplot] /: Implement zooming with Ctrl+mouse wheel

Yuri Chornoivan null at kde.org
Thu Dec 6 04:35:36 GMT 2018


Git commit acf37fcffd9de49144a182e64ffc2d4c61916df9 by Yuri Chornoivan.
Committed on 06/12/2018 at 04:35.
Pushed by yurchor into branch 'master'.

Implement zooming with Ctrl+mouse wheel

BUG: 159772
Differential Revision: https://phabricator.kde.org/D17120

M  +8    -3    doc/index.docbook
M  +68   -51   kmplot/view.cpp
M  +25   -1    kmplot/view.h

https://commits.kde.org/kmplot/acf37fcffd9de49144a182e64ffc2d4c61916df9

diff --git a/doc/index.docbook b/doc/index.docbook
index 0fdeb9f..645f89e 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -43,8 +43,8 @@
 
 <legalnotice>&FDLNotice;</legalnotice>
 
-<date>2018-11-09</date>
-<releaseinfo>1.2.2 (Applications 18.12)</releaseinfo>
+<date>2018-11-23</date>
+<releaseinfo>1.3.0 (Applications 19.04)</releaseinfo>
 
 <!-- Abstract about this handbook -->
 
@@ -469,7 +469,7 @@ url="http://edu.kde.org/">http://edu.kde.org/</ulink></para></abstract>
 		</mediaobject>
 	</screenshot>
 
-	<para>Here you can set global settings which automatic will be saved when you exit &kmplot;. you can set angle-mode (radians and degrees), zoom in and zoom out factors, and whether to show advanced plot tracing. </para>
+    <para>Here you can set global settings which automatic will be saved when you exit &kmplot;. You can set angle-mode (radians and degrees), zoom in and zoom out factors for zooming using &Ctrl; with mouse wheel or the <link linkend="a-view-menu">corresponding menu items</link>, and whether to show advanced plot tracing.</para>
 </sect1>
 
 <sect1 id="diagram-config">
@@ -1214,6 +1214,11 @@ chapter of the &kde; Fundamentals documentation &kmplot; has these application s
 <sect2 id="a-view-menu">
 	<title>The View Menu</title>
 	<para>The first three items in the menu are related to zooming.</para>
+	<note>
+		<para>
+			The mouse wheel can also be used as a zoom control. To zoom in or out using the mouse, hold down the &Ctrl; key while you turn the mouse wheel. Each tick increases or decreases the zoom factor by the value defined in the <link linkend="general-config">&kmplot; General settings</link>.
+		</para>
+	</note>
 
 	<variablelist>
 		<varlistentry>
diff --git a/kmplot/view.cpp b/kmplot/view.cpp
index 1e11fdc..44761f0 100644
--- a/kmplot/view.cpp
+++ b/kmplot/view.cpp
@@ -87,7 +87,9 @@ View::View( bool readOnly, QMenu * functionPopup, QWidget* parent )
 	: QWidget( parent ),
 	  buffer( width(), height() ),
 	  m_popupMenu( functionPopup ),
-	  m_readonly( readOnly )
+	  m_readonly( readOnly ),
+	  m_AccumulatedDelta(0),
+	  m_viewportAnimation( new QPropertyAnimation( this, "viewport" ) )
 {
 	assert( !m_self ); // this class should only be constructed once
 	m_self = this;
@@ -2972,6 +2974,7 @@ bool View::crosshairPositionValid( Function * plot ) const
 
 void View::mousePressEvent(QMouseEvent *e)
 {
+	m_AccumulatedDelta = 0;
 	m_mousePressTimer->start();
 
 	// In general, we want to update the view
@@ -3326,6 +3329,12 @@ QString View::posToString( double x, double delta, PositionFormatting format, co
 
 void View::mouseMoveEvent(QMouseEvent *e)
 {
+	if ( m_previousMouseMovePos != e->globalPos() )
+	{
+		m_AccumulatedDelta = 0;
+	}
+	m_previousMouseMovePos = e->globalPos();
+	m_AccumulatedDelta = 0;
 	if ( m_isDrawing || !e)
 		return;
 
@@ -3392,6 +3401,33 @@ void View::leaveEvent(QEvent *)
 }
 
 
+void View::wheelEvent(QWheelEvent *e)
+{
+	m_AccumulatedDelta += e->delta();
+
+	if (e->modifiers() & Qt::ControlModifier)
+	{
+		if (m_AccumulatedDelta >= QWheelEvent::DefaultDeltasPerStep)
+		{
+			zoomIn( e->pos(), double(Settings::zoomInStep())/100.0 );
+			m_AccumulatedDelta = 0;
+		}
+		else if (m_AccumulatedDelta <= -QWheelEvent::DefaultDeltasPerStep)
+		{
+			zoomIn( e->pos(), (double(Settings::zoomOutStep())/100.0) + 1.0 );
+			m_AccumulatedDelta = 0;
+		}
+		e->accept();
+		return;
+	}
+	else
+	{
+		m_AccumulatedDelta = 0;
+	}
+	QWidget::wheelEvent(e);
+}
+
+
 bool View::updateCrosshairPosition()
 {
 	QPointF mousePos = mapFromGlobal( QCursor::pos() );
@@ -3621,66 +3657,36 @@ void View::animateZoom( const QRectF & _newCoords )
 
 	m_zoomMode = AnimatingZoom;
 
-	double oldCoordsArea = (m_xmax-m_xmin) * (m_ymax-m_ymin);
-	double newCoordsArea = newCoords.width() * newCoords.height();
-
-	QPointF beginTL, beginBR, endTL, endBR;
-
-	if ( oldCoordsArea > newCoordsArea )
+	if ( style()->styleHint(QStyle::SH_Widget_Animate) && m_viewportAnimation->state() == QAbstractAnimation::Stopped )
 	{
-		// zooming in
-		beginTL = newCoords.topLeft();
-		beginBR = newCoords.bottomRight();
-		endTL = QPointF( m_xmin, m_ymin );
-		endBR = QPointF( m_xmax, m_ymax );
+		m_viewportAnimation->setDuration( 150 );
+		m_viewportAnimation->setEasingCurve( QEasingCurve::OutCubic );
+		m_viewportAnimation->setStartValue( oldCoords );
+		m_viewportAnimation->setEndValue( newCoords );
+		m_viewportAnimation->start();
+		connect(m_viewportAnimation, &QPropertyAnimation::finished, [this, newCoords]
+		{
+			finishAnimation( newCoords );
+		});
 	}
 	else
-	{
-		// zooming out
-		beginTL = QPointF( m_xmin, m_ymin );
-		beginBR = QPointF( m_xmax, m_ymax );
-
-		double kx = ( m_xmin - m_xmax ) / ( newCoords.left() - newCoords.right() );
-		double ky = ( m_ymin - m_ymax ) / ( newCoords.top() - newCoords.bottom() );
-
-		double lx = m_xmin - (kx * newCoords.left());
-		double ly = m_ymin - (ky * newCoords.top());
-
-		endTL = QPointF( (kx * m_xmin) + lx, (ky * m_ymin) + ly );
-		endBR = QPointF( (kx * m_xmax) + lx, (ky * m_ymax) + ly );
+        {
+		finishAnimation( newCoords );
 	}
+	Settings::self()->save();
+}
 
-	double MAX = 10;
-	double ms = MAX*16; // milliseconds to animate for
-
-	for ( int i = 0; i <= MAX; ++i )
-	{
-		QTime t;
-		t.start();
-
-		QPointF tl = (( i*endTL) + ((MAX-i)*beginTL)) / MAX;
-		QPointF br = (( i*endBR) + ((MAX-i)*beginBR)) / MAX;
-
-		m_animateZoomRect = QRectF( tl, QSizeF( br.x()-tl.x(), br.y()-tl.y() ) );
-
-		repaint();
-
-		if ( i == MAX )
-			break;
-		else while ( t.elapsed() < (ms/MAX) )
-			; // do nothing
-	}
-	
-	m_xmin = newCoords.left();
-	m_xmax = newCoords.right();
-	m_ymin = newCoords.top();
-	m_ymax = newCoords.bottom();
+void View::finishAnimation( const QRectF & rect )
+{
+	m_xmin = rect.left();
+	m_xmax = rect.right();
+	m_ymin = rect.top();
+	m_ymax = rect.bottom();
 
 	Settings::setXMin( Parser::number( m_xmin ) );
 	Settings::setXMax( Parser::number( m_xmax ) );
 	Settings::setYMin( Parser::number( m_ymin ) );
 	Settings::setYMax( Parser::number( m_ymax ) );
-	Settings::self()->save();
 	MainDlg::self()->coordsDialog()->updateXYRange();
 	MainDlg::self()->requestSaveCurrentState();
 
@@ -3689,6 +3695,17 @@ void View::animateZoom( const QRectF & _newCoords )
 	m_zoomMode = Normal;
 }
 
+const QRectF View::getViewport()
+{
+	return m_animateZoomRect;
+}
+
+void View::setViewport( const QRectF & rect )
+{
+	m_animateZoomRect = rect;
+	repaint();
+}
+
 
 void View::translateView( int dx, int dy )
 {
diff --git a/kmplot/view.h b/kmplot/view.h
index f529717..19af8c2 100644
--- a/kmplot/view.h
+++ b/kmplot/view.h
@@ -30,11 +30,13 @@
 
 // Qt includes
 #include <QDebug>
+#include <QEasingCurve>
 #include <QEvent>
 #include <QKeyEvent>
 #include <QMouseEvent>
 #include <QPixmap>
 #include <QPointer>
+#include <QPropertyAnimation>
 #include <QResizeEvent>
 
 // KDE includes
@@ -81,6 +83,7 @@ class QMenu;
 class View : public QWidget
 {
 	Q_OBJECT
+	Q_PROPERTY( QRectF viewport READ getViewport WRITE setViewport )
 	public:
 		/// Constructor
 		View( bool readOnly, QMenu * functionPopup, QWidget* parent );
@@ -250,6 +253,8 @@ class View : public QWidget
 		void keyPressEvent(QKeyEvent * ) Q_DECL_OVERRIDE;
 		/// called when a mouse key is released
 		void mouseReleaseEvent ( QMouseEvent * e ) Q_DECL_OVERRIDE;
+		/// called for zooming with Ctrl+mouse wheel
+		void wheelEvent(QWheelEvent *event);
 		/// Is needed to be reimplement so that the user can stop a preview-drawing
 		bool event( QEvent * e ) Q_DECL_OVERRIDE;
 		/**
@@ -498,7 +503,12 @@ class View : public QWidget
 		 * Positions of the first grid line.
 		 */
 		double ticStartX, ticStartY;
-	
+
+		/**
+		 * Mouse pointer previous for zooming.
+		 */
+		QPoint m_previousMouseMovePos;
+
 		QPointF m_crosshairPixelCoords;
 		QPointF m_crosshairPosition;	///< in real coordinates
 	
@@ -601,6 +611,8 @@ class View : public QWidget
 		QPoint m_prevDragMousePos;
 		/// timer that is started when the mouse is pressed
 		QTime * m_mousePressTimer;
+		/** Current plot viewport. */
+		const QRectF getViewport();
 		
 		/**
 		 * The rectangle (in painter, and hence pixel, coordinates) that the
@@ -628,6 +640,18 @@ class View : public QWidget
 		
 		KTextEdit * m_textEdit; ///< Contains m_textDocument
 		QTextDocument * m_textDocument; ///< Used for layout of axis labels
+
+		/// Accumulates mouse or trackpad scrolling to enable Ctrl+mouse wheel scaling on faulty devices
+		int m_AccumulatedDelta;
+
+		/// Animation for the viewport
+		QPropertyAnimation * m_viewportAnimation;
+
+		/// Finishes animation of the viewport and get the View back to the Normal mode
+		void finishAnimation( const QRectF & rect );
+
+	private slots:
+		void setViewport( const QRectF & rect );
 };
 
 #endif // View_included


More information about the kde-doc-english mailing list