Skip to content

Commit

Permalink
[FEATURE] add a map canvas magnifier
Browse files Browse the repository at this point in the history
  • Loading branch information
pblottiere committed May 12, 2016
1 parent 948c1f0 commit 9a62613
Show file tree
Hide file tree
Showing 19 changed files with 400 additions and 6 deletions.
6 changes: 6 additions & 0 deletions python/gui/editorwidgets/qgsdoublespinbox.sip
Expand Up @@ -14,6 +14,12 @@ class QgsDoubleSpinBox : QDoubleSpinBox


explicit QgsDoubleSpinBox( QWidget *parent /TransferThis/ = 0 ); explicit QgsDoubleSpinBox( QWidget *parent /TransferThis/ = 0 );


/** Sets background color of QLineEdit widget within spin box
* @param color the background color
* @note added in QGIS 2.16
*/
void setBackgroundColor( const QColor *color = nullptr );

//! determines if the widget will show a clear button //! determines if the widget will show a clear button
//! @note the clear button will set the widget to its minimum value //! @note the clear button will set the widget to its minimum value
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
Expand Down
9 changes: 9 additions & 0 deletions python/gui/qgsmapcanvas.sip
Expand Up @@ -50,6 +50,15 @@ class QgsMapCanvas : QGraphicsView
//! Destructor //! Destructor
~QgsMapCanvas(); ~QgsMapCanvas();


//! Sets the factor of magnification to apply to the map canvas. Indeed, we
//! increase/decrease the DPI of the map settings according to this factor
//! in order to render marker point, labels, ... bigger.
//! @note added in 2.16
void setMagnificationFactor( double level );

//! Returns the magnification factor
double magnificationFactor() const;

void setLayerSet( QList<QgsMapCanvasLayer>& layers ); void setLayerSet( QList<QgsMapCanvasLayer>& layers );


