Fix incorrect sizing & pixelation of symbol previews on hidpi

displays
This commit is contained in:
Nyall Dawson 2023-06-21 17:33:14 +10:00
parent 1298018bc4
commit 0641766902
23 changed files with 99 additions and 84 deletions

View File

@ -9,6 +9,7 @@
typedef QList<QgsSymbolLayer *> QgsSymbolLayerList;
class QgsSymbolAnimationSettings
@ -334,7 +335,7 @@ layer.
%End
void drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext *customContext = 0, bool selected = false, const QgsExpressionContext *expressionContext = 0,
const QgsLegendPatchShape *patchShape = 0 );
const QgsLegendPatchShape *patchShape = 0, const QScreen *screen = 0 );
%Docstring
Draws an icon of the symbol that occupies an area given by ``size`` using the specified ``painter``.
@ -344,18 +345,15 @@ matches the settings from that context.
:param painter: destination painter
:param size: size of the icon
:param customContext: the context in which the rendering happens
:param selected: set to ``True`` to render the symbol in a selected state
:param selected: set to ``True`` to render the symbol in a selected state (since QGIS 3.10)
:param expressionContext: optional custom expression context
:param patchShape: optional patch shape to use for symbol preview. If not specified a default shape will be used instead.
:param screen: can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
.. seealso:: :py:func:`exportImage`
.. seealso:: :py:func:`asImage`
.. note::
Parameter selected added in QGIS 3.10
.. versionadded:: 2.6
%End
@ -383,13 +381,14 @@ matches the settings from that context.
.. seealso:: :py:func:`drawPreviewIcon`
%End
QImage bigSymbolPreviewImage( QgsExpressionContext *expressionContext = 0, Qgis::SymbolPreviewFlags flags = Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols ) /PyName=bigSymbolPreviewImageV2/;
QImage bigSymbolPreviewImage( QgsExpressionContext *expressionContext = 0, Qgis::SymbolPreviewFlags flags = Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols, const QScreen *screen = 0 ) /PyName=bigSymbolPreviewImageV2/;
%Docstring
Returns a large (roughly 100x100 pixel) preview image for the symbol.
:param expressionContext: optional expression context, for evaluation of
data defined symbol properties
:param flags: optional flags to control how preview image is generated
:param screen: can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
.. seealso:: :py:func:`asImage`

View File

@ -276,7 +276,7 @@ Decodes a symbol scale method from a string.
static QPainter::CompositionMode decodeBlendMode( const QString &s );
static QIcon symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding = 0, QgsLegendPatchShape *shape = 0 );
static QIcon symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding = 0, QgsLegendPatchShape *shape = 0, const QScreen *screen = 0 );
%Docstring
Returns an icon preview for a color ramp.
@ -284,39 +284,26 @@ Returns an icon preview for a color ramp.
:param size: target pixmap size
:param padding: space between icon edge and symbol
:param shape: optional legend patch shape to use for rendering the preview icon
:param screen: can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
.. seealso:: :py:func:`symbolPreviewPixmap`
%End
static QPixmap symbolPreviewPixmap( const QgsSymbol *symbol, QSize size, int padding = 0, QgsRenderContext *customContext = 0, bool selected = false,
const QgsExpressionContext *expressionContext = 0,
const QgsLegendPatchShape *shape = 0 );
const QgsLegendPatchShape *shape = 0,
const QScreen *screen = 0 );
%Docstring
Returns a pixmap preview for a color ramp.
:param symbol: symbol
:param size: target pixmap size
:param padding: space between icon edge and symbol
:param customContext: render context to use when rendering symbol
:param selected: set to ``True`` to render the symbol in a selected state
:param expressionContext: optional custom expression context
:param shape: optional legend patch shape to use for rendering the preview icon
.. note::
Parameter customContext added in QGIS 2.6
.. note::
Parameter selected added in QGIS 3.10
.. note::
Parameter expressionContext added in QGIS 3.10
.. note::
Parameter shape added in QGIS 3.14
:param customContext: render context to use when rendering symbol (since QGIS 2.6)
:param selected: set to ``True`` to render the symbol in a selected state (since QGIS 3.10)
:param expressionContext: optional custom expression context (since QGIS 3.10)
:param shape: optional legend patch shape to use for rendering the preview icon (since QGIS 3.14)
:param screen: can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
.. seealso:: :py:func:`symbolPreviewIcon`
%End

