Skip to content

Commit 3843b5e

Browse files
committed
Create rubber band classes for layout views
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.
1 parent 4ebea75 commit 3843b5e

14 files changed

+751
-96
lines changed

python/core/layout/qgslayoutitemregistry.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class QgsLayoutItemAbstractMetadata
6161
:rtype: QWidget
6262
%End
6363

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

7980

8081

82+
8183
class QgsLayoutItemRegistry : QObject
8284
{
8385
%Docstring
@@ -141,6 +143,7 @@ class QgsLayoutItemRegistry : QObject
141143
:rtype: QWidget
142144
%End
143145

146+
144147
void resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const;
145148
%Docstring
146149
Resolve paths in properties of a particular symbol layer.

python/gui/gui_auto.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
%Include editorwidgets/core/qgseditorwidgetautoconf.sip
4343
%Include layertree/qgslayertreeembeddedconfigwidget.sip
4444
%Include layertree/qgslayertreeembeddedwidgetregistry.sip
45+
%Include layout/qgslayoutitemregistryguiutils.sip
4546
%Include layout/qgslayoutviewmouseevent.sip
47+
%Include layout/qgslayoutviewrubberband.sip
4648
%Include locator/qgslocatorcontext.sip
4749
%Include raster/qgsrasterrendererwidget.sip
4850
%Include symbology-ng/qgssymbolwidgetcontext.sip
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/layout/qgslayoutitemregistryguiutils.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
class QgsLayoutItemRegistryGuiUtils
13+
{
14+
%Docstring
15+
A group of static utilities for working with the gui based portions of
16+
QgsLayoutItemRegistry.
17+
18+
This class is designed to allow Python item subclasses to override the
19+
default GUI based QgsLayoutItemAbstractMetadata methods, which
20+
cannot be directly overridden from Python subclasses.
21+
22+
.. versionadded:: 3.0
23+
%End
24+
25+
%TypeHeaderCode
26+
#include "qgslayoutitemregistryguiutils.h"
27+
%End
28+
public:
29+
30+
static void setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype /Transfer/ );
31+
%Docstring
32+
Sets a ``prototype`` for the rubber bands for the layout item with specified ``type``.
33+
Python subclasses of QgsLayoutItem must call this method to register their prototypes,
34+
as the usual c++ QgsLayoutItemAbstractMetadata are not accessible via the Python bindings.
35+
%End
36+
37+
38+
};
39+
40+
/************************************************************************
41+
* This file has been generated automatically from *
42+
* *
43+
* src/gui/layout/qgslayoutitemregistryguiutils.h *
44+
* *
45+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
46+
************************************************************************/
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/gui/layout/qgslayoutviewrubberband.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
class QgsLayoutViewRubberBand
14+
{
15+
%Docstring
16+
QgsLayoutViewRubberBand is an abstract base class for temporary rubber band items
17+
in various shapes, for use within QgsLayoutView widgets.
18+
.. versionadded:: 3.0
19+
%End
20+
21+
%TypeHeaderCode
22+
#include "qgslayoutviewrubberband.h"
23+
%End
24+
25+
%ConvertToSubClassCode
26+
if ( dynamic_cast<QgsLayoutViewMouseEvent *>( sipCpp ) )
27+
sipType = sipType_QgsLayoutViewMouseEvent;
28+
else
29+
sipType = 0;
30+
%End
31+
public:
32+
33+
QgsLayoutViewRubberBand( QgsLayoutView *view );
34+
%Docstring
35+
Constructor for QgsLayoutViewRubberBand.
36+
%End
37+
38+
virtual ~QgsLayoutViewRubberBand();
39+
40+
virtual QgsLayoutViewRubberBand *create( QgsLayoutView *view ) const = 0 /Factory/;
41+
%Docstring
42+
Creates a new instance of the QgsLayoutViewRubberBand subclass.
43+
:rtype: QgsLayoutViewRubberBand
44+
%End
45+
46+
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
47+
%Docstring
48+
Called when a rubber band should be created at the specified
49+
starting ``position`` (in layout coordinate space).
50+
%End
51+
52+
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
53+
%Docstring
54+
Called when a rubber band should be updated to reflect a temporary
55+
ending ``position`` (in layout coordinate space).
56+
%End
57+
58+
virtual void finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0;
59+
%Docstring
60+
Called when a rubber band use has finished and the rubber
61+
band is no longer required.
62+
%End
63+
64+
QgsLayoutView *view() const;
65+
%Docstring
66+
Returns the view associated with the rubber band.
67+
.. seealso:: layout()
68+
:rtype: QgsLayoutView
69+
%End
70+
71+
QgsLayout *layout() const;
72+
%Docstring
73+
Returns the layout associated with the rubber band.
74+
.. seealso:: view()
75+
:rtype: QgsLayout
76+
%End
77+
78+
protected:
79+
80+
QRectF updateRect( QPointF start, QPointF position, bool constrainSquare, bool fromCenter );
81+
%Docstring
82+
Calculates an updated bounding box rectangle from a original ``start`` position
83+
and new ``position``. If ``constrainSquare`` is true then the bounding box will be
84+
forced to a square shape. If ``fromCenter`` is true then the original ``start``
85+
position will form the center point of the returned rectangle.
86+
:rtype: QRectF
87+
%End
88+
89+
};
90+
91+
92+
class QgsLayoutViewRectangularRubberBand : QgsLayoutViewRubberBand
93+
{
94+
%Docstring
95+
QgsLayoutViewRectangularRubberBand is rectangular rubber band for use within QgsLayoutView widgets.
96+
.. versionadded:: 3.0
97+
%End
98+
99+
%TypeHeaderCode
100+
#include "qgslayoutviewrubberband.h"
101+
%End
102+
public:
103+
104+
QgsLayoutViewRectangularRubberBand( QgsLayoutView *view );
105+
%Docstring
106+
Constructor for QgsLayoutViewRectangularRubberBand.
107+
%End
108+
virtual QgsLayoutViewRectangularRubberBand *create( QgsLayoutView *view ) const /Factory/;
109+
110+
111+
~QgsLayoutViewRectangularRubberBand();
112+
113+
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );
114+
115+
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
116+
117+
virtual void finish( QPointF, Qt::KeyboardModifiers );
118+
119+
120+
};
121+
122+
class QgsLayoutViewEllipticalRubberBand : QgsLayoutViewRubberBand
123+
{
124+
%Docstring
125+
QgsLayoutViewEllipseRubberBand is elliptical rubber band for use within QgsLayoutView widgets.
126+
.. versionadded:: 3.0
127+
%End
128+
129+
%TypeHeaderCode
130+
#include "qgslayoutviewrubberband.h"
131+
%End
132+
public:
133+
134+
QgsLayoutViewEllipticalRubberBand( QgsLayoutView *view );
135+
%Docstring
136+
Constructor for QgsLayoutViewEllipticalRubberBand.
137+
%End
138+
virtual QgsLayoutViewEllipticalRubberBand *create( QgsLayoutView *view ) const /Factory/;
139+
140+
141+
~QgsLayoutViewEllipticalRubberBand();
142+
143+
virtual void start( QPointF position, Qt::KeyboardModifiers modifiers );
144+
145+
virtual void update( QPointF position, Qt::KeyboardModifiers modifiers );
146+
147+
virtual void finish( QPointF, Qt::KeyboardModifiers );
148+
149+
150+
};
151+
/************************************************************************
152+
* This file has been generated automatically from *
153+
* *
154+
* src/gui/layout/qgslayoutviewrubberband.h *
155+
* *
156+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
157+
************************************************************************/

