Skip to content

Commit

Permalink
Add API to allow generation of icons for 3d symbols from app
Browse files Browse the repository at this point in the history
(still not implement -- but a necessary prerequisite to proper icons)
  • Loading branch information
nyalldawson committed Jul 29, 2020
1 parent c938de4 commit 1484a30
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 0 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/symbology/qgsstylemodel.sip.in
Expand Up @@ -9,6 +9,7 @@




class QgsStyleModel: QAbstractItemModel
{
%Docstring
Expand Down Expand Up @@ -85,6 +86,7 @@ This allows style icons to be generated at an icon size which
corresponds exactly to the view's icon size in which this model is used.
%End


};

class QgsStyleProxyModel: QSortFilterProxyModel
Expand Down
37 changes: 37 additions & 0 deletions src/app/3d/qgs3dicongenerator.cpp
@@ -0,0 +1,37 @@
/***************************************************************************
qgs3dicongenerator.cpp
---------------
begin : July 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgs3dicongenerator.h"
#include "qgsapplication.h"

Qgs3DIconGenerator::Qgs3DIconGenerator( QObject *parent )
: QgsAbstractStyleEntityIconGenerator( parent )
{

}

void Qgs3DIconGenerator::generateIcon( QgsStyle *, QgsStyle::StyleEntity type, const QString &name )
{
QIcon icon;
const QList< QSize > sizes = iconSizes();
if ( sizes.isEmpty() )
icon.addFile( QgsApplication::defaultThemePath() + QDir::separator() + QStringLiteral( "3d.svg" ), QSize( 24, 24 ) );
for ( const QSize &s : sizes )
{
icon.addFile( QgsApplication::defaultThemePath() + QDir::separator() + QStringLiteral( "3d.svg" ), s );
}

emit iconGenerated( type, name, icon );
}
34 changes: 34 additions & 0 deletions src/app/3d/qgs3dicongenerator.h
@@ -0,0 +1,34 @@
/***************************************************************************
qgs3dicongenerator.h
---------------
begin : July 2020
copyright : (C) 2020 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGS3DICONGENERATOR_H
#define QGS3DICONGENERATOR_H

#include "qgsstylemodel.h"

class QgsSymbol;

class Qgs3DIconGenerator : public QgsAbstractStyleEntityIconGenerator
{
Q_OBJECT

public:

Qgs3DIconGenerator( QObject *parent );

void generateIcon( QgsStyle *style, QgsStyle::StyleEntity type, const QString &name ) override;
};

#endif //QGS3DICONGENERATOR_H
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -262,6 +262,7 @@ IF (WITH_3D)
3d/qgs3danimationwidget.cpp
3d/qgs3danimationexportdialog.cpp
3d/qgs3dapputils.cpp
3d/qgs3dicongenerator.cpp
3d/qgs3dmapcanvas.cpp
3d/qgs3dmapcanvasdockwidget.cpp
3d/qgs3dmapconfigwidget.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -12657,6 +12657,8 @@ void QgisApp::init3D()
// initialize 3D registries
Qgs3D::initialize();
Qgs3DAppUtils::initialize();

QgsStyleModel::setIconGenerator( new Qgs3DIconGenerator( QgsApplication::defaultStyleModel() ) );
#else
mActionNew3DMapCanvas->setVisible( false );
#endif
Expand Down
71 changes: 71 additions & 0 deletions src/core/symbology/qgsstylemodel.cpp
Expand Up @@ -27,6 +27,33 @@ const double ICON_PADDING_FACTOR = 0.16;

const auto ENTITIES = { QgsStyle::SymbolEntity, QgsStyle::ColorrampEntity, QgsStyle::TextFormatEntity, QgsStyle::LabelSettingsEntity, QgsStyle::LegendPatchShapeEntity, QgsStyle::Symbol3DEntity };

QgsAbstractStyleEntityIconGenerator *QgsStyleModel::sIconGenerator = nullptr;

//
// QgsAbstractStyleEntityIconGenerator
//

QgsAbstractStyleEntityIconGenerator::QgsAbstractStyleEntityIconGenerator( QObject *parent )
: QObject( parent )
{

}

void QgsAbstractStyleEntityIconGenerator::setIconSizes( const QList<QSize> &sizes )
{
mIconSizes = sizes;
}

QList<QSize> QgsAbstractStyleEntityIconGenerator::iconSizes() const
{
return mIconSizes;
}


//
// QgsStyleModel
//

QgsStyleModel::QgsStyleModel( QgsStyle *style, QObject *parent )
: QAbstractItemModel( parent )
, mStyle( style )
Expand Down Expand Up @@ -55,6 +82,9 @@ QgsStyleModel::QgsStyleModel( QgsStyle *style, QObject *parent )
// if project color scheme changes, we need to redraw symbols - they may use project colors and accordingly
// need updating to reflect the new colors
connect( QgsProject::instance(), &QgsProject::projectColorsChanged, this, &QgsStyleModel::rebuildSymbolIcons );

if ( sIconGenerator )
connect( sIconGenerator, &QgsAbstractStyleEntityIconGenerator::iconGenerated, this, &QgsStyleModel::iconGenerated, Qt::QueuedConnection );
}

QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
Expand Down Expand Up @@ -326,6 +356,13 @@ QVariant QgsStyleModel::data( const QModelIndex &index, int role ) const
if ( !icon.isNull() )
return icon;

if ( sIconGenerator && !mPending3dSymbolIcons.contains( name ) )
{
mPending3dSymbolIcons.insert( name );
sIconGenerator->generateIcon( mStyle, QgsStyle::Symbol3DEntity, name );
}

// TODO - use hourglass icon
if ( mAdditionalSizes.isEmpty() )
icon.addFile( QgsApplication::defaultThemePath() + QDir::separator() + QStringLiteral( "3d.svg" ), QSize( 24, 24 ) );
for ( const QSize &s : mAdditionalSizes )
Expand Down Expand Up @@ -553,9 +590,19 @@ void QgsStyleModel::addDesiredIconSize( QSize size )
return;

mAdditionalSizes << size;

if ( sIconGenerator )
sIconGenerator->setIconSizes( mAdditionalSizes );

mIconCache.clear();
}

void QgsStyleModel::setIconGenerator( QgsAbstractStyleEntityIconGenerator *generator )
{
sIconGenerator = generator;
connect( sIconGenerator, &QgsAbstractStyleEntityIconGenerator::iconGenerated, QgsApplication::defaultStyleModel(), &QgsStyleModel::iconGenerated, Qt::QueuedConnection );
}

void QgsStyleModel::onEntityAdded( QgsStyle::StyleEntity type, const QString &name )
{
mIconCache[ type ].remove( name );
Expand Down Expand Up @@ -651,6 +698,29 @@ void QgsStyleModel::rebuildSymbolIcons()
emit dataChanged( index( 0, 0 ), index( mEntityNames[ QgsStyle::SymbolEntity ].count() - 1, 0 ), QVector<int>() << Qt::DecorationRole );
}

void QgsStyleModel::iconGenerated( QgsStyle::StyleEntity type, const QString &name, const QIcon &icon )
{
int row = mEntityNames[type].indexOf( name ) + offsetForEntity( type );

switch ( type )
{
case QgsStyle::Symbol3DEntity:
mPending3dSymbolIcons.remove( name );
mIconCache[ QgsStyle::Symbol3DEntity ].insert( name, icon );
emit dataChanged( index( row, 0 ), index( row, 0 ) );
break;

case QgsStyle::SymbolEntity:
case QgsStyle::TagEntity:
case QgsStyle::ColorrampEntity:
case QgsStyle::LegendPatchShapeEntity:
case QgsStyle::TextFormatEntity:
case QgsStyle::SmartgroupEntity:
case QgsStyle::LabelSettingsEntity:
break;
}
}

QgsStyle::StyleEntity QgsStyleModel::entityTypeFromRow( int row ) const
{
int maxRowForEntity = 0;
Expand Down Expand Up @@ -946,3 +1016,4 @@ void QgsStyleProxyModel::setEntityFilters( const QList<QgsStyle::StyleEntity> &f
mEntityFilters = filters;
invalidateFilter();
}

76 changes: 76 additions & 0 deletions src/core/symbology/qgsstylemodel.h
Expand Up @@ -27,6 +27,68 @@

class QgsSymbol;

#ifndef SIP_RUN

/**
* \ingroup core
* \class QgsAbstractStyleEntityIconGenerator
*
* An abstract base class for icon generators for a QgsStyleModel.
*
* This base class allows for creation of specialised icon generators for
* entities in a style database, and allows for deferred icon generation.
*
* \note Not available in Python bindings
* \since QGIS 3.16
*/
class CORE_EXPORT QgsAbstractStyleEntityIconGenerator : public QObject
{
Q_OBJECT

public:

/**
* Constructor for QgsAbstractStyleEntityIconGenerator, with the specified \a parent
* object.
*/
QgsAbstractStyleEntityIconGenerator( QObject *parent );

/**
* Triggers generation of an icon for an entity from the specified \a style database,
* with matching entity \a type and \a name.
*/
virtual void generateIcon( QgsStyle *style, QgsStyle::StyleEntity type, const QString &name ) = 0;

/**
* Sets the list of icon \a sizes to generate.
*
* \see iconSizes()
*/
void setIconSizes( const QList< QSize > &sizes );

/**
* Returns the list of icon \a sizes to generate.
*
* \see setIconSizes()
*/
QList< QSize > iconSizes() const;

signals:

/**
* Emitted when the \a icon for the style entity with matching \a type and \a name
* has been generated.
*/
void iconGenerated( QgsStyle::StyleEntity type, const QString &name, const QIcon &icon );

private:

QList< QSize > mIconSizes;

};