View File

@ -27,7 +27,7 @@ Tree model for the rules:
%End
public:
QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent );
QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent, const QScreen *screen = 0 );
%Docstring
Constructor for QgsRuleBasedRendererModel, for the specified ``renderer``.
%End

View File

@ -923,7 +923,7 @@ QColor QgsSymbol::color() const
return QColor( 0, 0, 0 );
}
void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext *customContext, bool selected, const QgsExpressionContext *expressionContext, const QgsLegendPatchShape *patchShape )
void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext *customContext, bool selected, const QgsExpressionContext *expressionContext, const QgsLegendPatchShape *patchShape, const QScreen *screen )
{
QgsRenderContext *context = customContext;
std::unique_ptr< QgsRenderContext > tempContext;
@ -934,6 +934,12 @@ void QgsSymbol::drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext
context->setFlag( Qgis::RenderContextFlag::RenderSymbolPreview, true );
}
if ( screen )
{
context->setScaleFactor( screen->physicalDotsPerInch() / 25.4 );
context->setDevicePixelRatio( screen->devicePixelRatio() );
}
const bool prevForceVector = context->forceVectorOutput();
context->setForceVectorOutput( true );
@ -1055,10 +1061,12 @@ QImage QgsSymbol::asImage( QSize size, QgsRenderContext *customContext )
}
QImage QgsSymbol::bigSymbolPreviewImage( QgsExpressionContext *expressionContext, Qgis::SymbolPreviewFlags flags )
QImage QgsSymbol::bigSymbolPreviewImage( QgsExpressionContext *expressionContext, Qgis::SymbolPreviewFlags flags, const QScreen *screen )
{
QImage preview( QSize( 100, 100 ), QImage::Format_ARGB32_Premultiplied );
const double devicePixelRatio = screen ? screen->devicePixelRatio() : 1;
QImage preview( QSize( 100, 100 ) * devicePixelRatio, QImage::Format_ARGB32_Premultiplied );
preview.fill( 0 );
preview.setDevicePixelRatio( devicePixelRatio );
QPainter p( &preview );
p.setRenderHint( QPainter::Antialiasing );
@ -1067,8 +1075,8 @@ QImage QgsSymbol::bigSymbolPreviewImage( QgsExpressionContext *expressionContext
if ( mType == Qgis::SymbolType::Marker && flags & Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols )
{
p.setPen( QPen( Qt::gray ) );
p.drawLine( 0, 50, 100, 50 );
p.drawLine( 50, 0, 50, 100 );
p.drawLine( QLineF( 0, 50, 100, 50 ) );
p.drawLine( QLineF( 50, 0, 50, 100 ) );
}
QgsRenderContext context = QgsRenderContext::fromQPainter( &p );
@ -1076,6 +1084,13 @@ QImage QgsSymbol::bigSymbolPreviewImage( QgsExpressionContext *expressionContext
context.setFlag( Qgis::RenderContextFlag::Antialiasing );
context.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms );
context.setPainterFlagsUsingContext( &p );
context.setDevicePixelRatio( devicePixelRatio );
if ( screen )
{
context.setScaleFactor( screen->physicalDotsPerInch() / 25.4 );
}
if ( expressionContext )
context.setExpressionContext( *expressionContext );

View File

@ -26,6 +26,8 @@ class QgsLegendPatchShape;
class QgsSymbolRenderContext;
class QgsLineSymbolLayer;
class QScreen;
typedef QList<QgsSymbolLayer *> QgsSymbolLayerList;
/**
@ -371,17 +373,17 @@ class CORE_EXPORT QgsSymbol
* \param painter destination painter
* \param size size of the icon
* \param customContext the context in which the rendering happens
* \param selected set to TRUE to render the symbol in a selected state
* \param selected set to TRUE to render the symbol in a selected state (since QGIS 3.10)
* \param expressionContext optional custom expression context
* \param patchShape optional patch shape to use for symbol preview. If not specified a default shape will be used instead.
* \param screen can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
*
* \see exportImage()
* \see asImage()
* \note Parameter selected added in QGIS 3.10
* \since QGIS 2.6
*/
void drawPreviewIcon( QPainter *painter, QSize size, QgsRenderContext *customContext = nullptr, bool selected = false, const QgsExpressionContext *expressionContext = nullptr,
const QgsLegendPatchShape *patchShape = nullptr );
const QgsLegendPatchShape *patchShape = nullptr, const QScreen *screen = nullptr );
/**
* Export the symbol as an image format, to the specified \a path and with the given \a size.
@ -411,11 +413,12 @@ class CORE_EXPORT QgsSymbol
* \param expressionContext optional expression context, for evaluation of
* data defined symbol properties
* \param flags optional flags to control how preview image is generated
* \param screen can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
*
* \see asImage()
* \see drawPreviewIcon()
*/
QImage bigSymbolPreviewImage( QgsExpressionContext *expressionContext = nullptr, Qgis::SymbolPreviewFlags flags = Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols ) SIP_PYNAME( bigSymbolPreviewImageV2 );
QImage bigSymbolPreviewImage( QgsExpressionContext *expressionContext = nullptr, Qgis::SymbolPreviewFlags flags = Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols, const QScreen *screen = nullptr ) SIP_PYNAME( bigSymbolPreviewImageV2 );
/**
* \deprecated use bigSymbolPreviewImageV2 instead.

View File

@ -868,15 +868,19 @@ QPainter::CompositionMode QgsSymbolLayerUtils::decodeBlendMode( const QString &s
return QPainter::CompositionMode_SourceOver; // "Normal"
}
QIcon QgsSymbolLayerUtils::symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding, QgsLegendPatchShape *shape )
QIcon QgsSymbolLayerUtils::symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding, QgsLegendPatchShape *shape, const QScreen *screen )
{
return QIcon( symbolPreviewPixmap( symbol, size, padding, nullptr, false, nullptr, shape ) );
return QIcon( symbolPreviewPixmap( symbol, size, padding, nullptr, false, nullptr, shape, screen ) );
}
QPixmap QgsSymbolLayerUtils::symbolPreviewPixmap( const QgsSymbol *symbol, QSize size, int padding, QgsRenderContext *customContext, bool selected, const QgsExpressionContext *expressionContext, const QgsLegendPatchShape *shape )
QPixmap QgsSymbolLayerUtils::symbolPreviewPixmap( const QgsSymbol *symbol, QSize size, int padding, QgsRenderContext *customContext, bool selected, const QgsExpressionContext *expressionContext, const QgsLegendPatchShape *shape, const QScreen *screen )
{
Q_ASSERT( symbol );
QPixmap pixmap( size );
const double devicePixelRatio = screen ? screen->devicePixelRatio() : 1;
QPixmap pixmap( size * devicePixelRatio );
pixmap.setDevicePixelRatio( devicePixelRatio );
pixmap.fill( Qt::transparent );
QPainter painter;
painter.begin( &pixmap );
@ -919,12 +923,12 @@ QPixmap QgsSymbolLayerUtils::symbolPreviewPixmap( const QgsSymbol *symbol, QSize
prop.setActive( false );
}
}
symbol_noDD->drawPreviewIcon( &painter, size, customContext, selected, expressionContext, shape );
symbol_noDD->drawPreviewIcon( &painter, size, customContext, selected, expressionContext, shape, screen );
}
else
{
std::unique_ptr<QgsSymbol> symbolClone( symbol->clone( ) );
symbolClone->drawPreviewIcon( &painter, size, customContext, selected, expressionContext, shape );
symbolClone->drawPreviewIcon( &painter, size, customContext, selected, expressionContext, shape, screen );
}
painter.end();

View File

@ -281,28 +281,27 @@ class CORE_EXPORT QgsSymbolLayerUtils
* \param size target pixmap size
* \param padding space between icon edge and symbol
* \param shape optional legend patch shape to use for rendering the preview icon
* \param screen can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
* \see symbolPreviewPixmap()
*/
static QIcon symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding = 0, QgsLegendPatchShape *shape = nullptr );
static QIcon symbolPreviewIcon( const QgsSymbol *symbol, QSize size, int padding = 0, QgsLegendPatchShape *shape = nullptr, const QScreen *screen = nullptr );
/**
* Returns a pixmap preview for a color ramp.
* \param symbol symbol
* \param size target pixmap size
* \param padding space between icon edge and symbol
* \param customContext render context to use when rendering symbol
* \param selected set to TRUE to render the symbol in a selected state
* \param expressionContext optional custom expression context
* \param shape optional legend patch shape to use for rendering the preview icon
* \note Parameter customContext added in QGIS 2.6
* \note Parameter selected added in QGIS 3.10
* \note Parameter expressionContext added in QGIS 3.10
* \note Parameter shape added in QGIS 3.14
* \param customContext render context to use when rendering symbol (since QGIS 2.6)
* \param selected set to TRUE to render the symbol in a selected state (since QGIS 3.10)
* \param expressionContext optional custom expression context (since QGIS 3.10)
* \param shape optional legend patch shape to use for rendering the preview icon (since QGIS 3.14)
* \param screen can be used to specify the destination screen for the icon. This allows the icon to be generated using the correct DPI and device pixel ratio for the target screen (since QGIS 3.32)
* \see symbolPreviewIcon()
*/
static QPixmap symbolPreviewPixmap( const QgsSymbol *symbol, QSize size, int padding = 0, QgsRenderContext *customContext = nullptr, bool selected = false,
const QgsExpressionContext *expressionContext = nullptr,
const QgsLegendPatchShape *shape = nullptr );
const QgsLegendPatchShape *shape = nullptr,
const QScreen *screen = nullptr );
/**
* Draws a symbol layer preview to a QPicture

View File

@ -287,7 +287,7 @@ void QgsLegendPatchShapeButton::updatePreview()
}
//create an icon pixmap
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mPreviewSymbol.get(), currentIconSize, currentIconSize.height() / 10, &mShape );
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mPreviewSymbol.get(), currentIconSize, currentIconSize.height() / 10, &mShape, screen() );
setIconSize( currentIconSize );
setIcon( icon );

View File

@ -125,7 +125,7 @@ void QgsMaskSourceSelectionWidget::update()
return true;
std::unique_ptr< QTreeWidgetItem > symbolItem = std::make_unique< QTreeWidgetItem >( mLayerItem, QStringList() << ( mCurrentDescription + leaf.description ) );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ) );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ), 0, nullptr, mScreen );
symbolItem->setIcon( 0, icon );
if ( visitSymbol( symbolItem.get(), leaf.identifier, symbol, {} ) )

View File

@ -507,7 +507,7 @@ void QgsSymbolButton::prepareMenu()
std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
if ( tempSymbol && tempSymbol->type() == mType )
{
pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1 ) );
pasteSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( tempSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, screen() ) );
}
else
{
@ -528,7 +528,7 @@ void QgsSymbolButton::prepareMenu()
if ( mDefaultSymbol )
{
QAction *defaultSymbolAction = new QAction( tr( "Default Symbol" ), this );
defaultSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( mDefaultSymbol.get(), QSize( iconSize, iconSize ), 1 ) );
defaultSymbolAction->setIcon( QgsSymbolLayerUtils::symbolPreviewIcon( mDefaultSymbol.get(), QSize( iconSize, iconSize ), 1, nullptr, screen() ) );
mMenu->addAction( defaultSymbolAction );
connect( defaultSymbolAction, &QAction::triggered, this, &QgsSymbolButton::setToDefaultSymbol );
}
@ -703,7 +703,7 @@ void QgsSymbolButton::updatePreview( const QColor &color, QgsSymbol *tempSymbol
previewSymbol->setColor( color );
//create an icon pixmap
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, screen() );
setIconSize( currentIconSize );
setIcon( icon );

View File

@ -119,7 +119,7 @@ void QgsSymbolLayerSelectionWidget::setLayer( const QgsVectorLayer *layer )
// either leaf.description or mCurrentDescription is defined
QTreeWidgetItem *symbolItem = new QTreeWidgetItem( QStringList() << ( mCurrentDescription + leaf.description ) );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ) );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( symbol, QSize( iconSize, iconSize ), 0, nullptr, mScreen );
symbolItem->setData( 0, Qt::UserRole, mCurrentIdentifier );
symbolItem->setIcon( 0, icon );
mLayerItem->addChild( symbolItem );

View File

@ -51,8 +51,9 @@
///@cond PRIVATE
QgsCategorizedSymbolRendererModel::QgsCategorizedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
QgsCategorizedSymbolRendererModel::QgsCategorizedSymbolRendererModel( QObject *parent, const QScreen *screen ) : QAbstractItemModel( parent )
, mMimeFormat( QStringLiteral( "application/x-qgscategorizedsymbolrendererv2model" ) )
, mScreen( screen )
{
}
@ -197,7 +198,7 @@ QVariant QgsCategorizedSymbolRendererModel::data( const QModelIndex &index, int
if ( index.column() == 0 && category.symbol() )
{
const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
return QgsSymbolLayerUtils::symbolPreviewIcon( category.symbol(), QSize( iconSize, iconSize ) );
return QgsSymbolLayerUtils::symbolPreviewIcon( category.symbol(), QSize( iconSize, iconSize ), 0, nullptr, mScreen );
}
break;
}
@ -669,7 +670,7 @@ QgsCategorizedSymbolRendererWidget::QgsCategorizedSymbolRendererWidget( QgsVecto
btnChangeCategorizedSymbol->setSymbol( mCategorizedSymbol->clone() );
}
mModel = new QgsCategorizedSymbolRendererModel( this );
mModel = new QgsCategorizedSymbolRendererModel( this, screen() );
mModel->setRenderer( mRenderer.get() );
// update GUI from renderer

View File

@ -37,7 +37,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererModel : public QAbstractItemModel
{
Q_OBJECT
public:
QgsCategorizedSymbolRendererModel( QObject *parent = nullptr );
QgsCategorizedSymbolRendererModel( QObject *parent = nullptr, const QScreen *screen = nullptr );
Qt::ItemFlags flags( const QModelIndex &index ) const override;
Qt::DropActions supportedDropActions() const override;
QVariant data( const QModelIndex &index, int role ) const override;
@ -66,6 +66,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererModel : public QAbstractItemModel
private:
QgsCategorizedSymbolRenderer *mRenderer = nullptr;
QString mMimeFormat;
const QScreen *mScreen = nullptr;
};
/**

View File

@ -82,7 +82,7 @@ QgsDataDefinedSizeLegendWidget::QgsDataDefinedSizeLegendWidget( const QgsDataDef
btnChangeSymbol->setEnabled( !mOverrideSymbol );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSourceSymbol.get(), btnChangeSymbol->iconSize() );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSourceSymbol.get(), btnChangeSymbol->iconSize(), 0, nullptr, screen() );
btnChangeSymbol->setIcon( icon );
editTitle->setText( ddsLegend ? ddsLegend->title() : QString() );
@ -212,7 +212,7 @@ void QgsDataDefinedSizeLegendWidget::changeSymbol()
return;
mSourceSymbol = std::move( newSymbol );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSourceSymbol.get(), btnChangeSymbol->iconSize() );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( mSourceSymbol.get(), btnChangeSymbol->iconSize(), 0, nullptr, screen() );
btnChangeSymbol->setIcon( icon );
emit widgetChanged();

View File

@ -61,8 +61,9 @@
///@cond PRIVATE
QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent ) : QAbstractItemModel( parent )
QgsGraduatedSymbolRendererModel::QgsGraduatedSymbolRendererModel( QObject *parent, const QScreen *screen ) : QAbstractItemModel( parent )
, mMimeFormat( QStringLiteral( "application/x-qgsgraduatedsymbolrendererv2model" ) )
, mScreen( screen )
{
}
@ -178,7 +179,7 @@ QVariant QgsGraduatedSymbolRendererModel::data( const QModelIndex &index, int ro
else if ( role == Qt::DecorationRole && index.column() == 0 && range.symbol() )
{
const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
return QgsSymbolLayerUtils::symbolPreviewIcon( range.symbol(), QSize( iconSize, iconSize ) );
return QgsSymbolLayerUtils::symbolPreviewIcon( range.symbol(), QSize( iconSize, iconSize ), 0, nullptr, mScreen );
}
else if ( role == Qt::TextAlignmentRole )
{
@ -481,7 +482,7 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay
connect( methodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGraduatedSymbolRendererWidget::methodComboBox_currentIndexChanged );
this->layout()->setContentsMargins( 0, 0, 0, 0 );
mModel = new QgsGraduatedSymbolRendererModel( this );
mModel = new QgsGraduatedSymbolRendererModel( this, screen() );
mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date );
mExpressionWidget->setLayer( mLayer );

View File

@ -39,7 +39,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererModel : public QAbstractItemModel
{
Q_OBJECT
public:
QgsGraduatedSymbolRendererModel( QObject *parent = nullptr );
QgsGraduatedSymbolRendererModel( QObject *parent = nullptr, const QScreen *screen = nullptr );
Qt::ItemFlags flags( const QModelIndex &index ) const override;
Qt::DropActions supportedDropActions() const override;
QVariant data( const QModelIndex &index, int role ) const override;
@ -70,6 +70,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererModel : public QAbstractItemModel
private:
QgsGraduatedSymbolRenderer *mRenderer = nullptr;
QString mMimeFormat;
const QScreen *mScreen = nullptr;
};
// View style which shows drop indicator line between items

View File

@ -76,7 +76,7 @@ QgsRuleBasedRendererWidget::QgsRuleBasedRendererWidget( QgsVectorLayer *layer, Q
setupUi( this );
this->layout()->setContentsMargins( 0, 0, 0, 0 );
mModel = new QgsRuleBasedRendererModel( mRenderer.get(), viewRules );
mModel = new QgsRuleBasedRendererModel( mRenderer.get(), viewRules, screen() );
#ifdef ENABLE_MODELTEST
new ModelTest( mModel, this ); // for model validity checking
#endif
@ -914,9 +914,10 @@ void QgsRendererRulePropsWidget::setDockMode( bool dockMode )
/////
QgsRuleBasedRendererModel::QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent )
QgsRuleBasedRendererModel::QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent, const QScreen *screen )
: QAbstractItemModel( parent )
, mR( renderer )
, mScreen( screen )
{
}
@ -1002,7 +1003,7 @@ QVariant QgsRuleBasedRendererModel::data( const QModelIndex &index, int role ) c
else if ( role == Qt::DecorationRole && index.column() == 0 && rule->symbol() )
{
const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
return QgsSymbolLayerUtils::symbolPreviewIcon( rule->symbol(), QSize( iconSize, iconSize ) );
return QgsSymbolLayerUtils::symbolPreviewIcon( rule->symbol(), QSize( iconSize, iconSize ), 0, nullptr, mScreen );
}
else if ( role == Qt::TextAlignmentRole )
{

View File

@ -53,7 +53,7 @@ class GUI_EXPORT QgsRuleBasedRendererModel : public QAbstractItemModel
/**
* Constructor for QgsRuleBasedRendererModel, for the specified \a renderer.
*/
QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent );
QgsRuleBasedRendererModel( QgsRuleBasedRenderer *renderer, QObject *parent, const QScreen *screen = nullptr );
Qt::ItemFlags flags( const QModelIndex &index ) const override;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
@ -103,6 +103,7 @@ class GUI_EXPORT QgsRuleBasedRendererModel : public QAbstractItemModel
protected:
QgsRuleBasedRenderer *mR = nullptr;
QHash<QgsRuleBasedRenderer::Rule *, QgsRuleBasedRendererCount> mFeatureCountMap;
const QScreen *mScreen = nullptr;
};

