Skip to content

Commit

Permalink
Create rubber band classes for layout views
Browse files Browse the repository at this point in the history
c++ QgsLayoutItem metadata classes can directly register
a function which creates a QgsLayoutViewRubberBand for the item
subclass.

Python code cannot utilise this shortcut (due to inaccessibility
of forward declared gui classes from core Python classes), so
there's a separate gui registry utility class added for registering
prototypes for rubber bands for already registered item types.
  • Loading branch information
nyalldawson committed Jul 11, 2017
1 parent 4ebea75 commit 3843b5e
Show file tree
Hide file tree
Showing 14 changed files with 751 additions and 96 deletions.
3 changes: 3 additions & 0 deletions python/core/layout/qgslayoutitemregistry.sip
Expand Up @@ -61,6 +61,7 @@ class QgsLayoutItemAbstractMetadata
:rtype: QWidget
%End


virtual void resolvePaths( QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving );
%Docstring
Resolve paths in the item's ``properties`` (if there are any paths).
Expand All @@ -78,6 +79,7 @@ class QgsLayoutItemAbstractMetadata




class QgsLayoutItemRegistry : QObject
{
%Docstring
Expand Down Expand Up @@ -141,6 +143,7 @@ class QgsLayoutItemRegistry : QObject
:rtype: QWidget
%End


void resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const;
%Docstring
Resolve paths in properties of a particular symbol layer.
Expand Down
2 changes: 2 additions & 0 deletions python/gui/gui_auto.sip
Expand Up @@ -42,7 +42,9 @@
%Include editorwidgets/core/qgseditorwidgetautoconf.sip
%Include layertree/qgslayertreeembeddedconfigwidget.sip
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
%Include layout/qgslayoutitemregistryguiutils.sip
%Include layout/qgslayoutviewmouseevent.sip
%Include layout/qgslayoutviewrubberband.sip
%Include locator/qgslocatorcontext.sip
%Include raster/qgsrasterrendererwidget.sip
%Include symbology-ng/qgssymbolwidgetcontext.sip
Expand Down
46 changes: 46 additions & 0 deletions python/gui/layout/qgslayoutitemregistryguiutils.sip
@@ -0,0 +1,46 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutitemregistryguiutils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsLayoutItemRegistryGuiUtils
{
%Docstring
A group of static utilities for working with the gui based portions of
QgsLayoutItemRegistry.

This class is designed to allow Python item subclasses to override the
default GUI based QgsLayoutItemAbstractMetadata methods, which
cannot be directly overridden from Python subclasses.

.. versionadded:: 3.0
%End

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

static void setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype /Transfer/ );
%Docstring
Sets a ``prototype`` for the rubber bands for the layout item with specified ``type``.
Python subclasses of QgsLayoutItem must call this method to register their prototypes,
as the usual c++ QgsLayoutItemAbstractMetadata are not accessible via the Python bindings.
%End


};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutitemregistryguiutils.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
157 changes: 157 additions & 0 deletions python/gui/layout/qgslayoutviewrubberband.sip
@@ -0,0 +1,157 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutviewrubberband.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsLayoutViewRubberBand
{
%Docstring
QgsLayoutViewRubberBand is an abstract base class for temporary rubber band items
in various shapes, for use within QgsLayoutView widgets.
.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgslayoutviewrubberband.h"
%End

%ConvertToSubClassCode
if ( dynamic_cast<QgsLayoutViewMouseEvent *>( sipCpp ) )
sipType = sipType_QgsLayoutViewMouseEvent;
else
sipType = 0;
%End
public:

QgsLayoutViewRubberBand( QgsLayoutView *view );
%Docstring
Constructor for QgsLayoutViewRubberBand.
%End

virtual ~QgsLayoutViewRubberBand();

virtual QgsLayoutViewRubberBand *create( QgsLayoutView *view ) const = 0 /Factory/;
%Docstring
Creates a new instance of the QgsLayoutViewRubberBand subclass.
:rtype: QgsLayoutViewRubberBand
%End

virtual void start( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
%Docstring
Called when a rubber band should be created at the specified
starting ``position`` (in layout coordinate space).
%End

virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
%Docstring
Called when a rubber band should be updated to reflect a temporary
ending ``position`` (in layout coordinate space).
%End

virtual void finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
%Docstring
Called when a rubber band use has finished and the rubber
band is no longer required.
%End

QgsLayoutView *view() const;
%Docstring
Returns the view associated with the rubber band.
.. seealso:: layout()
:rtype: QgsLayoutView
%End

QgsLayout *layout() const;
%Docstring
Returns the layout associated with the rubber band.
.. seealso:: view()
:rtype: QgsLayout
%End

protected:

QRectF updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter );
%Docstring
Calculates an updated bounding box rectangle from a original ``start`` position
and new ``position``. If ``constrainSquare`` is true then the bounding box will be
forced to a square shape. If ``fromCenter`` is true then the original ``start``
position will form the center point of the returned rectangle.
:rtype: QRectF
%End

};


