-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
qgslegendrenderer.h
303 lines (252 loc) · 10.2 KB
/
qgslegendrenderer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/***************************************************************************
qgslegendrenderer.h
--------------------------------------
Date : July 2014
Copyright : (C) 2014 by Martin Dobias
Email : wonder dot sk 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 QGSLEGENDRENDERER_H
#define QGSLEGENDRENDERER_H
#include "qgis_core.h"
#include <QPointF>
class QRectF;
class QStandardItem;
class QJsonObject;
class QgsLayerTreeGroup;
class QgsLayerTreeLayer;
class QgsLayerTreeModel;
class QgsLayerTreeModelLegendNode;
class QgsLayerTreeNode;
class QgsSymbol;
class QgsRenderContext;
#include "qgslegendsettings.h"
/**
* \ingroup core
* \brief The QgsLegendRenderer class handles automatic layout and rendering of legend.
* The content is given by QgsLayerTreeModel instance. Various layout properties can be configured
* within QgsLegendRenderer.
*
* All spacing and sizes are in millimeters.
*
* \since QGIS 2.6
*/
class CORE_EXPORT QgsLegendRenderer
{
public:
/**
* Constructor for QgsLegendRenderer. The ownership of the legend model is not changed,
* and the model must exist for the lifetime of this renderer.
*/
QgsLegendRenderer( QgsLayerTreeModel *legendModel, const QgsLegendSettings &settings );
/**
* Runs the layout algorithm and returns the minimum size required for the legend.
* \see setLegendSize()
* \see legendSize()
*/
QSizeF minimumSize( QgsRenderContext *renderContext = nullptr );
/**
* Sets the preferred resulting legend size.
*
* If the size is null, the legend will be drawn with the minimum possible size to fit its content.
*
* \see legendSize()
* \see minimumSize()
*/
void setLegendSize( QSizeF s ) { mLegendSize = s; }
/**
* Returns the preferred legend size set by the client.
*
* If the returned size is null, the legend will be drawn with the minimum possible size to fit its content.
*
* \see minimumSize()
* \see setLegendSize()
*/
QSizeF legendSize() const { return mLegendSize; }
/**
* Draws the legend with given \a painter. The legend will occupy the area reported in legendSize().
* The \a painter should be scaled beforehand so that units correspond to millimeters.
*
* \deprecated Use the variant which accepts a QgsRenderContext instead.
*/
Q_DECL_DEPRECATED void drawLegend( QPainter *painter ) SIP_DEPRECATED;
/**
* Draws the legend using a given render \a context. The legend will occupy the area reported in legendSize().
*
* \since QGIS 3.6
*/
void drawLegend( QgsRenderContext &context );
/**
* Renders the legend in a \a json object.
*
* \since QGIS 3.8
*/
QJsonObject exportLegendToJson( const QgsRenderContext &context );
/**
* Sets the \a style of a \a node.
*
* \see nodeLegendStyle()
*/
static void setNodeLegendStyle( QgsLayerTreeNode *node, QgsLegendStyle::Style style );
/**
* Returns the style for the given \a node, within the specified \a model.
*
* \see setNodeLegendStyle()
*/
static QgsLegendStyle::Style nodeLegendStyle( QgsLayerTreeNode *node, QgsLayerTreeModel *model );
private:
#ifndef SIP_RUN
/**
* A legend component is either a group title, a layer title or a layer child item.
*
* E.g. a layer title component is just the layer's title, it does not
* include all of that layer's subitems. Similarly, a group's title component is just
* the group title, and does not include the actual content of that group.
*/
class LegendComponent
{
public:
LegendComponent() = default;
QObject *item = nullptr;
//! Symbol size, not including any preset padding space around the symbol
QSizeF symbolSize;
//! Label size, not including any preset padding space around the label
QSizeF labelSize;
//! Component size
QSizeF size;
/**
* Horizontal offset for the symbol label.
*
* This offset is the same for all symbol labels belonging to the same layer,
* within the same legend column.
*/
double labelXOffset = 0.0;
/**
* Largest symbol width, considering all other sibling components associated with
* this component.
*/
double maxSiblingSymbolWidth = 0.0;
};
/**
* An component group is an indivisible set of legend components (i.e. it is indivisible into more columns).
*
* A group may consist of one or more component(s), depending on the layer splitting mode:
*
* 1) no layer split: [group_title ...] layer_title layer_item [layer_item ...]
* 2) layer split: [group_title ...] layer_title layer_item
* or: layer_item
*
* This means that group titles must not be split from layer titles and layer titles
* must not be split from the first layer item, because this results in a poor layout
* and it would not be logical to leave a group or layer title at the bottom of a column,
* separated from the actual content of that group or layer.
*/
class LegendComponentGroup
{
public:
//! List of child components belonging to this group.
QList<LegendComponent> components;
//! Group size, including internal spacing between components, but excluding any padding space around the group itself.
QSizeF size = QSizeF( 0, 0 );
//! Corresponding column index
int column = 0;
/**
* TRUE if a forced column break should be placed just before the group
*/
bool placeColumnBreakBeforeGroup = false;
};
/**
* Contains contextual information about the current column being rendered
*/
class ColumnContext
{
public:
ColumnContext()
: left( 0 )
, right( 0 )
{}
//! Left edge of column
double left = 0;
//! Right edge of column
double right = 0;
};
/**
* Returns a list of component groups for the specified \a parentGroup, respecting the current layer's
* splitting settings.
*/
QList<LegendComponentGroup> createComponentGroupList( QgsLayerTreeGroup *parentGroup, QgsRenderContext &context );
/**
* Divides a list of component groups into columns, and sets the column index for each group in the list.
*
* Returns the calculated number of columns.
*/
int setColumns( QList<LegendComponentGroup> &groupList );
/**
* Returns the calculated padding space required above the given component \a group.
*/
double spaceAboveGroup( const LegendComponentGroup &group );
/**
* Renders a group item in a \a json object.
*
* \since QGIS 3.8
*/
void exportLegendToJson( const QgsRenderContext &context, QgsLayerTreeGroup *nodeGroup, QJsonObject &json );
/**
* Draws the legend using the specified render \a context, and returns the actual size of the legend.
*
* If \a context is NULLPTR, only the size of the legend will be calculated and no
* painting will be attempted.
*/
QSizeF paintAndDetermineSize( QgsRenderContext &context );
/**
* Draws a title in the legend using the specified render \a context, with the title font and the specified alignment settings.
*
* Returns the size required to draw the complete title.
*
* If \a context is NULLPTR, no painting will be attempted, but the required size will still be calculated and returned.
*/
QSizeF drawTitle( QgsRenderContext &context, double top, Qt::AlignmentFlag halignment = Qt::AlignLeft, double legendWidth = 0 );
/**
* Draws an \a group and return its actual size, using the specified render \a context.
*
* The \a group is drawn with the space above it, so that the first groups in a column are all
* aligned to the same line regardless of their style top spacing.
*
* If \a context is NULLPTR, no painting will be attempted, but the required size will still be calculated and returned.
*/
QSizeF drawGroup( const LegendComponentGroup &group, QgsRenderContext &context, ColumnContext columnContext, double top = 0 );
/**
* Draws the symbol of a given symbol QgsLayerTreeModelLegendNode, using the specified render \a context.
*/
LegendComponent drawSymbolItem( QgsLayerTreeModelLegendNode *symbolItem, QgsRenderContext &context, ColumnContext columnContext, double top, double maxSiblingSymbolWidth = 0 );
/**
* Draws the title of a layer, given a QgsLayerTreeLayer, and a destination render \a context.
*
* Returns the size of the title.
*
* The \a context may be NULLPTR, in which case on the size is calculated and no painting is attempted.
*/
QSizeF drawLayerTitle( QgsLayerTreeLayer *nodeLayer, QgsRenderContext &context, ColumnContext columnContext = ColumnContext(), double top = 0 );
/**
* Draws a group's title, using the specified render \a context.
*
* Returns the size of the title.
*/
QSizeF drawGroupTitle( QgsLayerTreeGroup *nodeGroup, QgsRenderContext &context, ColumnContext columnContext = ColumnContext(), double top = 0 );
/**
* Returns the style of the given \a node.
*/
QgsLegendStyle::Style nodeLegendStyle( QgsLayerTreeNode *node );
QgsLayerTreeModel *mLegendModel = nullptr;
QgsLegendSettings mSettings;
QSizeF mLegendSize;
#endif
void widthAndOffsetForTitleText( const Qt::AlignmentFlag halignment, double legendWidth, double &width, double &offset );
};
#endif // QGSLEGENDRENDERER_H