Merge pull request #9839 from wonder-sk/fix-3d-extra-terrain-updates

[3d] Fix unnecessary terrain map updates when changing 3D renderer
This commit is contained in:
Martin Dobias 2019-04-23 16:27:19 +02:00 committed by GitHub
commit 1106f6ab23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 9 deletions

View File

@ -36,6 +36,15 @@ A panel widget that can be shown in the map style dock
Keep the loading light as possible for speed in the UI. Keep the loading light as possible for speed in the UI.
%End %End
virtual bool shouldTriggerLayerRepaint() const;
%Docstring
Whether this config widget changes map layer properties in a way that triggerRepaint() should
be called for the layer after applying changes. This is true by default, but some config widgets
(for example 3D rendering config) do not need layer repaint as they do not modify 2D map rendering.
.. versionadded:: 3.8
%End
public slots: public slots:
virtual void apply() = 0; virtual void apply() = 0;

View File

@ -66,6 +66,9 @@ class QgsVectorLayer3DRendererWidget : public QgsMapLayerConfigWidget
void setDockMode( bool dockMode ) override; void setDockMode( bool dockMode ) override;
//! Only modifies 3D renderer so we do not want layer repaint (which would trigger unnecessary terrain map update)
bool shouldTriggerLayerRepaint() const override { return false; }
public slots: public slots:
void apply() override; void apply() override;

View File

@ -272,6 +272,7 @@ void QgsLayerStylingWidget::apply()
QWidget *current = mWidgetStack->mainPanel(); QWidget *current = mWidgetStack->mainPanel();
bool styleWasChanged = false; bool styleWasChanged = false;
bool triggerRepaint = false; // whether the change needs the layer to be repainted
if ( QgsLabelingWidget *widget = qobject_cast<QgsLabelingWidget *>( current ) ) if ( QgsLabelingWidget *widget = qobject_cast<QgsLabelingWidget *>( current ) )
{ {
widget->apply(); widget->apply();
@ -287,31 +288,34 @@ void QgsLayerStylingWidget::apply()
QgsRendererAbstractMetadata *m = QgsApplication::rendererRegistry()->rendererMetadata( layer->renderer()->type() ); QgsRendererAbstractMetadata *m = QgsApplication::rendererRegistry()->rendererMetadata( layer->renderer()->type() );
undoName = QStringLiteral( "Style Change - %1" ).arg( m->visibleName() ); undoName = QStringLiteral( "Style Change - %1" ).arg( m->visibleName() );
styleWasChanged = true; styleWasChanged = true;
triggerRepaint = true;
} }
} }
else if ( QgsRasterTransparencyWidget *widget = qobject_cast<QgsRasterTransparencyWidget *>( current ) ) else if ( QgsRasterTransparencyWidget *widget = qobject_cast<QgsRasterTransparencyWidget *>( current ) )
{ {
widget->apply(); widget->apply();
styleWasChanged = true; styleWasChanged = true;
triggerRepaint = true;
} }
else if ( qobject_cast<QgsRasterHistogramWidget *>( current ) ) else if ( qobject_cast<QgsRasterHistogramWidget *>( current ) )
{ {
mRasterStyleWidget->apply(); mRasterStyleWidget->apply();
styleWasChanged = true; styleWasChanged = true;
triggerRepaint = true;
} }
else if ( QgsMapLayerConfigWidget *widget = qobject_cast<QgsMapLayerConfigWidget *>( current ) ) else if ( QgsMapLayerConfigWidget *widget = qobject_cast<QgsMapLayerConfigWidget *>( current ) )
{ {
widget->apply(); widget->apply();
styleWasChanged = true; styleWasChanged = true;
triggerRepaint = widget->shouldTriggerLayerRepaint();
} }
pushUndoItem( undoName ); pushUndoItem( undoName, triggerRepaint );
if ( styleWasChanged ) if ( styleWasChanged )
{ {
emit styleChanged( mCurrentLayer ); emit styleChanged( mCurrentLayer );
QgsProject::instance()->setDirty( true ); QgsProject::instance()->setDirty( true );
mCurrentLayer->triggerRepaint();
} }
connect( mCurrentLayer, &QgsMapLayer::styleChanged, this, &QgsLayerStylingWidget::updateCurrentWidgetLayer ); connect( mCurrentLayer, &QgsMapLayer::styleChanged, this, &QgsLayerStylingWidget::updateCurrentWidgetLayer );
} }
@ -609,25 +613,26 @@ void QgsLayerStylingWidget::liveApplyToggled( bool value )
settings.setValue( QStringLiteral( "UI/autoApplyStyling" ), value ); settings.setValue( QStringLiteral( "UI/autoApplyStyling" ), value );
} }
void QgsLayerStylingWidget::pushUndoItem( const QString &name ) void QgsLayerStylingWidget::pushUndoItem( const QString &name, bool triggerRepaint )
{ {
QString errorMsg; QString errorMsg;
QDomDocument doc( QStringLiteral( "style" ) ); QDomDocument doc( QStringLiteral( "style" ) );
QDomElement rootNode = doc.createElement( QStringLiteral( "qgis" ) ); QDomElement rootNode = doc.createElement( QStringLiteral( "qgis" ) );
doc.appendChild( rootNode ); doc.appendChild( rootNode );
mCurrentLayer->writeStyle( rootNode, doc, errorMsg, QgsReadWriteContext() ); mCurrentLayer->writeStyle( rootNode, doc, errorMsg, QgsReadWriteContext() );
mCurrentLayer->undoStackStyles()->push( new QgsMapLayerStyleCommand( mCurrentLayer, name, rootNode, mLastStyleXml ) ); mCurrentLayer->undoStackStyles()->push( new QgsMapLayerStyleCommand( mCurrentLayer, name, rootNode, mLastStyleXml, triggerRepaint ) );
// Override the last style on the stack // Override the last style on the stack
mLastStyleXml = rootNode.cloneNode(); mLastStyleXml = rootNode.cloneNode();
} }
QgsMapLayerStyleCommand::QgsMapLayerStyleCommand( QgsMapLayer *layer, const QString &text, const QDomNode &current, const QDomNode &last ) QgsMapLayerStyleCommand::QgsMapLayerStyleCommand( QgsMapLayer *layer, const QString &text, const QDomNode &current, const QDomNode &last, bool triggerRepaint )
: QUndoCommand( text ) : QUndoCommand( text )
, mLayer( layer ) , mLayer( layer )
, mXml( current ) , mXml( current )
, mLastState( last ) , mLastState( last )
, mTime( QTime::currentTime() ) , mTime( QTime::currentTime() )
, mTriggerRepaint( triggerRepaint )
{ {
} }
@ -636,7 +641,8 @@ void QgsMapLayerStyleCommand::undo()
QString error; QString error;
QgsReadWriteContext context = QgsReadWriteContext(); QgsReadWriteContext context = QgsReadWriteContext();
mLayer->readStyle( mLastState, error, context ); mLayer->readStyle( mLastState, error, context );
mLayer->triggerRepaint(); if ( mTriggerRepaint )
mLayer->triggerRepaint();
} }
void QgsMapLayerStyleCommand::redo() void QgsMapLayerStyleCommand::redo()
@ -644,7 +650,8 @@ void QgsMapLayerStyleCommand::redo()
QString error; QString error;
QgsReadWriteContext context = QgsReadWriteContext(); QgsReadWriteContext context = QgsReadWriteContext();
mLayer->readStyle( mXml, error, context ); mLayer->readStyle( mXml, error, context );
mLayer->triggerRepaint(); if ( mTriggerRepaint )
mLayer->triggerRepaint();
} }
bool QgsMapLayerStyleCommand::mergeWith( const QUndoCommand *other ) bool QgsMapLayerStyleCommand::mergeWith( const QUndoCommand *other )
@ -665,6 +672,7 @@ bool QgsMapLayerStyleCommand::mergeWith( const QUndoCommand *other )
mXml = otherCmd->mXml; mXml = otherCmd->mXml;
mTime = otherCmd->mTime; mTime = otherCmd->mTime;
mTriggerRepaint |= otherCmd->mTriggerRepaint;
return true; return true;
} }