void setCurrentLayer( QgsMapLayer* layer ); void setCurrentLayer( QgsMapLayer* layer );
Expand Down
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -51,6 +51,7 @@ SET(QGIS_APP_SRCS
qgsrulebasedlabelingwidget.cpp qgsrulebasedlabelingwidget.cpp
qgssavestyletodbdialog.cpp qgssavestyletodbdialog.cpp
qgsstatusbarcoordinateswidget.cpp qgsstatusbarcoordinateswidget.cpp
qgsstatusbarmagnifierwidget.cpp
qgsversioninfo.cpp qgsversioninfo.cpp
qgswelcomepageitemsmodel.cpp qgswelcomepageitemsmodel.cpp
qgswelcomepage.cpp qgswelcomepage.cpp
Expand Down Expand Up @@ -226,6 +227,7 @@ SET (QGIS_APP_MOC_HDRS
qgssavestyletodbdialog.h qgssavestyletodbdialog.h
qgsshortcutsmanager.h qgsshortcutsmanager.h
qgsstatusbarcoordinateswidget.h qgsstatusbarcoordinateswidget.h
qgsstatusbarmagnifierwidget.h
qgsversioninfo.h qgsversioninfo.h
qgswelcomepageitemsmodel.h qgswelcomepageitemsmodel.h
qgswelcomepage.h qgswelcomepage.h
Expand Down
12 changes: 12 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -123,6 +123,7 @@
#include "qgscomposermanager.h" #include "qgscomposermanager.h"
#include "qgscomposerview.h" #include "qgscomposerview.h"
#include "qgsstatusbarcoordinateswidget.h" #include "qgsstatusbarcoordinateswidget.h"
#include "qgsstatusbarmagnifierwidget.h"
#include "qgsconfigureshortcutsdialog.h" #include "qgsconfigureshortcutsdialog.h"
#include "qgscoordinatetransform.h" #include "qgscoordinatetransform.h"
#include "qgscoordinateutils.h" #include "qgscoordinateutils.h"
Expand Down Expand Up @@ -544,6 +545,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
, mScaleLabel( nullptr ) , mScaleLabel( nullptr )
, mScaleEdit( nullptr ) , mScaleEdit( nullptr )
, mScaleEditValidator( nullptr ) , mScaleEditValidator( nullptr )
, mMagnifierWidget( nullptr )
, mCoordsEdit( nullptr ) , mCoordsEdit( nullptr )
, mRotationLabel( nullptr ) , mRotationLabel( nullptr )
, mRotationEdit( nullptr ) , mRotationEdit( nullptr )
Expand Down Expand Up @@ -997,6 +999,7 @@ QgisApp::QgisApp()
, mScaleLabel( nullptr ) , mScaleLabel( nullptr )
, mScaleEdit( nullptr ) , mScaleEdit( nullptr )
, mScaleEditValidator( nullptr ) , mScaleEditValidator( nullptr )
, mMagnifierWidget( nullptr )
, mCoordsEdit( nullptr ) , mCoordsEdit( nullptr )
, mRotationLabel( nullptr ) , mRotationLabel( nullptr )
, mRotationEdit( nullptr ) , mRotationEdit( nullptr )
Expand Down Expand Up @@ -2095,6 +2098,13 @@ void QgisApp::createStatusBar()
statusBar()->addPermanentWidget( mScaleEdit, 0 ); statusBar()->addPermanentWidget( mScaleEdit, 0 );
connect( mScaleEdit, SIGNAL( scaleChanged( double ) ), this, SLOT( userScale() ) ); connect( mScaleEdit, SIGNAL( scaleChanged( double ) ), this, SLOT( userScale() ) );


// zoom widget
QSettings mySettings;
mMagnifierWidget = new QgsStatusBarMagnifierWidget( statusBar(), mMapCanvas );
mMagnifierWidget->setFont( myFont );
mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level", 100 ).toInt() );
statusBar()->addPermanentWidget( mMagnifierWidget, 0 );

if ( QgsMapCanvas::rotationEnabled() ) if ( QgsMapCanvas::rotationEnabled() )
{ {
// add a widget to show/set current rotation // add a widget to show/set current rotation
Expand Down Expand Up @@ -8478,6 +8488,8 @@ void QgisApp::showOptionsDialog( QWidget *parent, const QString& currentPage )
layer->setLayerName( layer->originalName() ); layer->setLayerName( layer->originalName() );
} }


mMagnifierWidget->setMagnificationLevel( mySettings.value( "/qgis/magnifier_level" ).toInt() );

//update any open compositions so they reflect new composer settings //update any open compositions so they reflect new composer settings
//we have to push the changes to the compositions here, because compositions //we have to push the changes to the compositions here, because compositions
//have no access to qgisapp and accordingly can't listen in to changes //have no access to qgisapp and accordingly can't listen in to changes
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -45,6 +45,7 @@ class QgsComposer;
class QgsComposerManager; class QgsComposerManager;
class QgsComposerView; class QgsComposerView;
class QgsStatusBarCoordinatesWidget; class QgsStatusBarCoordinatesWidget;
class QgsStatusBarMagnifierWidget;
class QgsContrastEnhancement; class QgsContrastEnhancement;
class QgsCustomLayerOrderWidget; class QgsCustomLayerOrderWidget;
class QgsDoubleSpinBox; class QgsDoubleSpinBox;
Expand Down Expand Up @@ -1591,6 +1592,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! The validator for the mScaleEdit //! The validator for the mScaleEdit
QValidator * mScaleEditValidator; QValidator * mScaleEditValidator;


//! zoom widget
QgsStatusBarMagnifierWidget *mMagnifierWidget;

//! Widget that will live in the statusbar to display and edit coords //! Widget that will live in the statusbar to display and edit coords
QgsStatusBarCoordinatesWidget *mCoordsEdit; QgsStatusBarCoordinatesWidget *mCoordsEdit;


Expand Down
10 changes: 10 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -589,6 +589,13 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl )
mSimplifyMaximumScaleComboBox->updateScales( myScalesList ); mSimplifyMaximumScaleComboBox->updateScales( myScalesList );
mSimplifyMaximumScaleComboBox->setScale( 1.0 / mSettings->value( "/qgis/simplifyMaxScale", 1 ).toFloat() ); mSimplifyMaximumScaleComboBox->setScale( 1.0 / mSettings->value( "/qgis/simplifyMaxScale", 1 ).toFloat() );


// Magnifier
doubleSpinBoxMagnifierDefault->setRange( 100, 1000 );
doubleSpinBoxMagnifierDefault->setSingleStep( 50 );
doubleSpinBoxMagnifierDefault->setDecimals( 0 );
doubleSpinBoxMagnifierDefault->setSuffix( "%" );
doubleSpinBoxMagnifierDefault->setValue( mSettings->value( "/qgis/magnifier_level", 100 ).toInt() );

// Slightly awkard here at the settings value is true to use QImage, // Slightly awkard here at the settings value is true to use QImage,
// but the checkbox is true to use QPixmap // but the checkbox is true to use QPixmap
chkAddedVisibility->setChecked( mSettings->value( "/qgis/new_layers_visible", true ).toBool() ); chkAddedVisibility->setChecked( mSettings->value( "/qgis/new_layers_visible", true ).toBool() );
Expand Down Expand Up @@ -1194,6 +1201,9 @@ void QgsOptions::saveOptions()
mSettings->setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() ); mSettings->setValue( "/qgis/simplifyLocal", !mSimplifyDrawingAtProvider->isChecked() );
mSettings->setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() ); mSettings->setValue( "/qgis/simplifyMaxScale", 1.0 / mSimplifyMaximumScaleComboBox->scale() );


