Gui: Refactor DlgMaterialPropertiesImp

Because a PropertyMaterialList property is used now it makes no sense any more to pass a list of view providers to the dialog
as it's impossible to set the material at a certain index.
Therefore the dialog has been simplified and setting the material property must be done by the calling instance.
This commit is contained in:
wmayer
2024-06-03 18:37:24 +02:00
committed by Chris Hennes
parent 3df1095580
commit 954d2c1ac3
6 changed files with 81 additions and 265 deletions

View File

@@ -23,7 +23,6 @@
#include "PreCompiled.h"
#include <App/Color.h>
#include <App/Material.h>
#include <App/PropertyStandard.h>
#include "Application.h"
@@ -37,43 +36,23 @@ using namespace Gui::Dialog;
/* TRANSLATOR Gui::Dialog::DlgMaterialPropertiesImp */
/**
* Constructs a Gui::Dialog::DlgMaterialPropertiesImp as a child of 'parent', with the
* name 'name' and widget flags set to 'f'.
*
* The dialog will by default be modeless, unless you set 'modal' to
* true to construct a modal dialog.
*/
DlgMaterialPropertiesImp::DlgMaterialPropertiesImp(const std::string& mat, QWidget* parent,
Qt::WindowFlags fl)
DlgMaterialPropertiesImp::DlgMaterialPropertiesImp(QWidget* parent, Qt::WindowFlags fl)
: QDialog(parent, fl)
, ui(new Ui_DlgMaterialProperties)
, material(mat)
, updateColors(true)
{
ui->setupUi(this);
setupConnections();
if (material != "ShapeAppearance") {
ui->textLabel1->hide();
ui->diffuseColor->hide();
}
ui->ambientColor->setAutoChangeColor(true);
ui->diffuseColor->setAutoChangeColor(true);
ui->emissiveColor->setAutoChangeColor(true);
ui->specularColor->setAutoChangeColor(true);
}
/**
* Destroys the object and frees any allocated resources
*/
DlgMaterialPropertiesImp::~DlgMaterialPropertiesImp() = default;
void DlgMaterialPropertiesImp::setupConnections()
{
Base::Console().Log("DlgMaterialPropertiesImp::setupConnections()\n");
connect(ui->ambientColor, &ColorButton::changed,
this, &DlgMaterialPropertiesImp::onAmbientColorChanged);
connect(ui->diffuseColor, &ColorButton::changed,
@@ -90,41 +69,25 @@ void DlgMaterialPropertiesImp::setupConnections()
this, &DlgMaterialPropertiesImp::onButtonDefault);
}
QColor DlgMaterialPropertiesImp::diffuseColor() const
void DlgMaterialPropertiesImp::setCustomMaterial(const App::Material& mat)
{
return ui->diffuseColor->color();
customMaterial = mat;
setButtonColors(customMaterial);
}
App::Material DlgMaterialPropertiesImp::getMaterial()
App::Material DlgMaterialPropertiesImp::getCustomMaterial() const
{
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto& materials = ShapeAppearance->getValues();
auto mat = materials[0];
mat.setType(App::Material::USER_DEFINED);
// Reset any texture data
mat.image = "";
mat.imagePath = "";
mat.uuid = "";
return mat;
}
}
return App::Material::getDefaultAppearance();
return customMaterial;
}
App::Color DlgMaterialPropertiesImp::getColor(const QColor& color) const
void DlgMaterialPropertiesImp::setDefaultMaterial(const App::Material& mat)
{
float r = (float)color.red() / 255.0F;
float g = (float)color.green() / 255.0F;
float b = (float)color.blue() / 255.0F;
defaultMaterial = mat;
}
return App::Color(r, g, b);
App::Material DlgMaterialPropertiesImp::getDefaultMaterial() const
{
return defaultMaterial;
}
/**
@@ -132,19 +95,7 @@ App::Color DlgMaterialPropertiesImp::getColor(const QColor& color) const
*/
void DlgMaterialPropertiesImp::onAmbientColorChanged()
{
if (updateColors) {
App::Color ambient = getColor(ui->ambientColor->color());
for (std::vector<ViewProvider*>::iterator it= Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
mat.ambientColor = ambient;
ShapeAppearance->setValue(mat);
}
}
}
customMaterial.ambientColor.setValue(ui->ambientColor->color());
}
/**
@@ -152,19 +103,7 @@ void DlgMaterialPropertiesImp::onAmbientColorChanged()
*/
void DlgMaterialPropertiesImp::onDiffuseColorChanged()
{
if (updateColors) {
App::Color diffuse = getColor(ui->diffuseColor->color());
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
mat.diffuseColor = diffuse;
ShapeAppearance->setValue(mat);
}
}
}
customMaterial.diffuseColor.setValue(ui->diffuseColor->color());
}
/**
@@ -172,19 +111,7 @@ void DlgMaterialPropertiesImp::onDiffuseColorChanged()
*/
void DlgMaterialPropertiesImp::onEmissiveColorChanged()
{
if (updateColors) {
App::Color emissive = getColor(ui->emissiveColor->color());
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
mat.emissiveColor = emissive;
ShapeAppearance->setValue(mat);
}
}
}
customMaterial.emissiveColor.setValue(ui->emissiveColor->color());
}
/**
@@ -192,19 +119,7 @@ void DlgMaterialPropertiesImp::onEmissiveColorChanged()
*/
void DlgMaterialPropertiesImp::onSpecularColorChanged()
{
if (updateColors) {
App::Color specular = getColor(ui->specularColor->color());
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
mat.specularColor = specular;
ShapeAppearance->setValue(mat);
}
}
}
customMaterial.specularColor.setValue(ui->specularColor->color());
}
/**
@@ -212,18 +127,7 @@ void DlgMaterialPropertiesImp::onSpecularColorChanged()
*/
void DlgMaterialPropertiesImp::onShininessValueChanged(int sh)
{
if (updateColors) {
float shininess = (float)sh / 100.0F;
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
mat.shininess = shininess;
ShapeAppearance->setValue(mat);
}
}
}
customMaterial.shininess = (float)sh / 100.0F;
}
/**
@@ -231,27 +135,7 @@ void DlgMaterialPropertiesImp::onShininessValueChanged(int sh)
*/
void DlgMaterialPropertiesImp::onButtonReset()
{
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = getMaterial();
App::Color defaultAmbient(0.2, 0.2, 0.2);
App::Color defaultDiffuse(0.8, 0.8, 0.8);
App::Color black(0, 0, 0);
mat.ambientColor = defaultAmbient;
mat.diffuseColor = defaultDiffuse;
mat.emissiveColor = black;
mat.specularColor = black;
mat.shininess = 0.2;
ShapeAppearance->setValue(mat);
setButtonColors();
break;
}
}
setCustomMaterial(getDefaultMaterial());
}
/**
@@ -259,103 +143,22 @@ void DlgMaterialPropertiesImp::onButtonReset()
*/
void DlgMaterialPropertiesImp::onButtonDefault()
{
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto mat = App::Material::getDefaultAppearance();
ShapeAppearance->setValue(mat);
setButtonColors();
break;
}
}
}
/**
* Sets the document objects and their view providers to manipulate the material.
*/
void DlgMaterialPropertiesImp::setViewProviders(const std::vector<Gui::ViewProvider*>& Obj)
{
Objects = Obj;
setButtonColors();
App::Material mat = App::Material::getDefaultAppearance();
setCustomMaterial(mat);
}
/**
* Sets the button colors to match the current material settings.
*/
void DlgMaterialPropertiesImp::setButtonColors()
void DlgMaterialPropertiesImp::setButtonColors(const App::Material& mat)
{
for (std::vector<ViewProvider*>::iterator it = Objects.begin(); it != Objects.end(); ++it) {
App::Property* prop = (*it)->getPropertyByName(material.c_str());
if (prop && prop->isDerivedFrom<App::PropertyMaterialList>()) {
auto ShapeAppearance = static_cast<App::PropertyMaterialList*>(prop);
auto& materials = ShapeAppearance->getValues();
auto& mat = materials[0];
int r = int(mat.ambientColor.r * 255.0F);
int g = int(mat.ambientColor.g * 255.0F);
int b = int(mat.ambientColor.b * 255.0F);
ui->ambientColor->setColor(QColor(r, g, b));
r = int(mat.diffuseColor.r * 255.0F);
g = int(mat.diffuseColor.g * 255.0F);
b = int(mat.diffuseColor.b * 255.0F);
ui->diffuseColor->setColor(QColor(r, g, b));
r = int(mat.emissiveColor.r * 255.0F);
g = int(mat.emissiveColor.g * 255.0F);
b = int(mat.emissiveColor.b * 255.0F);
ui->emissiveColor->setColor(QColor(r, g, b));
r = int(mat.specularColor.r * 255.0F);
g = int(mat.specularColor.g * 255.0F);
b = int(mat.specularColor.b * 255.0F);
ui->specularColor->setColor(QColor(r, g, b));
ui->shininess->blockSignals(true);
ui->shininess->setValue((int)(100.0f * (mat.shininess + 0.001F)));
ui->shininess->blockSignals(false);
break;
}
}
}
/**
* Constructs a Gui::Dialog::DlgFaceMaterialPropertiesImp as a child of 'parent', with the
* name 'name' and widget flags set to 'f'.
*
* The dialog will by default be modeless, unless you set 'modal' to
* true to construct a modal dialog.
*
* This differs from Gui::Dialog::DlgMaterialPropertiesImp in that it does not update
* the underlying object. This is undesirable when we're updating only a single face.
*/
DlgFaceMaterialPropertiesImp::DlgFaceMaterialPropertiesImp(const std::string& mat,
QWidget* parent,
Qt::WindowFlags fl)
: DlgMaterialPropertiesImp(mat, parent, fl)
{
Base::Console().Log("DlgFaceMaterialPropertiesImp::DlgFaceMaterialPropertiesImp()\n");
// Override the base class on this. Otherwise the whole object changes
updateColors = false;
}
/**
* Destroys the object and frees any allocated resources
*/
DlgFaceMaterialPropertiesImp::~DlgFaceMaterialPropertiesImp() = default;
App::Material DlgFaceMaterialPropertiesImp::getCustomAppearance() const
{
App::Material material;
material.setType(App::Material::USER_DEFINED);
material.ambientColor = getColor(ui->ambientColor->color());
material.diffuseColor = getColor(ui->diffuseColor->color());
material.emissiveColor = getColor(ui->emissiveColor->color());
material.specularColor = getColor(ui->specularColor->color());
material.shininess = (float)ui->shininess->value() / 100.0F;
return material;
ui->ambientColor->setColor(mat.ambientColor.asValue<QColor>());
ui->diffuseColor->setColor(mat.diffuseColor.asValue<QColor>());
ui->emissiveColor->setColor(mat.emissiveColor.asValue<QColor>());
ui->specularColor->setColor(mat.specularColor.asValue<QColor>());
ui->shininess->blockSignals(true);
ui->shininess->setValue((int)(100.0F * (mat.shininess + 0.001F)));
ui->shininess->blockSignals(false);
}
#include "moc_DlgMaterialPropertiesImp.cpp"

