QGIS API Documentation 4.3.0-Master (16eddb2670e)
Loading...
Searching...
No Matches
qgscolorramplegendnode.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscolorramplegendnode.cpp
3 --------------------------------------
4 Date : December 2020
5 Copyright : (C) 2020 by 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
17
18#include "qgsapplication.h"
19#include "qgscolorrampimpl.h"
21#include "qgslayertreelayer.h"
22#include "qgslayertreemodel.h"
23#include "qgslegendsettings.h"
24#include "qgsnumericformat.h"
25#include "qgspainting.h"
26#include "qgssymbollayerutils.h"
27#include "qgstextrenderer.h"
28
29#include <QBuffer>
30#include <QPalette>
31#include <QString>
32
33#include "moc_qgscolorramplegendnode.cpp"
34
35using namespace Qt::StringLiterals;
36
38 QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent, const QString &key, const QString &parentKey
39)
40 : QgsLayerTreeModelLegendNode( nodeLayer, parent )
41 , mRamp( ramp )
42 , mKey( key )
43 , mParentKey( parentKey )
44{
45 mSettings.setMinimumLabel( minimumLabel );
46 mSettings.setMaximumLabel( maximumLabel );
47
48 init( nodeLayer );
49}
50
52 QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QgsColorRampLegendNodeSettings &settings, double minimumValue, double maximumValue, QObject *parent, const QString &key, const QString &parentKey
53)
54 : QgsLayerTreeModelLegendNode( nodeLayer, parent )
55 , mRamp( ramp )
56 , mSettings( settings )
57 , mMinimumValue( minimumValue )
58 , mMaximumValue( maximumValue )
59 , mKey( key )
60 , mParentKey( parentKey )
61{
62 init( nodeLayer );
63}
64
65void QgsColorRampLegendNode::init( QgsLayerTreeLayer *nodeLayer )
66{
68 mIconSize = mSettings.orientation() == Qt::Vertical ? QSize( iconSize, iconSize * 6 ) : QSize( iconSize * 6, iconSize );
69
70 connect( nodeLayer, &QObject::destroyed, this, [this]() { mLayerNode = nullptr; } );
71}
72
74{
75 return mRamp.get();
76}
77
82
87
88QString QgsColorRampLegendNode::labelForMinimum() const
89{
90 if ( !mSettings.minimumLabel().isEmpty() )
91 return mSettings.prefix() + mSettings.minimumLabel() + mSettings.suffix();
92
93 const QgsNumericFormatContext numericContext;
94 return mSettings.prefix() + mSettings.numericFormat()->formatDouble( mMinimumValue, numericContext ) + mSettings.suffix();
95}
96
97QString QgsColorRampLegendNode::labelForMaximum() const
98{
99 if ( !mSettings.maximumLabel().isEmpty() )
100 return mSettings.prefix() + mSettings.maximumLabel() + mSettings.suffix();
101
102 const QgsNumericFormatContext numericContext;
103 return mSettings.prefix() + mSettings.numericFormat()->formatDouble( mMaximumValue, numericContext ) + mSettings.suffix();
104}
105
106QVariant QgsColorRampLegendNode::data( int role ) const
107{
108 if ( role == Qt::DisplayRole )
109 {
110 return QString();
111 }
112 else if ( role == Qt::EditRole )
113 {
114 return QString();
115 }
116 else if ( role == Qt::DecorationRole )
117 {
118 if ( mPixmap.isNull() )
119 {
120 const QFont font = data( Qt::FontRole ).value< QFont >();
121
122 const QString minLabel = labelForMinimum();
123 const QString maxLabel = labelForMaximum();
124
125 const QFontMetrics fm( font );
126
127 const QRect minBoundingRect = fm.boundingRect( minLabel );
128 const QRect maxBoundingRect = fm.boundingRect( maxLabel );
129
130 QgsScreenProperties targetScreen = model() && !model()->targetScreenProperties().isEmpty() ? *model()->targetScreenProperties().begin() : QgsScreenProperties();
131 double devicePixelRatio = 1;
132 if ( targetScreen.isValid() )
133 {
134 devicePixelRatio = targetScreen.devicePixelRatio();
135 }
136
137 const double minLabelWidth = minBoundingRect.width() * devicePixelRatio;
138 const double maxLabelWidth = maxBoundingRect.width() * devicePixelRatio;
139 const double maxTextWidth = std::max( minLabelWidth, maxLabelWidth );
140 const double labelGapFromRamp = fm.boundingRect( u"x"_s ).width() * devicePixelRatio;
141 const double extraAllowance = labelGapFromRamp * 0.4; // extra allowance to avoid text clipping on right
142 QRectF labelRect;
143 QSize rampSize;
144 switch ( mSettings.orientation() )
145 {
146 case Qt::Vertical:
147 labelRect = QRectF( ( mIconSize.width() + labelGapFromRamp ) / devicePixelRatio, 0, ( maxTextWidth + extraAllowance ) / devicePixelRatio, mIconSize.height() / devicePixelRatio );
148 mPixmap = QPixmap( mIconSize.width() + maxTextWidth + labelGapFromRamp + extraAllowance, mIconSize.height() );
149 rampSize = mIconSize;
150 break;
151
152 case Qt::Horizontal:
153 labelRect = QRectF(
154 0,
155 ( mIconSize.height() + labelGapFromRamp ) / devicePixelRatio,
156 std::max( static_cast<double>( mIconSize.width() ), minLabelWidth + maxLabelWidth + labelGapFromRamp ) / devicePixelRatio,
157 ( std::max( minBoundingRect.height() * devicePixelRatio, maxBoundingRect.height() * devicePixelRatio ) + extraAllowance ) / devicePixelRatio
158 );
159 mPixmap = QPixmap( std::max( static_cast< double >( mIconSize.width() ), minLabelWidth + maxLabelWidth + labelGapFromRamp ), mIconSize.height() + maxTextWidth + labelGapFromRamp + extraAllowance );
160 rampSize = QSize( labelRect.width(), mIconSize.height() );
161 break;
162 }
163
164 mPixmap.fill( Qt::transparent );
165 mPixmap.setDevicePixelRatio( devicePixelRatio );
166
167 QPixmap pix;
168
169 if ( mRamp )
170 {
172 mRamp.get(),
173 rampSize,
174 0,
175 mSettings.orientation(),
176 mSettings.orientation() == Qt::Vertical ? mSettings.direction() != QgsColorRampLegendNodeSettings::MaximumToMinimum : mSettings.direction() != QgsColorRampLegendNodeSettings::MinimumToMaximum,
177 false
178 );
179 }
180 else
181 {
182 pix = QPixmap( rampSize );
183 pix.fill( Qt::transparent );
184 }
185
186 pix.setDevicePixelRatio( devicePixelRatio );
187
188 QPainter p( &mPixmap );
189 p.drawPixmap( 0, 0, pix );
190 p.setFont( font );
191 p.setPen( qApp->palette().color( QPalette::Text ) );
192
193 switch ( mSettings.orientation() )
194 {
195 case Qt::Vertical:
196 p.drawText( labelRect, Qt::AlignBottom | Qt::AlignLeft, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? minLabel : maxLabel );
197 p.drawText( labelRect, Qt::AlignTop | Qt::AlignLeft, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? maxLabel : minLabel );
198 break;
199
200 case Qt::Horizontal:
201 p.drawText( labelRect, Qt::AlignTop | Qt::AlignLeft, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? minLabel : maxLabel );
202 p.drawText( labelRect, Qt::AlignTop | Qt::AlignRight, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? maxLabel : minLabel );
203 break;
204 }
205
206 p.end();
207 }
208 return mPixmap;
209 }
210 else if ( role == static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::NodeType ) )
211 {
213 }
214 else if ( role == static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::RuleKey ) )
215 return mKey;
216 else if ( role == static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::ParentRuleKey ) )
217 return mParentKey;
218 return QVariant();
219}
220
222{
223 if ( !mRamp )
224 {
225 return QSizeF();
226 }
227
228 // setup temporary render context
229 QgsRenderContext *context = nullptr;
230 std::unique_ptr< QgsRenderContext > tempRenderContext;
231 if ( ctx && ctx->context )
232 context = ctx->context;
233 else
234 {
235 tempRenderContext = std::make_unique< QgsRenderContext >();
236 // QGIS 5.0 - make ItemContext compulsory, so we don't have to construct temporary render contexts here
238 tempRenderContext->setScaleFactor( settings.dpi() / 25.4 );
239 tempRenderContext->setRendererScale( settings.mapScale() );
240 tempRenderContext->setFlag( Qgis::RenderContextFlag::Antialiasing, true );
241 tempRenderContext->setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
243 tempRenderContext->setRasterizedRenderingPolicy( Qgis::RasterizedRenderingPolicy::PreferVector );
244 tempRenderContext->setPainter( ctx ? ctx->painter : nullptr );
245
246 // setup a minimal expression context
247 QgsExpressionContext expContext;
249 tempRenderContext->setExpressionContext( expContext );
250 context = tempRenderContext.get();
251 }
252
253 const QgsTextFormat format = mSettings.textFormat().isValid() ? mSettings.textFormat() : settings.style( Qgis::LegendComponent::SymbolLabel ).textFormat();
254 const QString minLabel = labelForMinimum();
255 const QString maxLabel = labelForMaximum();
256
257 const double patchWidth = ctx && ctx->patchSize.width() > 0 ? ctx->patchSize.width() : settings.symbolSize().width();
258 const double patchHeight = ctx && ctx->patchSize.height() > 0 ? ctx->patchSize.height() : settings.symbolSize().height();
259
260 double minHeightMm = 0;
261 double minWidthMm = 0;
262 double rampHeight = 0;
263 double rampWidth = 0;
264 switch ( mSettings.orientation() )
265 {
266 case Qt::Vertical:
267 // vertical bar, min height is the text height of the min and max labels
268 minHeightMm = QgsTextRenderer::textHeight( *context, format, QStringList() << minLabel << maxLabel, Qgis::TextLayoutMode::Rectangle ) / context->scaleFactor();
269 rampHeight = ctx && ctx->patchSize.height() > 0 ? std::max( minHeightMm / 2, ctx->patchSize.height() ) : std::max( minHeightMm, settings.symbolSize().height() );
270 rampWidth = patchWidth;
271 break;
272
273 case Qt::Horizontal:
274 // horizontal bar, min width is text width of the min and max labels
275 minWidthMm = ( QgsTextRenderer::textWidth( *context, format, QStringList() << minLabel ) + QgsTextRenderer::textWidth( *context, format, QStringList() << maxLabel ) ) / context->scaleFactor();
276 rampHeight = patchHeight;
277 rampWidth = std::max( minWidthMm, patchWidth );
278 break;
279 }
280
281 if ( ctx && ctx->painter )
282 {
283 const double currentYCoord = ctx->top;
284 QPainter *p = ctx->painter;
285
286 //setup painter scaling to dots so that raster symbology is drawn to scale
287 const double dotsPerMM = context->scaleFactor();
288
289 double opacity = 1;
290 if ( QgsMapLayer *layer = layerNode()->layer() )
291 opacity = layer->opacity();
292
293 const QgsScopedQPainterState painterState( p );
294 context->setPainterFlagsUsingContext( p );
295
296 double rampLeftMm = 0;
297 const double rampTopMm = currentYCoord;
298 switch ( settings.symbolAlignment() )
299 {
300 case Qt::AlignLeft:
301 default:
302 rampLeftMm = ctx->columnLeft;
303 break;
304
305 case Qt::AlignRight:
306 rampLeftMm = ctx->columnRight - rampWidth;
307 break;
308 }
309
310 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
311
312 QLinearGradient gradient;
313 switch ( mSettings.orientation() )
314 {
315 case Qt::Vertical:
316 {
317 const double gradientTop = rampTopMm * dotsPerMM;
318 const double gradientBottom = gradientTop + rampHeight * dotsPerMM;
319 gradient
320 = QLinearGradient( 0, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientBottom : gradientTop, 0, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientTop : gradientBottom );
321 break;
322 }
323
324 case Qt::Horizontal:
325 {
326 const double gradientLeft = rampLeftMm * dotsPerMM;
327 const double gradientRight = gradientLeft + rampWidth * dotsPerMM;
328 gradient
329 = QLinearGradient( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientLeft : gradientRight, 0, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientRight : gradientLeft, 0 );
330 break;
331 }
332 }
333
334
335 if ( mRamp->type() == QgsGradientColorRamp::typeString() || mRamp->type() == QgsCptCityColorRamp::typeString() )
336 {
337 //color ramp gradient
338 QgsGradientColorRamp *gradRamp = static_cast<QgsGradientColorRamp *>( mRamp.get() );
339 gradRamp->addStopsToGradient( &gradient, opacity );
340 }
341
342 if ( settings.drawRasterStroke() )
343 {
344 QPen pen;
345 pen.setColor( settings.rasterStrokeColor() );
346 pen.setWidthF( settings.rasterStrokeWidth() * dotsPerMM );
347 pen.setJoinStyle( Qt::MiterJoin );
348 ctx->painter->setPen( pen );
349 }
350 else
351 {
352 ctx->painter->setPen( Qt::NoPen );
353 }
354
355 p->setBrush( QBrush( gradient ) );
356 p->drawRect( rampLeftMm * dotsPerMM, rampTopMm * dotsPerMM, rampWidth * dotsPerMM, rampHeight * dotsPerMM );
357 }
358
359 double labelHeight = 0;
360 if ( mSettings.orientation() == Qt::Horizontal )
361 {
362 // we treat the text as part of the symbol for horizontal bar items
363 if ( ctx && ctx->painter )
364 {
365 const double currentYCoord = ctx->top;
366 QPainter *p = ctx->painter;
367
368 //setup painter scaling to dots so that raster symbology is drawn to scale
369 const double dotsPerMM = context->scaleFactor();
370
371 const QgsScopedQPainterState painterState( p );
372 context->setPainterFlagsUsingContext( p );
373
374 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
375
376 double labelXMin = 0;
377 double labelXMax = 0;
378 // NOTE -- while the below calculations use the flipped margins from the style, that's only done because
379 // those are the only margins we expose and use for now! (and we expose them as generic margins, not side-specific
380 // ones) TODO when/if we expose other margin settings, these should be reversed...
381 const double labelYMin = currentYCoord
382 + rampHeight
385 const double labelHeight = std::max( QgsTextRenderer::textHeight( *context, format, QStringList() << minLabel ), QgsTextRenderer::textHeight( *context, format, QStringList() << maxLabel ) )
386 / dotsPerMM;
387 switch ( settings.symbolAlignment() )
388 {
389 case Qt::AlignLeft:
390 default:
391 labelXMin = ctx->columnLeft;
392 labelXMax = ctx->columnLeft + rampWidth;
393 break;
394
395 case Qt::AlignRight:
396 labelXMin = ctx->columnRight - rampWidth;
397 labelXMax = ctx->columnRight;
398 break;
399 }
400
401 const QRectF textRect( labelXMin * dotsPerMM, labelYMin * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, labelHeight * dotsPerMM );
403 drawText( textRect, 0, Qgis::TextHorizontalAlignment::Left, QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? minLabel : maxLabel ), *context, format, true, Qgis::TextVerticalAlignment::Top );
405 drawText( textRect, 0, Qgis::TextHorizontalAlignment::Right, QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? maxLabel : minLabel ), *context, format, true, Qgis::TextVerticalAlignment::Bottom );
406 }
407 else
408 {
409 // we only need this when we are calculating the size of the node, not at render time
410 labelHeight = std::max( QgsTextRenderer::textHeight( *context, format, QStringList() << minLabel ), QgsTextRenderer::textHeight( *context, format, QStringList() << maxLabel ) )
411 / context->scaleFactor()
414 }
415 }
416
417 return QSizeF( rampWidth, rampHeight + labelHeight );
418}
419
421{
422 if ( !mRamp || mSettings.orientation() == Qt::Horizontal )
423 {
424 return QSizeF();
425 }
426
427 // setup temporary render context
428 QgsRenderContext *context = nullptr;
429 std::unique_ptr< QgsRenderContext > tempRenderContext;
430 if ( ctx && ctx->context )
431 context = ctx->context;
432 else
433 {
434 tempRenderContext = std::make_unique< QgsRenderContext >();
435 // QGIS 5.0 - make ItemContext compulsory, so we don't have to construct temporary render contexts here
437 tempRenderContext->setScaleFactor( settings.dpi() / 25.4 );
438 tempRenderContext->setRendererScale( settings.mapScale() );
439 tempRenderContext->setFlag( Qgis::RenderContextFlag::Antialiasing, true );
440 tempRenderContext->setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
442 tempRenderContext->setRasterizedRenderingPolicy( Qgis::RasterizedRenderingPolicy::PreferVector );
443 tempRenderContext->setPainter( ctx ? ctx->painter : nullptr );
444
445 // setup a minimal expression context
446 QgsExpressionContext expContext;
448 tempRenderContext->setExpressionContext( expContext );
449 context = tempRenderContext.get();
450 }
451
452 const QgsTextFormat format = mSettings.textFormat().isValid() ? mSettings.textFormat() : settings.style( Qgis::LegendComponent::SymbolLabel ).textFormat();
453
454 const QString minLabel = labelForMinimum();
455 const QString maxLabel = labelForMaximum();
456
457 const double rampHeight = symbolSize.height();
458 const double rampWidth = symbolSize.width();
459 double textWidth = 0;
460 double textHeight = 0;
461
462 if ( ctx && ctx->painter )
463 {
464 const double currentYCoord = ctx->top;
465 QPainter *p = ctx->painter;
466
467 //setup painter scaling to dots so that raster symbology is drawn to scale
468 const double dotsPerMM = context->scaleFactor();
469
470 const QgsScopedQPainterState painterState( p );
471 context->setPainterFlagsUsingContext( p );
472
473 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
474
475 double labelXMin = 0;
476 double labelXMax = 0;
477 switch ( settings.symbolAlignment() )
478 {
479 case Qt::AlignLeft:
480 default:
481 labelXMin = ctx->columnLeft
482 + std::max( rampWidth, ctx->maxSiblingSymbolWidth )
485 labelXMax = ctx->columnRight;
486 break;
487
488 case Qt::AlignRight:
489 labelXMin = ctx->columnLeft;
490 // NOTE -- while the below calculations use the flipped margins from the style, that's only done because
491 // those are the only margins we expose and use for now! (and we expose them as generic margins, not side-specific
492 // ones) TODO when/if we expose other margin settings, these should be reversed...
493 labelXMax = ctx->columnRight
494 - std::max( rampWidth, ctx->maxSiblingSymbolWidth )
497 break;
498 }
499
500 const QRectF textRect( labelXMin * dotsPerMM, currentYCoord * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, rampHeight * dotsPerMM );
502 textRect,
503 0,
505 QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? maxLabel : minLabel ),
506 *context,
507 format,
508 true,
510 );
512 textRect,
513 0,
515 QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? minLabel : maxLabel ),
516 *context,
517 format,
518 true,
520 );
521 }
522 else
523 {
524 // we only need this when we are calculating the size of the node, not at render time
525 textWidth = QgsTextRenderer::textWidth( *context, format, QStringList() << minLabel << maxLabel ) / context->scaleFactor();
526 textHeight = rampHeight;
527 }
528
529 return QSizeF( textWidth, textHeight );
530}
531
533{
534 Q_UNUSED( settings );
535 Q_UNUSED( context );
536
537 QJsonObject json;
538
539 const QPixmap icon = data( Qt::DecorationRole ).value<QPixmap>();
540
541 if ( !icon.isNull() )
542 {
543 const QImage image( icon.toImage() );
544 QByteArray byteArray;
545 QBuffer buffer( &byteArray );
546 image.save( &buffer, "PNG" );
547 const QString base64 = QString::fromLatin1( byteArray.toBase64().data() );
548 json[u"icon"_s] = base64;
549 }
550
551 json[u"min"_s] = mMinimumValue;
552 json[u"max"_s] = mMaximumValue;
553
554 return json;
555}
556
558{
559 mPixmap = QPixmap();
561 mIconSize = mSettings.orientation() == Qt::Vertical ? QSize( iconSize, iconSize * 6 ) : QSize( iconSize * 6, iconSize );
562}
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
Definition qgis.h:2918
@ Symbol
Symbol icon (excluding label).
Definition qgis.h:5094
@ SymbolLabel
Symbol label (excluding icon).
Definition qgis.h:5095
@ Rectangle
Text within rectangle layout mode.
Definition qgis.h:3127
@ Antialiasing
Use antialiasing while drawing.
Definition qgis.h:2972
@ Bottom
Align to bottom.
Definition qgis.h:3189
@ Top
Align to top.
Definition qgis.h:3187
Settings for a color ramp legend node.
const QgsNumericFormat * numericFormat() const
Returns the numeric format used for numbers in the scalebar.
QString suffix() const
Returns the suffix to show after legend text.
@ MaximumToMinimum
Maximum value on bottom, minimum value on top.
@ MinimumToMaximum
Minimum value on bottom, maximum value on top.
QString prefix() const
Returns the prefix to show before legend text.
Qt::Orientation orientation() const
Returns the ramp orientation (i.e.
QString minimumLabel() const
Returns the label for the minimum value on the ramp.
QSizeF drawSymbolText(const QgsLegendSettings &settings, ItemContext *ctx, QSizeF symbolSize) const override
Draws label on the right side of the item.
const QgsColorRamp * ramp() const
Returns the color ramp used by the node.
QSize iconSize() const
Returns the icon size, which is how large the ramp will render in a layer tree widget.
void setSettings(const QgsColorRampLegendNodeSettings &settings)
Sets the node's settings.
QgsColorRampLegendNode(QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent=nullptr, const QString &key=QString(), const QString &parentKey=QString())
Constructor for QgsColorRampLegendNode.
QJsonObject exportSymbolToJson(const QgsLegendSettings &settings, const QgsRenderContext &context) const override
Adds a symbol in base64 string within a JSON object with the key "icon".
void invalidateDisplayData() override
Invalidates cached display data for the node.
QgsColorRampLegendNodeSettings settings() const
Returns the node's settings.
QVariant data(int role) const override
Returns data associated with the item. Must be implemented in derived class.
QSizeF drawSymbol(const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight) const override
Draws symbol on the left side of the item.
Abstract base class for color ramps.
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
static QString typeString()
Returns the string identifier for QgsGradientColorRamp.
void addStopsToGradient(QGradient *gradient, double opacity=1) const
Copy color ramp stops to a QGradient.
Layer tree node points to a map layer.
@ ParentRuleKey
Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2....
QgsLayerTreeModelLegendNode(QgsLayerTreeLayer *nodeL, QObject *parent=nullptr)
Construct the node with pointer to its parent layer node.
QgsLayerTreeModel * model() const
Returns pointer to model owning this legend node.
QgsLayerTreeLayer * layerNode() const
Returns pointer to the parent layer node.
QSet< QgsScreenProperties > targetScreenProperties() const
Returns the target screen properties to use when generating icons.
static int scaleIconSize(int standardSize)
Scales an layer tree model icon size to compensate for display pixel density, making the icon size hi...
Stores the appearance and layout settings for legend drawing with QgsLegendRenderer.
@ Right
Right side.
@ Left
Left side.
Base class for all map layer types.
Definition qgsmaplayer.h:83
Perform transforms between map coordinates and device coordinates.
A context for numeric formats.
virtual QString formatDouble(double value, const QgsNumericFormatContext &context) const =0
Returns a formatted string representation of a numeric double value.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
Scoped object for saving and restoring a QPainter object's state.
Stores properties relating to a screen.
double devicePixelRatio() const
Returns the ratio between physical pixels and device-independent pixels for the screen.
bool isValid() const
Returns true if the properties are valid.
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0, Qt::Orientation direction=Qt::Horizontal, bool flipDirection=false, bool drawTransparentBackground=true)
Returns a pixmap preview for a color ramp.
Container for all settings relating to text rendering.
bool isValid() const
Returns true if the format is valid.
static double textWidth(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, QFontMetricsF *fontMetrics=nullptr)
Returns the width of a text based on a given format.
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
static double textHeight(const QgsRenderContext &context, const QgsTextFormat &format, const QStringList &textLines, Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Point, QFontMetricsF *fontMetrics=nullptr, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), double maxLineWidth=0)
Returns the height of a text based on a given format.
static Qgis::TextHorizontalAlignment convertQtHAlignment(Qt::Alignment alignment)
Converts a Qt horizontal alignment flag to a Qgis::TextHorizontalAlignment value.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:8379
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:8378
double maxSiblingSymbolWidth
Largest symbol width, considering all other sibling legend components associated with the current com...
QSizeF patchSize
Symbol patch size to render for the node.
double columnLeft
Left side of current legend column.
double columnRight
Right side of current legend column.
Q_NOWARN_DEPRECATED_POP QgsRenderContext * context
Render context, if available.