Skip to content

Commit

Permalink
Add status bar zoom control to layout designer
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 11, 2017
1 parent ac83093 commit e27a32d
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 1 deletion.
5 changes: 5 additions & 0 deletions python/gui/layout/qgslayoutdesignerinterface.sip
Expand Up @@ -55,6 +55,11 @@ class QgsLayoutDesignerInterface: QObject
Closes the layout designer.
%End

virtual void zoomFull() = 0;
%Docstring
Zooms to full extent of layout.
%End

};

/************************************************************************
Expand Down
9 changes: 9 additions & 0 deletions python/gui/layout/qgslayoutview.sip
Expand Up @@ -112,6 +112,8 @@ class QgsLayoutView: QGraphicsView
.. seealso:: zoomOut()
%End

void emitZoomLevelChanged();

signals:

void layoutSet( QgsLayout *layout );
Expand All @@ -127,6 +129,11 @@ class QgsLayoutView: QGraphicsView
.. seealso:: setTool()
%End

void zoomLevelChanged();
%Docstring
Is emitted whenever the zoom level of the view is changed.
%End

protected:
virtual void mousePressEvent( QMouseEvent *event );

Expand All @@ -142,6 +149,8 @@ class QgsLayoutView: QGraphicsView

virtual void keyReleaseEvent( QKeyEvent *event );

virtual void resizeEvent( QResizeEvent *event );


};

Expand Down
69 changes: 69 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -29,6 +29,12 @@
#include "qgsgui.h"
#include "qgslayoutitemguiregistry.h"
#include <QShortcut>
#include <QComboBox>
#include <QLineEdit>
#include <QDesktopWidget>

//add some nice zoom levels for zoom comboboxes
QList<double> QgsLayoutDesignerDialog::sStatusZoomLevelsList { 0.125, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0};

QgsAppLayoutDesignerInterface::QgsAppLayoutDesignerInterface( QgsLayoutDesignerDialog *dialog )
: QgsLayoutDesignerInterface( dialog )
Expand All @@ -50,6 +56,11 @@ void QgsAppLayoutDesignerInterface::close()
mDesigner->close();
}

void QgsAppLayoutDesignerInterface::zoomFull()
{
mDesigner->zoomFull();
}


QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFlags flags )
: QMainWindow( parent, flags )
Expand Down Expand Up @@ -122,8 +133,28 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
connect( mActionZoomAll, &QAction::triggered, mView, &QgsLayoutView::zoomFull );
connect( mActionZoomActual, &QAction::triggered, mView, &QgsLayoutView::zoomActual );

mStatusZoomCombo = new QComboBox();
mStatusZoomCombo->setEditable( true );
mStatusZoomCombo->setInsertPolicy( QComboBox::NoInsert );
mStatusZoomCombo->setCompleter( nullptr );
mStatusZoomCombo->setMinimumWidth( 100 );
//zoom combo box accepts decimals in the range 1-9999, with an optional decimal point and "%" sign
QRegularExpression zoomRx( "\\s*\\d{1,4}(\\.\\d?)?\\s*%?" );
QValidator *zoomValidator = new QRegularExpressionValidator( zoomRx, mStatusZoomCombo );
mStatusZoomCombo->lineEdit()->setValidator( zoomValidator );

Q_FOREACH ( double level, sStatusZoomLevelsList )
{
mStatusZoomCombo->insertItem( 0, tr( "%1%" ).arg( level * 100.0, 0, 'f', 1 ) );
}
connect( mStatusZoomCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLayoutDesignerDialog::statusZoomCombo_currentIndexChanged );
connect( mStatusZoomCombo->lineEdit(), &QLineEdit::returnPressed, this, &QgsLayoutDesignerDialog::statusZoomCombo_zoomEntered );

mStatusBar->addPermanentWidget( mStatusZoomCombo );

mView->setTool( mSelectTool );
mView->setFocus();
connect( mView, &QgsLayoutView::zoomLevelChanged, this, &QgsLayoutDesignerDialog::updateStatusZoom );

restoreWindowState();
}
Expand Down Expand Up @@ -220,6 +251,44 @@ void QgsLayoutDesignerDialog::itemTypeAdded( int type )
} );
}

void QgsLayoutDesignerDialog::statusZoomCombo_currentIndexChanged( int index )
{
double selectedZoom = sStatusZoomLevelsList.at( sStatusZoomLevelsList.count() - index - 1 );
if ( mView )
{
mView->setZoomLevel( selectedZoom );
//update zoom combobox text for correct format (one decimal place, trailing % sign)
whileBlocking( mStatusZoomCombo )->lineEdit()->setText( tr( "%1%" ).arg( selectedZoom * 100.0, 0, 'f', 1 ) );
}
}

void QgsLayoutDesignerDialog::statusZoomCombo_zoomEntered()
{
if ( !mView )
{
return;
}

//need to remove spaces and "%" characters from input text
QString zoom = mStatusZoomCombo->currentText().remove( QChar( '%' ) ).trimmed();
mView->setZoomLevel( zoom.toDouble() / 100 );
}

void QgsLayoutDesignerDialog::updateStatusZoom()
{
double dpi = QgsApplication::desktop()->logicalDpiX();
//monitor dpi is not always correct - so make sure the value is sane
if ( ( dpi < 60 ) || ( dpi > 1200 ) )
dpi = 72;

//pixel width for 1mm on screen
double scale100 = dpi / 25.4;
//current zoomLevel
double zoomLevel = mView->transform().m11() * 100 / scale100;

whileBlocking( mStatusZoomCombo )->lineEdit()->setText( tr( "%1%" ).arg( zoomLevel, 0, 'f', 1 ) );
}

QgsLayoutView *QgsLayoutDesignerDialog::view()
{
return mView;
Expand Down
12 changes: 12 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.h
Expand Up @@ -26,6 +26,7 @@ class QgsLayoutViewToolAddItem;
class QgsLayoutViewToolPan;
class QgsLayoutViewToolZoom;
class QgsLayoutViewToolSelect;
class QComboBox;

class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
{
Expand All @@ -39,6 +40,7 @@ class QgsAppLayoutDesignerInterface : public QgsLayoutDesignerInterface
public slots:

void close() override;
void zoomFull() override;

private:

Expand Down Expand Up @@ -116,6 +118,11 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
private slots:

void itemTypeAdded( int type );
void statusZoomCombo_currentIndexChanged( int index );
void statusZoomCombo_zoomEntered();

//! Updates zoom level in status bar
void updateStatusZoom();

private:

Expand All @@ -127,6 +134,11 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner

QgsLayoutView *mView = nullptr;

//! Combobox in status bar which shows/adjusts current zoom level
QComboBox *mStatusZoomCombo = nullptr;

static QList<double> sStatusZoomLevelsList;

QgsLayoutViewToolAddItem *mAddItemTool = nullptr;
QgsLayoutViewToolPan *mPanTool = nullptr;
QgsLayoutViewToolZoom *mZoomTool = nullptr;
Expand Down
5 changes: 5 additions & 0 deletions src/gui/layout/qgslayoutdesignerinterface.h
Expand Up @@ -68,6 +68,11 @@ class GUI_EXPORT QgsLayoutDesignerInterface: public QObject
*/
virtual void close() = 0;

