mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
Add tools to create node based items
This commit is contained in:
parent
6b629e199e
commit
44fe2a8d08
@ -28,7 +28,7 @@ class QgsLayout : QGraphicsScene, QgsExpressionContextGenerator, QgsLayoutUndoOb
|
||||
ZGuide,
|
||||
ZSmartGuide,
|
||||
ZMouseHandles,
|
||||
ZMapTool,
|
||||
ZViewTool,
|
||||
ZSnapIndicator,
|
||||
};
|
||||
|
||||
|
@ -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.
|
||||
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
@ -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.
|
||||
@ -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.
|
||||
@ -100,6 +117,7 @@ class QgsLayoutItemAbstractGuiMetadata
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLayoutItemGuiGroup
|
||||
{
|
||||
%Docstring
|
||||
@ -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.
|
||||
|
66
python/gui/layout/qgslayoutviewtooladdnodeitem.sip
Normal file
66
python/gui/layout/qgslayoutviewtooladdnodeitem.sip
Normal file
@ -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 *
|
||||
************************************************************************/
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "qgslayoutapputils.h"
|
||||
#include "qgsgui.h"
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayoutitemguiregistry.h"
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
@ -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() );
|
||||
}
|
||||
|
@ -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"
|
||||
@ -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 );
|
||||
@ -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 );
|
||||
@ -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() )
|
||||
@ -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 );
|
||||
} );
|
||||
}
|
||||
|
||||
@ -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 )
|
||||
{
|
||||
mView->setTool( mAddItemTool );
|
||||
mAddItemTool->setItemMetadataId( id );
|
||||
if ( mView )
|
||||
mView->setTool( mAddItemTool );
|
||||
}
|
||||
else
|
||||
{
|
||||
mAddNodeItemTool->setItemMetadataId( id );
|
||||
if ( mView )
|
||||
mView->setTool( mAddNodeItemTool );
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 ) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
class QgsLayoutDesignerDialog;
|
||||
class QgsLayoutView;
|
||||
class QgsLayoutViewToolAddItem;
|
||||
class QgsLayoutViewToolAddNodeItem;
|
||||
class QgsLayoutViewToolPan;
|
||||
class QgsLayoutViewToolZoom;
|
||||
class QgsLayoutViewToolSelect;
|
||||
@ -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;
|
||||
@ -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();
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -23,21 +23,23 @@
|
||||
#include <cmath>
|
||||
#include <QStyleOptionGraphicsItem>
|
||||
|
||||
void QgsLayoutNodesItem::setNodes( const QPolygonF &nodes )
|
||||
{
|
||||
mPolygon = nodes;
|
||||
updateSceneRect();
|
||||
}
|
||||
|
||||
QgsLayoutNodesItem::QgsLayoutNodesItem( QgsLayout *layout )
|
||||
: QgsLayoutItem( layout )
|
||||
{
|
||||
// no cache - the node based items cannot reliably determine their real bounds (e.g. due to mitred corners).
|
||||
// this blocks use of the pixmap based cache for these
|
||||
setCacheMode( QGraphicsItem::NoCache );
|
||||
init();
|
||||
}
|
||||
|
||||
QgsLayoutNodesItem::QgsLayoutNodesItem( const QPolygonF &polygon,
|
||||
QgsLayout *layout )
|
||||
: QgsLayoutItem( layout )
|
||||
{
|
||||
// no cache - the node based items cannot reliably determine their real bounds (e.g. due to mitred corners).
|
||||
// this blocks use of the pixmap based cache for these
|
||||
setCacheMode( QGraphicsItem::NoCache );
|
||||
init();
|
||||
|
||||
const QRectF boundingRect = polygon.boundingRect();
|
||||
attemptSetSceneRect( boundingRect );
|
||||
@ -46,6 +48,15 @@ QgsLayoutNodesItem::QgsLayoutNodesItem( const QPolygonF &polygon,
|
||||
mPolygon = polygon.translated( -topLeft );
|
||||
}
|
||||
|
||||
void QgsLayoutNodesItem::init()
|
||||
{
|
||||
// no cache - the node based items cannot reliably determine their real bounds (e.g. due to mitred corners).
|
||||
// this blocks use of the pixmap based cache for these
|
||||
setCacheMode( QGraphicsItem::NoCache );
|
||||
setBackgroundEnabled( false );
|
||||
setFrameEnabled( false );
|
||||
}
|
||||
|
||||
void QgsLayoutNodesItem::draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *style )
|
||||
{
|
||||
QPainter *painter = context.painter();
|
||||
@ -309,6 +320,8 @@ void QgsLayoutNodesItem::updateSceneRect()
|
||||
emit sizePositionChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool QgsLayoutNodesItem::writePropertiesToElement( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
|
||||
{
|
||||
// style
|
||||
|
@ -32,6 +32,18 @@ class CORE_EXPORT QgsLayoutNodesItem: public QgsLayoutItem
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Sets the \a nodes the shape consists of.
|
||||
* \see nodes()
|
||||
*/
|
||||
void setNodes( const QPolygonF &nodes );
|
||||
|
||||
/**
|
||||
* Returns the nodes the shape consists of.
|
||||
* \see setNodes()
|
||||
*/
|
||||
QPolygonF nodes() const { return mPolygon; }
|
||||
|
||||
/**
|
||||
* Add a node in current shape.
|
||||
* \param point is the location of the new node (in scene coordinates)
|
||||
@ -95,11 +107,6 @@ class CORE_EXPORT QgsLayoutNodesItem: public QgsLayoutItem
|
||||
*/
|
||||
void deselectNode() { mSelectedNode = -1; }
|
||||
|
||||
/**
|
||||
* Returns the nodes the shape consists of.
|
||||
*/
|
||||
QPolygonF nodes() const { return mPolygon; }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -154,6 +161,8 @@ class CORE_EXPORT QgsLayoutNodesItem: public QgsLayoutItem
|
||||
|
||||
private:
|
||||
|
||||
void init();
|
||||
|
||||
//! The index of the node currently selected.
|
||||
int mSelectedNode = -1;
|
||||
|
||||
|
@ -170,6 +170,7 @@ SET(QGIS_GUI_SRCS
|
||||
layout/qgslayoutviewrubberband.cpp
|
||||
layout/qgslayoutviewtool.cpp
|
||||
layout/qgslayoutviewtooladditem.cpp
|
||||
layout/qgslayoutviewtooladdnodeitem.cpp
|
||||
layout/qgslayoutviewtoolpan.cpp
|
||||
layout/qgslayoutviewtoolselect.cpp
|
||||
layout/qgslayoutviewtooltemporarykeypan.cpp
|
||||
@ -673,6 +674,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
layout/qgslayoutview.h
|
||||
layout/qgslayoutviewtool.h
|
||||
layout/qgslayoutviewtooladditem.h
|
||||
layout/qgslayoutviewtooladdnodeitem.h
|
||||
layout/qgslayoutviewtoolpan.h
|
||||
layout/qgslayoutviewtoolselect.h
|
||||
layout/qgslayoutviewtooltemporarykeypan.h
|
||||
|
@ -25,6 +25,11 @@ QgsLayoutViewRubberBand *QgsLayoutItemAbstractGuiMetadata::createRubberBand( Qgs
|
||||
return new QgsLayoutViewRectangularRubberBand( view );
|
||||
}
|
||||
|
||||
QAbstractGraphicsShapeItem *QgsLayoutItemAbstractGuiMetadata::createNodeRubberBand( QgsLayoutView *view )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsLayoutItem *QgsLayoutItemAbstractGuiMetadata::createItem( QgsLayout * )
|
||||
{
|
||||
return nullptr;
|
||||
@ -105,6 +110,14 @@ QgsLayoutViewRubberBand *QgsLayoutItemGuiRegistry::createItemRubberBand( int met
|
||||
return mMetadata[metadataId]->createRubberBand( view );
|
||||
}
|
||||
|
||||
QAbstractGraphicsShapeItem *QgsLayoutItemGuiRegistry::createNodeItemRubberBand( int metadataId, QgsLayoutView *view )
|
||||
{
|
||||
if ( !mMetadata.contains( metadataId ) )
|
||||
return nullptr;
|
||||
|
||||
return mMetadata[metadataId]->createNodeRubberBand( view );
|
||||
}
|
||||
|
||||
QList<int> QgsLayoutItemGuiRegistry::itemMetadataIds() const
|
||||
{
|
||||
return mMetadata.keys();
|
||||
|
@ -60,10 +60,13 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
|
||||
* \a visibleName should be set to a translated, user visible name identifying the corresponding layout item.
|
||||
*
|
||||
* An optional \a groupId can be set, which allows grouping of related layout item classes. See QgsLayoutItemGuiMetadata for details.
|
||||
*
|
||||
* If \a isNodeBased is true, then the corresponding item is a node based item.
|
||||
*/
|
||||
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 )
|
||||
: mType( type )
|
||||
, mGroupId( groupId )
|
||||
, mIsNodeBased( isNodeBased )
|
||||
, mName( visibleName )
|
||||
, mFlags( flags )
|
||||
{}
|
||||
@ -85,6 +88,11 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
|
||||
*/
|
||||
QString groupId() const { return mGroupId; }
|
||||
|
||||
/**
|
||||
* Returns true if the associated item is a node based item.
|
||||
*/
|
||||
bool isNodeBased() const { return mIsNodeBased; }
|
||||
|
||||
/**
|
||||
* Returns a translated, user visible name identifying the corresponding layout item.
|
||||
*/
|
||||
@ -103,9 +111,17 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
|
||||
/**
|
||||
* Creates a rubber band for use when creating layout items of this type. Can return nullptr if no rubber band
|
||||
* should be created. The default behavior is to create a rectangular rubber band.
|
||||
* \see createNodeRubberBand()
|
||||
*/
|
||||
virtual QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates a rubber band for use when creating layout node based items of this type. Can return nullptr if no rubber band
|
||||
* should be created. The default behavior is to return nullptr.
|
||||
* \see createRubberBand()
|
||||
*/
|
||||
virtual QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates an instance of the corresponding item type.
|
||||
*/
|
||||
@ -115,6 +131,7 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata
|
||||
|
||||
int mType = -1;
|
||||
QString mGroupId;
|
||||
bool mIsNodeBased = false;
|
||||
QString mName;
|
||||
Flags mFlags;
|
||||
|
||||
@ -126,6 +143,9 @@ typedef std::function<QgsLayoutItemBaseWidget *( QgsLayoutItem * )> QgsLayoutIte
|
||||
//! Layout rubber band creation function
|
||||
typedef std::function<QgsLayoutViewRubberBand *( QgsLayoutView * )> QgsLayoutItemRubberBandFunc SIP_SKIP;
|
||||
|
||||
//! Layout node based rubber band creation function
|
||||
typedef std::function<QAbstractGraphicsShapeItem *( QgsLayoutView * )> QgsLayoutNodeItemRubberBandFunc SIP_SKIP;
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
@ -146,12 +166,16 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad
|
||||
* \a visibleName should be set to a translated, user visible name identifying the corresponding layout item.
|
||||
*
|
||||
* An optional \a groupId can be set, which allows grouping of related layout item classes. See QgsLayoutItemGuiMetadata for details.
|
||||
*
|
||||
* If \a isNodeBased is true, then the corresponding item is a node based item.
|
||||
*/
|
||||
QgsLayoutItemGuiMetadata( int type, const QString &visibleName, const QIcon &creationIcon,
|
||||
QgsLayoutItemWidgetFunc pfWidget = nullptr,
|
||||
QgsLayoutItemRubberBandFunc pfRubberBand = nullptr, const QString &groupId = QString(), QgsLayoutItemAbstractGuiMetadata::Flags flags = 0,
|
||||
QgsLayoutItemRubberBandFunc pfRubberBand = nullptr, const QString &groupId = QString(),
|
||||
bool isNodeBased = false,
|
||||
QgsLayoutItemAbstractGuiMetadata::Flags flags = 0,
|
||||
QgsLayoutItemCreateFunc pfCreateFunc = nullptr )
|
||||
: QgsLayoutItemAbstractGuiMetadata( type, visibleName, groupId, flags )
|
||||
: QgsLayoutItemAbstractGuiMetadata( type, visibleName, groupId, isNodeBased, flags )
|
||||
, mIcon( creationIcon )
|
||||
, mWidgetFunc( pfWidget )
|
||||
, mRubberBandFunc( pfRubberBand )
|
||||
@ -182,6 +206,18 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad
|
||||
*/
|
||||
void setRubberBandCreationFunction( QgsLayoutItemRubberBandFunc function ) { mRubberBandFunc = function; }
|
||||
|
||||
/**
|
||||
* Returns the classes' node based rubber band creation function.
|
||||
* \see setNodeRubberBandCreationFunction()
|
||||
*/
|
||||
QgsLayoutNodeItemRubberBandFunc nodeRubberBandCreationFunction() const { return mNodeRubberBandFunc; }
|
||||
|
||||
/**
|
||||
* Sets the classes' node based rubber band creation \a function.
|
||||
* \see nodeRubberBandCreationFunction()
|
||||
*/
|
||||
void setNodeRubberBandCreationFunction( QgsLayoutNodeItemRubberBandFunc function ) { mNodeRubberBandFunc = function; }
|
||||
|
||||
/**
|
||||
* Returns the classes' item creation function.
|
||||
* \see setItemCreationFunction()
|
||||
@ -197,12 +233,14 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad
|
||||
QIcon creationIcon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractGuiMetadata::creationIcon() : mIcon; }
|
||||
QgsLayoutItemBaseWidget *createItemWidget( QgsLayoutItem *item ) override { return mWidgetFunc ? mWidgetFunc( item ) : nullptr; }
|
||||
QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) override { return mRubberBandFunc ? mRubberBandFunc( view ) : nullptr; }
|
||||
QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) override { return mNodeRubberBandFunc ? mNodeRubberBandFunc( view ) : nullptr; }
|
||||
QgsLayoutItem *createItem( QgsLayout *layout ) override;
|
||||
|
||||
protected:
|
||||
QIcon mIcon;
|
||||
QgsLayoutItemWidgetFunc mWidgetFunc = nullptr;
|
||||
QgsLayoutItemRubberBandFunc mRubberBandFunc = nullptr;
|
||||
QgsLayoutNodeItemRubberBandFunc mNodeRubberBandFunc = nullptr;
|
||||
QgsLayoutItemCreateFunc mCreateFunc = nullptr;
|
||||
|
||||
};
|
||||
@ -329,9 +367,18 @@ class GUI_EXPORT QgsLayoutItemGuiRegistry : public QObject
|
||||
/**
|
||||
* Creates a new rubber band item for the specified item \a metadataId and destination \a view.
|
||||
* \note not available from Python bindings
|
||||
* \see createNodeItemRubberBand()
|
||||
*/
|
||||
QgsLayoutViewRubberBand *createItemRubberBand( int metadataId, QgsLayoutView *view ) const SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Creates a rubber band for the specified item \a metadataId and destination \a view.
|
||||
* Can return nullptr if no node based rubber band should be created or is applicable for the item.
|
||||
* \see createItemRubberBand()
|
||||
* \note not available from Python bindings
|
||||
*/
|
||||
QAbstractGraphicsShapeItem *createNodeItemRubberBand( int metadataId, QgsLayoutView *view ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns a list of available item metadata ids handled by the registry.
|
||||
*/
|
||||
|
@ -149,7 +149,7 @@ void QgsLayoutViewRectangularRubberBand::start( QPointF position, Qt::KeyboardMo
|
||||
mRubberBandStartPos = position;
|
||||
t.translate( position.x(), position.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZViewTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
}
|
||||
@ -214,7 +214,7 @@ void QgsLayoutViewEllipticalRubberBand::start( QPointF position, Qt::KeyboardMod
|
||||
mRubberBandStartPos = position;
|
||||
t.translate( position.x(), position.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZViewTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
}
|
||||
@ -283,7 +283,7 @@ void QgsLayoutViewTriangleRubberBand::start( QPointF position, Qt::KeyboardModif
|
||||
mRubberBandStartPos = position;
|
||||
t.translate( position.x(), position.y() );
|
||||
mRubberBandItem->setTransform( t );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZMapTool );
|
||||
mRubberBandItem->setZValue( QgsLayout::ZViewTool );
|
||||
layout()->addItem( mRubberBandItem );
|
||||
layout()->update();
|
||||
}
|
||||
|
172
src/gui/layout/qgslayoutviewtooladdnodeitem.cpp
Normal file
172
src/gui/layout/qgslayoutviewtooladdnodeitem.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
/***************************************************************************
|
||||
qgslayoutviewtooladdnodeitem.cpp
|
||||
----------------------------
|
||||
Date : July 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson 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 "qgslayoutviewtooladdnodeitem.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgscursors.h"
|
||||
#include "qgslayoutview.h"
|
||||
#include "qgslayout.h"
|
||||
#include "qgslayoutitemregistry.h"
|
||||
#include "qgslayoutviewmouseevent.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgslayoutviewrubberband.h"
|
||||
#include "qgsgui.h"
|
||||
#include "qgslayoutitemguiregistry.h"
|
||||
#include "qgslayoutnewitempropertiesdialog.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgslayoututils.h"
|
||||
#include "qgslayoutitemnodeitem.h"
|
||||
#include <QGraphicsRectItem>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QMouseEvent>
|
||||
|
||||
QgsLayoutViewToolAddNodeItem::QgsLayoutViewToolAddNodeItem( QgsLayoutView *view )
|
||||
: QgsLayoutViewTool( view, tr( "Add item" ) )
|
||||
{
|
||||
setFlags( QgsLayoutViewTool::FlagSnaps );
|
||||
QPixmap crosshairQPixmap = QPixmap( ( const char ** )( cross_hair_cursor ) );
|
||||
setCursor( QCursor( crosshairQPixmap, 8, 8 ) );
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::setItemMetadataId( int metadataId )
|
||||
{
|
||||
mItemMetadataId = metadataId;
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::layoutPressEvent( QgsLayoutViewMouseEvent *event )
|
||||
{
|
||||
if ( event->button() == Qt::LeftButton )
|
||||
{
|
||||
if ( !mRubberBand )
|
||||
{
|
||||
mPolygon.clear();
|
||||
mRubberBand.reset( QgsGui::layoutItemGuiRegistry()->createNodeItemRubberBand( mItemMetadataId, view() ) );
|
||||
if ( mRubberBand )
|
||||
layout()->addItem( mRubberBand.get() );
|
||||
}
|
||||
|
||||
if ( mRubberBand )
|
||||
{
|
||||
//add a new node
|
||||
addNode( event->snappedPoint() );
|
||||
}
|
||||
}
|
||||
else if ( event->button() == Qt::RightButton && mRubberBand )
|
||||
{
|
||||
// finish up
|
||||
|
||||
// last (temporary) point is removed
|
||||
mPolygon.remove( mPolygon.count() - 1 );
|
||||
|
||||
QgsLayoutItem *item = QgsGui::layoutItemGuiRegistry()->createItem( mItemMetadataId, layout() );
|
||||
if ( !item )
|
||||
return;
|
||||
|
||||
if ( QgsLayoutNodesItem *nodesItem = qobject_cast< QgsLayoutNodesItem * >( item ) )
|
||||
nodesItem->setNodes( mPolygon );
|
||||
|
||||
layout()->addLayoutItem( item );
|
||||
layout()->setSelectedItem( item );
|
||||
emit createdItem();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
mRubberBand.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event )
|
||||
{
|
||||
if ( mRubberBand )
|
||||
{
|
||||
moveTemporaryNode( event->snappedPoint(), event->modifiers() );
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *event )
|
||||
{
|
||||
if ( !mRubberBand )
|
||||
{
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::deactivate()
|
||||
{
|
||||
if ( mRubberBand )
|
||||
{
|
||||
// canceled mid operation
|
||||
mRubberBand.reset();
|
||||
}
|
||||
QgsLayoutViewTool::deactivate();
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::addNode( QPointF scenePoint )
|
||||
{
|
||||
mPolygon.append( scenePoint );
|
||||
|
||||
if ( mPolygon.size() == 1 )
|
||||
mPolygon.append( scenePoint );
|
||||
|
||||
setRubberBandNodes();
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::moveTemporaryNode( QPointF scenePoint, Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
if ( mPolygon.isEmpty() )
|
||||
return;
|
||||
|
||||
if ( mPolygon.size() > 1 && ( modifiers & Qt::ShiftModifier ) )
|
||||
{
|
||||
QPointF start = mPolygon.at( mPolygon.size() - 2 );
|
||||
QLineF newLine = QLineF( start, scenePoint );
|
||||
|
||||
//movement is contrained to 45 degree angles
|
||||
double angle = QgsLayoutUtils::snappedAngle( newLine.angle() );
|
||||
newLine.setAngle( angle );
|
||||
scenePoint = newLine.p2();
|
||||
}
|
||||
|
||||
mPolygon.replace( mPolygon.size() - 1, scenePoint );
|
||||
setRubberBandNodes();
|
||||
}
|
||||
|
||||
void QgsLayoutViewToolAddNodeItem::setRubberBandNodes()
|
||||
{
|
||||
if ( QGraphicsPolygonItem *polygonItem = dynamic_cast< QGraphicsPolygonItem *>( mRubberBand.get() ) )
|
||||
{
|
||||
polygonItem->setPolygon( mPolygon );
|
||||
}
|
||||
else if ( QGraphicsPathItem *polylineItem = dynamic_cast< QGraphicsPathItem *>( mRubberBand.get() ) )
|
||||
{
|
||||
// rebuild a new qpainter path
|
||||
QPainterPath path;
|
||||
path.addPolygon( mPolygon );
|
||||
polylineItem->setPath( path );
|
||||
}
|
||||
}
|
||||
|
||||
int QgsLayoutViewToolAddNodeItem::itemMetadataId() const
|
||||
{
|
||||
return mItemMetadataId;
|
||||
}
|
82
src/gui/layout/qgslayoutviewtooladdnodeitem.h
Normal file
82
src/gui/layout/qgslayoutviewtooladdnodeitem.h
Normal file
@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
qgslayoutviewtooladdnodeitem.h
|
||||
--------------------------
|
||||
Date : October 2017
|
||||
Copyright : (C) 2017 Nyall Dawson
|
||||
Email : nyall dot dawson 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 QGSLAYOUTVIEWTOOLADDNODEITEM_H
|
||||
#define QGSLAYOUTVIEWTOOLADDNODEITEM_H
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgis_gui.h"
|
||||
#include "qgslayoutviewtool.h"
|
||||
#include <memory>
|
||||
#include <QAbstractGraphicsShapeItem>
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* Layout view tool for adding node based items to a layout.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class GUI_EXPORT QgsLayoutViewToolAddNodeItem : public QgsLayoutViewTool
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
QgsLayoutViewToolAddNodeItem( QgsLayoutView *view SIP_TRANSFERTHIS );
|
||||
|
||||
/**
|
||||
* Returns the item metadata id for items created by the tool.
|
||||
* \see setItemMetadataId()
|
||||
*/
|
||||
int itemMetadataId() const;
|
||||
|
||||
/**
|
||||
* Sets the item metadata \a metadataId for items created by the tool.
|
||||
*
|
||||
* The \a metadataId associates the current tool behavior with a metadata entry
|
||||
* from QgsLayoutItemGuiRegistry.
|
||||
*
|
||||
* \see itemMetadataId()
|
||||
*/
|
||||
void setItemMetadataId( int metadataId );
|
||||
|
||||
void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override;
|
||||
void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override;
|
||||
void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override;
|
||||
void deactivate() override;
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when an item has been created using the tool.
|
||||
*/
|
||||
void createdItem();
|
||||
|
||||
private:
|
||||
|
||||
int mItemMetadataId = -1;
|
||||
|
||||
//! Rubber band item
|
||||
std::unique_ptr< QAbstractGraphicsShapeItem > mRubberBand;
|
||||
|
||||
QPolygonF mPolygon;
|
||||
|
||||
void addNode( QPointF scenePoint );
|
||||
void moveTemporaryNode( QPointF scenePoint, Qt::KeyboardModifiers modifiers );
|
||||
void setRubberBandNodes();
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSLAYOUTVIEWTOOLADDNODEITEM_H
|
@ -76,6 +76,15 @@ class TestQgsLayoutPolygon(unittest.TestCase):
|
||||
p = QgsLayoutItemPolygon(polygon, self.layout)
|
||||
self.assertEqual(p.nodes(), polygon)
|
||||
|
||||
polygon = QPolygonF()
|
||||
polygon.append(QPointF(0.0, 0.0))
|
||||
polygon.append(QPointF(1000.0, 0.0))
|
||||
polygon.append(QPointF(2000.0, 100.0))
|
||||
polygon.append(QPointF(1000.0, 200.0))
|
||||
|
||||
p.setNodes(polygon)
|
||||
self.assertEqual(p.nodes(), polygon)
|
||||
|
||||
def testDisplayName(self):
|
||||
"""Test if displayName is valid"""
|
||||
|
||||
|
@ -64,6 +64,25 @@ class TestQgsLayoutPolyline(unittest.TestCase):
|
||||
style = QgsLineSymbol.createSimple(props)
|
||||
self.polyline.setSymbol(style)
|
||||
|
||||
def testNodes(self):
|
||||
polygon = QPolygonF()
|
||||
polygon.append(QPointF(0.0, 0.0))
|
||||
polygon.append(QPointF(100.0, 0.0))
|
||||
polygon.append(QPointF(200.0, 100.0))
|
||||
polygon.append(QPointF(100.0, 200.0))
|
||||
|
||||
p = QgsLayoutItemPolyline(polygon, self.layout)
|
||||
self.assertEqual(p.nodes(), polygon)
|
||||
|
||||
polygon = QPolygonF()
|
||||
polygon.append(QPointF(0.0, 0.0))
|
||||
polygon.append(QPointF(1000.0, 0.0))
|
||||
polygon.append(QPointF(2000.0, 100.0))
|
||||
polygon.append(QPointF(1000.0, 200.0))
|
||||
|
||||
p.setNodes(polygon)
|
||||
self.assertEqual(p.nodes(), polygon)
|
||||
|
||||
def testDisplayName(self):
|
||||
"""Test if displayName is valid"""
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user