Skip to content
Permalink
Browse files

Use registry to create material widget

  • Loading branch information
nyalldawson committed Jul 28, 2020
1 parent beece16 commit 752288637a08553987731dc5f5d06851a7c55e95
@@ -63,7 +63,7 @@ void Qgs3D::initialize()
QgsApplication::symbol3DRegistry()->addSymbolType( new Qgs3DSymbolMetadata( QStringLiteral( "polygon" ), QObject::tr( "Polygon" ),
&QgsPolygon3DSymbol::create, nullptr, Qgs3DSymbolImpl::handlerForPolygon3DSymbol ) );

instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "phong" ), QObject::tr( "Phong" ),
instance()->materialRegistry()->addMaterialSettingsType( new QgsMaterialSettingsMetadata( QStringLiteral( "phong" ), QObject::tr( "Realistic (Phong)" ),
QgsPhongMaterialSettings::create, nullptr ) );
}

@@ -37,7 +37,7 @@ QgsLine3DSymbolWidget::QgsLine3DSymbolWidget( QWidget *parent )
connect( cboAltBinding, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLine3DSymbolWidget::changed );
connect( chkSimpleLines, &QCheckBox::clicked, this, &QgsLine3DSymbolWidget::changed );
connect( chkSimpleLines, &QCheckBox::clicked, this, &QgsLine3DSymbolWidget::updateGuiState );
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsLine3DSymbolWidget::changed );
connect( widgetMaterial, &QgsMaterialWidget::changed, this, &QgsLine3DSymbolWidget::changed );
}

