Skip to content
Permalink
Browse files

Snapping api work

  • Loading branch information
nyalldawson committed Mar 10, 2020
1 parent a386ca0 commit e3f1c576a9a89a49e31508df1a585d5f4815fadc
@@ -60,6 +60,11 @@ Ownership of ``model`` is transferred to the dialog.
void loadModel( const QString &path );
%Docstring
Loads a model into the designer from the specified file ``path``.
%End

void setModelScene( QgsModelGraphicsScene *scene /Transfer/ );
%Docstring
Sets the related ``scene``.
%End

protected:
@@ -32,6 +32,7 @@ QGraphicsScene subclass representing the model designer.
ArrowLink,
ModelComponent,
RubberBand,
ZSnapIndicator,
};

enum Flag
@@ -54,6 +54,11 @@ Constructor for QgsModelGraphicsView, with the specified ``parent`` widget.
virtual void keyReleaseEvent( QKeyEvent *event );


void setModelScene( QgsModelGraphicsScene *scene );
%Docstring
Sets the related ``scene``.
%End

QgsModelGraphicsScene *modelScene() const;
%Docstring
Returns the scene associated with the tool.
@@ -64,6 +69,7 @@ Returns the scene associated with the tool.




signals:

void algorithmDropped( const QString &algorithmId, const QPointF &pos );
@@ -92,6 +98,26 @@ but is still in a perfectly valid state.
};


class QgsModelViewSnapMarker : QGraphicsRectItem
{
%Docstring
A simple graphics item rendered as an 'x'.
%End

%TypeHeaderCode
#include "qgsmodelgraphicsview.h"
%End
public:

QgsModelViewSnapMarker();

virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0 );


};



/************************************************************************
* This file has been generated automatically from *
* *
@@ -85,13 +85,10 @@ def __init__(self, model=None, parent=None):
self.toolbar().setIconSize(iface.iconSize())
self.setStyleSheet(iface.mainWindow().styleSheet())

self.scene = ModelerScene(self)
self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
self.scene.rebuildRequired.connect(self.repaintModel)
self.scene.componentAboutToChange.connect(self.componentAboutToChange)
self.scene.componentChanged.connect(self.componentChanged)
scene = ModelerScene(self)
scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
self.setModelScene(scene)

self.view().setScene(self.scene)
self.view().ensureVisible(0, 0, 10, 10)
self.view().scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96)

@@ -194,24 +191,20 @@ def openModel(self):
self.loadModel(filename)

def repaintModel(self, showControls=True):
self.scene = ModelerScene(self)
self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE,
self.CANVAS_SIZE))
scene = ModelerScene(self)
scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE,
self.CANVAS_SIZE))

if not showControls:
self.scene.setFlag(QgsModelGraphicsScene.FlagHideControls)
scene.setFlag(QgsModelGraphicsScene.FlagHideControls)

showComments = QgsSettings().value("/Processing/Modeler/ShowComments", True, bool)
if not showComments:
self.scene.setFlag(QgsModelGraphicsScene.FlagHideComments)

context = createContext()
self.scene.createItems(self.model(), context)
self.view().setScene(self.scene)

self.scene.rebuildRequired.connect(self.repaintModel)
self.scene.componentAboutToChange.connect(self.componentAboutToChange)
self.scene.componentChanged.connect(self.componentChanged)
scene.createItems(self.model(), context)
self.setModelScene(scene)

def componentAboutToChange(self, description, id):
self.beginUndoCommand(description, id)
@@ -282,6 +282,7 @@ SET(QGIS_GUI_SRCS
processing/models/qgsmodelgraphicitem.cpp
processing/models/qgsmodelgraphicsscene.cpp
processing/models/qgsmodelgraphicsview.cpp
processing/models/qgsmodelsnapper.cpp
processing/models/qgsmodelundocommand.cpp
processing/models/qgsmodelviewmouseevent.cpp
processing/models/qgsmodelviewrubberband.cpp
@@ -951,6 +952,7 @@ SET(QGIS_GUI_HDRS
processing/models/qgsmodelgraphicitem.h
processing/models/qgsmodelgraphicsscene.h
processing/models/qgsmodelgraphicsview.h
processing/models/qgsmodelsnapper.h
processing/models/qgsmodelundocommand.h
processing/models/qgsmodelviewmouseevent.h
processing/models/qgsmodelviewrubberband.h
@@ -25,6 +25,7 @@
#include "qgsprocessingparametertype.h"
#include "qgsmodelundocommand.h"
#include "qgsmodelviewtoolselect.h"
#include "qgsmodelgraphicsscene.h"

#include <QShortcut>
#include <QDesktopWidget>
@@ -311,6 +312,22 @@ void QgsModelDesignerDialog::loadModel( const QString &path )
}
}

void QgsModelDesignerDialog::setModelScene( QgsModelGraphicsScene *scene )
{
QgsModelGraphicsScene *oldScene = mScene;

mScene = scene;
mScene->setParent( this );

mView->setModelScene( mScene );

connect( mScene, &QgsModelGraphicsScene::rebuildRequired, this, [ = ] { repaintModel(); } );
connect( mScene, &QgsModelGraphicsScene::componentChanged, this, [ = ] { setDirty(); } );

if ( oldScene )
oldScene->deleteLater();
}

void QgsModelDesignerDialog::updateVariablesGui()
{
mBlockUndoCommands++;
@@ -85,6 +85,11 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
*/
void loadModel( const QString &path );

