Skip to content

Commit 27bb2c1

Browse files
committedJan 27, 2019
Fix undersized layertree icons on hidpi displays
1 parent fc9796f commit 27bb2c1

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed
 

‎python/core/auto_generated/layertree/qgslayertreemodel.sip.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,17 @@ Gets map of map layer style overrides (key: layer ID, value: style name) where a
307307
Sets map of map layer style overrides (key: layer ID, value: style name) where a different style should be used instead of the current one
308308

309309
.. versionadded:: 2.10
310+
%End
311+
312+
static int scaleIconSize( int standardSize );
313+
%Docstring
314+
Scales an layer tree model icon size to compensate for display pixel density, making the icon
315+
size hi-dpi friendly, whilst still resulting in pixel-perfect sizes for low-dpi
316+
displays.
317+
318+
``standardSize`` should be set to a standard icon size, e.g. 16, 24, 48, etc.
319+
320+
.. versionadded:: 3.6
310321
%End
311322

312323
protected slots:

‎src/core/layertree/qgslayertreemodel.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,11 @@ QVariant QgsLayerTreeModel::data( const QModelIndex &index, int role ) const
224224

225225
if ( vlayer && vlayer->isEditable() )
226226
{
227-
QPixmap pixmap( icon.pixmap( 16, 16 ) );
227+
const int iconSize = scaleIconSize( 16 );
228+
QPixmap pixmap( icon.pixmap( iconSize, iconSize ) );
228229

229230
QPainter painter( &pixmap );
230-
painter.drawPixmap( 0, 0, 16, 16, QgsApplication::getThemePixmap( vlayer->isModified() ? "/mIconEditableEdits.svg" : "/mActionToggleEditing.svg" ) );
231+
painter.drawPixmap( 0, 0, iconSize, iconSize, QgsApplication::getThemePixmap( vlayer->isModified() ? QStringLiteral( "/mIconEditableEdits.svg" ) : QStringLiteral( "/mActionToggleEditing.svg" ) ) );
231232
painter.end();
232233

233234
icon = QIcon( pixmap );
@@ -690,6 +691,13 @@ void QgsLayerTreeModel::setLayerStyleOverrides( const QMap<QString, QString> &ov
690691
mLayerStyleOverrides = overrides;
691692
}
692693

694+
int QgsLayerTreeModel::scaleIconSize( int standardSize )
695+
{
696+
QFontMetrics fm( ( QFont() ) );
697+
const double scale = 1.1 * standardSize / 24;
698+
return static_cast< int >( std::floor( std::max( Qgis::UI_SCALE_FACTOR * fm.height() * scale, static_cast< double >( standardSize ) ) ) );
699+
}
700+
693701
void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo )
694702
{
695703
Q_ASSERT( node );

‎src/core/layertree/qgslayertreemodel.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,17 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
274274
*/
275275
void setLayerStyleOverrides( const QMap<QString, QString> &overrides );
276276

277+
/**
278+
* Scales an layer tree model icon size to compensate for display pixel density, making the icon
279+
* size hi-dpi friendly, whilst still resulting in pixel-perfect sizes for low-dpi
280+
* displays.
281+
*
282+
* \a standardSize should be set to a standard icon size, e.g. 16, 24, 48, etc.
283+
*
284+
* \since QGIS 3.6
285+
*/
286+
static int scaleIconSize( int standardSize );
287+
277288
protected slots:
278289
void nodeWillAddChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );
279290
void nodeAddedChildren( QgsLayerTreeNode *node, int indexFrom, int indexTo );

‎src/core/layertree/qgslayertreemodellegendnode.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,14 @@ QSizeF QgsLayerTreeModelLegendNode::drawSymbolText( const QgsLegendSettings &set
130130

131131
// -------------------------------------------------------------------------
132132

133-
134133
QgsSymbolLegendNode::QgsSymbolLegendNode( QgsLayerTreeLayer *nodeLayer, const QgsLegendSymbolItem &item, QObject *parent )
135134
: QgsLayerTreeModelLegendNode( nodeLayer, parent )
136135
, mItem( item )
137136
, mSymbolUsesMapUnits( false )
138-
, mIconSize( 16, 16 )
139137
{
138+
const int iconSize = QgsLayerTreeModel::scaleIconSize( 16 );
139+
mIconSize = QSize( iconSize, iconSize );
140+
140141
updateLabel();
141142
connect( qobject_cast<QgsVectorLayer *>( nodeLayer->layer() ), &QgsVectorLayer::symbolFeatureCountMapChanged, this, &QgsSymbolLegendNode::updateLabel );
142143
connect( nodeLayer, &QObject::destroyed, this, [ = ]() { mLayerNode = nullptr; } );
@@ -162,19 +163,21 @@ QSize QgsSymbolLegendNode::minimumIconSize() const
162163

163164
QSize QgsSymbolLegendNode::minimumIconSize( QgsRenderContext *context ) const
164165
{
165-
QSize minSz( 16, 16 );
166+
const int iconSize = QgsLayerTreeModel::scaleIconSize( 16 );
167+
const int largeIconSize = QgsLayerTreeModel::scaleIconSize( 512 );
168+
QSize minSz( iconSize, iconSize );
166169
if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbol::Marker )
167170
{
168171
minSz = QgsImageOperation::nonTransparentImageRect(
169-
QgsSymbolLayerUtils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ), 0,
172+
QgsSymbolLayerUtils::symbolPreviewPixmap( mItem.symbol(), QSize( largeIconSize, largeIconSize ), 0,
170173
context ).toImage(),
171174
minSz,
172175
true ).size();
173176
}
174177
else if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbol::Line )
175178
{
176179
minSz = QgsImageOperation::nonTransparentImageRect(
177-
QgsSymbolLayerUtils::symbolPreviewPixmap( mItem.symbol(), QSize( minSz.width(), 512 ), 0,
180+
QgsSymbolLayerUtils::symbolPreviewPixmap( mItem.symbol(), QSize( minSz.width(), largeIconSize ), 0,
178181
context ).toImage(),
179182
minSz,
180183
true ).size();
@@ -607,8 +610,8 @@ QVariant QgsRasterSymbolLegendNode::data( int role ) const
607610
{
608611
if ( role == Qt::DecorationRole )
609612
{
610-
QSize iconSize( 16, 16 ); // TODO: configurable?
611-
QPixmap pix( iconSize );
613+
const int iconSize = QgsLayerTreeModel::scaleIconSize( 16 ); // TODO: configurable?
614+
QPixmap pix( iconSize, iconSize );
612615
pix.fill( mColor );
613616
return QIcon( pix );
614617
}

0 commit comments

Comments
 (0)
Please sign in to comment.