Skip to content

Commit

Permalink
Add tools to create node based items
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 7, 2017
1 parent 6b629e1 commit 44fe2a8
Show file tree
Hide file tree
Showing 19 changed files with 537 additions and 43 deletions.
2 changes: 1 addition & 1 deletion python/core/layout/qgslayout.sip
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
ZGuide,
ZSmartGuide,
ZMouseHandles,
ZMapTool,
ZViewTool,
ZSnapIndicator,
};

Expand Down
19 changes: 13 additions & 6 deletions python/core/layout/qgslayoutitemnodeitem.sip
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ class QgsLayoutNodesItem: QgsLayoutItem
%End
public:

void setNodes( const QPolygonF &nodes );
%Docstring
Sets the ``nodes`` the shape consists of.
.. seealso:: nodes()
%End

QPolygonF nodes() const;
%Docstring
Returns the nodes the shape consists of.
.. seealso:: setNodes()
:rtype: QPolygonF
%End

bool addNode( QPointF point, bool checkArea = true, double radius = 10 );
%Docstring
Add a node in current shape.
Expand Down Expand Up @@ -95,12 +108,6 @@ Returns the number of nodes in the shape.
Deselects any selected nodes.
%End

QPolygonF nodes() const;
%Docstring
Returns the nodes the shape consists of.
:rtype: QPolygonF
%End

protected:

QgsLayoutNodesItem( QgsLayout *layout );
Expand Down
1 change: 1 addition & 0 deletions python/gui/gui_auto.sip
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@
%Include layout/qgslayoutview.sip
%Include layout/qgslayoutviewtool.sip
%Include layout/qgslayoutviewtooladditem.sip
%Include layout/qgslayoutviewtooladdnodeitem.sip
%Include layout/qgslayoutviewtoolpan.sip
%Include layout/qgslayoutviewtoolselect.sip
%Include layout/qgslayoutviewtooltemporarykeypan.sip
Expand Down
21 changes: 20 additions & 1 deletion python/gui/layout/qgslayoutitemguiregistry.sip
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ class QgsLayoutItemAbstractGuiMetadata
typedef QFlags<QgsLayoutItemAbstractGuiMetadata::Flag> Flags;


QgsLayoutItemAbstractGuiMetadata( int type, const QString &visibleName, const QString &groupId = QString(), Flags flags = 0 );
QgsLayoutItemAbstractGuiMetadata( int type, const QString &visibleName, const QString &groupId = QString(), bool isNodeBased = false, Flags flags = 0 );
%Docstring
Constructor for QgsLayoutItemAbstractGuiMetadata with the specified class ``type``.

``visibleName`` should be set to a translated, user visible name identifying the corresponding layout item.

An optional ``groupId`` can be set, which allows grouping of related layout item classes. See QgsLayoutItemGuiMetadata for details.

If ``isNodeBased`` is true, then the corresponding item is a node based item.
%End

virtual ~QgsLayoutItemAbstractGuiMetadata();
Expand All @@ -64,6 +66,12 @@ class QgsLayoutItemAbstractGuiMetadata
:rtype: str
%End

bool isNodeBased() const;
%Docstring
Returns true if the associated item is a node based item.
:rtype: bool
%End

QString visibleName() const;
%Docstring
Returns a translated, user visible name identifying the corresponding layout item.
Expand All @@ -86,9 +94,18 @@ class QgsLayoutItemAbstractGuiMetadata
%Docstring
Creates a rubber band for use when creating layout items of this type. Can return None if no rubber band
should be created. The default behavior is to create a rectangular rubber band.
.. seealso:: createNodeRubberBand()
:rtype: QgsLayoutViewRubberBand
%End

virtual QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) /Factory/;
%Docstring
Creates a rubber band for use when creating layout node based items of this type. Can return None if no rubber band
should be created. The default behavior is to return None.
.. seealso:: createRubberBand()
:rtype: QAbstractGraphicsShapeItem
%End

virtual QgsLayoutItem *createItem( QgsLayout *layout ) /Factory/;
%Docstring
Creates an instance of the corresponding item type.
Expand All @@ -100,6 +117,7 @@ class QgsLayoutItemAbstractGuiMetadata




class QgsLayoutItemGuiGroup
{
%Docstring
Expand Down Expand Up @@ -219,6 +237,7 @@ class QgsLayoutItemGuiRegistry : QObject
%End



QList< int > itemMetadataIds() const;
%Docstring
Returns a list of available item metadata ids handled by the registry.
Expand Down
66 changes: 66 additions & 0 deletions python/gui/layout/qgslayoutviewtooladdnodeitem.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutviewtooladdnodeitem.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsLayoutViewToolAddNodeItem : QgsLayoutViewTool
{
%Docstring
Layout view tool for adding node based items to a layout.
.. versionadded:: 3.0
%End

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

QgsLayoutViewToolAddNodeItem( QgsLayoutView *view /TransferThis/ );

int itemMetadataId() const;
%Docstring
Returns the item metadata id for items created by the tool.
.. seealso:: setItemMetadataId()
:rtype: int
%End

void setItemMetadataId( int metadataId );
%Docstring
Sets the item metadata ``metadataId`` for items created by the tool.

The ``metadataId`` associates the current tool behavior with a metadata entry
from QgsLayoutItemGuiRegistry.

.. seealso:: itemMetadataId()
%End

virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event );

virtual void layoutMoveEvent( QgsLayoutViewMouseEvent *event );

virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event );