#endif

/**
* \ingroup core
* \class QgsStyleModel
Expand Down Expand Up @@ -99,6 +161,16 @@ class CORE_EXPORT QgsStyleModel: public QAbstractItemModel
*/
void addDesiredIconSize( QSize size );

/**
* Sets the icon \a generator to use for deferred style entity icon generation.
*
* Currently this is used for 3D symbol icons only.
*
* \note Not available in Python bindings
* \since QGIS 3.16
*/
static void setIconGenerator( QgsAbstractStyleEntityIconGenerator *generator ) SIP_SKIP;

private slots:

void onEntityAdded( QgsStyle::StyleEntity type, const QString &name );
Expand All @@ -107,6 +179,7 @@ class CORE_EXPORT QgsStyleModel: public QAbstractItemModel
void onEntityRename( QgsStyle::StyleEntity type, const QString &oldName, const QString &newName );
void onTagsChanged( int entity, const QString &name, const QStringList &tags );
void rebuildSymbolIcons();
void iconGenerated( QgsStyle::StyleEntity type, const QString &name, const QIcon &icon );

private:

Expand All @@ -119,6 +192,9 @@ class CORE_EXPORT QgsStyleModel: public QAbstractItemModel

mutable QHash< QgsStyle::StyleEntity, QHash< QString, QIcon > > mIconCache;

static QgsAbstractStyleEntityIconGenerator *sIconGenerator;
mutable QSet< QString > mPending3dSymbolIcons;

QgsStyle::StyleEntity entityTypeFromRow( int row ) const;

int offsetForEntity( QgsStyle::StyleEntity entity ) const;
Expand Down

0 comments on commit 1484a30

Please sign in to comment.