Qgs3DSymbolWidget *QgsLine3DSymbolWidget::create( QgsVectorLayer * )
@@ -0,0 +1,116 @@
/***************************************************************************
qgsmaterialwidget.h
--------------------------------------
Date : 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 "qgsmaterialwidget.h"
#include "qgs3d.h"
#include "qgsmaterialregistry.h"
#include "qgsabstractmaterialsettings.h"
#include "qgsmaterialsettingswidget.h"
#include "qgsreadwritecontext.h"
#include "qgsphongmaterialsettings.h"

QgsMaterialWidget::QgsMaterialWidget( QWidget *parent )
: QWidget( parent )
, mCurrentSettings( qgis::make_unique< QgsPhongMaterialSettings >() )
{
setupUi( this );

const QStringList materialTypes = Qgs3D::materialRegistry()->materialSettingsTypes();
for ( const QString &type : materialTypes )
{
mMaterialTypeComboBox->addItem( Qgs3D::materialRegistry()->materialSettingsMetadata( type )->visibleName(), type );
}

connect( mMaterialTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsMaterialWidget::materialTypeChanged );
}

void QgsMaterialWidget::setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer * )
{
mMaterialTypeComboBox->setCurrentIndex( mMaterialTypeComboBox->findData( settings->type() ) );
mCurrentSettings.reset( settings->clone() );
updateMaterialWidget();
}

QgsAbstractMaterialSettings *QgsMaterialWidget::settings()
{
return mCurrentSettings->clone();
}

void QgsMaterialWidget::materialTypeChanged()
{
std::unique_ptr< QgsAbstractMaterialSettings > currentSettings( settings() );
const QString existingType = currentSettings ? currentSettings->type() : QString();
const QString newType = mMaterialTypeComboBox->currentData().toString();
if ( existingType == newType )
return;

if ( QgsMaterialSettingsAbstractMetadata *am = Qgs3D::materialRegistry()->materialSettingsMetadata( newType ) )
{
// change material to a new (with different type)
// base new layer on existing materials's properties
std::unique_ptr< QgsAbstractMaterialSettings > newMaterial( am->create() );
if ( newMaterial )
{
if ( currentSettings )
{
QDomDocument doc;
QDomElement tempElem = doc.createElement( QStringLiteral( "temp" ) );
currentSettings->writeXml( tempElem, QgsReadWriteContext() );
newMaterial->readXml( tempElem, QgsReadWriteContext() );
}

mCurrentSettings = std::move( newMaterial );
updateMaterialWidget();
emit changed();
}
}
}

void QgsMaterialWidget::materialWidgetChanged()
{
if ( QgsMaterialSettingsWidget *w = qobject_cast< QgsMaterialSettingsWidget * >( mStackedWidget->currentWidget() ) )
{
mCurrentSettings.reset( w->settings() );
}
emit changed();
}

void QgsMaterialWidget::updateMaterialWidget()
{
if ( mStackedWidget->currentWidget() != mPageDummy )
{
// stop updating from the original widget
if ( QgsMaterialSettingsWidget *w = qobject_cast< QgsMaterialSettingsWidget * >( mStackedWidget->currentWidget() ) )
disconnect( w, &QgsMaterialSettingsWidget::changed, this, &QgsMaterialWidget::materialWidgetChanged );
mStackedWidget->removeWidget( mStackedWidget->currentWidget() );
}

const QString settingsType = mCurrentSettings->type();
if ( QgsMaterialSettingsAbstractMetadata *am = Qgs3D::materialRegistry()->materialSettingsMetadata( settingsType ) )
{
if ( QgsMaterialSettingsWidget *w = am->createWidget() )
{
w->setSettings( mCurrentSettings.get(), nullptr );
mStackedWidget->addWidget( w );
mStackedWidget->setCurrentWidget( w );
// start receiving updates from widget
connect( w, &QgsMaterialSettingsWidget::changed, this, &QgsMaterialWidget::materialWidgetChanged );
return;
}
}
// When anything is not right
mStackedWidget->setCurrentWidget( mPageDummy );
}

@@ -0,0 +1,51 @@
/***************************************************************************
qgsmaterialwidget.h
--------------------------------------
Date : 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 QGSMATERIALWIDGET_H
#define QGSMATERIALWIDGET_H

#include <QWidget>
#include <ui_materialwidget.h>

class QgsAbstractMaterialSettings;
class QgsVectorLayer;

//! Widget for configuration of material settings
class QgsMaterialWidget : public QWidget, private Ui::MaterialWidgetBase
{
Q_OBJECT
public:
explicit QgsMaterialWidget( QWidget *parent = nullptr );

void setSettings( const QgsAbstractMaterialSettings *settings, QgsVectorLayer *layer );
QgsAbstractMaterialSettings *settings();

signals:

void changed();

private slots:
void materialTypeChanged();
void materialWidgetChanged();

private:
void updateMaterialWidget();

std::unique_ptr< QgsAbstractMaterialSettings > mCurrentSettings;


};

#endif // QGSMATERIALWIDGET_H
@@ -23,6 +23,8 @@ QgsPhongMaterialWidget::QgsPhongMaterialWidget( QWidget *parent )
{
setupUi( this );

activateTexturingUI( true );

QgsPhongMaterialSettings defaultMaterial;
setSettings( &defaultMaterial, nullptr );
textureScaleSpinBox->setClearValue( 0 );
@@ -36,7 +38,6 @@ QgsPhongMaterialWidget::QgsPhongMaterialWidget( QWidget *parent )
connect( textureFile, &QgsImageSourceLineEdit::sourceChanged, this, &QgsPhongMaterialWidget::changed );
connect( textureScaleSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPhongMaterialWidget::changed );
connect( textureRotationSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPhongMaterialWidget::changed );
this->activateTexturingUI( false );
}

QgsMaterialSettingsWidget *QgsPhongMaterialWidget::create()
@@ -40,10 +40,7 @@ class QgsPhongMaterialWidget : public QgsMaterialSettingsWidget, private Ui::Pho

//! activates the texturing UI (to make sure texturing UI isn't visible when the user doesn't need it like in the 3D configuration window)
void activateTexturingUI( bool activated );
signals:
void changed();

public slots:
};

#endif // QGSPHONGMATERIALWIDGET_H
@@ -67,7 +67,7 @@ QgsPoint3DSymbolWidget::QgsPoint3DSymbolWidget( QWidget *parent )
connect( spinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPoint3DSymbolWidget::changed );
connect( lineEditModel, &QgsAbstractFileContentSourceLineEdit::sourceChanged, this, &QgsPoint3DSymbolWidget::changed );
connect( cbOverwriteMaterial, static_cast<void ( QCheckBox::* )( int )>( &QCheckBox::stateChanged ), this, &QgsPoint3DSymbolWidget::onOverwriteMaterialChecked );
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsPoint3DSymbolWidget::changed );
connect( widgetMaterial, &QgsMaterialWidget::changed, this, &QgsPoint3DSymbolWidget::changed );
connect( btnChangeSymbol, static_cast<void ( QgsSymbolButton::* )( )>( &QgsSymbolButton::changed ), this, &QgsPoint3DSymbolWidget::changed );

// Sync between billboard height and TY
@@ -36,14 +36,12 @@ QgsPolygon3DSymbolWidget::QgsPolygon3DSymbolWidget( QWidget *parent )
connect( cboRenderedFacade, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsPolygon3DSymbolWidget::changed );
connect( chkAddBackFaces, &QCheckBox::clicked, this, &QgsPolygon3DSymbolWidget::changed );
connect( chkInvertNormals, &QCheckBox::clicked, this, &QgsPolygon3DSymbolWidget::changed );
connect( widgetMaterial, &QgsPhongMaterialWidget::changed, this, &QgsPolygon3DSymbolWidget::changed );
connect( widgetMaterial, &QgsMaterialWidget::changed, this, &QgsPolygon3DSymbolWidget::changed );
connect( btnHeightDD, &QgsPropertyOverrideButton::changed, this, &QgsPolygon3DSymbolWidget::changed );
connect( btnExtrusionDD, &QgsPropertyOverrideButton::changed, this, &QgsPolygon3DSymbolWidget::changed );
connect( groupEdges, &QGroupBox::clicked, this, &QgsPolygon3DSymbolWidget::changed );
connect( btnEdgeColor, &QgsColorButton::colorChanged, this, &QgsPolygon3DSymbolWidget::changed );
connect( spinEdgeWidth, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsPolygon3DSymbolWidget::changed );

widgetMaterial->activateTexturingUI( true );
}

Qgs3DSymbolWidget *QgsPolygon3DSymbolWidget::create( QgsVectorLayer * )
@@ -273,6 +273,7 @@ IF (WITH_3D)
3d/qgs3dnavigationwidget.cpp
3d/qgslightswidget.cpp
3d/qgsline3dsymbolwidget.cpp
3d/qgsmaterialwidget.cpp
3d/qgsmesh3dsymbolwidget.cpp
3d/qgspoint3dsymbolwidget.cpp
3d/qgspolygon3dsymbolwidget.cpp
@@ -54,6 +54,13 @@ class GUI_EXPORT QgsMaterialSettingsWidget : public QWidget
* Caller takes ownership of the returned settings.
*/
virtual QgsAbstractMaterialSettings *settings() = 0 SIP_FACTORY;

