33#include "moc_qgscolorramplegendnode.cpp"
35using namespace Qt::StringLiterals;
38 QgsLayerTreeLayer *nodeLayer,
QgsColorRamp *
ramp,
const QString &minimumLabel,
const QString &maximumLabel, QObject *parent,
const QString &key,
const QString &parentKey
43 , mParentKey( parentKey )
45 mSettings.setMinimumLabel( minimumLabel );
46 mSettings.setMaximumLabel( maximumLabel );
57 , mMinimumValue( minimumValue )
58 , mMaximumValue( maximumValue )
60 , mParentKey( parentKey )
70 connect( nodeLayer, &QObject::destroyed,
this, [
this]() {
mLayerNode =
nullptr; } );
88QString QgsColorRampLegendNode::labelForMinimum()
const
97QString QgsColorRampLegendNode::labelForMaximum()
const
99 if ( !mSettings.maximumLabel().isEmpty() )
100 return mSettings.prefix() + mSettings.maximumLabel() + mSettings.suffix();
102 const QgsNumericFormatContext numericContext;
103 return mSettings.prefix() + mSettings.numericFormat()->formatDouble( mMaximumValue, numericContext ) + mSettings.suffix();
108 if ( role == Qt::DisplayRole )
112 else if ( role == Qt::EditRole )
116 else if ( role == Qt::DecorationRole )
118 if ( mPixmap.isNull() )
120 const QFont font =
data( Qt::FontRole ).value< QFont >();
122 const QString minLabel = labelForMinimum();
123 const QString maxLabel = labelForMaximum();
125 const QFontMetrics fm( font );
127 const QRect minBoundingRect = fm.boundingRect( minLabel );
128 const QRect maxBoundingRect = fm.boundingRect( maxLabel );
131 double devicePixelRatio = 1;
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;
144 switch ( mSettings.orientation() )
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;
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
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() );
164 mPixmap.fill( Qt::transparent );
165 mPixmap.setDevicePixelRatio( devicePixelRatio );
175 mSettings.orientation(),
182 pix = QPixmap( rampSize );
183 pix.fill( Qt::transparent );
186 pix.setDevicePixelRatio( devicePixelRatio );
188 QPainter p( &mPixmap );
189 p.drawPixmap( 0, 0, pix );
191 p.setPen( qApp->palette().color( QPalette::Text ) );
193 switch ( mSettings.orientation() )
230 std::unique_ptr< QgsRenderContext > tempRenderContext;
235 tempRenderContext = std::make_unique< QgsRenderContext >();
238 tempRenderContext->setScaleFactor(
settings.dpi() / 25.4 );
239 tempRenderContext->setRendererScale(
settings.mapScale() );
241 tempRenderContext->setMapToPixel(
QgsMapToPixel( 1 / (
settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
244 tempRenderContext->setPainter( ctx ? ctx->
painter :
nullptr );
249 tempRenderContext->setExpressionContext( expContext );
250 context = tempRenderContext.get();
254 const QString minLabel = labelForMinimum();
255 const QString maxLabel = labelForMaximum();
260 double minHeightMm = 0;
261 double minWidthMm = 0;
262 double rampHeight = 0;
263 double rampWidth = 0;
264 switch ( mSettings.orientation() )
269 rampHeight = ctx && ctx->
patchSize.height() > 0 ? std::max( minHeightMm / 2, ctx->
patchSize.height() ) : std::max( minHeightMm,
settings.symbolSize().height() );
270 rampWidth = patchWidth;
276 rampHeight = patchHeight;
277 rampWidth = std::max( minWidthMm, patchWidth );
283 const double currentYCoord = ctx->
top;
291 opacity = layer->opacity();
296 double rampLeftMm = 0;
297 const double rampTopMm = currentYCoord;
298 switch (
settings.symbolAlignment() )
310 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
312 QLinearGradient gradient;
313 switch ( mSettings.orientation() )
317 const double gradientTop = rampTopMm * dotsPerMM;
318 const double gradientBottom = gradientTop + rampHeight * dotsPerMM;
326 const double gradientLeft = rampLeftMm * dotsPerMM;
327 const double gradientRight = gradientLeft + rampWidth * dotsPerMM;
345 pen.setColor(
settings.rasterStrokeColor() );
346 pen.setWidthF(
settings.rasterStrokeWidth() * dotsPerMM );
347 pen.setJoinStyle( Qt::MiterJoin );
352 ctx->
painter->setPen( Qt::NoPen );
355 p->setBrush( QBrush( gradient ) );
356 p->drawRect( rampLeftMm * dotsPerMM, rampTopMm * dotsPerMM, rampWidth * dotsPerMM, rampHeight * dotsPerMM );
359 double labelHeight = 0;
360 if ( mSettings.orientation() == Qt::Horizontal )
365 const double currentYCoord = ctx->
top;
374 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
376 double labelXMin = 0;
377 double labelXMax = 0;
381 const double labelYMin = currentYCoord
387 switch (
settings.symbolAlignment() )
401 const QRectF textRect( labelXMin * dotsPerMM, labelYMin * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, labelHeight * dotsPerMM );
417 return QSizeF( rampWidth, rampHeight + labelHeight );
422 if ( !mRamp || mSettings.orientation() == Qt::Horizontal )
429 std::unique_ptr< QgsRenderContext > tempRenderContext;
434 tempRenderContext = std::make_unique< QgsRenderContext >();
437 tempRenderContext->setScaleFactor(
settings.dpi() / 25.4 );
438 tempRenderContext->setRendererScale(
settings.mapScale() );
440 tempRenderContext->setMapToPixel(
QgsMapToPixel( 1 / (
settings.mmPerMapUnit() * tempRenderContext->scaleFactor() ) ) );
443 tempRenderContext->setPainter( ctx ? ctx->
painter :
nullptr );
448 tempRenderContext->setExpressionContext( expContext );
449 context = tempRenderContext.get();
454 const QString minLabel = labelForMinimum();
455 const QString maxLabel = labelForMaximum();
457 const double rampHeight = symbolSize.height();
458 const double rampWidth = symbolSize.width();
459 double textWidth = 0;
460 double textHeight = 0;
464 const double currentYCoord = ctx->
top;
473 p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
475 double labelXMin = 0;
476 double labelXMax = 0;
477 switch (
settings.symbolAlignment() )
500 const QRectF textRect( labelXMin * dotsPerMM, currentYCoord * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, rampHeight * dotsPerMM );
526 textHeight = rampHeight;
529 return QSizeF( textWidth, textHeight );
539 const QPixmap icon =
data( Qt::DecorationRole ).value<QPixmap>();
541 if ( !icon.isNull() )
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;
551 json[u
"min"_s] = mMinimumValue;
552 json[u
"max"_s] = mMaximumValue;
@ PreferVector
Prefer vector-based rendering, when the result will still be visually near-identical to a raster-base...
@ Symbol
Symbol icon (excluding label).
@ SymbolLabel
Symbol label (excluding icon).
@ Rectangle
Text within rectangle layout mode.
@ Antialiasing
Use antialiasing while drawing.
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.
@ ColorRampLegend
Color ramp legend.
@ ParentRuleKey
Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2....
@ NodeType
Type of node. Added in 3.16.
@ RuleKey
Rule key of the node (QString).
QgsLayerTreeLayer * mLayerNode
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.
Base class for all map layer types.
Perform transforms between map coordinates and device coordinates.
A context for numeric formats.
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
#define Q_NOWARN_DEPRECATED_PUSH
QPainter * painter
Painter.
double top
Top y-position of legend item.
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.