View File

@ -612,7 +612,7 @@ void QgsSimpleLineSymbolLayerWidget::updatePatternIcon()
//create an icon pixmap
const std::unique_ptr< QgsLineSymbol > previewSymbol = std::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << layerCopy.release() );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize );
const QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( previewSymbol.get(), currentIconSize, 0, nullptr, screen() );
mChangePatternButton->setIconSize( currentIconSize );
mChangePatternButton->setIcon( icon );
@ -621,7 +621,7 @@ void QgsSimpleLineSymbolLayerWidget::updatePatternIcon()
const int width = static_cast< int >( Qgis::UI_SCALE_FACTOR * fontMetrics().horizontalAdvance( 'X' ) * 23 );
const int height = static_cast< int >( width / 1.61803398875 ); // golden ratio
const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20 );
const QPixmap pm = QgsSymbolLayerUtils::symbolPreviewPixmap( previewSymbol.get(), QSize( width, height ), height / 20, nullptr, false, nullptr, nullptr, screen() );
QByteArray data;
QBuffer buffer( &data );
pm.save( &buffer, "PNG", 100 );

View File

@ -60,7 +60,7 @@ QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( const QgsLegendSymbolList &symbols
QgsSymbol *sym = mLegendSymbols.at( i ).symbol();
// set icons for the rows
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( sym, QSize( iconSize, iconSize ) );
QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( sym, QSize( iconSize, iconSize ), 0, nullptr, screen() );
tableLevels->setVerticalHeaderItem( i, new QTableWidgetItem( icon, QString() ) );
// find out max. number of layers per symbol

View File

@ -163,7 +163,7 @@ class SymbolLayerItem : public QStandardItem
{
QgsExpressionContext expContext;
expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mVectorLayer ) );
icon = QIcon( QgsSymbolLayerUtils::symbolPreviewPixmap( mSymbol, mSize, 0, nullptr, false, &expContext, nullptr ) );
icon = QIcon( QgsSymbolLayerUtils::symbolPreviewPixmap( mSymbol, mSize, 0, nullptr, false, &expContext, nullptr, mScreen ) );
}
setIcon( icon );
@ -461,7 +461,7 @@ void QgsSymbolSelectorWidget::updatePreview()
return;
std::unique_ptr< QgsSymbol > symbolClone( mSymbol->clone() );
const QImage preview = symbolClone->bigSymbolPreviewImage( &mPreviewExpressionContext, Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols );
const QImage preview = symbolClone->bigSymbolPreviewImage( &mPreviewExpressionContext, Qgis::SymbolPreviewFlag::FlagIncludeCrosshairsForMarkerSymbols, screen() );
lblPreview->setPixmap( QPixmap::fromImage( preview ) );
// Hope this is a appropriate place
if ( !mBlockModified )

