Skip to content

Commit

Permalink
various fixes to rotation map tool
Browse files Browse the repository at this point in the history
* do not go through the user input to do the rotation (avoid rounding in spin box, except when magnet is on)
* allow to escape the tool by pressing ESC even when user input lost focus
  • Loading branch information
3nids committed Feb 13, 2018
1 parent 77f864b commit 231dae3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 31 deletions.
72 changes: 46 additions & 26 deletions src/app/qgsmaptoolrotatefeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@
* *
***************************************************************************/

#include <QMouseEvent>
#include <QSettings>
#include <QEvent>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLabel>

#include <limits>
#include <cmath>

#include "qgsmaptoolrotatefeature.h"
#include "qgsfeatureiterator.h"
#include "qgsgeometry.h"
Expand All @@ -21,20 +31,10 @@
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgstolerance.h"
#include "qgsvertexmarker.h"
#include "qgisapp.h"
#include "qgsspinbox.h"
#include "qgsdoublespinbox.h"

#include <QMouseEvent>
#include <QSettings>
#include <QEvent>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QLabel>

#include <limits>
#include <cmath>

QgsAngleMagnetWidget::QgsAngleMagnetWidget( const QString &label, QWidget *parent )
: QWidget( parent )
Expand Down Expand Up @@ -69,7 +69,8 @@ QgsAngleMagnetWidget::QgsAngleMagnetWidget( const QString &label, QWidget *paren
mMagnetSpinBox->setSingleStep( 15 );
mMagnetSpinBox->setValue( 0 );
mMagnetSpinBox->setClearValue( 0, tr( "No snapping" ) );
mMagnetSpinBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
//mMagnetSpinBox->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
mMagnetSpinBox->setMinimumWidth( 120 );
mLayout->addWidget( mMagnetSpinBox );

// connect signals
Expand All @@ -82,18 +83,18 @@ QgsAngleMagnetWidget::QgsAngleMagnetWidget( const QString &label, QWidget *paren

void QgsAngleMagnetWidget::setAngle( double angle )
{
const int magnet = mMagnetSpinBox->value();
if ( magnet )
const int m = magnet();
if ( m )
{
mAngleSpinBox->setValue( std::round( angle / magnet ) * magnet );
mAngleSpinBox->setValue( std::round( angle / m ) * m );
}
else
{
mAngleSpinBox->setValue( angle );
}
}

double QgsAngleMagnetWidget::angle()
double QgsAngleMagnetWidget::angle() const
{
return mAngleSpinBox->value();
}
Expand All @@ -103,6 +104,11 @@ void QgsAngleMagnetWidget::setMagnet( int magnet )
mMagnetSpinBox->setValue( magnet );
}

int QgsAngleMagnetWidget::magnet() const
{
return mMagnetSpinBox->value();
}


bool QgsAngleMagnetWidget::eventFilter( QObject *obj, QEvent *ev )
{
Expand Down Expand Up @@ -140,7 +146,7 @@ QgsMapToolRotateFeature::QgsMapToolRotateFeature( QgsMapCanvas *canvas )
QgsMapToolRotateFeature::~QgsMapToolRotateFeature()
{
deleteRotationWidget();
delete mAnchorPoint;
mAnchorPoint.reset();
deleteRubberband();
}

Expand All @@ -150,17 +156,21 @@ void QgsMapToolRotateFeature::canvasMoveEvent( QgsMapMouseEvent *e )
{
const double XDistance = e->pos().x() - mStPoint.x();
const double YDistance = e->pos().y() - mStPoint.y();
double rotation = std::atan2( YDistance, XDistance ) * ( 180 / M_PI );
double rotation = std::atan2( YDistance, XDistance ) * ( 180 / M_PI ) - mRotationOffset;

if ( mRotationWidget )
{
mRotationWidget->setAngle( rotation - mRotationOffset );
disconnect( mRotationWidget, &QgsAngleMagnetWidget::angleChanged, this, &QgsMapToolRotateFeature::updateRubberband );
mRotationWidget->setAngle( rotation );
mRotationWidget->setFocus( Qt::TabFocusReason );
mRotationWidget->editor()->selectAll();
connect( mRotationWidget, &QgsAngleMagnetWidget::angleChanged, this, &QgsMapToolRotateFeature::updateRubberband );
if ( mRotationWidget->magnet() )
{
rotation = mRotationWidget->angle();
}
}
else
{
updateRubberband( rotation - mRotationOffset );
}
updateRubberband( rotation );
}
}

Expand Down Expand Up @@ -262,7 +272,7 @@ void QgsMapToolRotateFeature::canvasReleaseEvent( QgsMapMouseEvent *e )

if ( !mAnchorPoint )
{
mAnchorPoint = new QgsVertexMarker( mCanvas );
mAnchorPoint = qgis::make_unique<QgsVertexMarker>( mCanvas );
}
mAnchorPoint->setIconType( QgsVertexMarker::ICON_CROSS );
mAnchorPoint->setCenter( mStartPointMapCoords );
Expand Down Expand Up @@ -318,6 +328,7 @@ void QgsMapToolRotateFeature::cancel()
{
deleteRotationWidget();
deleteRubberband();
mAnchorPoint.reset();
mRotationActive = false;
}

Expand Down Expand Up @@ -408,6 +419,16 @@ void QgsMapToolRotateFeature::applyRotation( double rotation )
vlayer->triggerRepaint();
}

void QgsMapToolRotateFeature::keyReleaseEvent( QKeyEvent *e )
{
if ( mRotationActive && e->key() == Qt::Key_Escape )
{
cancel();
return;
}
QgsMapTool::keyReleaseEvent( e );
}

void QgsMapToolRotateFeature::activate()
{
QgsVectorLayer *vlayer = currentVectorLayer();
Expand All @@ -426,7 +447,7 @@ void QgsMapToolRotateFeature::activate()
QgsRectangle bound = vlayer->boundingBoxOfSelected();
mStartPointMapCoords = toMapCoordinates( vlayer, bound.center() );

mAnchorPoint = new QgsVertexMarker( mCanvas );
mAnchorPoint = qgis::make_unique<QgsVertexMarker>( mCanvas );
mAnchorPoint->setIconType( QgsVertexMarker::ICON_CROSS );
mAnchorPoint->setCenter( mStartPointMapCoords );

Expand All @@ -445,8 +466,7 @@ void QgsMapToolRotateFeature::deactivate()
{
deleteRotationWidget();
mRotationActive = false;
delete mAnchorPoint;
mAnchorPoint = nullptr;
mAnchorPoint.reset();
mRotationOffset = 0;
deleteRubberband();
QgsMapTool::deactivate();
Expand Down
14 changes: 9 additions & 5 deletions src/app/qgsmaptoolrotatefeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
#include <QWidget>

#include "qgsmaptooledit.h"
#include "qgsvertexmarker.h"
#include "qgis_app.h"

class QgsDoubleSpinBox;
class QHBoxLayout;
class QgsSpinBox;
class QgsVertexMarker;

class APP_EXPORT QgsAngleMagnetWidget : public QWidget
{
Expand All @@ -35,10 +35,11 @@ class APP_EXPORT QgsAngleMagnetWidget : public QWidget
explicit QgsAngleMagnetWidget( const QString &label = QString(), QWidget *parent = nullptr );

void setAngle( double angle );

double angle();

double angle() const;
void setMagnet( int magnet );
int magnet() const;

QgsDoubleSpinBox *editor() const {return mAngleSpinBox;}

signals:
void angleChanged( double angle );
Expand Down Expand Up @@ -78,6 +79,9 @@ class APP_EXPORT QgsMapToolRotateFeature: public QgsMapToolEdit

void activate() override;

//! catch escape when active to cancel selection
void keyReleaseEvent( QKeyEvent *e ) override;

private slots:
void updateRubberband( double rotation );

Expand Down Expand Up @@ -105,7 +109,7 @@ class APP_EXPORT QgsMapToolRotateFeature: public QgsMapToolEdit
double mRotationOffset;

QPoint mStPoint;
QgsVertexMarker *mAnchorPoint = nullptr;
std::unique_ptr<QgsVertexMarker> mAnchorPoint = nullptr;

bool mRotationActive;

Expand Down

0 comments on commit 231dae3

Please sign in to comment.