Skip to content

Commit 8776449

Browse files
committedAug 12, 2015
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.
1 parent 45d4dbe commit 8776449

File tree

3 files changed

+41
-32
lines changed

3 files changed

+41
-32
lines changed
 

‎src/core/layertree/qgslayertreemodel.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,10 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
11181118

11191119
if ( hasStyleOverride )
11201120
ml->styleManager()->restoreOverrideStyle();
1121+
1122+
// invalidate map based data even if the data is not map-based to make sure
1123+
// the symbol sizes are computed at least once
1124+
legendInvalidateMapBasedData();
11211125
}
11221126

11231127

@@ -1299,10 +1303,41 @@ QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::layerLegendNodes( QgsLaye
12991303

13001304
void QgsLayerTreeModel::legendInvalidateMapBasedData()
13011305
{
1306+
// we have varying icon sizes, and we want icon to be centered and
1307+
// text to be left aligned, so we have to compute the max width of icons
1308+
//
1309+
// we do that for nodes who share a common parent
1310+
//
1311+
// we do that here because for symbols with size defined in map units
1312+
// the symbol sizes changes depends on the zoom level
1313+
1314+
QList<QgsSymbolV2LegendNode*> symbolNodes;
1315+
QMap<QString, int> widthMax;
13021316
foreach ( const LayerLegendData& data, mLegend )
13031317
{
13041318
foreach ( QgsLayerTreeModelLegendNode* legendNode, data.originalNodes )
1319+
{
13051320
legendNode->invalidateMapBasedData();
1321+
QgsSymbolV2LegendNode* n = dynamic_cast<QgsSymbolV2LegendNode*>( legendNode );
1322+
if ( n )
1323+
{
1324+
n->setParent( this ); // map scale are in the model, so the parent needs to be set
1325+
const QSize sz( n->minimumIconSize() );
1326+
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
1327+
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
1328+
n->setIconSize( sz );
1329+
symbolNodes.append( n );
1330+
}
1331+
}
1332+
}
1333+
1334+
foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
1335+
{
1336+
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
1337+
Q_ASSERT( widthMax[parentKey] > 0 );
1338+
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
1339+
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
1340+
n->invalidateMapBasedData();
13061341
}
13071342
}
13081343

‎src/core/layertree/qgslayertreemodellegendnode.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,14 @@ Qt::ItemFlags QgsSymbolV2LegendNode::flags() const
159159

160160
QSize QgsSymbolV2LegendNode::minimumIconSize() const
161161
{
162-
QSize minSz;
162+
QSize minSz( 16, 16 );
163163
if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Marker )
164164
{
165165
QScopedPointer<QgsRenderContext> context( createTemporaryRenderContext() );
166166
minSz = QgsImageOperation::nonTransparentImageRect(
167-
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ), context.data() ).toImage(),
168-
mIconSize,
167+
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ),
168+
context.data() ).toImage(),
169+
minSz,
169170
true ).size();
170171
}
171172
else if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Line )
@@ -174,16 +175,12 @@ QSize QgsSymbolV2LegendNode::minimumIconSize() const
174175
minSz = QgsImageOperation::nonTransparentImageRect(
175176
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( mIconSize.width(), 512 ),
176177
context.data() ).toImage(),
177-
mIconSize,
178+
minSz,
178179
true ).size();
179180
}
180-
else
181-
{
182-
minSz = mIconSize;
183-
}
184181

185182
if ( mItem.level() != 0 && !( model() && model()->testFlag( QgsLayerTreeModel::ShowLegendAsTree ) ) )
186-
minSz.setWidth( indentSize + minSz.width() );
183+
minSz.setWidth( mItem.level() * indentSize + minSz.width() );
187184

188185
return minSz;
189186
}

‎src/core/qgsmaplayerlegend.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -199,33 +199,10 @@ QList<QgsLayerTreeModelLegendNode*> QgsDefaultVectorLayerLegend::createLayerTree
199199
nodes.append( new QgsSimpleLegendNode( nodeLayer, r->legendClassificationAttribute() ) );
200200
}
201201

202-
// we have varying icon sizes, and we want icon to be centered and
203-
// text to be left aligned, so we have to compute the max width of icons
204-
//
205-
// we do that for nodes who share a common parent
206-
207-
QList<QgsSymbolV2LegendNode*> symbolNodes;
208-
QMap<QString, int> widthMax;
209202
foreach ( const QgsLegendSymbolItemV2& i, r->legendSymbolItemsV2() )
210203
{
211204
QgsSymbolV2LegendNode * n = new QgsSymbolV2LegendNode( nodeLayer, i );
212205
nodes.append( n );
213-
if ( i.symbol() )
214-
{
215-
const QSize sz( n->minimumIconSize() );
216-
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
217-
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
218-
n->setIconSize( sz );
219-
symbolNodes.append( n );
220-
}
221-
}
222-
223-
foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
224-
{
225-
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
226-
Q_ASSERT( widthMax[parentKey] > 0 );
227-
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
228-
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
229206
}
230207

231208
if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() )

0 commit comments

Comments
 (0)
Please sign in to comment.