View File

@@ -27,7 +27,7 @@
#include <QDialog>
#include <memory>
#include <vector>
#include <FCGlobal.h>
#include <App/Material.h>
namespace App
{
@@ -48,17 +48,16 @@ class GuiExport DlgMaterialPropertiesImp: public QDialog
Q_OBJECT
public:
explicit DlgMaterialPropertiesImp(const std::string& mat,
QWidget* parent = nullptr,
explicit DlgMaterialPropertiesImp(QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgMaterialPropertiesImp() override;
void setViewProviders(const std::vector<Gui::ViewProvider*>&);
QColor diffuseColor() const;
App::Material getCustomMaterial() const;
void setCustomMaterial(const App::Material& mat);
App::Material getDefaultMaterial() const;
void setDefaultMaterial(const App::Material& mat);
protected:
private:
void setupConnections();
App::Material getMaterial();
App::Color getColor(const QColor& color) const;
void onAmbientColorChanged();
void onDiffuseColorChanged();
void onEmissiveColorChanged();
@@ -66,25 +65,12 @@ protected:
void onShininessValueChanged(int);
void onButtonReset();
void onButtonDefault();
void setButtonColors();
void setButtonColors(const App::Material& mat);
protected:
private:
std::unique_ptr<Ui_DlgMaterialProperties> ui;
std::string material;
std::vector<Gui::ViewProvider*> Objects;
bool updateColors;
};
class GuiExport DlgFaceMaterialPropertiesImp: public DlgMaterialPropertiesImp
{
Q_OBJECT
public:
explicit DlgFaceMaterialPropertiesImp(const std::string& mat,
QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgFaceMaterialPropertiesImp() override;
App::Material getCustomAppearance() const;
App::Material customMaterial;
App::Material defaultMaterial;
};
} // namespace Dialog

View File

@@ -34,7 +34,7 @@
#include <Gui/DockWindowManager.h>
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Gui/ViewProvider.h>
#include <Gui/ViewProviderGeometryObject.h>
#include <Gui/WaitCursor.h>
#include <Mod/Material/App/ModelUuids.h>
@@ -278,7 +278,7 @@ void DlgDisplayPropertiesImp::setupConnections()
connect(d->ui.buttonCustomAppearance,
&Gui::ColorButton::clicked,
this,
&DlgDisplayPropertiesImp::onbuttonCustomAppearanceClicked);
&DlgDisplayPropertiesImp::onButtonCustomAppearanceClicked);
connect(d->ui.buttonColorPlot,
&Gui::ColorButton::clicked,
this,
@@ -412,14 +412,24 @@ void DlgDisplayPropertiesImp::reject()
/**
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onbuttonCustomAppearanceClicked()
void DlgDisplayPropertiesImp::onButtonCustomAppearanceClicked()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
Gui::Dialog::DlgMaterialPropertiesImp dlg("ShapeAppearance", this);
dlg.setViewProviders(Provider);
Gui::Dialog::DlgMaterialPropertiesImp dlg(this);
if (!Provider.empty()) {
if (auto vp = dynamic_cast<Gui::ViewProviderGeometryObject*>(Provider.front())) {
App::Material mat = vp->ShapeAppearance[0];
dlg.setCustomMaterial(mat);
dlg.setDefaultMaterial(mat);
}
}
dlg.exec();
// d->ui.buttonColor->setColor(dlg.diffuseColor());
App::Material mat = dlg.getCustomMaterial();
for (auto vp : Provider) {
if (auto vpg = dynamic_cast<Gui::ViewProviderGeometryObject*>(vp)) {
vpg->ShapeAppearance.setValue(mat);
}
}
}
/**
@@ -430,11 +440,18 @@ void DlgDisplayPropertiesImp::onButtonColorPlotClicked()
std::vector<Gui::ViewProvider*> Provider = getSelection();
static QPointer<Gui::Dialog::DlgMaterialPropertiesImp> dlg = nullptr;
if (!dlg) {
dlg = new Gui::Dialog::DlgMaterialPropertiesImp("TextureMaterial", this);
dlg = new Gui::Dialog::DlgMaterialPropertiesImp(this);
}
dlg->setModal(false);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setViewProviders(Provider);
if (!Provider.empty()) {
App::Property* prop = Provider.front()->getPropertyByName("TextureMaterial");
if (auto matProp = dynamic_cast<App::PropertyMaterialList*>(prop)) {
App::Material mat = (*matProp)[0];
dlg->setCustomMaterial(mat);
dlg->setDefaultMaterial(mat);
}
}
dlg->show();
}

View File

@@ -75,7 +75,7 @@ private Q_SLOTS:
void onButtonPointColorChanged();
void onSpinLineWidthValueChanged(int);
void onSpinLineTransparencyValueChanged(int);
void onbuttonCustomAppearanceClicked();
void onButtonCustomAppearanceClicked();
void onButtonColorPlotClicked();
void onMaterialSelected(const std::shared_ptr<Materials::Material>& material);

View File

@@ -418,21 +418,30 @@ void FaceAppearances::updatePanel()
d->ui->buttonCustomAppearance->setDisabled(d->index.isEmpty());
}
int FaceAppearances::getFirstIndex() const
{
if (!d->index.isEmpty()) {
return *(d->index.begin());
}
return 0;
}
/**
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
*/
void FaceAppearances::onButtonCustomAppearanceClicked()
{
std::vector<Gui::ViewProvider*> Provider;
Provider.push_back(d->vp);
Gui::Dialog::DlgFaceMaterialPropertiesImp dlg("ShapeAppearance", this);
dlg.setViewProviders(Provider);
Gui::Dialog::DlgMaterialPropertiesImp dlg(this);
App::Material mat = d->perface[getFirstIndex()];
dlg.setCustomMaterial(mat);
dlg.setDefaultMaterial(mat);
dlg.exec();
// Set the face appearance
if (!d->index.isEmpty()) {
for (int it : d->index) {
d->perface[it] = dlg.getCustomAppearance();
d->perface[it] = dlg.getCustomMaterial();
}
d->vp->ShapeAppearance.setValues(d->perface);
// new color has been applied, unselect so that users can see this

View File

@@ -65,6 +65,7 @@ protected:
void slotDeleteDocument(const Gui::Document&);
void slotDeleteObject(const Gui::ViewProvider&);
void updatePanel();
int getFirstIndex() const;
private:
class Private;