From f96ba98bb88f1f4b7591e9ea31a402a6eb85b8bf Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 16 Dec 2020 16:51:22 +1000 Subject: [PATCH] Use QgsColorRampLegendNodeSettings to control settings for QgsColorRampLegendNode items --- .../layertree/qgscolorramplegendnode.sip.in | 17 +++++++ src/core/layertree/qgscolorramplegendnode.cpp | 50 +++++++++++++++---- src/core/layertree/qgscolorramplegendnode.h | 22 ++++++-- .../qgspointcloudattributebyramprenderer.cpp | 5 +- src/core/qgsmaplayerlegend.cpp | 5 +- .../qgssinglebandpseudocolorrenderer.cpp | 4 +- 6 files changed, 83 insertions(+), 20 deletions(-) diff --git a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in index 9010b43b8cfc..f587609ee91f 100644 --- a/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in +++ b/python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in @@ -33,6 +33,21 @@ Constructor for QgsColorRampLegendNode. :param parent: attach a parent QObject to the legend node. %End + QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp /Transfer/, + const QgsColorRampLegendNodeSettings &settings, double minimumValue, + double maximumValue, QObject *parent /TransferThis/ = 0 ); +%Docstring +Constructor for QgsColorRampLegendNode. + +:param nodeLayer: layer node +:param ramp: color ramp to render in node. Ownership is transferred to the node. +:param settings: node settings +:param minimumValue: value associated with minimum of ramp +:param maximumValue: value associated with maximum of ramp +:param parent: attach a parent QObject to the legend node. +%End + + virtual QVariant data( int role ) const; virtual QSizeF drawSymbol( const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight ) const; @@ -59,6 +74,8 @@ Returns the color ramp used by the node. }; + + /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/core/layertree/qgscolorramplegendnode.cpp b/src/core/layertree/qgscolorramplegendnode.cpp index ef08556ecf9d..8a1deaddeb3a 100644 --- a/src/core/layertree/qgscolorramplegendnode.cpp +++ b/src/core/layertree/qgscolorramplegendnode.cpp @@ -20,13 +20,33 @@ #include "qgssymbollayerutils.h" #include "qgsexpressioncontextutils.h" #include "qgstextrenderer.h" +#include "qgsnumericformat.h" QgsColorRampLegendNode::QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QString &minimumLabel, const QString &maximumLabel, QObject *parent ) : QgsLayerTreeModelLegendNode( nodeLayer, parent ) , mRamp( ramp ) - , mMinimumLabel( minimumLabel ) - , mMaximumLabel( maximumLabel ) { + mSettings.setMinimumLabel( minimumLabel ); + mSettings.setMaximumLabel( maximumLabel ); + + const int iconSize = QgsLayerTreeModel::scaleIconSize( 16 ); + mIconSize = QSize( iconSize, iconSize * 6 ); + + connect( nodeLayer, &QObject::destroyed, this, [ = ]() { mLayerNode = nullptr; } ); +} + +QgsColorRampLegendNode::QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp, const QgsColorRampLegendNodeSettings &settings, double minimumValue, double maximumValue, QObject *parent ) + : QgsLayerTreeModelLegendNode( nodeLayer, parent ) + , mRamp( ramp ) + , mSettings( settings ) +{ + QgsNumericFormatContext numericContext; + if ( mSettings.minimumLabel().isEmpty() ) + mSettings.setMinimumLabel( settings.numericFormat()->formatDouble( minimumValue, numericContext ) ); + + if ( mSettings.maximumLabel().isEmpty() ) + mSettings.setMaximumLabel( settings.numericFormat()->formatDouble( maximumValue, numericContext ) ); + const int iconSize = QgsLayerTreeModel::scaleIconSize( 16 ); mIconSize = QSize( iconSize, iconSize * 6 ); @@ -56,7 +76,7 @@ QVariant QgsColorRampLegendNode::data( int role ) const if ( mRamp ) { - pix = QgsSymbolLayerUtils::colorRampPreviewPixmap( mRamp.get(), mIconSize, 0, Qt::Vertical, true, false ); + pix = QgsSymbolLayerUtils::colorRampPreviewPixmap( mRamp.get(), mIconSize, 0, Qt::Vertical, mSettings.direction() != QgsColorRampLegendNodeSettings::MaximumToMinimum, false ); } else { @@ -67,7 +87,7 @@ QVariant QgsColorRampLegendNode::data( int role ) const const QFont font = data( Qt::FontRole ).value< QFont >(); const QFontMetrics fm( font ); - const int maxTextWidth = std::max( fm.boundingRect( mMinimumLabel ).width(), fm.boundingRect( mMaximumLabel ).width() ); + const int maxTextWidth = std::max( fm.boundingRect( mSettings.minimumLabel() ).width(), fm.boundingRect( mSettings.maximumLabel() ).width() ); const int labelGapFromRamp = fm.boundingRect( QStringLiteral( "x" ) ).width(); const int extraAllowance = labelGapFromRamp * 0.4; // extra allowance to avoid text clipping on right const QRect labelRect( mIconSize.width() + labelGapFromRamp, 0, maxTextWidth + extraAllowance, mIconSize.height() ); @@ -79,8 +99,8 @@ QVariant QgsColorRampLegendNode::data( int role ) const p.drawPixmap( 0, 0, pix ); p.setFont( font ); - p.drawText( labelRect, Qt::AlignTop | Qt::AlignLeft, mMaximumLabel ); - p.drawText( labelRect, Qt::AlignBottom | Qt::AlignLeft, mMinimumLabel ); + p.drawText( labelRect, Qt::AlignBottom | Qt::AlignLeft, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? mSettings.minimumLabel() : mSettings.maximumLabel() ); + p.drawText( labelRect, Qt::AlignTop | Qt::AlignLeft, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? mSettings.maximumLabel() : mSettings.minimumLabel() ); p.end(); } return mPixmap; @@ -129,7 +149,7 @@ QSizeF QgsColorRampLegendNode::drawSymbol( const QgsLegendSettings &settings, It QgsTextFormat format = QgsTextFormat::fromQFont( symbolLabelFont ); format.setColor( settings.fontColor() ); - double minHeightMm = QgsTextRenderer::textHeight( *context, format, QStringList() << mMinimumLabel << mMaximumLabel, QgsTextRenderer::Rect ) / context->scaleFactor(); + double minHeightMm = QgsTextRenderer::textHeight( *context, format, QStringList() << mSettings.minimumLabel() << mSettings.maximumLabel(), QgsTextRenderer::Rect ) / context->scaleFactor(); const double height = ctx && ctx->patchSize.height() > 0 ? std::max( minHeightMm / 2, ctx->patchSize.height() ) : std::max( minHeightMm, settings.symbolSize().height() ); const double width = ctx && ctx->patchSize.width() > 0 ? ctx->patchSize.width() : settings.symbolSize().width(); @@ -165,7 +185,11 @@ QSizeF QgsColorRampLegendNode::drawSymbol( const QgsLegendSettings &settings, It p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM ); - QLinearGradient gradient( 0, rampTopMm * dotsPerMM, 0, rampTopMm * dotsPerMM + height * dotsPerMM ); + const double gradientTop = rampTopMm * dotsPerMM; + const double gradientBottom = gradientTop + height * dotsPerMM; + + QLinearGradient gradient( 0, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientBottom : gradientTop, + 0, mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? gradientTop : gradientBottom ); if ( mRamp->type() == QgsGradientColorRamp::typeString() || mRamp->type() == QgsCptCityColorRamp::typeString() ) { //color ramp gradient @@ -213,11 +237,17 @@ QSizeF QgsColorRampLegendNode::drawSymbol( const QgsLegendSettings &settings, It } const QRectF textRect( labelXMin * dotsPerMM, currentYCoord * dotsPerMM, ( labelXMax - labelXMin ) * dotsPerMM, height * dotsPerMM ); - QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::convertQtHAlignment( settings.style( QgsLegendStyle::SymbolLabel ).alignment() ), QStringList() << mMaximumLabel, *context, format, true, QgsTextRenderer::AlignTop ); - QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::convertQtHAlignment( settings.style( QgsLegendStyle::SymbolLabel ).alignment() ), QStringList() << mMinimumLabel, *context, format, true, QgsTextRenderer::AlignBottom ); + QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::convertQtHAlignment( settings.style( QgsLegendStyle::SymbolLabel ).alignment() ), + QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? mSettings.maximumLabel() : mSettings.minimumLabel() ), + *context, format, true, QgsTextRenderer::AlignTop ); + QgsTextRenderer::drawText( textRect, 0, QgsTextRenderer::convertQtHAlignment( settings.style( QgsLegendStyle::SymbolLabel ).alignment() ), + QStringList() << ( mSettings.direction() == QgsColorRampLegendNodeSettings::MinimumToMaximum ? mSettings.minimumLabel() : mSettings.maximumLabel() ), + *context, format, true, QgsTextRenderer::AlignBottom ); } return QSizeF( width, height ); } + + diff --git a/src/core/layertree/qgscolorramplegendnode.h b/src/core/layertree/qgscolorramplegendnode.h index 1b2e3d8c6140..c3e62f415486 100644 --- a/src/core/layertree/qgscolorramplegendnode.h +++ b/src/core/layertree/qgscolorramplegendnode.h @@ -21,6 +21,7 @@ #include "qgslayertreemodellegendnode.h" #include "qgslegendsymbolitem.h" #include "qgstextformat.h" +#include "qgscolorramplegendnodesettings.h" /** * \ingroup core @@ -46,6 +47,20 @@ class CORE_EXPORT QgsColorRampLegendNode : public QgsLayerTreeModelLegendNode QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp SIP_TRANSFER, const QString &minimumLabel, const QString &maximumLabel, QObject *parent SIP_TRANSFERTHIS = nullptr ); + /** + * Constructor for QgsColorRampLegendNode. + * \param nodeLayer layer node + * \param ramp color ramp to render in node. Ownership is transferred to the node. + * \param settings node settings + * \param minimumValue value associated with minimum of ramp + * \param maximumValue value associated with maximum of ramp + * \param parent attach a parent QObject to the legend node. + */ + QgsColorRampLegendNode( QgsLayerTreeLayer *nodeLayer, QgsColorRamp *ramp SIP_TRANSFER, + const QgsColorRampLegendNodeSettings &settings, double minimumValue, + double maximumValue, QObject *parent SIP_TRANSFERTHIS = nullptr ); + + QVariant data( int role ) const override; QSizeF drawSymbol( const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight ) const override; @@ -72,13 +87,12 @@ class CORE_EXPORT QgsColorRampLegendNode : public QgsLayerTreeModelLegendNode std::unique_ptr< QgsColorRamp > mRamp; mutable QPixmap mPixmap; // cached symbol preview - QString mMinimumLabel; - QString mMaximumLabel; - QSize mIconSize; - QgsTextFormat mTextFormat; + QgsColorRampLegendNodeSettings mSettings; }; + + #endif // QGSCOLORRAMPLEGENDNODE_H diff --git a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp index 2ca30a80fccf..a577a95f6968 100644 --- a/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp +++ b/src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp @@ -181,8 +181,9 @@ QList QgsPointCloudAttributeByRampRenderer::creat case QgsColorRampShader::Interpolated: // for interpolated shaders we use a ramp legend node res << new QgsColorRampLegendNode( nodeLayer, mColorRampShader.sourceColorRamp()->clone(), - QString::number( mColorRampShader.minimumValue() ), - QString::number( mColorRampShader.maximumValue() ) ); + mColorRampShader.legendSettings() ? *mColorRampShader.legendSettings() : QgsColorRampLegendNodeSettings(), + mColorRampShader.minimumValue(), + mColorRampShader.maximumValue() ); break; case QgsColorRampShader::Discrete: diff --git a/src/core/qgsmaplayerlegend.cpp b/src/core/qgsmaplayerlegend.cpp index 958ffa6dabe4..fc9938e39b8d 100644 --- a/src/core/qgsmaplayerlegend.cpp +++ b/src/core/qgsmaplayerlegend.cpp @@ -478,8 +478,9 @@ QList QgsDefaultMeshLayerLegend::createLayerTreeM case QgsColorRampShader::Interpolated: // for interpolated shaders we use a ramp legend node nodes << new QgsColorRampLegendNode( nodeLayer, shader.sourceColorRamp()->clone(), - QString::number( shader.minimumValue() ), - QString::number( shader.maximumValue() ) ); + shader.legendSettings() ? *shader.legendSettings() : QgsColorRampLegendNodeSettings(), + shader.minimumValue(), + shader.maximumValue() ); break; case QgsColorRampShader::Discrete: diff --git a/src/core/raster/qgssinglebandpseudocolorrenderer.cpp b/src/core/raster/qgssinglebandpseudocolorrenderer.cpp index 256e44756199..f380c8889fca 100644 --- a/src/core/raster/qgssinglebandpseudocolorrenderer.cpp +++ b/src/core/raster/qgssinglebandpseudocolorrenderer.cpp @@ -443,8 +443,8 @@ QList QgsSingleBandPseudoColorRenderer::createLeg case QgsColorRampShader::Interpolated: // for interpolated shaders we use a ramp legend node res << new QgsColorRampLegendNode( nodeLayer, rampShader->sourceColorRamp()->clone(), - QString::number( rampShader->minimumValue() ), - QString::number( rampShader->maximumValue() ) ); + rampShader->legendSettings() ? *rampShader->legendSettings() : QgsColorRampLegendNodeSettings(), + rampShader->minimumValue(), rampShader->maximumValue() ); break; case QgsColorRampShader::Discrete: