Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE][processing] Add option to enable automatic snapping to grid
while designer models

If enabled, model component moving or resizing will be automatically
snapped to a grid
  • Loading branch information
nyalldawson committed Mar 23, 2020
1 parent 78d445e commit 4bad254
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 11 deletions.
11 changes: 10 additions & 1 deletion src/gui/processing/models/qgsmodeldesignerdialog.cpp
Expand Up @@ -118,6 +118,7 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags
mainLayout->insertWidget( 0, mMessageBar );

mView->setAcceptDrops( true );
QgsSettings settings;

connect( mActionClose, &QAction::triggered, this, &QWidget::close );
connect( mActionZoomIn, &QAction::triggered, this, &QgsModelDesignerDialog::zoomIn );
Expand All @@ -132,6 +133,14 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags
connect( mActionSaveAs, &QAction::triggered, this, [ = ] { saveModel( true ); } );
connect( mActionDeleteComponents, &QAction::triggered, this, &QgsModelDesignerDialog::deleteSelected );

mActionSnappingEnabled->setChecked( settings.value( QStringLiteral( "/Processing/modelDesignerEnableSnap" ), true ).toBool() );
connect( mActionSnappingEnabled, &QAction::toggled, this, [ = ]( bool enabled )
{
mView->snapper()->setSnapToGrid( enabled );
QgsSettings().setValue( QStringLiteral( "/Processing/modelDesignerEnableSnap" ), enabled );
} );
mView->snapper()->setSnapToGrid( mActionSnappingEnabled->isChecked() );

