Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #5451 from wonder-sk/snap-indicators
Snap indicators improvements
  • Loading branch information
wonder-sk committed Oct 27, 2017
2 parents 8ef715b + b726ba2 commit 6476fef
Show file tree
Hide file tree
Showing 15 changed files with 299 additions and 99 deletions.
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -14,6 +14,7 @@
%Include qgsmapmouseevent.sip
%Include qgsmaptip.sip
%Include qgsrubberband.sip
%Include qgssnapindicator.sip
%Include qgstablewidgetitem.sip
%Include qgsuserinputdockwidget.sip
%Include qgsbrowserdockwidget.sip
Expand Down
65 changes: 65 additions & 0 deletions python/gui/qgssnapindicator.sip
@@ -0,0 +1,65 @@
/************************************************************************
* 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

private:
QgsSnapIndicator( const QgsSnapIndicator &rh );
QgsSnapIndicator &operator=( const QgsSnapIndicator & );
%Docstring
:rtype: QgsSnapIndicator
%End
};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgssnapindicator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
3 changes: 2 additions & 1 deletion python/gui/qgsvertexmarker.sip
Expand Up @@ -37,7 +37,8 @@ class QgsVertexMarker : QgsMapCanvasItem
ICON_CROSS,
ICON_X,
ICON_BOX,
ICON_CIRCLE
ICON_CIRCLE,
ICON_DOUBLE_TRIANGLE,
};

QgsVertexMarker( QgsMapCanvas *mapCanvas /TransferThis/ );
Expand Down
25 changes: 8 additions & 17 deletions src/app/nodetool/qgsnodetool.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -248,7 +245,6 @@ QgsNodeTool::QgsNodeTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget

QgsNodeTool::~QgsNodeTool()
{
delete mSnapMarker;
delete mEdgeCenterMarker;
delete mFeatureBand;
delete mFeatureBandMarkers;
Expand All @@ -263,6 +259,8 @@ void QgsNodeTool::deactivate()
removeTemporaryRubberBands();
cleanupNodeEditor();

mSnapIndicator->setMatch( QgsPointLocator::Match() );

QHash< QPair<QgsVectorLayer *, QgsFeatureId>, GeometryValidation>::iterator it = mValidations.begin();
for ( ; it != mValidations.end(); ++it )
it->cleanup();
Expand Down Expand Up @@ -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() );
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 )
Expand Down
3 changes: 2 additions & 1 deletion src/app/nodetool/qgsnodetool.h
Expand Up @@ -27,6 +27,7 @@ class QRubberBand;
class QgsGeometryValidator;
class QgsNodeEditor;
class QgsSelectedFeature;
class QgsSnapIndicator;
class QgsVertexMarker;

//! helper structure for a vertex being dragged
Expand Down Expand Up @@ -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<QgsSnapIndicator> mSnapIndicator;

/**
* marker in the middle of an edge while pointer is close to a vertex and not dragging anything
Expand Down
6 changes: 6 additions & 0 deletions src/app/qgsoptions.cpp
Expand Up @@ -950,6 +950,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
}
mSearchRadiusVertexEditComboBox->setCurrentIndex( index );

mSnappingMarkerColorButton->setColor( mSettings->value( QStringLiteral( "/qgis/digitizing/snap_color" ), QColor( Qt::magenta ) ).value<QColor>() );
mSnappingTooltipsCheckbox->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/snap_tooltip" ), false ).toBool() );

//vertex marker
mMarkersOnlyForSelectedCheckBox->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/marker_only_for_selected" ), true ).toBool() );

Expand Down Expand Up @@ -1468,6 +1471,9 @@ void QgsOptions::saveOptions()
mSettings->setValue( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit_unit" ),
( mSearchRadiusVertexEditComboBox->currentIndex() == 0 ? QgsTolerance::ProjectUnits : QgsTolerance::Pixels ) );

mSettings->setValue( QStringLiteral( "/qgis/digitizing/snap_color" ), mSnappingMarkerColorButton->color() );
mSettings->setValue( QStringLiteral( "/qgis/digitizing/snap_tooltip" ), mSnappingTooltipsCheckbox->isChecked() );

mSettings->setValue( QStringLiteral( "/qgis/digitizing/marker_only_for_selected" ), mMarkersOnlyForSelectedCheckBox->isChecked() );

QString markerComboText = mMarkerStyleComboBox->currentText();
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -334,6 +334,7 @@ SET(QGIS_GUI_SRCS
qgssearchquerybuilder.cpp
qgsshortcutsmanager.cpp
qgsslider.cpp
qgssnapindicator.cpp
qgssublayersdialog.cpp
qgssubstitutionlistwidget.cpp
qgssqlcomposerdialog.cpp
Expand Down Expand Up @@ -713,6 +714,7 @@ SET(QGIS_GUI_HDRS
qgsmapmouseevent.h
qgsmaptip.h
qgsrubberband.h
qgssnapindicator.h
qgssqlcomposerdialog.h
qgstablewidgetitem.h
qgsuserinputdockwidget.h
Expand Down
26 changes: 5 additions & 21 deletions src/gui/qgsmaptoolcapture.cpp
Expand Up @@ -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"
Expand All @@ -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 ) );

Expand All @@ -57,8 +60,6 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas *canvas, QgsAdvancedDigitizin

QgsMapToolCapture::~QgsMapToolCapture()
{
delete mSnappingMarker;

stopCapturing();

if ( mValidator )
Expand All @@ -81,8 +82,7 @@ void QgsMapToolCapture::deactivate()
if ( mTempRubberBand )
mTempRubberBand->hide();

delete mSnappingMarker;
mSnappingMarker = nullptr;
mSnapIndicator->setMatch( QgsPointLocator::Match() );

QgsMapToolAdvancedDigitizing::deactivate();
}
Expand Down Expand Up @@ -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 )
{
Expand Down
3 changes: 2 additions & 1 deletion src/gui/qgsmaptoolcapture.h
Expand Up @@ -26,6 +26,7 @@
#include "qgis_gui.h"

class QgsRubberBand;
class QgsSnapIndicator;
class QgsVertexMarker;
class QgsMapLayer;
class QgsGeometryValidator;
Expand Down Expand Up @@ -248,7 +249,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing

bool mCaptureModeFromLayer;

QgsVertexMarker *mSnappingMarker = nullptr;
std::unique_ptr<QgsSnapIndicator> mSnapIndicator;

/**
* Keeps point (in map units) snapped to a segment where we most recently finished tracing,
Expand Down
92 changes: 92 additions & 0 deletions src/gui/qgssnapindicator.cpp
@@ -0,0 +1,92 @@
/***************************************************************************
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 "qgsmapcanvas.h"
#include "qgssettings.h"
#include "qgsvectorlayer.h"
#include "qgsvertexmarker.h"

#include <QToolTip>


QgsSnapIndicator::QgsSnapIndicator( QgsMapCanvas *canvas )
: mCanvas( canvas )
{
}

QgsSnapIndicator::~QgsSnapIndicator() = default;


void QgsSnapIndicator::setMatch( const QgsPointLocator::Match &match )
{
mMatch = match;

if ( !mMatch.isValid() )
{
mSnappingMarker.reset();
QToolTip::hideText();
}
else
{
if ( !mSnappingMarker )
{
mSnappingMarker.reset( new QgsVertexMarker( mCanvas ) );
mSnappingMarker->setPenWidth( 3 );
}

QgsSettings s;

QColor color = s.value( QStringLiteral( "/qgis/digitizing/snap_color" ), QColor( Qt::magenta ) ).value<QColor>();
mSnappingMarker->setColor( color );

int iconType;
if ( match.hasVertex() )
{
if ( match.layer() )
iconType = QgsVertexMarker::ICON_BOX; // vertex snap
else
iconType = QgsVertexMarker::ICON_X; // intersection snap
}
else // must be segment snap
{
iconType = QgsVertexMarker::ICON_DOUBLE_TRIANGLE;
}
mSnappingMarker->setIconType( iconType );

mSnappingMarker->setCenter( match.point() );

// tooltip
if ( s.value( QStringLiteral( "/qgis/digitizing/snap_tooltip" ), false ).toBool() )
{
QPoint ptCanvas = mSnappingMarker->toCanvasCoordinates( match.point() ).toPoint();
QPoint ptGlobal = mCanvas->mapToGlobal( ptCanvas );
QRect rect( ptCanvas.x(), ptCanvas.y(), 1, 1 ); // area where is the tooltip valid
QString layerName = match.layer() ? match.layer()->name() : QString();
QToolTip::showText( ptGlobal, layerName, mCanvas, rect );
}
}
}

void QgsSnapIndicator::setVisible( bool visible )
{
mSnappingMarker->setVisible( visible );
}

bool QgsSnapIndicator::isVisible() const
{
return mSnappingMarker->isVisible();
}

0 comments on commit 6476fef

Please sign in to comment.