diff --git a/src/Gui/propertyeditor/PropertyItem.cpp b/src/Gui/propertyeditor/PropertyItem.cpp index 63662b3f3..016ed1650 100644 --- a/src/Gui/propertyeditor/PropertyItem.cpp +++ b/src/Gui/propertyeditor/PropertyItem.cpp @@ -2308,6 +2308,22 @@ QVariant PropertyColorItem::editorData(QWidget *editor) const // -------------------------------------------------------------------- +namespace Gui { namespace PropertyEditor { + class Material + { + public: + QColor diffuseColor; + QColor ambientColor; + QColor specularColor; + QColor emissiveColor; + float shininess; + float transparency; + }; +} +} + +Q_DECLARE_METATYPE(Gui::PropertyEditor::Material) + TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyMaterialItem, Gui::PropertyEditor::PropertyItem); PropertyMaterialItem::PropertyMaterialItem() @@ -2354,134 +2370,134 @@ void PropertyMaterialItem::propertyBound() QColor PropertyMaterialItem::getDiffuseColor() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return QColor(); - const QVariantList& val = value.toList(); - return val[0].value(); + Material val = value.value(); + return val.diffuseColor; } void PropertyMaterialItem::setDiffuseColor(const QColor& color) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[0] = QVariant(color); - setValue(val); + Material mat = value.value(); + mat.diffuseColor = color; + setValue(QVariant::fromValue(mat)); } QColor PropertyMaterialItem::getAmbientColor() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return QColor(); - const QVariantList& val = value.toList(); - return val[1].value(); + Material val = value.value(); + return val.ambientColor; } void PropertyMaterialItem::setAmbientColor(const QColor& color) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[1] = QVariant(color); - setValue(val); + Material mat = value.value(); + mat.ambientColor = color; + setValue(QVariant::fromValue(mat)); } QColor PropertyMaterialItem::getSpecularColor() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return QColor(); - const QVariantList& val = value.toList(); - return val[2].value(); + Material val = value.value(); + return val.specularColor; } void PropertyMaterialItem::setSpecularColor(const QColor& color) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[2] = QVariant(color); - setValue(val); + Material mat = value.value(); + mat.specularColor = color; + setValue(QVariant::fromValue(mat)); } QColor PropertyMaterialItem::getEmissiveColor() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return QColor(); - const QVariantList& val = value.toList(); - return val[3].value(); + Material val = value.value(); + return val.emissiveColor; } void PropertyMaterialItem::setEmissiveColor(const QColor& color) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[3] = QVariant(color); - setValue(val); + Material mat = value.value(); + mat.emissiveColor = color; + setValue(QVariant::fromValue(mat)); } float PropertyMaterialItem::getShininess() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return 0; - const QVariantList& val = value.toList(); - return val[4].toFloat(); + Material val = value.value(); + return val.shininess; } void PropertyMaterialItem::setShininess(float s) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[4] = QVariant(s); - setValue(val); + Material mat = value.value(); + mat.shininess = s; + setValue(QVariant::fromValue(mat)); } float PropertyMaterialItem::getTransparency() const { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return 0; - const QVariantList& val = value.toList(); - return val[5].toFloat(); + Material val = value.value(); + return val.transparency; } void PropertyMaterialItem::setTransparency(float t) { QVariant value = data(1, Qt::EditRole); - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - val[5] = QVariant(t); - setValue(val); + Material mat = value.value(); + mat.transparency = t; + setValue(QVariant::fromValue(mat)); } QVariant PropertyMaterialItem::decoration(const QVariant& value) const { // use the diffuse color - const QVariantList& val = value.toList(); - QColor color = val[0].value(); + Material val = value.value(); + QColor color = val.diffuseColor; int size = QApplication::style()->pixelMetric(QStyle::PM_ListViewIconSize); QPixmap p(size, size); @@ -2493,8 +2509,8 @@ QVariant PropertyMaterialItem::decoration(const QVariant& value) const QVariant PropertyMaterialItem::toString(const QVariant& prop) const { // use the diffuse color - const QVariantList& val = prop.toList(); - QColor value = val[0].value(); + Material val = prop.value(); + QColor value = val.diffuseColor; QString color = QString::fromLatin1("[%1, %2, %3]") .arg(value.red()).arg(value.green()).arg(value.blue()); return QVariant(color); @@ -2534,30 +2550,30 @@ QVariant PropertyMaterialItem::value(const App::Property* prop) const assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyMaterial::getClassTypeId())); const App::Material& value = static_cast(prop)->getValue(); - QVariantList variantList; + Material mat; - variantList << QVariant(toQColor(value.diffuseColor)); - variantList << QVariant(toQColor(value.ambientColor)); - variantList << QVariant(toQColor(value.specularColor)); - variantList << QVariant(toQColor(value.emissiveColor)); - variantList << QVariant(value.shininess); - variantList << QVariant(value.transparency); + mat.diffuseColor = toQColor(value.diffuseColor); + mat.ambientColor = toQColor(value.ambientColor); + mat.specularColor = toQColor(value.specularColor); + mat.emissiveColor = toQColor(value.emissiveColor); + mat.shininess = value.shininess; + mat.transparency = value.transparency; - return variantList; + return QVariant::fromValue(mat); } void PropertyMaterialItem::setValue(const QVariant& value) { - if (!value.canConvert()) + if (!value.canConvert()) return; - QVariantList val = value.toList(); - App::Color dc = fromQColor(val[0].value()); - App::Color ac = fromQColor(val[1].value()); - App::Color sc = fromQColor(val[2].value()); - App::Color ec = fromQColor(val[3].value()); - float s = val[4].toFloat(); - float t = val[5].toFloat(); + Material mat = value.value(); + App::Color dc = fromQColor(mat.diffuseColor); + App::Color ac = fromQColor(mat.ambientColor); + App::Color sc = fromQColor(mat.specularColor); + App::Color ec = fromQColor(mat.emissiveColor); + float s = mat.shininess; + float t = mat.transparency; QString data = QString::fromLatin1( "App.Material(" @@ -2597,12 +2613,324 @@ QWidget* PropertyMaterialItem::createEditor(QWidget* parent, const QObject* rece } void PropertyMaterialItem::setEditorData(QWidget *editor, const QVariant& data) const +{ + if (!data.canConvert()) + return; + + Material val = data.value(); + Gui::ColorButton *cb = qobject_cast(editor); + cb->setColor(val.diffuseColor); +} + +QVariant PropertyMaterialItem::editorData(QWidget *editor) const +{ + Gui::ColorButton *cb = qobject_cast(editor); + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return QVariant(); + + Material val = value.value(); + val.diffuseColor = cb->color(); + return QVariant::fromValue(val); +} + +// -------------------------------------------------------------------- + +TYPESYSTEM_SOURCE(Gui::PropertyEditor::PropertyMaterialListItem, Gui::PropertyEditor::PropertyItem); + +PropertyMaterialListItem::PropertyMaterialListItem() +{ + diffuse = static_cast(PropertyColorItem::create()); + diffuse->setParent(this); + diffuse->setPropertyName(QLatin1String("DiffuseColor")); + this->appendChild(diffuse); + + ambient = static_cast(PropertyColorItem::create()); + ambient->setParent(this); + ambient->setPropertyName(QLatin1String("AmbientColor")); + this->appendChild(ambient); + + specular = static_cast(PropertyColorItem::create()); + specular->setParent(this); + specular->setPropertyName(QLatin1String("SpecularColor")); + this->appendChild(specular); + + emissive = static_cast(PropertyColorItem::create()); + emissive->setParent(this); + emissive->setPropertyName(QLatin1String("EmissiveColor")); + this->appendChild(emissive); + + shininess = static_cast(PropertyFloatItem::create()); + shininess->setParent(this); + shininess->setPropertyName(QLatin1String("Shininess")); + this->appendChild(shininess); + + transparency = static_cast(PropertyFloatItem::create()); + transparency->setParent(this); + transparency->setPropertyName(QLatin1String("Transparency")); + this->appendChild(transparency); +} + +PropertyMaterialListItem::~PropertyMaterialListItem() +{ +} + +void PropertyMaterialListItem::propertyBound() +{ +} + +QColor PropertyMaterialListItem::getDiffuseColor() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return QColor(); + + const QVariantList& val = value.toList(); + return val[0].value(); +} + +void PropertyMaterialListItem::setDiffuseColor(const QColor& color) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[0] = QVariant(color); + setValue(val); +} + +QColor PropertyMaterialListItem::getAmbientColor() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return QColor(); + + const QVariantList& val = value.toList(); + return val[1].value(); +} + +void PropertyMaterialListItem::setAmbientColor(const QColor& color) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[1] = QVariant(color); + setValue(val); +} + +QColor PropertyMaterialListItem::getSpecularColor() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return QColor(); + + const QVariantList& val = value.toList(); + return val[2].value(); +} + +void PropertyMaterialListItem::setSpecularColor(const QColor& color) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[2] = QVariant(color); + setValue(val); +} + +QColor PropertyMaterialListItem::getEmissiveColor() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return QColor(); + + const QVariantList& val = value.toList(); + return val[3].value(); +} + +void PropertyMaterialListItem::setEmissiveColor(const QColor& color) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[3] = QVariant(color); + setValue(val); +} + +float PropertyMaterialListItem::getShininess() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return 0; + + const QVariantList& val = value.toList(); + return val[4].toFloat(); +} + +void PropertyMaterialListItem::setShininess(float s) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[4] = QVariant(s); + setValue(val); +} + +float PropertyMaterialListItem::getTransparency() const +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return 0; + + const QVariantList& val = value.toList(); + return val[5].toFloat(); +} + +void PropertyMaterialListItem::setTransparency(float t) +{ + QVariant value = data(1, Qt::EditRole); + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + val[5] = QVariant(t); + setValue(val); +} + +QVariant PropertyMaterialListItem::decoration(const QVariant& value) const +{ + // use the diffuse color + const QVariantList& val = value.toList(); + QColor color = val[0].value(); + + int size = QApplication::style()->pixelMetric(QStyle::PM_ListViewIconSize); + QPixmap p(size, size); + p.fill(color); + + return QVariant(p); +} + +QVariant PropertyMaterialListItem::toString(const QVariant& prop) const +{ + // use the diffuse color + const QVariantList& val = prop.toList(); + QColor value = val[0].value(); + QString color = QString::fromLatin1("[%1, %2, %3]") + .arg(value.red()).arg(value.green()).arg(value.blue()); + return QVariant(color); +} + +QVariant PropertyMaterialListItem::toolTip(const App::Property* prop) const +{ + assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyMaterial::getClassTypeId())); + + const App::Material& value = static_cast(prop)->getValue(); + QColor dc = toQColor(value.diffuseColor); + QColor ac = toQColor(value.ambientColor); + QColor sc = toQColor(value.specularColor); + QColor ec = toQColor(value.emissiveColor); + + QString data = QString::fromUtf8( + "Diffuse color: [%1, %2, %3]\n" + "Ambient color: [%4, %5, %6]\n" + "Specular color: [%7, %8, %9]\n" + "Emissive color: [%10, %11, %12]\n" + "Shininess: %13\n" + "Transparency: %14" + ) + .arg(dc.red()).arg(dc.green()).arg(dc.blue()) + .arg(ac.red()).arg(ac.green()).arg(ac.blue()) + .arg(sc.red()).arg(sc.green()).arg(sc.blue()) + .arg(ec.red()).arg(ec.green()).arg(ec.blue()) + .arg(value.shininess) + .arg(value.transparency) + ; + + return QVariant(data); +} + +QVariant PropertyMaterialListItem::value(const App::Property* prop) const +{ + assert(prop && prop->getTypeId().isDerivedFrom(App::PropertyMaterial::getClassTypeId())); + + const App::Material& value = static_cast(prop)->getValue(); + QVariantList variantList; + + variantList << QVariant(toQColor(value.diffuseColor)); + variantList << QVariant(toQColor(value.ambientColor)); + variantList << QVariant(toQColor(value.specularColor)); + variantList << QVariant(toQColor(value.emissiveColor)); + variantList << QVariant(value.shininess); + variantList << QVariant(value.transparency); + + return variantList; +} + +void PropertyMaterialListItem::setValue(const QVariant& value) +{ + if (!value.canConvert()) + return; + + QVariantList val = value.toList(); + App::Color dc = fromQColor(val[0].value()); + App::Color ac = fromQColor(val[1].value()); + App::Color sc = fromQColor(val[2].value()); + App::Color ec = fromQColor(val[3].value()); + float s = val[4].toFloat(); + float t = val[5].toFloat(); + + QString data = QString::fromLatin1( + "App.Material(" + "DiffuseColor=(%1,%2,%3)," + "AmbientColor=(%4,%5,%6)," + "SpecularColor=(%7,%8,%9)," + "EmissiveColor=(%10,%11,%12)," + "Shininess=(%13)," + "Transparency=(%14)," + ")" + ) + .arg(dc.r, 0, 'f', decimals()) + .arg(dc.g, 0, 'f', decimals()) + .arg(dc.b, 0, 'f', decimals()) + .arg(ac.r, 0, 'f', decimals()) + .arg(ac.g, 0, 'f', decimals()) + .arg(ac.b, 0, 'f', decimals()) + .arg(sc.r, 0, 'f', decimals()) + .arg(sc.g, 0, 'f', decimals()) + .arg(sc.b, 0, 'f', decimals()) + .arg(ec.r, 0, 'f', decimals()) + .arg(ec.g, 0, 'f', decimals()) + .arg(ec.b, 0, 'f', decimals()) + .arg(s, 0, 'f', decimals()) + .arg(t, 0, 'f', decimals()) + ; + + setPropertyValue(data); +} + +QWidget* PropertyMaterialListItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const +{ + Gui::ColorButton* cb = new Gui::ColorButton(parent); + cb->setDisabled(isReadOnly()); + QObject::connect(cb, SIGNAL(changed()), receiver, method); + return cb; +} + +void PropertyMaterialListItem::setEditorData(QWidget *editor, const QVariant& data) const { Gui::ColorButton *cb = qobject_cast(editor); cb->setColor(getDiffuseColor()); } -QVariant PropertyMaterialItem::editorData(QWidget *editor) const +QVariant PropertyMaterialListItem::editorData(QWidget *editor) const { Gui::ColorButton *cb = qobject_cast(editor); QVariant value = data(1, Qt::EditRole); diff --git a/src/Gui/propertyeditor/PropertyItem.h b/src/Gui/propertyeditor/PropertyItem.h index 0850732ee..f6d57cebf 100644 --- a/src/Gui/propertyeditor/PropertyItem.h +++ b/src/Gui/propertyeditor/PropertyItem.h @@ -716,6 +716,55 @@ private: PropertyFloatItem* transparency; }; +class GuiExport PropertyMaterialListItem : public PropertyItem +{ + Q_OBJECT + Q_PROPERTY(QColor AmbientColor READ getAmbientColor WRITE setAmbientColor DESIGNABLE true USER true) + Q_PROPERTY(QColor DiffuseColor READ getDiffuseColor WRITE setDiffuseColor DESIGNABLE true USER true) + Q_PROPERTY(QColor SpecularColor READ getSpecularColor WRITE setSpecularColor DESIGNABLE true USER true) + Q_PROPERTY(QColor EmissiveColor READ getEmissiveColor WRITE setEmissiveColor DESIGNABLE true USER true) + Q_PROPERTY(float Shininess READ getShininess WRITE setShininess DESIGNABLE true USER true) + Q_PROPERTY(float Transparency READ getTransparency WRITE setTransparency DESIGNABLE true USER true) + TYPESYSTEM_HEADER(); + + virtual QWidget* createEditor(QWidget* parent, const QObject* receiver, const char* method) const; + virtual void setEditorData(QWidget *editor, const QVariant& data) const; + virtual QVariant editorData(QWidget *editor) const; + + virtual void propertyBound(); + + QColor getAmbientColor() const; + void setAmbientColor(const QColor&); + QColor getDiffuseColor() const; + void setDiffuseColor(const QColor&); + QColor getSpecularColor() const; + void setSpecularColor(const QColor&); + QColor getEmissiveColor() const; + void setEmissiveColor(const QColor&); + float getShininess() const; + void setShininess(float); + float getTransparency() const; + void setTransparency(float); + +protected: + PropertyMaterialListItem(); + virtual ~PropertyMaterialListItem(); + + virtual QVariant decoration(const QVariant&) const; + virtual QVariant toolTip(const App::Property*) const; + virtual QVariant toString(const QVariant&) const; + virtual QVariant value(const App::Property*) const; + virtual void setValue(const QVariant&); + +private: + PropertyColorItem* ambient; + PropertyColorItem* diffuse; + PropertyColorItem* specular; + PropertyColorItem* emissive; + PropertyFloatItem* shininess; + PropertyFloatItem* transparency; +}; + /** * Change a file. * \author Werner Mayer