[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