// magnification
mSettings->setValue( "/qgis/magnifier_level", doubleSpinBoxMagnifierDefault->value() );

// project // project
mSettings->setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() ); mSettings->setValue( "/qgis/projOpenAtLaunch", mProjectOnLaunchCmbBx->currentIndex() );
mSettings->setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() ); mSettings->setValue( "/qgis/projOpenAtLaunchPath", mProjectOnLaunchLineEdit->text() );
Expand Down
114 changes: 114 additions & 0 deletions src/app/qgsstatusbarmagnifierwidget.cpp
@@ -0,0 +1,114 @@
/***************************************************************************
qgsstatusbarmagnifierwidget.cpp
begin : April 2016
copyright : (C) 2016 Paul Blottiere, Oslandia
email : paul dot blottiere at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/

#include <QFont>
#include <QHBoxLayout>
#include <QLabel>

#include <qgsapplication.h>
#include "qgsstatusbarmagnifierwidget.h"
#include "qgsmapcanvas.h"
#include "qgsdoublespinbox.h"

QgsStatusBarMagnifierWidget::QgsStatusBarMagnifierWidget( QWidget* parent,
QgsMapCanvas *canvas ) :
QWidget( parent ),
mCanvas( canvas ),
mMagnifier( 100 ),
mMagnifierMin( 100 ),
mMagnifierMax( 1000 )
{
// label
mLabel = new QLabel( this );
mLabel->setMinimumWidth( 10 );
mLabel->setMargin( 3 );
mLabel->setAlignment( Qt::AlignCenter );
mLabel->setFrameStyle( QFrame::NoFrame );
mLabel->setText( tr( "Magnifier" ) );
mLabel->setToolTip( tr( "Magnifier" ) );

mSpinBox = new QgsDoubleSpinBox( this );
mSpinBox->setSuffix( "%" );
mSpinBox->setClearValue( mMagnifierMin );
mSpinBox->setKeyboardTracking( false );
mSpinBox->setMaximumWidth( 120 );
mSpinBox->setDecimals( 0 );
mSpinBox->setRange( mMagnifierMin, mMagnifierMax );
mSpinBox->setWrapping( false );
mSpinBox->setSingleStep( 50 );
mSpinBox->setToolTip( tr( "Magnifier level" ) );

connect( mSpinBox, SIGNAL( valueChanged( double ) ), this,
SLOT( updateMagnifier() ) );

// layout
mLayout = new QHBoxLayout( this );
mLayout->addWidget( mLabel );
mLayout->addWidget( mSpinBox );
mLayout->setContentsMargins( 0, 0, 0, 0 );
mLayout->setAlignment( Qt::AlignRight );
mLayout->setSpacing( 0 );

setLayout( mLayout );

updateMagnifier();
}

QgsStatusBarMagnifierWidget::~QgsStatusBarMagnifierWidget()
{
}

double QgsStatusBarMagnifierWidget::magnificationLevel()
{
return mMagnifier;
}

void QgsStatusBarMagnifierWidget::setFont( const QFont& myFont )
{
mLabel->setFont( myFont );
mSpinBox->setFont( myFont );
}

bool QgsStatusBarMagnifierWidget::setMagnificationLevel( int level )
{
bool rc = false;

if ( level >= mMagnifierMin && level <= mMagnifierMax )
{
mSpinBox->setValue( level );
rc = true;
}

return rc;
}

void QgsStatusBarMagnifierWidget::updateMagnifier()
{
// get current data
mMagnifier = mSpinBox->value();

// update background color
QSettings mySettings;
int value = mySettings.value( "/qgis/magnifier_level", 100 ).toInt();

if ( mMagnifier == value )
mSpinBox->setBackgroundColor();
else
mSpinBox->setBackgroundColor( new QColor( 200, 200, 255 ) );

// update map canvas
mCanvas->setMagnificationFactor( mMagnifier / double( mMagnifierMin ) );
}
78 changes: 78 additions & 0 deletions src/app/qgsstatusbarmagnifierwidget.h
@@ -0,0 +1,78 @@
/***************************************************************************
qgsstatusbarmagnifierwidget.h
begin : April 2016
copyright : (C) 2016 Paul Blottiere, Oslandia
email : paul dot blottiere at oslandia dot com
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/

#ifndef QGSSTATUSBARMAGNIFIERWIDGET_H
#define QGSSTATUSBARMAGNIFIERWIDGET_H

class QLabel;
class QFont;
class QHBoxLayout;
class QgsMapCanvas;
class QgsDoubleSpinBox;

#include <QWidget>

/**
* A widget which lets the user select the current level of magnification to
* apply to the canvas.
* @note added in 2.16
*/
class APP_EXPORT QgsStatusBarMagnifierWidget : public QWidget
{
Q_OBJECT

public:

/** Constructor
* @param parent is the parent widget
* @param canvas the map canvas
*/
QgsStatusBarMagnifierWidget( QWidget* parent, QgsMapCanvas *canvas );

/** Destructor */
virtual ~QgsStatusBarMagnifierWidget();

/** Set the font of the text
* @param font the font to use
*/
void setFont( const QFont& font );

/** Returns the current magnification level
* @return magnification level
*/
double magnificationLevel();

/** Set the magnification level
* @param level the magnification level
* @return true if the level is valid, false otherwise
*/
bool setMagnificationLevel( int level );

private slots:

void updateMagnifier();

private:
QgsMapCanvas *mCanvas;
QHBoxLayout *mLayout;
QLabel *mLabel;
QgsDoubleSpinBox *mSpinBox;
int mMagnifier;
int mMagnifierMin;
int mMagnifierMax;
};

