mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
Fix legend symbol size when using map units
fix #13078 The computation of icon sizes for legend symbols has been moved to QgsLayerTreeModel::legendInvalidateMapBasedData() susch that icon size is recomputed when zooming.
This commit is contained in:
parent
45d4dbe144
commit
8776449a14
@ -1118,6 +1118,10 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
|
||||
|
||||
if ( hasStyleOverride )
|
||||
ml->styleManager()->restoreOverrideStyle();
|
||||
|
||||
// invalidate map based data even if the data is not map-based to make sure
|
||||
// the symbol sizes are computed at least once
|
||||
legendInvalidateMapBasedData();
|
||||
}
|
||||
|
||||
|
||||
@ -1299,10 +1303,41 @@ QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::layerLegendNodes( QgsLaye
|
||||
|
||||
void QgsLayerTreeModel::legendInvalidateMapBasedData()
|
||||
{
|
||||
// we have varying icon sizes, and we want icon to be centered and
|
||||
// text to be left aligned, so we have to compute the max width of icons
|
||||
//
|
||||
// we do that for nodes who share a common parent
|
||||
//
|
||||
// we do that here because for symbols with size defined in map units
|
||||
// the symbol sizes changes depends on the zoom level
|
||||
|
||||
QList<QgsSymbolV2LegendNode*> symbolNodes;
|
||||
QMap<QString, int> widthMax;
|
||||
foreach ( const LayerLegendData& data, mLegend )
|
||||
{
|
||||
foreach ( QgsLayerTreeModelLegendNode* legendNode, data.originalNodes )
|
||||
{
|
||||
legendNode->invalidateMapBasedData();
|
||||
QgsSymbolV2LegendNode* n = dynamic_cast<QgsSymbolV2LegendNode*>( legendNode );
|
||||
if ( n )
|
||||
{
|
||||
n->setParent( this ); // map scale are in the model, so the parent needs to be set
|
||||
const QSize sz( n->minimumIconSize() );
|
||||
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
|
||||
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
|
||||
n->setIconSize( sz );
|
||||
symbolNodes.append( n );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
|
||||
{
|
||||
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
|
||||
Q_ASSERT( widthMax[parentKey] > 0 );
|
||||
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
|
||||
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
|
||||
n->invalidateMapBasedData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,13 +159,14 @@ Qt::ItemFlags QgsSymbolV2LegendNode::flags() const
|
||||
|
||||
QSize QgsSymbolV2LegendNode::minimumIconSize() const
|
||||
{
|
||||
QSize minSz;
|
||||
QSize minSz( 16, 16 );
|
||||
if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Marker )
|
||||
{
|
||||
QScopedPointer<QgsRenderContext> context( createTemporaryRenderContext() );
|
||||
minSz = QgsImageOperation::nonTransparentImageRect(
|
||||
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ), context.data() ).toImage(),
|
||||
mIconSize,
|
||||
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ),
|
||||
context.data() ).toImage(),
|
||||
minSz,
|
||||
true ).size();
|
||||
}
|
||||
else if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Line )
|
||||
@ -174,16 +175,12 @@ QSize QgsSymbolV2LegendNode::minimumIconSize() const
|
||||
minSz = QgsImageOperation::nonTransparentImageRect(
|
||||
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( mIconSize.width(), 512 ),
|
||||
context.data() ).toImage(),
|
||||
mIconSize,
|
||||
minSz,
|
||||
true ).size();
|
||||
}
|
||||
else
|
||||
{
|
||||
minSz = mIconSize;
|
||||
}
|
||||
|
||||
if ( mItem.level() != 0 && !( model() && model()->testFlag( QgsLayerTreeModel::ShowLegendAsTree ) ) )
|
||||
minSz.setWidth( indentSize + minSz.width() );
|
||||
minSz.setWidth( mItem.level() * indentSize + minSz.width() );
|
||||
|
||||
return minSz;
|
||||
}
|
||||
|
@ -199,33 +199,10 @@ QList<QgsLayerTreeModelLegendNode*> QgsDefaultVectorLayerLegend::createLayerTree
|
||||
nodes.append( new QgsSimpleLegendNode( nodeLayer, r->legendClassificationAttribute() ) );
|
||||
}
|
||||
|
||||
// we have varying icon sizes, and we want icon to be centered and
|
||||
// text to be left aligned, so we have to compute the max width of icons
|
||||
//
|
||||
// we do that for nodes who share a common parent
|
||||
|
||||
QList<QgsSymbolV2LegendNode*> symbolNodes;
|
||||
QMap<QString, int> widthMax;
|
||||
foreach ( const QgsLegendSymbolItemV2& i, r->legendSymbolItemsV2() )
|
||||
{
|
||||
QgsSymbolV2LegendNode * n = new QgsSymbolV2LegendNode( nodeLayer, i );
|
||||
nodes.append( n );
|
||||
if ( i.symbol() )
|
||||
{
|
||||
const QSize sz( n->minimumIconSize() );
|
||||
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
|
||||
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
|
||||
n->setIconSize( sz );
|
||||
symbolNodes.append( n );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
|
||||
{
|
||||
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
|
||||
Q_ASSERT( widthMax[parentKey] > 0 );
|
||||
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
|
||||
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
|
||||
}
|
||||
|
||||
if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() )
|
||||
|
Loading…
x
Reference in New Issue
Block a user