/**
* Zooms to full extent of layout.
*/
virtual void zoomFull() = 0;

};

#endif // QGSLAYOUTDESIGNERINTERFACE_H
14 changes: 13 additions & 1 deletion src/gui/layout/qgslayoutview.cpp
Expand Up @@ -107,6 +107,7 @@ void QgsLayoutView::setZoomLevel( double level )
//desired pixel width for 1mm on screen
double scale = qBound( MIN_VIEW_SCALE, level * dpi / 25.4, MAX_VIEW_SCALE );
setTransform( QTransform::fromScale( scale, scale ) );
emit zoomLevelChanged();
}

void QgsLayoutView::zoomFull()
Expand All @@ -129,6 +130,11 @@ void QgsLayoutView::zoomActual()
setZoomLevel( 1.0 );
}

void QgsLayoutView::emitZoomLevelChanged()
{
emit zoomLevelChanged();
}

void QgsLayoutView::mousePressEvent( QMouseEvent *event )
{
if ( mTool )
Expand Down Expand Up @@ -249,6 +255,12 @@ void QgsLayoutView::keyReleaseEvent( QKeyEvent *event )
QGraphicsView::keyReleaseEvent( event );
}

void QgsLayoutView::resizeEvent( QResizeEvent *event )
{
QGraphicsView::resizeEvent( event );
emit zoomLevelChanged();
}

void QgsLayoutView::wheelZoom( QWheelEvent *event )
{
//get mouse wheel zoom behavior settings
Expand Down Expand Up @@ -292,8 +304,8 @@ void QgsLayoutView::wheelZoom( QWheelEvent *event )
}

//update layout for new zoom
#if 0 // TODO
emit zoomLevelChanged();
#if 0 // TODO
updateRulers();
#endif
update();
Expand Down
17 changes: 17 additions & 0 deletions src/gui/layout/qgslayoutview.h
Expand Up @@ -133,6 +133,17 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void zoomActual();

/**
* Emits the zoomLevelChanged() signal. This should be called after
* calling any of the QGraphicsView base class methods which alter
* the view's zoom level, i.e. QGraphicsView::fitInView().
*/
// NOTE - I realize these emitXXX methods are gross, but there's no clean
// alternative here. We can't override the non-virtual Qt QGraphicsView
// methods, and adding our own renamed methods which call the base class
// methods also adds noise to the API.
void emitZoomLevelChanged();

signals:

/**
Expand All @@ -148,6 +159,11 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
*/
void toolSet( QgsLayoutViewTool *tool );

/**
* Is emitted whenever the zoom level of the view is changed.
*/
void zoomLevelChanged();

protected:
void mousePressEvent( QMouseEvent *event ) override;
void mouseReleaseEvent( QMouseEvent *event ) override;
Expand All @@ -156,6 +172,7 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView
void wheelEvent( QWheelEvent *event ) override;
void keyPressEvent( QKeyEvent *event ) override;
void keyReleaseEvent( QKeyEvent *event ) override;
void resizeEvent( QResizeEvent *event ) override;

private:

Expand Down
2 changes: 2 additions & 0 deletions src/gui/layout/qgslayoutviewtoolzoom.cpp
Expand Up @@ -54,6 +54,7 @@ void QgsLayoutViewToolZoom::layoutPressEvent( QgsLayoutViewMouseEvent *event )

//zoom view to fit desired bounds
view()->fitInView( boundsRect, Qt::KeepAspectRatio );
view()->emitZoomLevelChanged();
}
else
{
Expand Down Expand Up @@ -99,6 +100,7 @@ void QgsLayoutViewToolZoom::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )

//zoom view to fit desired bounds
view()->fitInView( newBoundsRect, Qt::KeepAspectRatio );
view()->emitZoomLevelChanged();
}

void QgsLayoutViewToolZoom::keyPressEvent( QKeyEvent *event )
Expand Down

0 comments on commit e27a32d

Please sign in to comment.