mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Port ability to wheel zoom into/out of layout designer
This commit is contained in:
parent
4065a7ff67
commit
20ca51b59c
@ -67,6 +67,12 @@ class QgsLayoutView: QGraphicsView
|
||||
You don't have to call it manually, QgsLayoutViewTool takes care of it.
|
||||
%End
|
||||
|
||||
void scaleSafe( double scale );
|
||||
%Docstring
|
||||
Scales the view in a safe way, by limiting the acceptable range
|
||||
of the scale applied. The ``scale`` parameter specifies the zoom factor to scale the view by.
|
||||
%End
|
||||
|
||||
signals:
|
||||
|
||||
void layoutSet( QgsLayout *layout );
|
||||
|
@ -19,8 +19,13 @@
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayoutviewtool.h"
|
||||
#include "qgslayoutviewmouseevent.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsrectangle.h"
|
||||
#include <memory>
|
||||
|
||||
#define MIN_VIEW_SCALE 0.05
|
||||
#define MAX_VIEW_SCALE 1000.0
|
||||
|
||||
QgsLayoutView::QgsLayoutView( QWidget *parent )
|
||||
: QGraphicsView( parent )
|
||||
{
|
||||
@ -74,6 +79,14 @@ void QgsLayoutView::unsetTool( QgsLayoutViewTool *tool )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutView::scaleSafe( double scale )
|
||||
{
|
||||
double currentScale = transform().m11();
|
||||
scale *= currentScale;
|
||||
scale = qBound( MIN_VIEW_SCALE, scale, MAX_VIEW_SCALE );
|
||||
setTransform( QTransform::fromScale( scale, scale ) );
|
||||
}
|
||||
|
||||
void QgsLayoutView::mousePressEvent( QMouseEvent *event )
|
||||
{
|
||||
if ( mTool )
|
||||
@ -134,7 +147,10 @@ void QgsLayoutView::wheelEvent( QWheelEvent *event )
|
||||
}
|
||||
|
||||
if ( !mTool || !event->isAccepted() )
|
||||
QGraphicsView::wheelEvent( event );
|
||||
{
|
||||
event->accept();
|
||||
wheelZoom( event );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutView::keyPressEvent( QKeyEvent *event )
|
||||
@ -158,3 +174,53 @@ void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
|
||||
if ( !mTool || !event->isAccepted() )
|
||||
QGraphicsView::keyReleaseEvent( event );
|
||||
}
|
||||
|
||||
void QgsLayoutView::wheelZoom( QWheelEvent *event )
|
||||
{
|
||||
//get mouse wheel zoom behavior settings
|
||||
QgsSettings settings;
|
||||
double zoomFactor = settings.value( QStringLiteral( "qgis/zoom_factor" ), 2 ).toDouble();
|
||||
|
||||
// "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
|
||||
zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * qAbs( event->angleDelta().y() );
|
||||
|
||||
if ( event->modifiers() & Qt::ControlModifier )
|
||||
{
|
||||
//holding ctrl while wheel zooming results in a finer zoom
|
||||
zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
|
||||
}
|
||||
|
||||
//calculate zoom scale factor
|
||||
bool zoomIn = event->angleDelta().y() > 0;
|
||||
double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor );
|
||||
|
||||
//get current visible part of scene
|
||||
QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
|
||||
QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );
|
||||
|
||||
//transform the mouse pos to scene coordinates
|
||||
QPointF scenePoint = mapToScene( event->pos() );
|
||||
|
||||
//adjust view center
|
||||
QgsPointXY oldCenter( visibleRect.center() );
|
||||
QgsPointXY newCenter( scenePoint.x() + ( ( oldCenter.x() - scenePoint.x() ) * scaleFactor ),
|
||||
scenePoint.y() + ( ( oldCenter.y() - scenePoint.y() ) * scaleFactor ) );
|
||||
centerOn( newCenter.x(), newCenter.y() );
|
||||
|
||||
//zoom layout
|
||||
if ( zoomIn )
|
||||
{
|
||||
scaleSafe( zoomFactor );
|
||||
}
|
||||
else
|
||||
{
|
||||
scaleSafe( 1 / zoomFactor );
|
||||
}
|
||||
|
||||
//update layout for new zoom
|
||||
#if 0 // TODO
|
||||
emit zoomLevelChanged();
|
||||
updateRulers();
|
||||
#endif
|
||||
update();
|
||||
}
|
||||
|
@ -85,6 +85,12 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
|
||||
*/
|
||||
void unsetTool( QgsLayoutViewTool *tool );
|
||||
|
||||
/**
|
||||
* Scales the view in a safe way, by limiting the acceptable range
|
||||
* of the scale applied. The \a scale parameter specifies the zoom factor to scale the view by.
|
||||
*/
|
||||
void scaleSafe( double scale );
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
@ -111,6 +117,9 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
|
||||
|
||||
private:
|
||||
|
||||
//! Zoom layout from a mouse wheel event
|
||||
void wheelZoom( QWheelEvent *event );
|
||||
|
||||
QPointer< QgsLayoutViewTool > mTool;
|
||||
|
||||
friend class TestQgsLayoutView;
|
||||
|
@ -73,6 +73,7 @@ ADD_PYTHON_TEST(PyQgsJsonUtils test_qgsjsonutils.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayerTreeMapCanvasBridge test_qgslayertreemapcanvasbridge.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayerTree test_qgslayertree.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutManager test_qgslayoutmanager.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayoutView test_qgslayoutview.py)
|
||||
ADD_PYTHON_TEST(PyQgsLineSymbolLayers test_qgslinesymbollayers.py)
|
||||
ADD_PYTHON_TEST(PyQgsLayerMetadata test_qgslayermetadata.py)
|
||||
ADD_PYTHON_TEST(PyQgsLocator test_qgslocator.py)
|
||||
|
63
tests/src/python/test_qgslayoutview.py
Normal file
63
tests/src/python/test_qgslayoutview.py
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""QGIS Unit tests for QgsLayoutView.
|
||||
|
||||
.. note:: This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
"""
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = '05/07/2017'
|
||||
__copyright__ = 'Copyright 2017, The QGIS Project'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from qgis.gui import QgsLayoutView
|
||||
from qgis.PyQt.QtCore import QRectF
|
||||
from qgis.PyQt.QtGui import QTransform
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
start_app()
|
||||
|
||||
|
||||
class TestQgsLayoutView(unittest.TestCase):
|
||||
|
||||
def testScaleSafe(self):
|
||||
""" test scaleSafe method """
|
||||
|
||||
view = QgsLayoutView()
|
||||
view.fitInView(QRectF(0, 0, 10, 10))
|
||||
scale = view.transform().m11()
|
||||
view.scaleSafe(2)
|
||||
self.assertAlmostEqual(view.transform().m11(), 2)
|
||||
view.scaleSafe(4)
|
||||
self.assertAlmostEqual(view.transform().m11(), 8)
|
||||
|
||||
# try to zoom in heaps
|
||||
view.scaleSafe(99999999)
|
||||
# assume we have hit the limit
|
||||
scale = view.transform().m11()
|
||||
view.scaleSafe(2)
|
||||
self.assertAlmostEqual(view.transform().m11(), scale)
|
||||
|
||||
view.setTransform(QTransform.fromScale(1, 1))
|
||||
self.assertAlmostEqual(view.transform().m11(), 1)
|
||||
# test zooming out
|
||||
view.scaleSafe(0.5)
|
||||
self.assertAlmostEqual(view.transform().m11(), 0.5)
|
||||
view.scaleSafe(0.1)
|
||||
self.assertAlmostEqual(view.transform().m11(), 0.05)
|
||||
|
||||
# try zooming out heaps
|
||||
view.scaleSafe(0.000000001)
|
||||
# assume we have hit the limit
|
||||
scale = view.transform().m11()
|
||||
view.scaleSafe(0.5)
|
||||
self.assertAlmostEqual(view.transform().m11(), scale)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user