View File

@ -33,9 +33,10 @@
///@cond PRIVATE
QgsVectorTileBasicRendererListModel::QgsVectorTileBasicRendererListModel( QgsVectorTileBasicRenderer *r, QObject *parent )
QgsVectorTileBasicRendererListModel::QgsVectorTileBasicRendererListModel( QgsVectorTileBasicRenderer *r, QObject *parent, const QScreen *screen )
: QAbstractListModel( parent )
, mRenderer( r )
, mScreen( screen )
{
}
@ -100,7 +101,7 @@ QVariant QgsVectorTileBasicRendererListModel::data( const QModelIndex &index, in
if ( index.column() == 0 && style.symbol() )
{
const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
return QgsSymbolLayerUtils::symbolPreviewIcon( style.symbol(), QSize( iconSize, iconSize ) );
return QgsSymbolLayerUtils::symbolPreviewIcon( style.symbol(), QSize( iconSize, iconSize ), 0, nullptr, mScreen );
}
break;
}
@ -395,7 +396,7 @@ void QgsVectorTileBasicRendererWidget::syncToLayer( QgsMapLayer *layer )
mRenderer.reset( new QgsVectorTileBasicRenderer() );
}
mModel = new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles );
mModel = new QgsVectorTileBasicRendererListModel( mRenderer.get(), viewStyles, screen() );
mProxyModel = new QgsVectorTileBasicRendererProxyModel( mModel, viewStyles );
viewStyles->setModel( mProxyModel );

View File

@ -88,7 +88,7 @@ class QgsVectorTileBasicRendererListModel : public QAbstractListModel
Filter
};
QgsVectorTileBasicRendererListModel( QgsVectorTileBasicRenderer *r, QObject *parent = nullptr );
QgsVectorTileBasicRendererListModel( QgsVectorTileBasicRenderer *r, QObject *parent = nullptr, const QScreen *screen = nullptr );
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
@ -109,6 +109,7 @@ class QgsVectorTileBasicRendererListModel : public QAbstractListModel
private:
QgsVectorTileBasicRenderer *mRenderer = nullptr;
const QScreen *mScreen = nullptr;
};
class QgsVectorTileBasicRendererProxyModel : public QSortFilterProxyModel