signals:

/**
* Emitted when the material definition is changed.
*/
void changed();
};

#endif // QGSMATERIALSETTINGSWIDGET_H
@@ -130,7 +130,7 @@
<number>0</number>
</property>
<item row="3" column="0" colspan="2">
<widget class="QgsPhongMaterialWidget" name="widgetMaterial" native="true">
<widget class="QgsMaterialWidget" name="widgetMaterial" native="true">
<property name="minimumSize">
<size>
<width>10</width>
@@ -159,9 +159,9 @@
</widget>
<customwidgets>
<customwidget>
<class>QgsPhongMaterialWidget</class>
<class>QgsMaterialWidget</class>
<extends>QWidget</extends>
<header>qgsphongmaterialwidget.h</header>
<header>qgsmaterialwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialWidgetBase</class>
<widget class="QWidget" name="MaterialWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>382</width>
<height>264</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="mMaterialTypeComboBox"/>
</item>
<item>
<widget class="QStackedWidget" name="mStackedWidget">
<widget class="QWidget" name="mPageDummy">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>This material doesn't have any editable properties</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -186,7 +186,7 @@
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QgsPhongMaterialWidget" name="widgetMaterial" native="true">
<widget class="QgsMaterialWidget" name="widgetMaterial" native="true">
<property name="enabled">
<bool>true</bool>
</property>
@@ -424,9 +424,9 @@
<container>1</container>
</customwidget>
<customwidget>
<class>QgsPhongMaterialWidget</class>
<class>QgsMaterialWidget</class>
<extends>QWidget</extends>
<header>qgsphongmaterialwidget.h</header>
<header>qgsmaterialwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
@@ -59,7 +59,7 @@
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QgsPhongMaterialWidget" name="widgetMaterial" native="true"/>
<widget class="QgsMaterialWidget" name="widgetMaterial" native="true"/>
</item>
</layout>
</widget>
@@ -291,9 +291,9 @@
</widget>
<customwidgets>
<customwidget>
<class>QgsPhongMaterialWidget</class>
<class>QgsMaterialWidget</class>
<extends>QWidget</extends>
<header>qgsphongmaterialwidget.h</header>
<header>qgsmaterialwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>

0 comments on commit 7522886

Please sign in to comment.
You can’t perform that action at this time.