Skip to content

Commit

Permalink
Use QgsColorRampLegendNodeSettings to control settings for QgsColorRa…
Browse files Browse the repository at this point in the history
…mpLegendNode items
  • Loading branch information
nyalldawson committed Dec 18, 2020
1 parent 45d2edd commit f96ba98
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 20 deletions.
17 changes: 17 additions & 0 deletions python/core/auto_generated/layertree/qgscolorramplegendnode.sip.in
Expand Up @@ -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;
Expand All @@ -59,6 +74,8 @@ Returns the color ramp used by the node.

};



/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
50 changes: 40 additions & 10 deletions src/core/layertree/qgscolorramplegendnode.cpp
Expand Up @@ -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 );

Expand Down Expand Up @@ -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
{
Expand All @@ -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() );
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 );
}




22 changes: 18 additions & 4 deletions src/core/layertree/qgscolorramplegendnode.h
Expand Up @@ -21,6 +21,7 @@
#include "qgslayertreemodellegendnode.h"
#include "qgslegendsymbolitem.h"
#include "qgstextformat.h"
#include "qgscolorramplegendnodesettings.h"

/**
* \ingroup core
Expand All @@ -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;

Expand All @@ -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
5 changes: 3 additions & 2 deletions src/core/pointcloud/qgspointcloudattributebyramprenderer.cpp
Expand Up @@ -181,8 +181,9 @@ QList<QgsLayerTreeModelLegendNode *> 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:
Expand Down
5 changes: 3 additions & 2 deletions src/core/qgsmaplayerlegend.cpp
Expand Up @@ -478,8 +478,9 @@ QList<QgsLayerTreeModelLegendNode *> 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:
Expand Down
4 changes: 2 additions & 2 deletions src/core/raster/qgssinglebandpseudocolorrenderer.cpp
Expand Up @@ -443,8 +443,8 @@ QList<QgsLayerTreeModelLegendNode *> 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:
Expand Down

0 comments on commit f96ba98

Please sign in to comment.