diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip index 114d63a3960..e5721684163 100644 --- a/python/gui/gui_auto.sip +++ b/python/gui/gui_auto.sip @@ -188,6 +188,7 @@ %Include qgssearchquerybuilder.sip %Include qgsshortcutsmanager.sip %Include qgsslider.sip +%Include qgssnapindicator.sip %Include qgsstatusbar.sip %Include qgssublayersdialog.sip %Include qgssubstitutionlistwidget.sip diff --git a/python/gui/qgssnapindicator.sip b/python/gui/qgssnapindicator.sip new file mode 100644 index 00000000000..69e96887228 --- /dev/null +++ b/python/gui/qgssnapindicator.sip @@ -0,0 +1,59 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgssnapindicator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + +class QgsSnapIndicator +{ +%Docstring + Class that shows snapping marker on map canvas for the current snapping match. +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgssnapindicator.h" +%End + public: + QgsSnapIndicator( QgsMapCanvas *canvas ); +%Docstring +Constructs an indicator for the given map canvas +%End + ~QgsSnapIndicator(); + + void setMatch( const QgsPointLocator::Match &match ); +%Docstring +Sets snapping match that should be displayed in map canvas. Invalid match hides the indicator +%End + QgsPointLocator::Match match() const; +%Docstring +Returns currently displayed snapping match + :rtype: QgsPointLocator.Match +%End + + void setVisible( bool visible = true ); +%Docstring +Sets whether the snapping indicator is visible +%End + bool isVisible() const; +%Docstring +Returns whether the snapping indicator is visible + :rtype: bool +%End + +}; + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/qgssnapindicator.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/src/app/nodetool/qgsnodetool.cpp b/src/app/nodetool/qgsnodetool.cpp index fcd9110fb3a..2ad1b5c2e32 100644 --- a/src/app/nodetool/qgsnodetool.cpp +++ b/src/app/nodetool/qgsnodetool.cpp @@ -28,6 +28,7 @@ #include "qgsproject.h" #include "qgsrubberband.h" #include "qgssettings.h" +#include "qgssnapindicator.h" #include "qgssnappingutils.h" #include "qgsvectorlayer.h" #include "qgsvertexmarker.h" @@ -204,11 +205,7 @@ QgsNodeTool::QgsNodeTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget { setAdvancedDigitizingAllowed( false ); - mSnapMarker = new QgsVertexMarker( canvas ); - mSnapMarker->setIconType( QgsVertexMarker::ICON_CROSS ); - mSnapMarker->setColor( Qt::magenta ); - mSnapMarker->setPenWidth( 3 ); - mSnapMarker->setVisible( false ); + mSnapIndicator.reset( new QgsSnapIndicator( canvas ) ); mEdgeCenterMarker = new QgsVertexMarker( canvas ); mEdgeCenterMarker->setIconType( QgsVertexMarker::ICON_CROSS ); @@ -248,7 +245,6 @@ QgsNodeTool::QgsNodeTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget QgsNodeTool::~QgsNodeTool() { - delete mSnapMarker; delete mEdgeCenterMarker; delete mFeatureBand; delete mFeatureBandMarkers; @@ -263,6 +259,8 @@ void QgsNodeTool::deactivate() removeTemporaryRubberBands(); cleanupNodeEditor(); + mSnapIndicator->setMatch( QgsPointLocator::Match() ); + QHash< QPair, GeometryValidation>::iterator it = mValidations.begin(); for ( ; it != mValidations.end(); ++it ) it->cleanup(); @@ -508,16 +506,7 @@ void QgsNodeTool::cadCanvasMoveEvent( QgsMapMouseEvent *e ) void QgsNodeTool::mouseMoveDraggingVertex( QgsMapMouseEvent *e ) { - if ( e->mapPointMatch().isValid() ) - { - mSnapMarker->setCenter( e->mapPoint() ); - mSnapMarker->setVisible( true ); - } - else - { - mSnapMarker->setVisible( false ); - } - + mSnapIndicator->setMatch( e->mapPointMatch() ); mEdgeCenterMarker->setVisible( false ); moveDragBands( e->mapPoint() ); @@ -554,7 +543,7 @@ void QgsNodeTool::moveDragBands( const QgsPointXY &mapPoint ) void QgsNodeTool::mouseMoveDraggingEdge( QgsMapMouseEvent *e ) { - mSnapMarker->setVisible( false ); + mSnapIndicator->setMatch( QgsPointLocator::Match() ); mEdgeCenterMarker->setVisible( false ); QgsPointXY mapPoint = toMapCoordinates( e->pos() ); // do not use e.mapPoint() as it may be snapped @@ -1349,6 +1338,8 @@ void QgsNodeTool::stopDragging() clearDragBands(); setHighlightedNodesVisible( true ); // highlight can be shown again + + mSnapIndicator->setMatch( QgsPointLocator::Match() ); } QgsPointXY QgsNodeTool::matchToLayerPoint( const QgsVectorLayer *destLayer, const QgsPointXY &mapPoint, const QgsPointLocator::Match *match ) diff --git a/src/app/nodetool/qgsnodetool.h b/src/app/nodetool/qgsnodetool.h index 60d42fc7918..2e279daaa4e 100644 --- a/src/app/nodetool/qgsnodetool.h +++ b/src/app/nodetool/qgsnodetool.h @@ -27,6 +27,7 @@ class QRubberBand; class QgsGeometryValidator; class QgsNodeEditor; class QgsSelectedFeature; +class QgsSnapIndicator; class QgsVertexMarker; //! helper structure for a vertex being dragged @@ -202,7 +203,7 @@ class APP_EXPORT QgsNodeTool : public QgsMapToolAdvancedDigitizing // members used for temporary highlight of stuff //! marker of a snap match (if any) when dragging a vertex - QgsVertexMarker *mSnapMarker = nullptr; + std::unique_ptr mSnapIndicator; /** * marker in the middle of an edge while pointer is close to a vertex and not dragging anything diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index d390a64051d..38e028fda5c 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -333,6 +333,7 @@ SET(QGIS_GUI_SRCS qgssearchquerybuilder.cpp qgsshortcutsmanager.cpp qgsslider.cpp + qgssnapindicator.cpp qgssublayersdialog.cpp qgssubstitutionlistwidget.cpp qgssqlcomposerdialog.cpp @@ -710,6 +711,7 @@ SET(QGIS_GUI_HDRS qgsmapmouseevent.h qgsmaptip.h qgsrubberband.h + qgssnapindicator.h qgssqlcomposerdialog.h qgstablewidgetitem.h qgsuserinputdockwidget.h diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index cd9c040ba19..0307335f6c6 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -27,6 +27,7 @@ #include "qgsmapmouseevent.h" #include "qgspolygon.h" #include "qgsrubberband.h" +#include "qgssnapindicator.h" #include "qgsvectorlayer.h" #include "qgsvertexmarker.h" #include "qgssettings.h" @@ -48,6 +49,8 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas *canvas, QgsAdvancedDigitizin mCaptureModeFromLayer = mode == CaptureNone; mCapturing = false; + mSnapIndicator.reset( new QgsSnapIndicator( canvas ) ); + QPixmap mySelectQPixmap = QPixmap( ( const char ** ) capture_point_cursor ); setCursor( QCursor( mySelectQPixmap, 8, 8 ) ); @@ -57,8 +60,6 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas *canvas, QgsAdvancedDigitizin QgsMapToolCapture::~QgsMapToolCapture() { - delete mSnappingMarker; - stopCapturing(); if ( mValidator ) @@ -81,8 +82,7 @@ void QgsMapToolCapture::deactivate() if ( mTempRubberBand ) mTempRubberBand->hide(); - delete mSnappingMarker; - mSnappingMarker = nullptr; + mSnapIndicator->setMatch( QgsPointLocator::Match() ); QgsMapToolAdvancedDigitizing::deactivate(); } @@ -309,25 +309,9 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point ) void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent( e ); - bool snapped = e->isSnapped(); QgsPointXY point = e->mapPoint(); - if ( !snapped ) - { - delete mSnappingMarker; - mSnappingMarker = nullptr; - } - else - { - if ( !mSnappingMarker ) - { - mSnappingMarker = new QgsVertexMarker( mCanvas ); - mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS ); - mSnappingMarker->setColor( Qt::magenta ); - mSnappingMarker->setPenWidth( 3 ); - } - mSnappingMarker->setCenter( point ); - } + mSnapIndicator->setMatch( e->mapPointMatch() ); if ( !mTempRubberBand && mCaptureCurve.numPoints() > 0 ) { diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 2fd4287aabb..4daa7647699 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -26,6 +26,7 @@ #include "qgis_gui.h" class QgsRubberBand; +class QgsSnapIndicator; class QgsVertexMarker; class QgsMapLayer; class QgsGeometryValidator; @@ -248,7 +249,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing bool mCaptureModeFromLayer; - QgsVertexMarker *mSnappingMarker = nullptr; + std::unique_ptr mSnapIndicator; /** * Keeps point (in map units) snapped to a segment where we most recently finished tracing, diff --git a/src/gui/qgssnapindicator.cpp b/src/gui/qgssnapindicator.cpp new file mode 100644 index 00000000000..c512c54d429 --- /dev/null +++ b/src/gui/qgssnapindicator.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + qgssnapindicator.cpp + -------------------------------------- + Date : October 2017 + Copyright : (C) 2017 by Martin Dobias + Email : wonder dot sk at gmail 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 "qgssnapindicator.h" + +#include "qgsvertexmarker.h" + + +QgsSnapIndicator::QgsSnapIndicator( QgsMapCanvas *canvas ) + : mCanvas( canvas ) +{ +} + +QgsSnapIndicator::~QgsSnapIndicator() +{ +} + +void QgsSnapIndicator::setMatch( const QgsPointLocator::Match &match ) +{ + mMatch = match; + + if ( !mMatch.isValid() ) + { + mSnappingMarker.reset(); + } + else + { + if ( !mSnappingMarker ) + { + mSnappingMarker.reset( new QgsVertexMarker( mCanvas ) ); + mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS ); + mSnappingMarker->setColor( Qt::magenta ); + mSnappingMarker->setPenWidth( 3 ); + } + mSnappingMarker->setCenter( match.point() ); + } +} + +void QgsSnapIndicator::setVisible( bool visible ) +{ + mSnappingMarker->setVisible( visible ); +} + +bool QgsSnapIndicator::isVisible() const +{ + return mSnappingMarker->isVisible(); +} diff --git a/src/gui/qgssnapindicator.h b/src/gui/qgssnapindicator.h new file mode 100644 index 00000000000..6a6fc4ee1f1 --- /dev/null +++ b/src/gui/qgssnapindicator.h @@ -0,0 +1,55 @@ +/*************************************************************************** + qgssnapindicator.h + -------------------------------------- + Date : October 2017 + Copyright : (C) 2017 by Martin Dobias + Email : wonder dot sk at gmail 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 QGSSNAPINDICATOR_H +#define QGSSNAPINDICATOR_H + +#include "qgspointlocator.h" + +#include "qgis_gui.h" + +class QgsMapCanvas; +class QgsVertexMarker; + + +/** + * \ingroup gui + * Class that shows snapping marker on map canvas for the current snapping match. + * \since QGIS 3.0 + */ +class GUI_EXPORT QgsSnapIndicator +{ + public: + //! Constructs an indicator for the given map canvas + QgsSnapIndicator( QgsMapCanvas *canvas ); + ~QgsSnapIndicator(); + + //! Sets snapping match that should be displayed in map canvas. Invalid match hides the indicator + void setMatch( const QgsPointLocator::Match &match ); + //! Returns currently displayed snapping match + QgsPointLocator::Match match() const { return mMatch; } + + //! Sets whether the snapping indicator is visible + void setVisible( bool visible = true ); + //! Returns whether the snapping indicator is visible + bool isVisible() const; + + private: + QgsMapCanvas *mCanvas; + QgsPointLocator::Match mMatch; + std::unique_ptr mSnappingMarker; +}; + +#endif // QGSSNAPINDICATOR_H diff --git a/src/plugins/georeferencer/qgsmapcoordsdialog.h b/src/plugins/georeferencer/qgsmapcoordsdialog.h index 3df5731986e..0d6fdae5bb9 100644 --- a/src/plugins/georeferencer/qgsmapcoordsdialog.h +++ b/src/plugins/georeferencer/qgsmapcoordsdialog.h @@ -16,9 +16,9 @@ #include #include "qgsmaptoolemitpoint.h" +#include "qgssnapindicator.h" #include "qgssnappingutils.h" #include "qgspointxy.h" -#include "qgsvertexmarker.h" #include "qgsmapcanvas.h" #include "ui_qgsmapcoordsdialogbase.h" @@ -33,40 +33,22 @@ class QgsGeorefMapToolEmitPoint : public QgsMapTool explicit QgsGeorefMapToolEmitPoint( QgsMapCanvas *canvas ) : QgsMapTool( canvas ) { + mSnapIndicator.reset( new QgsSnapIndicator( canvas ) ); } virtual ~QgsGeorefMapToolEmitPoint() { - delete mSnappingMarker; - mSnappingMarker = nullptr; } void canvasMoveEvent( QgsMapMouseEvent *e ) override { - MappedPoint mapped = mapPoint( e ); - - if ( !mapped.snapped ) - { - delete mSnappingMarker; - mSnappingMarker = nullptr; - } - else - { - if ( !mSnappingMarker ) - { - mSnappingMarker = new QgsVertexMarker( mCanvas ); - mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS ); - mSnappingMarker->setColor( Qt::magenta ); - mSnappingMarker->setPenWidth( 3 ); - } - mSnappingMarker->setCenter( mapped.point ); - } + mSnapIndicator->setMatch( mapPointMatch( e ) ); } void canvasPressEvent( QgsMapMouseEvent *e ) override { - MappedPoint mapped = mapPoint( e ); - emit canvasClicked( mapped.point, e->button() ); + QgsPointLocator::Match m = mapPointMatch( e ); + emit canvasClicked( m.isValid() ? m.point() : toMapCoordinates( e->pos() ), e->button() ); } void canvasReleaseEvent( QgsMapMouseEvent *e ) override @@ -77,8 +59,7 @@ class QgsGeorefMapToolEmitPoint : public QgsMapTool void deactivate() override { - delete mSnappingMarker; - mSnappingMarker = 0; + mSnapIndicator->setMatch( QgsPointLocator::Match() ); QgsMapTool::deactivate(); } @@ -88,26 +69,14 @@ class QgsGeorefMapToolEmitPoint : public QgsMapTool void mouseReleased(); private: - struct MappedPoint - { - MappedPoint() {} - QgsPointXY point; - bool snapped = false; - }; - MappedPoint mapPoint( QMouseEvent *e ) + QgsPointLocator::Match mapPointMatch( QMouseEvent *e ) { QgsPointXY pnt = toMapCoordinates( e->pos() ); - QgsSnappingUtils *snappingUtils = canvas()->snappingUtils(); - QgsPointLocator::Match match = snappingUtils->snapToMap( pnt ); - - MappedPoint ret; - ret.snapped = match.isValid(); - ret.point = ret.snapped ? match.point() : pnt; - return ret; + return canvas()->snappingUtils()->snapToMap( pnt ); } - QgsVertexMarker *mSnappingMarker = nullptr; + std::unique_ptr mSnapIndicator; }; class QgsMapCoordsDialog : public QDialog, private Ui::QgsMapCoordsDialogBase