python/gui/layout/qgslayoutviewtooladditem.sip

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99

1010

11-
1211
class QgsLayoutViewToolAddItem : QgsLayoutViewTool
1312
{
1413
%Docstring

src/core/layout/qgslayoutitemregistry.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ QWidget *QgsLayoutItemRegistry::createItemWidget( int type ) const
5858
return mMetadata[type]->createItemWidget();
5959
}
6060

61+
QgsLayoutViewRubberBand *QgsLayoutItemRegistry::createItemRubberBand( int type, QgsLayoutView *view ) const
62+
{
63+
if ( mRubberBandFunctions.contains( type ) )
64+
return mRubberBandFunctions.value( type )( view );
65+
66+
if ( !mMetadata.contains( type ) )
67+
return nullptr;
68+
69+
return mMetadata[type]->createRubberBand( view );
70+
}
71+
6172
void QgsLayoutItemRegistry::resolvePaths( int type, QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving ) const
6273
{
6374
if ( !mMetadata.contains( type ) )

src/core/layout/qgslayoutitemregistry.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#include <functional>
2626

2727
class QgsLayout;
28+
class QgsLayoutView;
2829
class QgsLayoutItem;
30+
class QgsLayoutViewRubberBand;
2931

3032
/**
3133
* \ingroup core
@@ -73,6 +75,14 @@ class CORE_EXPORT QgsLayoutItemAbstractMetadata
7375
*/
7476
virtual QWidget *createItemWidget() SIP_FACTORY { return nullptr; }
7577

78+
/**
79+
* Creates a rubber band for use when creating layout items of this type. Can return nullptr if no rubber band
80+
* should be created.
81+
* \note not available in Python bindings. Python item subclasses must use QgsLayoutItemRegistryGuiUtils
82+
* to override the default rubber band creation function.
83+
*/
84+
virtual QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) SIP_SKIP { Q_UNUSED( view ); return nullptr; }
85+
7686
/**
7787
* Resolve paths in the item's \a properties (if there are any paths).
7888
* When \a saving is true, paths are converted from absolute to relative,
@@ -99,6 +109,9 @@ typedef std::function<QgsLayoutItem *( QgsLayout *, const QVariantMap & )> QgsLa
99109
//! Layout item configuration widget creation function
100110
typedef std::function<QWidget *()> QgsLayoutItemWidgetFunc SIP_SKIP;
101111

112+
//! Layout rubber band creation function
113+
typedef std::function<QgsLayoutViewRubberBand *( QgsLayoutView * )> QgsLayoutItemRubberBandFunc SIP_SKIP;
114+
102115
//! Layout item path resolver function
103116
typedef std::function<void( QVariantMap &, const QgsPathResolver &, bool )> QgsLayoutItemPathResolverFunc SIP_SKIP;
104117

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

168+
/**
169+
* Returns the classes' rubber band creation function.
170+
* \see setRubberBandCreationFunction()
171+
*/
172+
QgsLayoutItemRubberBandFunc rubberBandCreationFunction() const { return mRubberBandFunc; }
173+
174+
/**
175+
* Sets the classes' rubber band creation \a function.
176+
* \see rubberBandCreationFunction()
177+
*/
178+
void setRubberBandCreationFunction( QgsLayoutItemRubberBandFunc function ) { mRubberBandFunc = function; }
179+
155180
QIcon icon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractMetadata::icon() : mIcon; }
156181
QgsLayoutItem *createItem( QgsLayout *layout, const QVariantMap &properties ) override { return mCreateFunc ? mCreateFunc( layout, properties ) : nullptr; }
157182
QWidget *createItemWidget() override { return mWidgetFunc ? mWidgetFunc() : nullptr; }
@@ -165,6 +190,7 @@ class CORE_EXPORT QgsLayoutItemMetadata : public QgsLayoutItemAbstractMetadata
165190
QIcon mIcon;
166191
QgsLayoutItemCreateFunc mCreateFunc = nullptr;
167192
QgsLayoutItemWidgetFunc mWidgetFunc = nullptr;
193+
QgsLayoutItemRubberBandFunc mRubberBandFunc = nullptr;
168194
QgsLayoutItemPathResolverFunc mPathResolverFunc = nullptr;
169195