virtual void deactivate();


signals:

void createdItem();
%Docstring
Emitted when an item has been created using the tool.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutviewtooladdnodeitem.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
40 changes: 31 additions & 9 deletions src/app/layout/qgslayoutapputils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "qgslayoutapputils.h"
#include "qgsgui.h"
#include "qgslayout.h"
#include "qgslayoutitemguiregistry.h"
#include "qgslayoutitemregistry.h"
#include "qgslayoutviewrubberband.h"
Expand Down Expand Up @@ -59,35 +60,56 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes()
return new QgsLayoutShapeWidget( qobject_cast< QgsLayoutItemShape * >( item ) );
};

registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Rectangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicRectangle.svg" ) ), createShapeWidget, createRubberBand, QStringLiteral( "shapes" ), false, 0, []( QgsLayout * layout )->QgsLayoutItem*
{
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
shape->setShapeType( QgsLayoutItemShape::Rectangle );
return shape.release();
} ) );
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Ellipse" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicCircle.svg" ) ), createShapeWidget, createEllipseBand, QStringLiteral( "shapes" ), false, 0, []( QgsLayout * layout )->QgsLayoutItem*
{
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
shape->setShapeType( QgsLayoutItemShape::Ellipse );
return shape.release();
} ) );
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), 0, []( QgsLayout * layout )->QgsLayoutItem*
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutShape, QObject::tr( "Triangle" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddBasicTriangle.svg" ) ), createShapeWidget, createTriangleBand, QStringLiteral( "shapes" ), false, 0, []( QgsLayout * layout )->QgsLayoutItem*
{
std::unique_ptr< QgsLayoutItemShape > shape = qgis::make_unique< QgsLayoutItemShape >( layout );
shape->setShapeType( QgsLayoutItemShape::Triangle );
return shape.release();
} ) );

registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
[ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *

std::unique_ptr< QgsLayoutItemGuiMetadata > polygonMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >(
QgsLayoutItemRegistry::LayoutPolygon, QObject::tr( "Polygon" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolygon.svg" ) ),
[ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
{
return nullptr;
//return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ) );
}, createRubberBand, QStringLiteral( "nodes" ) ) );
registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
[ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
}, createRubberBand, QStringLiteral( "nodes" ), true );
polygonMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPolygonItem*
{
std::unique_ptr< QGraphicsPolygonItem > band = qgis::make_unique< QGraphicsPolygonItem >();
band->setBrush( Qt::NoBrush );
band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
band->setZValue( QgsLayout::ZViewTool );
return band.release();
} );
registry->addLayoutItemGuiMetadata( polygonMetadata.release() );

std::unique_ptr< QgsLayoutItemGuiMetadata > polylineMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata>(
QgsLayoutItemRegistry::LayoutPolyline, QObject::tr( "Polyline" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddPolyline.svg" ) ),
[ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget *
{
return nullptr;
//return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ) );
}, createRubberBand, QStringLiteral( "nodes" ) ) );
}, createRubberBand, QStringLiteral( "nodes" ), true );
polylineMetadata->setNodeRubberBandCreationFunction( []( QgsLayoutView * )->QGraphicsPathItem*
{
std::unique_ptr< QGraphicsPathItem > band = qgis::make_unique< QGraphicsPathItem >();
band->setPen( QPen( QBrush( QColor( 227, 22, 22, 200 ) ), 0 ) );
band->setZValue( QgsLayout::ZViewTool );
return band.release();
} );
registry->addLayoutItemGuiMetadata( polylineMetadata.release() );
}
25 changes: 18 additions & 7 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "qgslayoutappmenuprovider.h"
#include "qgslayoutview.h"
#include "qgslayoutviewtooladditem.h"
#include "qgslayoutviewtooladdnodeitem.h"
#include "qgslayoutviewtoolpan.h"
#include "qgslayoutviewtoolzoom.h"
#include "qgslayoutviewtoolselect.h"
Expand Down Expand Up @@ -227,6 +228,7 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
mActionsToolbar->addWidget( resizeToolButton );