/**
* Sets the related \a scene.
*/
void setModelScene( QgsModelGraphicsScene *scene SIP_TRANSFER );

protected:

virtual void repaintModel( bool showControls = true ) = 0;
@@ -139,6 +144,7 @@ class GUI_EXPORT QgsModelDesignerDialog : public QMainWindow, public Ui::QgsMode
QgsMessageBar *mMessageBar = nullptr;
QgsModelerToolboxModel *mAlgorithmsModel = nullptr;
QgsModelViewToolSelect *mSelectTool = nullptr;
QgsModelGraphicsScene *mScene = nullptr;

bool mHasChanged = false;
QUndoStack *mUndoStack = nullptr;
@@ -49,6 +49,7 @@ class GUI_EXPORT QgsModelGraphicsScene : public QGraphicsScene
ArrowLink = 0, //!< An arrow linking model items
ModelComponent = 1, //!< Model components (e.g. algorithms, inputs and outputs)
RubberBand = 100, //!< Rubber band item
ZSnapIndicator = 101, //!< Z-value for snapping indicator
};

//! Flags for controlling how the scene is rendered and scene behavior
@@ -43,6 +43,7 @@ QgsModelGraphicsView::QgsModelGraphicsView( QWidget *parent )
mMidMouseButtonPanTool = new QgsModelViewToolTemporaryMousePan( this );
mSpaceZoomTool = new QgsModelViewToolTemporaryKeyZoom( this );

mSnapper.setSnapToGrid( true );
}

QgsModelGraphicsView::~QgsModelGraphicsView()
@@ -261,11 +262,9 @@ void QgsModelGraphicsView::mouseMoveEvent( QMouseEvent *event )
if ( mTool )
{
std::unique_ptr<QgsModelViewMouseEvent> me( new QgsModelViewMouseEvent( this, event, false ) );
#if 0
if ( mTool->flags() & QgsModelViewTool::FlagSnaps )
{

me->snapPoint( mHorizontalSnapLine, mVerticalSnapLine, mTool->ignoredSnapItems() );
me->snapPoint();
}
if ( mTool->flags() & QgsModelViewTool::FlagSnaps )
{
@@ -284,7 +283,6 @@ void QgsModelGraphicsView::mouseMoveEvent( QMouseEvent *event )
mSnapMarker->setVisible( false );
}
}
#endif
mTool->modelMoveEvent( me.get() );
event->setAccepted( me->isAccepted() );
}
@@ -380,6 +378,17 @@ void QgsModelGraphicsView::keyReleaseEvent( QKeyEvent *event )
QGraphicsView::keyReleaseEvent( event );
}

void QgsModelGraphicsView::setModelScene( QgsModelGraphicsScene *scene )
{
setScene( scene );

// IMPORTANT!
// previous snap markers, snap lines are owned by previous layout - so don't delete them here!
mSnapMarker = new QgsModelViewSnapMarker();
mSnapMarker->hide();
scene->addItem( mSnapMarker );
}