class QgsLayoutViewRectangularRubberBand : QgsLayoutViewRubberBand
{
%Docstring
QgsLayoutViewRectangularRubberBand is rectangular rubber band for use within QgsLayoutView widgets.
.. versionadded:: 3.0
%End

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

QgsLayoutViewRectangularRubberBand( QgsLayoutView *view );
%Docstring
Constructor for QgsLayoutViewRectangularRubberBand.
%End
virtual QgsLayoutViewRectangularRubberBand *create( QgsLayoutView *view ) const /Factory/;


~QgsLayoutViewRectangularRubberBand();

virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );

virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );

virtual void finish( QPointF, Qt::KeyboardModifiers );


};

class QgsLayoutViewEllipticalRubberBand : QgsLayoutViewRubberBand
{
%Docstring
QgsLayoutViewEllipseRubberBand is elliptical rubber band for use within QgsLayoutView widgets.
.. versionadded:: 3.0
%End

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

QgsLayoutViewEllipticalRubberBand( QgsLayoutView *view );
%Docstring
Constructor for QgsLayoutViewEllipticalRubberBand.
%End
virtual QgsLayoutViewEllipticalRubberBand *create( QgsLayoutView *view ) const /Factory/;


~QgsLayoutViewEllipticalRubberBand();

virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );

virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );

virtual void finish( QPointF, Qt::KeyboardModifiers );


};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/layout/qgslayoutviewrubberband.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 0 additions & 1 deletion python/gui/layout/qgslayoutviewtooladditem.sip
Expand Up @@ -8,7 +8,6 @@




class QgsLayoutViewToolAddItem : QgsLayoutViewTool
{
%Docstring
Expand Down
11 changes: 11 additions & 0 deletions src/core/layout/qgslayoutitemregistry.cpp
Expand Up @@ -58,6 +58,17 @@ QWidget *QgsLayoutItemRegistry::createItemWidget( int type ) const
return mMetadata[type]->createItemWidget();
}

QgsLayoutViewRubberBand *QgsLayoutItemRegistry::createItemRubberBand( int type, QgsLayoutView *view ) const
{
if ( mRubberBandFunctions.contains( type ) )
return mRubberBandFunctions.value( type )( view );

if ( !mMetadata.contains( type ) )
return nullptr;

return mMetadata[type]->createRubberBand( view );
}

void QgsLayoutItemRegistry::resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const
{
if ( !mMetadata.contains( type ) )
Expand Down
36 changes: 36 additions & 0 deletions src/core/layout/qgslayoutitemregistry.h
Expand Up @@ -25,7 +25,9 @@
#include <functional>

class QgsLayout;
class QgsLayoutView;
class QgsLayoutItem;
class QgsLayoutViewRubberBand;

/**
* \ingroup core
Expand Down Expand Up @@ -73,6 +75,14 @@ class CORE_EXPORT QgsLayoutItemAbstractMetadata
*/
virtual QWidget *createItemWidget() SIP_FACTORY { return nullptr; }

/**
* Creates a rubber band for use when creating layout items of this type. Can return nullptr if no rubber band
* should be created.
* \note not available in Python bindings. Python item subclasses must use QgsLayoutItemRegistryGuiUtils
* to override the default rubber band creation function.
*/
virtual QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) SIP_SKIP { Q_UNUSED( view ); return nullptr; }