View File

@ -56,7 +56,7 @@ class APP_EXPORT QgsLayerStyleManagerWidgetFactory : public QgsMapLayerConfigWid
class APP_EXPORT QgsMapLayerStyleCommand : public QUndoCommand class APP_EXPORT QgsMapLayerStyleCommand : public QUndoCommand
{ {
public: public:
QgsMapLayerStyleCommand( QgsMapLayer *layer, const QString &text, const QDomNode &current, const QDomNode &last ); QgsMapLayerStyleCommand( QgsMapLayer *layer, const QString &text, const QDomNode &current, const QDomNode &last, bool triggerRepaint = true );
/** /**
* Returns unique ID for this kind of undo command. * Returns unique ID for this kind of undo command.
@ -75,6 +75,7 @@ class APP_EXPORT QgsMapLayerStyleCommand : public QUndoCommand
QDomNode mXml; QDomNode mXml;
QDomNode mLastState; QDomNode mLastState;
QTime mTime; QTime mTime;
bool mTriggerRepaint = true;
}; };
class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerStylingWidgetBase class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerStylingWidgetBase
@ -129,7 +130,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty
void liveApplyToggled( bool value ); void liveApplyToggled( bool value );
private: private:
void pushUndoItem( const QString &name ); void pushUndoItem( const QString &name, bool triggerRepaint = true );
int mNotSupportedPage; int mNotSupportedPage;
int mLayerPage; int mLayerPage;
QTimer *mAutoApplyTimer = nullptr; QTimer *mAutoApplyTimer = nullptr;

View File

@ -45,6 +45,14 @@ class GUI_EXPORT QgsMapLayerConfigWidget : public QgsPanelWidget
*/ */
QgsMapLayerConfigWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr ); QgsMapLayerConfigWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr );
/**
* Whether this config widget changes map layer properties in a way that triggerRepaint() should
* be called for the layer after applying changes. This is true by default, but some config widgets
* (for example 3D rendering config) do not need layer repaint as they do not modify 2D map rendering.
* \since QGIS 3.8
*/
virtual bool shouldTriggerLayerRepaint() const { return true; }
public slots: public slots:
/** /**