QgsModelGraphicsScene *QgsModelGraphicsView::modelScene() const
{
return qobject_cast< QgsModelGraphicsScene * >( QgsModelGraphicsView::scene() );
@@ -419,6 +428,40 @@ void QgsModelGraphicsView::unsetTool( QgsModelViewTool *tool )
}
}

QgsModelSnapper *QgsModelGraphicsView::snapper()
{
return &mSnapper;
}


QgsModelViewSnapMarker::QgsModelViewSnapMarker()
: QGraphicsRectItem( QRectF( 0, 0, 0, 0 ) )
{
QFont f;
QFontMetrics fm( f );
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
mSize = fm.width( QStringLiteral( "X" ) );
#else
mSize = fm.horizontalAdvance( 'X' );
#endif
setPen( QPen( Qt::transparent, mSize ) );

setFlags( flags() | QGraphicsItem::ItemIgnoresTransformations );
setZValue( QgsModelGraphicsScene::ZSnapIndicator );
}

void QgsModelViewSnapMarker::paint( QPainter *p, const QStyleOptionGraphicsItem *, QWidget * )
{
QPen pen( QColor( 255, 0, 0 ) );
pen.setWidth( 0 );
p->setPen( pen );
p->setBrush( Qt::NoBrush );

double halfSize = mSize / 2.0;
p->drawLine( QLineF( -halfSize, -halfSize, halfSize, halfSize ) );
p->drawLine( QLineF( -halfSize, halfSize, halfSize, -halfSize ) );
}


///@endcond

@@ -19,14 +19,17 @@
#include "qgis.h"
#include "qgis_gui.h"
#include "qgsprocessingcontext.h"
#include "qgsmodelsnapper.h"
#include <QGraphicsView>
#include <QGraphicsRectItem>

class QgsModelViewTool;
class QgsModelViewToolTemporaryKeyPan;
class QgsModelViewToolTemporaryKeyZoom;
class QgsModelViewToolTemporaryMousePan;
class QgsModelComponentGraphicItem;
class QgsModelGraphicsScene;
class QgsModelViewSnapMarker;

///@cond NOT_STABLE

@@ -59,6 +62,11 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
void keyPressEvent( QKeyEvent *event ) override;
void keyReleaseEvent( QKeyEvent *event ) override;

/**
* Sets the related \a scene.
*/
void setModelScene( QgsModelGraphicsScene *scene );

/**
* Returns the scene associated with the tool.
* \see view()
@@ -87,6 +95,11 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView
*/
void unsetTool( QgsModelViewTool *tool ) SIP_SKIP;

/**
* Returns the view's coordinate snapper.
*/
QgsModelSnapper *snapper() SIP_SKIP;

signals:

/**
@@ -142,8 +155,30 @@ class GUI_EXPORT QgsModelGraphicsView : public QGraphicsView

QPoint mMouseCurrentXY;

QgsModelSnapper mSnapper;
QgsModelViewSnapMarker *mSnapMarker = nullptr;
};


/**
* \ingroup gui
* A simple graphics item rendered as an 'x'.
*/
class GUI_EXPORT QgsModelViewSnapMarker : public QGraphicsRectItem
{
public:

QgsModelViewSnapMarker();

void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr ) override;

private:

int mSize = 0;

};


///@endcond

#endif // QGSMODELGRAPHICVIEW_H

1 comment on commit e3f1c57

@telwertowski

This comment has been minimized.

Copy link
Contributor

@telwertowski telwertowski commented on e3f1c57 Mar 12, 2020

MacOS needs
#include <cmath>

~/qgis/QGIS/src/gui/processing/models/qgsmodelsnapper.cpp:120:27: error:
call to 'abs' is ambiguous
double currentDiffX = std::abs( xSnapped - point.x() );

~/qgis/QGIS/src/gui/processing/models/qgsmodelsnapper.cpp:127:27: error:
call to 'abs' is ambiguous
double currentDiffY = std::abs( ySnapped - point.y() );

Please sign in to comment.
You can’t perform that action at this time.