mAddItemTool = new QgsLayoutViewToolAddItem( mView );
mAddNodeItemTool = new QgsLayoutViewToolAddNodeItem( mView );
mPanTool = new QgsLayoutViewToolPan( mView );
mPanTool->setAction( mActionPan );
mToolsActionGroup->addAction( mActionPan );
Expand All @@ -241,6 +243,7 @@ QgsLayoutDesignerDialog::QgsLayoutDesignerDialog( QWidget *parent, Qt::WindowFla
connect( mActionSelectMoveItem, &QAction::triggered, mSelectTool, [ = ] { mView->setTool( mSelectTool ); } );
// after creating an item with the add item tool, switch immediately to select tool
connect( mAddItemTool, &QgsLayoutViewToolAddItem::createdItem, this, [ = ] { mView->setTool( mSelectTool ); } );
connect( mAddNodeItemTool, &QgsLayoutViewToolAddNodeItem::createdItem, this, [ = ] { mView->setTool( mSelectTool ); } );

//Ctrl+= should also trigger zoom in
QShortcut *ctrlEquals = new QShortcut( QKeySequence( QStringLiteral( "Ctrl+=" ) ), this );
Expand Down Expand Up @@ -847,6 +850,7 @@ void QgsLayoutDesignerDialog::itemTypeAdded( int id )

QString name = QgsGui::layoutItemGuiRegistry()->itemMetadata( id )->visibleName();
QString groupId = QgsGui::layoutItemGuiRegistry()->itemMetadata( id )->groupId();
bool nodeBased = QgsGui::layoutItemGuiRegistry()->itemMetadata( id )->isNodeBased();
QToolButton *groupButton = nullptr;
QMenu *itemSubmenu = nullptr;
if ( !groupId.isEmpty() )
Expand Down Expand Up @@ -905,9 +909,9 @@ void QgsLayoutDesignerDialog::itemTypeAdded( int id )
else
mToolsToolbar->addAction( action );

connect( action, &QAction::triggered, this, [this, id]()
connect( action, &QAction::triggered, this, [this, id, nodeBased]()
{
activateNewItemCreationTool( id );
activateNewItemCreationTool( id, nodeBased );
} );
}

Expand Down Expand Up @@ -1084,12 +1088,19 @@ void QgsLayoutDesignerDialog::restoreWindowState()
}
}

void QgsLayoutDesignerDialog::activateNewItemCreationTool( int id )
void QgsLayoutDesignerDialog::activateNewItemCreationTool( int id, bool nodeBasedItem )
{
mAddItemTool->setItemMetadataId( id );
if ( mView )
if ( !nodeBasedItem )
{
mAddItemTool->setItemMetadataId( id );
if ( mView )
mView->setTool( mAddItemTool );
}
else
{
mView->setTool( mAddItemTool );
mAddNodeItemTool->setItemMetadataId( id );
if ( mView )
mView->setTool( mAddNodeItemTool );
}
}

Expand Down Expand Up @@ -1123,7 +1134,7 @@ void QgsLayoutDesignerDialog::initializeRegistry()
return new QgsLayoutPagePropertiesWidget( nullptr, item );
} );

QgsGui::layoutItemGuiRegistry()->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPage, QObject::tr( "Page" ), QIcon(), createPageWidget, nullptr, QString(), QgsLayoutItemAbstractGuiMetadata::FlagNoCreationTools ) );
QgsGui::layoutItemGuiRegistry()->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutPage, QObject::tr( "Page" ), QIcon(), createPageWidget, nullptr, QString(), false, QgsLayoutItemAbstractGuiMetadata::FlagNoCreationTools ) );

}

Expand Down
4 changes: 3 additions & 1 deletion src/app/layout/qgslayoutdesignerdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
class QgsLayoutDesignerDialog;
class QgsLayoutView;
class QgsLayoutViewToolAddItem;
class QgsLayoutViewToolAddNodeItem;
class QgsLayoutViewToolPan;
class QgsLayoutViewToolZoom;
class QgsLayoutViewToolSelect;
Expand Down Expand Up @@ -270,6 +271,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
static QList<double> sStatusZoomLevelsList;

QgsLayoutViewToolAddItem *mAddItemTool = nullptr;
QgsLayoutViewToolAddNodeItem *mAddNodeItemTool = nullptr;
QgsLayoutViewToolPan *mPanTool = nullptr;
QgsLayoutViewToolZoom *mZoomTool = nullptr;
QgsLayoutViewToolSelect *mSelectTool = nullptr;
Expand Down Expand Up @@ -313,7 +315,7 @@ class QgsLayoutDesignerDialog: public QMainWindow, private Ui::QgsLayoutDesigner
void restoreWindowState();

//! Switch to new item creation tool, for a new item of the specified \a id.
void activateNewItemCreationTool( int id );
void activateNewItemCreationTool( int id, bool nodeBasedItem );

void createLayoutPropertiesWidget();

Expand Down
2 changes: 1 addition & 1 deletion src/core/layout/qgslayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
ZGuide = 9998, //!< Z-value for page guides
ZSmartGuide = 9999, //!< Z-value for smart (item bounds based) guides
ZMouseHandles = 10000, //!< Z-value for mouse handles
ZMapTool = 10001, //!< Z-value for temporary map tool items
ZViewTool = 10001, //!< Z-value for temporary view tool items
ZSnapIndicator = 10002, //!< Z-value for snapping indicator
};

Expand Down
Loading

0 comments on commit 44fe2a8

Please sign in to comment.