mUndoAction = mUndoStack->createUndoAction( this );
mUndoAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
mUndoAction->setShortcuts( QKeySequence::Undo );
Expand All @@ -146,7 +155,7 @@ QgsModelDesignerDialog::QgsModelDesignerDialog( QWidget *parent, Qt::WindowFlags
mToolbar->insertAction( mActionZoomIn, mRedoAction );
mToolbar->insertSeparator( mActionZoomIn );

QgsSettings settings;

QgsProcessingToolboxProxyModel::Filters filters = QgsProcessingToolboxProxyModel::FilterModeler;
if ( settings.value( QStringLiteral( "Processing/Configuration/SHOW_ALGORITHMS_KNOWN_ISSUES" ), false ).toBool() )
{
Expand Down
16 changes: 8 additions & 8 deletions src/gui/processing/models/qgsmodelsnapper.cpp
Expand Up @@ -21,7 +21,7 @@
QgsModelSnapper::QgsModelSnapper()
{
QgsSettings s;
mTolerance = s.value( QStringLiteral( "LayoutDesigner/defaultSnapTolerancePixels" ), 5, QgsSettings::Gui ).toInt();
mTolerance = s.value( QStringLiteral( "/Processing/modelDesignerSnapTolerancePixels" ), 20 ).toInt();
}

void QgsModelSnapper::setSnapTolerance( const int snapTolerance )
Expand All @@ -34,19 +34,19 @@ void QgsModelSnapper::setSnapToGrid( bool enabled )
mSnapToGrid = enabled;
}

QPointF QgsModelSnapper::snapPoint( QPointF point, double scaleFactor, bool &snapped ) const
QPointF QgsModelSnapper::snapPoint( QPointF point, double scaleFactor, bool &snapped, bool snapHorizontal, bool snapVertical ) const
{
snapped = false;

bool snappedXToGrid = false;
bool snappedYToGrid = false;
QPointF res = snapPointToGrid( point, scaleFactor, snappedXToGrid, snappedYToGrid );
if ( snappedXToGrid )
if ( snappedXToGrid && snapVertical )
{
snapped = true;
point.setX( res.x() );
}
if ( snappedYToGrid )
if ( snappedYToGrid && snapHorizontal )
{
snapped = true;
point.setY( res.y() );
Expand All @@ -55,7 +55,7 @@ QPointF QgsModelSnapper::snapPoint( QPointF point, double scaleFactor, bool &sna
return point;
}

QRectF QgsModelSnapper::snapRect( const QRectF &rect, double scaleFactor, bool &snapped ) const
QRectF QgsModelSnapper::snapRect( const QRectF &rect, double scaleFactor, bool &snapped, bool snapHorizontal, bool snapVertical ) const
{
snapped = false;
QRectF snappedRect = rect;
Expand All @@ -70,12 +70,12 @@ QRectF QgsModelSnapper::snapRect( const QRectF &rect, double scaleFactor, bool &
QList< QPointF > points;
points << rect.topLeft() << rect.topRight() << rect.bottomLeft() << rect.bottomRight();
QPointF res = snapPointsToGrid( points, scaleFactor, snappedXToGrid, snappedYToGrid );
if ( snappedXToGrid )
if ( snappedXToGrid && snapVertical )
{
snapped = true;
snappedRect.translate( res.x(), 0 );
}
if ( snappedYToGrid )
if ( snappedYToGrid && snapHorizontal )
{
snapped = true;
snappedRect.translate( 0, res.y() );
Expand Down Expand Up @@ -111,7 +111,7 @@ QPointF QgsModelSnapper::snapPointsToGrid( const QList<QPointF> &points, double
for ( QPointF point : points )
{
//snap x coordinate
double gridRes = 10; //mLayout->convertToLayoutUnits( grid.resolution() );
double gridRes = 30; //mLayout->convertToLayoutUnits( grid.resolution() );
int xRatio = static_cast< int >( ( point.x() ) / gridRes + 0.5 ); //NOLINT
int yRatio = static_cast< int >( ( point.y() ) / gridRes + 0.5 ); //NOLINT

Expand Down
4 changes: 2 additions & 2 deletions src/gui/processing/models/qgsmodelsnapper.h
Expand Up @@ -80,7 +80,7 @@ class GUI_EXPORT QgsModelSnapper
* \see snapRect()
*/
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped SIP_OUT ) const;
QPointF snapPoint( QPointF point, double scaleFactor, bool &snapped SIP_OUT, bool snapHorizontal = true, bool snapVertical = true ) const;

/**
* Snaps a layout coordinate \a rect. If \a rect was snapped, \a snapped will be set to TRUE.
Expand All @@ -101,7 +101,7 @@ class GUI_EXPORT QgsModelSnapper
*
* \see snapPoint()
*/
QRectF snapRect( const QRectF &rect, double scaleFactor, bool &snapped SIP_OUT ) const;
QRectF snapRect( const QRectF &rect, double scaleFactor, bool &snapped SIP_OUT, bool snapHorizontal = true, bool snapVertical = true ) const;

/**
* Snaps a layout coordinate \a point to the grid. If \a point
Expand Down
19 changes: 19 additions & 0 deletions src/gui/processing/models/qgsmodelviewmousehandles.cpp
Expand Up @@ -160,5 +160,24 @@ void QgsModelViewMouseHandles::endMacroCommand()
mView->endMacroCommand();
}

QPointF QgsModelViewMouseHandles::snapPoint( QPointF originalPoint, QgsGraphicsViewMouseHandles::SnapGuideMode mode, bool snapHorizontal, bool snapVertical )
{
bool snapped = false;

//depending on the mode, we either snap just the single point, or all the bounds of the selection
QPointF snappedPoint;
switch ( mode )
{
case Item:
snappedPoint = mView->snapper()->snapRect( rect().translated( originalPoint ), mView->transform().m11(), snapped, snapHorizontal, snapVertical ).topLeft();
break;
case Point:
snappedPoint = mView->snapper()->snapPoint( originalPoint, mView->transform().m11(), snapped, snapHorizontal, snapVertical );
break;
}

return snapped ? snappedPoint : originalPoint;
}


///@endcond PRIVATE
1 change: 1 addition & 0 deletions src/gui/processing/models/qgsmodelviewmousehandles.h
Expand Up @@ -65,6 +65,7 @@ class GUI_EXPORT QgsModelViewMouseHandles: public QgsGraphicsViewMouseHandles
QRectF previewSetItemRect( QGraphicsItem *item, QRectF rect ) override;
void startMacroCommand( const QString &text ) override;
void endMacroCommand() override;
QPointF snapPoint( QPointF originalPoint, SnapGuideMode mode, bool snapHorizontal = true, bool snapVertical = true ) override;

public slots:

Expand Down
10 changes: 10 additions & 0 deletions src/ui/processing/qgsmodeldesignerdialogbase.ui
Expand Up @@ -80,6 +80,8 @@
<addaction name="mActionZoomToItems"/>
<addaction name="separator"/>
<addaction name="mActionShowComments"/>
<addaction name="separator"/>
<addaction name="mActionSnappingEnabled"/>
</widget>
<widget class="QMenu" name="mMenuEdit">
<property name="title">
Expand Down Expand Up @@ -610,6 +612,14 @@
<string>Del</string>
</property>
</action>
<action name="mActionSnappingEnabled">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable Snapping</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
Expand Down

0 comments on commit 4bad254

Please sign in to comment.