/**
* Resolve paths in the item's \a properties (if there are any paths).
* When \a saving is true, paths are converted from absolute to relative,
Expand All @@ -99,6 +109,9 @@ typedef std::function<QgsLayoutItem *( QgsLayout *, const QVariantMap & )> QgsLa
//! Layout item configuration widget creation function
typedef std::function<QWidget *()> QgsLayoutItemWidgetFunc SIP_SKIP;

//! Layout rubber band creation function
typedef std::function<QgsLayoutViewRubberBand *( QgsLayoutView * )> QgsLayoutItemRubberBandFunc SIP_SKIP;

//! Layout item path resolver function
typedef std::function<void( QVariantMap &, const QgsPathResolver &, bool )> QgsLayoutItemPathResolverFunc SIP_SKIP;

Expand Down Expand Up @@ -152,6 +165,18 @@ class CORE_EXPORT QgsLayoutItemMetadata : public QgsLayoutItemAbstractMetadata
*/
void setWidgetFunction( QgsLayoutItemWidgetFunc function ) { mWidgetFunc = function; }

/**
* Returns the classes' rubber band creation function.
* \see setRubberBandCreationFunction()
*/
QgsLayoutItemRubberBandFunc rubberBandCreationFunction() const { return mRubberBandFunc; }

/**
* Sets the classes' rubber band creation \a function.
* \see rubberBandCreationFunction()
*/
void setRubberBandCreationFunction( QgsLayoutItemRubberBandFunc function ) { mRubberBandFunc = function; }

QIcon icon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractMetadata::icon() : mIcon; }
QgsLayoutItem *createItem( QgsLayout *layout, const QVariantMap &properties ) override { return mCreateFunc ? mCreateFunc( layout, properties ) : nullptr; }
QWidget *createItemWidget() override { return mWidgetFunc ? mWidgetFunc() : nullptr; }
Expand All @@ -165,6 +190,7 @@ class CORE_EXPORT QgsLayoutItemMetadata : public QgsLayoutItemAbstractMetadata
QIcon mIcon;
QgsLayoutItemCreateFunc mCreateFunc = nullptr;
QgsLayoutItemWidgetFunc mWidgetFunc = nullptr;
QgsLayoutItemRubberBandFunc mRubberBandFunc = nullptr;
QgsLayoutItemPathResolverFunc mPathResolverFunc = nullptr;

};
Expand Down Expand Up @@ -237,6 +263,12 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
*/
QWidget *createItemWidget( int type ) const SIP_FACTORY;

/**
* Creates a new rubber band item for the specified item \a type and destination \a view.
* \note not available from Python bindings
*/
QgsLayoutViewRubberBand *createItemRubberBand( int type, QgsLayoutView *view ) const SIP_SKIP;

/**
* Resolve paths in properties of a particular symbol layer.
* This normally means converting relative paths to absolute paths when loading
Expand Down Expand Up @@ -264,6 +296,10 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject

QMap<int, QgsLayoutItemAbstractMetadata *> mMetadata;

QMap<int, QgsLayoutItemRubberBandFunc > mRubberBandFunctions;

friend class QgsLayoutItemRegistryGuiUtils;

};

#endif //QGSLAYOUTITEMREGISTRY_H
Expand Down
4 changes: 4 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -158,8 +158,10 @@ SET(QGIS_GUI_SRCS
layertree/qgslayertreeview.cpp
layertree/qgslayertreeviewdefaultactions.cpp

layout/qgslayoutitemregistryguiutils.cpp
layout/qgslayoutview.cpp
layout/qgslayoutviewmouseevent.cpp
layout/qgslayoutviewrubberband.cpp
layout/qgslayoutviewtool.cpp
layout/qgslayoutviewtooladditem.cpp

Expand Down Expand Up @@ -721,7 +723,9 @@ SET(QGIS_GUI_HDRS
layertree/qgslayertreeembeddedconfigwidget.h
layertree/qgslayertreeembeddedwidgetregistry.h

layout/qgslayoutitemregistryguiutils.h
layout/qgslayoutviewmouseevent.h
layout/qgslayoutviewrubberband.h

locator/qgslocatorcontext.h

Expand Down
27 changes: 27 additions & 0 deletions src/gui/layout/qgslayoutitemregistryguiutils.cpp
@@ -0,0 +1,27 @@
/***************************************************************************
qgslayoutitemregistryguiutils.h
-------------------------------
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 "qgslayoutitemregistryguiutils.h"
#include "qgslayoutviewrubberband.h"

void QgsLayoutItemRegistryGuiUtils::setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype )
{
auto create = [prototype]( QgsLayoutView * view )->QgsLayoutViewRubberBand *
{
return prototype->create( view );
};
QgsApplication::layoutItemRegistry()->mRubberBandFunctions.insert( type, create );
}

0 comments on commit 3843b5e

Please sign in to comment.