170196
};
@@ -237,6 +263,12 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
237263
*/
238264
QWidget *createItemWidget( int type ) const SIP_FACTORY;
239265

266+
/**
267+
* Creates a new rubber band item for the specified item \a type and destination \a view.
268+
* \note not available from Python bindings
269+
*/
270+
QgsLayoutViewRubberBand *createItemRubberBand( int type, QgsLayoutView *view ) const SIP_SKIP;
271+
240272
/**
241273
* Resolve paths in properties of a particular symbol layer.
242274
* This normally means converting relative paths to absolute paths when loading
@@ -264,6 +296,10 @@ class CORE_EXPORT QgsLayoutItemRegistry : public QObject
264296

265297
QMap<int, QgsLayoutItemAbstractMetadata *> mMetadata;
266298

299+
QMap<int, QgsLayoutItemRubberBandFunc > mRubberBandFunctions;
300+
301+
friend class QgsLayoutItemRegistryGuiUtils;
302+
267303
};
268304

269305
#endif //QGSLAYOUTITEMREGISTRY_H

src/gui/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,10 @@ SET(QGIS_GUI_SRCS
158158
layertree/qgslayertreeview.cpp
159159
layertree/qgslayertreeviewdefaultactions.cpp
160160

161+
layout/qgslayoutitemregistryguiutils.cpp
161162
layout/qgslayoutview.cpp
162163
layout/qgslayoutviewmouseevent.cpp
164+
layout/qgslayoutviewrubberband.cpp
163165
layout/qgslayoutviewtool.cpp
164166
layout/qgslayoutviewtooladditem.cpp
165167

@@ -721,7 +723,9 @@ SET(QGIS_GUI_HDRS
721723
layertree/qgslayertreeembeddedconfigwidget.h
722724
layertree/qgslayertreeembeddedwidgetregistry.h
723725

726+
layout/qgslayoutitemregistryguiutils.h
724727
layout/qgslayoutviewmouseevent.h
728+
layout/qgslayoutviewrubberband.h
725729

726730
locator/qgslocatorcontext.h
727731

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/***************************************************************************
2+
qgslayoutitemregistryguiutils.h
3+
-------------------------------
4+
Date : July 2017
5+
Copyright : (C) 2017 Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
17+
#include "qgslayoutitemregistryguiutils.h"
18+
#include "qgslayoutviewrubberband.h"
19+
20+
void QgsLayoutItemRegistryGuiUtils::setItemRubberBandPrototype( int type, QgsLayoutViewRubberBand *prototype )
21+
{
22+
auto create = [prototype]( QgsLayoutView * view )->QgsLayoutViewRubberBand *
23+
{
24+
return prototype->create( view );
25+
};
26+
QgsApplication::layoutItemRegistry()->mRubberBandFunctions.insert( type, create );
27+
}

0 commit comments

Comments
 (0)