#endif
1 change: 0 additions & 1 deletion src/core/qgsmapsettings.h
Expand Up @@ -283,7 +283,6 @@ class CORE_EXPORT QgsMapSettings
double mMapUnitsPerPixel; double mMapUnitsPerPixel;
double mScale; double mScale;



// utiity stuff // utiity stuff
QgsScaleCalculator mScaleCalculator; QgsScaleCalculator mScaleCalculator;
QgsMapToPixel mMapToPixel; QgsMapToPixel mMapToPixel;
Expand Down
13 changes: 13 additions & 0 deletions src/gui/editorwidgets/qgsdoublespinbox.cpp
Expand Up @@ -46,6 +46,19 @@ QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) ); connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) );
} }


void QgsDoubleSpinBox::setBackgroundColor( const QColor *c )
{
if ( c )
{
QString rgb = QString( "rgb(%1, %2, %3)" ).arg( c->red() ).arg( c->green() ).arg( c->blue() );
this->lineEdit()->setStyleSheet( QString( "background-color: %1" ).arg( rgb ) );
}
else
this->lineEdit()->setStyleSheet( "" );

this->setStyleSheet( "" );
}

void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton ) void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton )
{ {
mShowClearButton = showClearButton; mShowClearButton = showClearButton;
Expand Down
11 changes: 10 additions & 1 deletion src/gui/editorwidgets/qgsdoublespinbox.h
Expand Up @@ -40,6 +40,12 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox


explicit QgsDoubleSpinBox( QWidget *parent = nullptr ); explicit QgsDoubleSpinBox( QWidget *parent = nullptr );


/** Sets background color of QLineEdit widget within spin box
* @param color the background color
* @note added in QGIS 2.16
*/
void setBackgroundColor( const QColor *color = nullptr );

//! determines if the widget will show a clear button //! determines if the widget will show a clear button
//! @note the clear button will set the widget to its minimum value //! @note the clear button will set the widget to its minimum value
void setShowClearButton( const bool showClearButton ); void setShowClearButton( const bool showClearButton );
Expand Down Expand Up @@ -80,10 +86,11 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
virtual double valueFromText( const QString & text ) const override; virtual double valueFromText( const QString & text ) const override;
virtual QValidator::State validate( QString & input, int & pos ) const override; virtual QValidator::State validate( QString & input, int & pos ) const override;


void paintEvent( QPaintEvent* e ) override;

protected: protected:
virtual void resizeEvent( QResizeEvent* event ) override; virtual void resizeEvent( QResizeEvent* event ) override;
virtual void changeEvent( QEvent* event ) override; virtual void changeEvent( QEvent* event ) override;
virtual void paintEvent( QPaintEvent* event ) override;


private slots: private slots:
void changed( double value ); void changed( double value );
Expand All @@ -92,6 +99,8 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
int frameWidth() const; int frameWidth() const;
bool shouldShowClearForValue( const double value ) const; bool shouldShowClearForValue( const double value ) const;


void updateStyleSheet( const QColor& backgroundColor = QColor() );

bool mShowClearButton; bool mShowClearButton;
ClearValueMode mClearValueMode; ClearValueMode mClearValueMode;
double mCustomClearValue; double mCustomClearValue;
Expand Down

0 comments on commit 9a62613

Please sign in to comment.