Material: Material editor enhancements
Continues the work of the material subsystem improvements. This merge covers the continued development of the material editor. The primary improvements are in the handling of 2D and 3D array properties. These properties are now fully editable, and can be saved and restored. The cards now separate the author and license. These were previously saved as a single item. Future support will be provided for standard open source licenses. Saving operations validate the cards to ensure UUIDs of materials are considered. Warnings are given when a save could potentially impact the models, such as saving over a material instead of creating a new instance. The editor is still not complete. There are a number of functional elements, such as drag/drop operations, folder creation, and deletion operations that need to be added to the main tree. State needs to be saved and restored to improve the user experience. The appearance preview also needs significant work. This will be handled in a future PR.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QIODevice>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
@@ -35,6 +36,7 @@
|
||||
#include <limits>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/License.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/Quantity.h>
|
||||
#include <Gui/Application.h>
|
||||
@@ -61,6 +63,7 @@ using namespace MatGui;
|
||||
MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui_MaterialsEditor)
|
||||
, _material(std::make_shared<Materials::Material>())
|
||||
, _edited(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@@ -72,6 +75,7 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
createPhysicalTree();
|
||||
createAppearanceTree();
|
||||
createPreviews();
|
||||
setMaterialDefaults();
|
||||
|
||||
ui->buttonURL->setIcon(QIcon(QString::fromStdString(":/icons/internet-web-browser.svg")));
|
||||
|
||||
@@ -88,12 +92,35 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
this,
|
||||
&MaterialsEditor::onSave);
|
||||
|
||||
connect(ui->editName, &QLineEdit::textEdited, this, &MaterialsEditor::onName);
|
||||
connect(ui->editAuthor, &QLineEdit::textEdited, this, &MaterialsEditor::onAuthor);
|
||||
connect(ui->editLicense, &QLineEdit::textEdited, this, &MaterialsEditor::onLicense);
|
||||
connect(ui->editSourceURL, &QLineEdit::textEdited, this, &MaterialsEditor::onSourceURL);
|
||||
connect(ui->editSourceReference,
|
||||
&QLineEdit::textEdited,
|
||||
this,
|
||||
&MaterialsEditor::onSourceReference);
|
||||
connect(ui->editDescription, &QTextEdit::textChanged, this, &MaterialsEditor::onDescription);
|
||||
|
||||
connect(ui->buttonURL, &QPushButton::clicked, this, &MaterialsEditor::onURL);
|
||||
connect(ui->buttonPhysicalAdd, &QPushButton::clicked, this, &MaterialsEditor::onPhysicalAdd);
|
||||
connect(ui->buttonPhysicalRemove,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onPhysicalRemove);
|
||||
connect(ui->buttonAppearanceAdd,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onAppearanceAdd);
|
||||
connect(ui->buttonAppearanceRemove,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onAppearanceRemove);
|
||||
connect(ui->buttonInheritNew,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&MaterialsEditor::onInheritNewMaterial);
|
||||
connect(ui->buttonNew, &QPushButton::clicked, this, &MaterialsEditor::onNewMaterial);
|
||||
connect(ui->buttonFavorite, &QPushButton::clicked, this, &MaterialsEditor::onFavourite);
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
@@ -101,6 +128,13 @@ MaterialsEditor::MaterialsEditor(QWidget* parent)
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
&MaterialsEditor::onSelectMaterial);
|
||||
connect(ui->treeMaterials, &QTreeView::doubleClicked, this, &MaterialsEditor::onDoubleClick);
|
||||
|
||||
ui->treeMaterials->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->treeMaterials,
|
||||
&QWidget::customContextMenuRequested,
|
||||
this,
|
||||
&MaterialsEditor::onContextMenu);
|
||||
}
|
||||
|
||||
void MaterialsEditor::getFavorites()
|
||||
@@ -144,7 +178,7 @@ void MaterialsEditor::addFavorite(const QString& uuid)
|
||||
{
|
||||
// Ensure it is a material. New, unsaved materials will not be
|
||||
try {
|
||||
const Materials::Material& material = _materialManager.getMaterial(uuid);
|
||||
auto material = _materialManager.getMaterial(uuid);
|
||||
Q_UNUSED(material)
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
@@ -227,7 +261,7 @@ void MaterialsEditor::addRecent(const QString& uuid)
|
||||
{
|
||||
// Ensure it is a material. New, unsaved materials will not be
|
||||
try {
|
||||
const Materials::Material& material = _materialManager.getMaterial(uuid);
|
||||
auto material = _materialManager.getMaterial(uuid);
|
||||
Q_UNUSED(material)
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
@@ -257,16 +291,46 @@ bool MaterialsEditor::isRecent(const QString& uuid) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialsEditor::onName(const QString& text)
|
||||
{
|
||||
_material->setName(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAuthor(const QString& text)
|
||||
{
|
||||
_material->setAuthor(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onLicense(const QString& text)
|
||||
{
|
||||
_material->setLicense(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onSourceURL(const QString& text)
|
||||
{
|
||||
_material->setURL(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onSourceReference(const QString& text)
|
||||
{
|
||||
_material->setReference(text);
|
||||
}
|
||||
|
||||
void MaterialsEditor::onDescription()
|
||||
{
|
||||
_material->setDescription(ui->editDescription->toPlainText());
|
||||
}
|
||||
|
||||
void MaterialsEditor::propertyChange(const QString& property, const QString value)
|
||||
{
|
||||
Base::Console().Log("MaterialsEditor::propertyChange(%s) = '%s'\n",
|
||||
property.toStdString().c_str(),
|
||||
value.toStdString().c_str());
|
||||
if (_material.hasPhysicalProperty(property)) {
|
||||
_material.setPhysicalValue(property, value);
|
||||
if (_material->hasPhysicalProperty(property)) {
|
||||
_material->setPhysicalValue(property, value);
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(property)) {
|
||||
_material.setAppearanceValue(property, value);
|
||||
else if (_material->hasAppearanceProperty(property)) {
|
||||
_material->setAppearanceValue(property, value);
|
||||
updatePreview();
|
||||
}
|
||||
_edited = true;
|
||||
@@ -287,12 +351,12 @@ void MaterialsEditor::onPhysicalAdd(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
ModelSelect dialog(this, Materials::ModelManager::ModelFilter_Physical);
|
||||
ModelSelect dialog(this, Materials::ModelFilter_Physical);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString selected = dialog.selectedModel();
|
||||
Base::Console().Log("Selected model '%s'\n", selected.toStdString().c_str());
|
||||
_material.addPhysical(selected);
|
||||
_material->addPhysical(selected);
|
||||
updateMaterial();
|
||||
}
|
||||
else {
|
||||
@@ -300,16 +364,39 @@ void MaterialsEditor::onPhysicalAdd(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onPhysicalRemove(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treePhysicalProperties->selectionModel();
|
||||
if (selectionModel->hasSelection()) {
|
||||
const QModelIndex index = selectionModel->currentIndex().siblingAtColumn(0);
|
||||
|
||||
const QStandardItemModel* treeModel = static_cast<const QStandardItemModel*>(index.model());
|
||||
|
||||
// Check we're the material model root.
|
||||
auto item = treeModel->itemFromIndex(index);
|
||||
auto group = item->parent();
|
||||
if (!group) {
|
||||
QString propertyName = index.data().toString();
|
||||
|
||||
QString uuid = _material->getModelByName(propertyName);
|
||||
_material->removePhysical(uuid);
|
||||
updateMaterial();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAppearanceAdd(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
ModelSelect dialog(this, Materials::ModelManager::ModelFilter_Appearance);
|
||||
ModelSelect dialog(this, Materials::ModelFilter_Appearance);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString selected = dialog.selectedModel();
|
||||
Base::Console().Log("Selected model '%s'\n", selected.toStdString().c_str());
|
||||
_material.addAppearance(selected);
|
||||
_material->addAppearance(selected);
|
||||
updateMaterial();
|
||||
}
|
||||
else {
|
||||
@@ -317,12 +404,35 @@ void MaterialsEditor::onAppearanceAdd(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onAppearanceRemove(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
QItemSelectionModel* selectionModel = ui->treeAppearance->selectionModel();
|
||||
if (selectionModel->hasSelection()) {
|
||||
const QModelIndex index = selectionModel->currentIndex().siblingAtColumn(0);
|
||||
|
||||
const QStandardItemModel* treeModel = static_cast<const QStandardItemModel*>(index.model());
|
||||
|
||||
// Check we're the material model root.
|
||||
auto item = treeModel->itemFromIndex(index);
|
||||
auto group = item->parent();
|
||||
if (!group) {
|
||||
QString propertyName = index.data().toString();
|
||||
|
||||
QString uuid = _material->getModelByName(propertyName);
|
||||
_material->removeAppearance(uuid);
|
||||
updateMaterial();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::onFavourite(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Favorite\n");
|
||||
auto selected = _material.getUUID();
|
||||
auto selected = _material->getUUID();
|
||||
if (isFavorite(selected)) {
|
||||
removeFavorite(selected);
|
||||
}
|
||||
@@ -331,6 +441,76 @@ void MaterialsEditor::onFavourite(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::setMaterialDefaults()
|
||||
{
|
||||
_material->setName(tr("Unnamed"));
|
||||
std::string Author = App::GetApplication()
|
||||
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/Document")
|
||||
->GetASCII("prefAuthor", "");
|
||||
_material->setAuthor(QString::fromStdString(Author));
|
||||
|
||||
// license stuff
|
||||
auto paramGrp {App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Document")};
|
||||
auto index = static_cast<int>(paramGrp->GetInt("prefLicenseType", 0));
|
||||
const char* name = App::licenseItems.at(index).at(App::posnOfFullName);
|
||||
// const char* url = App::licenseItems.at(index).at(App::posnOfUrl);
|
||||
// std::string licenseUrl = (paramGrp->GetASCII("prefLicenseUrl", url));
|
||||
_material->setLicense(QString::fromStdString(name));
|
||||
|
||||
// Empty materials will have no parent
|
||||
_materialManager.dereference(_material);
|
||||
|
||||
updateMaterial();
|
||||
_material->resetEditState();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onNewMaterial(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("New Material\n");
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new material
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
setMaterialDefaults();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInheritNewMaterial(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("Inherit New Material\n");
|
||||
|
||||
// Save the current UUID to use as out parent
|
||||
auto parent = _material->getUUID();
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
if (res == QMessageBox::Cancel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new material
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
_material->setParentUUID(parent);
|
||||
setMaterialDefaults();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onOk(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
@@ -354,17 +534,18 @@ void MaterialsEditor::onSave(bool checked)
|
||||
|
||||
void MaterialsEditor::saveMaterial()
|
||||
{
|
||||
MaterialSave dialog(&_material, this);
|
||||
MaterialSave dialog(_material, this);
|
||||
dialog.setModal(true);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
_material.resetEditState();
|
||||
updateMaterialGeneral();
|
||||
_material->resetEditState();
|
||||
refreshMaterialTree();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialsEditor::accept()
|
||||
{
|
||||
addRecent(_material.getUUID());
|
||||
addRecent(_material->getUUID());
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
@@ -379,15 +560,16 @@ void MaterialsEditor::reject()
|
||||
|
||||
void MaterialsEditor::addMaterials(
|
||||
QStandardItem& parent,
|
||||
const std::shared_ptr<std::map<QString, Materials::MaterialTreeNode*>> modelTree,
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon)
|
||||
{
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& mat : *modelTree) {
|
||||
Materials::MaterialTreeNode* nodePtr = mat.second;
|
||||
std::shared_ptr<Materials::MaterialTreeNode> nodePtr = mat.second;
|
||||
if (nodePtr->getType() == Materials::MaterialTreeNode::DataNode) {
|
||||
const Materials::Material* material = nodePtr->getData();
|
||||
auto material = nodePtr->getData();
|
||||
QString uuid = material->getUUID();
|
||||
// Base::Console().Log("Material path '%s'\n",
|
||||
// material->getDirectory().toStdString().c_str());
|
||||
@@ -429,9 +611,9 @@ void MaterialsEditor::createPhysicalTree()
|
||||
tree->setModel(model);
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -444,6 +626,12 @@ void MaterialsEditor::createPhysicalTree()
|
||||
tree->setItemDelegateForColumn(1, delegate);
|
||||
|
||||
connect(delegate, &MaterialDelegate::propertyChange, this, &MaterialsEditor::propertyChange);
|
||||
|
||||
// QItemSelectionModel* selectionModel = ui->treePhysicalProperties->selectionModel();
|
||||
// connect(selectionModel,
|
||||
// &QItemSelectionModel::selectionChanged,
|
||||
// this,
|
||||
// &MaterialsEditor::onSelectPhysicalProperty);
|
||||
}
|
||||
|
||||
void MaterialsEditor::createPreviews()
|
||||
@@ -468,9 +656,9 @@ void MaterialsEditor::createAppearanceTree()
|
||||
tree->setModel(model);
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
model->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -490,10 +678,10 @@ void MaterialsEditor::addRecents(QStandardItem* parent)
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& uuid : _recents) {
|
||||
try {
|
||||
const Materials::Material& material = getMaterialManager().getMaterial(uuid);
|
||||
auto material = getMaterialManager().getMaterial(uuid);
|
||||
|
||||
QIcon icon = QIcon(material.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, material.getName());
|
||||
QIcon icon = QIcon(material->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, libraryPath(material));
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -510,10 +698,10 @@ void MaterialsEditor::addFavorites(QStandardItem* parent)
|
||||
auto tree = ui->treeMaterials;
|
||||
for (auto& uuid : _favorites) {
|
||||
try {
|
||||
const Materials::Material& material = getMaterialManager().getMaterial(uuid);
|
||||
auto material = getMaterialManager().getMaterial(uuid);
|
||||
|
||||
QIcon icon = QIcon(material.getLibrary().getIconPath());
|
||||
auto card = new QStandardItem(icon, material.getName());
|
||||
QIcon icon = QIcon(material->getLibrary()->getIconPath());
|
||||
auto card = new QStandardItem(icon, libraryPath(material));
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -530,12 +718,12 @@ void MaterialsEditor::fillMaterialTree()
|
||||
auto tree = ui->treeMaterials;
|
||||
auto model = static_cast<QStandardItemModel*>(tree->model());
|
||||
|
||||
auto lib = new QStandardItem(QString::fromStdString("Favorites"));
|
||||
auto lib = new QStandardItem(tr("Favorites"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addFavorites(lib);
|
||||
|
||||
lib = new QStandardItem(QString::fromStdString("Recent"));
|
||||
lib = new QStandardItem(tr("Recent"));
|
||||
lib->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, model, lib);
|
||||
addRecents(lib);
|
||||
@@ -549,7 +737,7 @@ void MaterialsEditor::fillMaterialTree()
|
||||
QIcon icon(library->getIconPath());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
|
||||
auto modelTree = _materialManager.getMaterialTree(*library);
|
||||
auto modelTree = _materialManager.getMaterialTree(library);
|
||||
addMaterials(*lib, modelTree, folderIcon, icon);
|
||||
}
|
||||
}
|
||||
@@ -582,23 +770,23 @@ void MaterialsEditor::updatePreview() const
|
||||
QString highlightColor;
|
||||
QString sectionColor;
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("DiffuseColor"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("DiffuseColor"));
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("DiffuseColor"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("DiffuseColor"));
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(QString::fromStdString("ViewColor"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("ViewColor"));
|
||||
else if (_material->hasAppearanceProperty(QString::fromStdString("ViewColor"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("ViewColor"));
|
||||
}
|
||||
else if (_material.hasAppearanceProperty(QString::fromStdString("Color"))) {
|
||||
diffuseColor = _material.getAppearanceValueString(QString::fromStdString("Color"));
|
||||
else if (_material->hasAppearanceProperty(QString::fromStdString("Color"))) {
|
||||
diffuseColor = _material->getAppearanceValueString(QString::fromStdString("Color"));
|
||||
}
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("SpecularColor"))) {
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("SpecularColor"))) {
|
||||
highlightColor =
|
||||
_material.getAppearanceValueString(QString::fromStdString("SpecularColor"));
|
||||
_material->getAppearanceValueString(QString::fromStdString("SpecularColor"));
|
||||
}
|
||||
|
||||
if (_material.hasAppearanceProperty(QString::fromStdString("SectionColor"))) {
|
||||
sectionColor = _material.getAppearanceValueString(QString::fromStdString("SectionColor"));
|
||||
if (_material->hasAppearanceProperty(QString::fromStdString("SectionColor"))) {
|
||||
sectionColor = _material->getAppearanceValueString(QString::fromStdString("SectionColor"));
|
||||
}
|
||||
|
||||
if ((diffuseColor.length() + highlightColor.length()) > 0) {
|
||||
@@ -678,28 +866,28 @@ void MaterialsEditor::updateMaterialAppearance()
|
||||
treeModel->clear();
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
treeModel->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
tree->setColumnWidth(1, 250);
|
||||
tree->setColumnHidden(2, true);
|
||||
|
||||
const std::vector<QString>* models = _material.getAppearanceModels();
|
||||
auto models = _material->getAppearanceModels();
|
||||
if (models) {
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
QString name = model.getName();
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
QString name = model->getName();
|
||||
|
||||
auto modelRoot = new QStandardItem(name);
|
||||
modelRoot->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, treeModel, modelRoot);
|
||||
for (auto itp = model.begin(); itp != model.end(); itp++) {
|
||||
for (auto itp = model->begin(); itp != model->end(); itp++) {
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QString key = itp->first;
|
||||
@@ -707,10 +895,10 @@ void MaterialsEditor::updateMaterialAppearance()
|
||||
propertyItem->setToolTip(itp->second.getDescription());
|
||||
items.append(propertyItem);
|
||||
|
||||
auto valueItem = new QStandardItem(_material.getAppearanceValueString(key));
|
||||
auto valueItem = new QStandardItem(_material->getAppearanceValueString(key));
|
||||
valueItem->setToolTip(itp->second.getDescription());
|
||||
QVariant variant;
|
||||
variant.setValue(&_material);
|
||||
variant.setValue(_material);
|
||||
valueItem->setData(variant);
|
||||
items.append(valueItem);
|
||||
|
||||
@@ -737,10 +925,10 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
treeModel->clear();
|
||||
|
||||
QStringList headers;
|
||||
headers.append(QString::fromStdString("Property"));
|
||||
headers.append(QString::fromStdString("Value"));
|
||||
headers.append(QString::fromStdString("Type"));
|
||||
headers.append(QString::fromStdString("Units"));
|
||||
headers.append(tr("Property"));
|
||||
headers.append(tr("Value"));
|
||||
headers.append(tr("Type"));
|
||||
headers.append(tr("Units"));
|
||||
treeModel->setHorizontalHeaderLabels(headers);
|
||||
|
||||
tree->setColumnWidth(0, 250);
|
||||
@@ -748,19 +936,19 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
tree->setColumnHidden(2, true);
|
||||
tree->setColumnHidden(3, true);
|
||||
|
||||
const std::vector<QString>* models = _material.getPhysicalModels();
|
||||
auto models = _material->getPhysicalModels();
|
||||
if (models) {
|
||||
for (auto it = models->begin(); it != models->end(); it++) {
|
||||
QString uuid = *it;
|
||||
try {
|
||||
const Materials::Model& model = getModelManager().getModel(uuid);
|
||||
QString name = model.getName();
|
||||
auto model = getModelManager().getModel(uuid);
|
||||
QString name = model->getName();
|
||||
|
||||
auto modelRoot = new QStandardItem(name);
|
||||
modelRoot->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDragEnabled
|
||||
| Qt::ItemIsDropEnabled);
|
||||
addExpanded(tree, treeModel, modelRoot);
|
||||
for (auto itp = model.begin(); itp != model.end(); itp++) {
|
||||
for (auto itp = model->begin(); itp != model->end(); itp++) {
|
||||
QList<QStandardItem*> items;
|
||||
|
||||
QString key = itp->first;
|
||||
@@ -770,10 +958,10 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
propertyItem->setToolTip(modelProperty.getDescription());
|
||||
items.append(propertyItem);
|
||||
|
||||
auto valueItem = new QStandardItem(_material.getPhysicalValueString(key));
|
||||
auto valueItem = new QStandardItem(_material->getPhysicalValueString(key));
|
||||
valueItem->setToolTip(modelProperty.getDescription());
|
||||
QVariant variant;
|
||||
variant.setValue(&_material);
|
||||
variant.setValue(_material);
|
||||
valueItem->setData(variant);
|
||||
items.append(valueItem);
|
||||
|
||||
@@ -794,17 +982,47 @@ void MaterialsEditor::updateMaterialProperties()
|
||||
}
|
||||
}
|
||||
|
||||
QString MaterialsEditor::libraryPath(std::shared_ptr<Materials::Material> material) const
|
||||
{
|
||||
QString path;
|
||||
auto library = material->getLibrary();
|
||||
if (library) {
|
||||
path = QString::fromStdString("/%1/%2")
|
||||
.arg(material->getLibrary()->getName())
|
||||
.arg(material->getDirectory());
|
||||
}
|
||||
else {
|
||||
path = QString::fromStdString("%1").arg(material->getDirectory());
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void MaterialsEditor::updateMaterialGeneral()
|
||||
{
|
||||
QString parentString;
|
||||
try {
|
||||
auto parent = _materialManager.getParent(_material);
|
||||
parentString = libraryPath(parent);
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
}
|
||||
|
||||
// Update the general information
|
||||
ui->editName->setText(_material->getName());
|
||||
ui->editAuthor->setText(_material->getAuthor());
|
||||
ui->editLicense->setText(_material->getLicense());
|
||||
ui->editParent->setText(parentString);
|
||||
ui->editParent->setReadOnly(true);
|
||||
ui->editSourceURL->setText(_material->getURL());
|
||||
ui->editSourceReference->setText(_material->getReference());
|
||||
// ui->editTags->setText(_material->getName());
|
||||
ui->editDescription->setText(_material->getDescription());
|
||||
}
|
||||
|
||||
void MaterialsEditor::updateMaterial()
|
||||
{
|
||||
// Update the general information
|
||||
ui->editName->setText(_material.getName());
|
||||
ui->editAuthorLicense->setText(_material.getAuthorAndLicense());
|
||||
// ui->editParent->setText(_material.getName());
|
||||
ui->editSourceURL->setText(_material.getURL());
|
||||
ui->editSourceReference->setText(_material.getReference());
|
||||
// ui->editTags->setText(_material.getName());
|
||||
ui->editDescription->setText(_material.getDescription());
|
||||
|
||||
updateMaterialGeneral();
|
||||
updateMaterialProperties();
|
||||
updateMaterialAppearance();
|
||||
|
||||
@@ -830,13 +1048,13 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected,
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid.isEmpty() || uuid == _material.getUUID()) {
|
||||
if (uuid.isEmpty() || uuid == _material->getUUID()) {
|
||||
Base::Console().Log("*** Unchanged material '%s'\n", uuid.toStdString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure data is saved (or discarded) before changing materials
|
||||
if (_material.getEditState() != Materials::Material::ModelEdit_None) {
|
||||
if (_material->getEditState() != Materials::Material::ModelEdit_None) {
|
||||
// Prompt the user to save or discard changes
|
||||
Base::Console().Log("*** Material edited!!!\n");
|
||||
int res = confirmSave(this);
|
||||
@@ -847,16 +1065,85 @@ void MaterialsEditor::onSelectMaterial(const QItemSelection& selected,
|
||||
|
||||
// Get the selected material
|
||||
try {
|
||||
_material = getMaterialManager().getMaterial(uuid);
|
||||
_material = std::make_shared<Materials::Material>(*getMaterialManager().getMaterial(uuid));
|
||||
}
|
||||
catch (Materials::ModelNotFound const&) {
|
||||
Base::Console().Log("*** Unable to load material '%s'\n", uuid.toStdString().c_str());
|
||||
Materials::Material empty;
|
||||
_material = empty;
|
||||
_material = std::make_shared<Materials::Material>();
|
||||
}
|
||||
|
||||
updateMaterial();
|
||||
_material.resetEditState();
|
||||
_material->resetEditState();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onDoubleClick(const QModelIndex& index)
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onDoubleClick()\n");
|
||||
accept();
|
||||
}
|
||||
|
||||
void MaterialsEditor::onContextMenu(const QPoint& pos)
|
||||
{
|
||||
Base::Console().Log("MaterialsEditor::onContextMenu(%d,%d)\n", pos.x(), pos.y());
|
||||
// QModelIndex index = ui->treeMaterials->indexAt(pos);
|
||||
// QString path = pathFromIndex(index);
|
||||
// Base::Console().Log("\tindex at (%d,%d)->'%s'\n",
|
||||
// index.row(),
|
||||
// index.column(),
|
||||
// path.toStdString().c_str());
|
||||
|
||||
|
||||
QMenu contextMenu(tr("Context menu"), this);
|
||||
|
||||
QAction action1(tr("Inherit from"), this);
|
||||
// action1.setShortcut(Qt::Key_Delete);
|
||||
connect(&action1, &QAction::triggered, this, &MaterialsEditor::onInherit);
|
||||
contextMenu.addAction(&action1);
|
||||
|
||||
QAction action2(tr("Inherit new material"), this);
|
||||
// action1.setShortcut(Qt::Key_Delete);
|
||||
connect(&action2, &QAction::triggered, this, &MaterialsEditor::onInheritNew);
|
||||
contextMenu.addAction(&action2);
|
||||
|
||||
contextMenu.exec(ui->treeMaterials->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInherit(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onInherit()\n");
|
||||
// QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
// if (!selectionModel->hasSelection()) {
|
||||
// Base::Console().Log("\tNothing selected\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Base::Console().Log("\tSelected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
// int res = confirmDelete(this);
|
||||
// if (res == QMessageBox::Cancel) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
void MaterialsEditor::onInheritNew(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
Base::Console().Log("MaterialsEditor::onInherit()\n");
|
||||
// QItemSelectionModel* selectionModel = ui->treeMaterials->selectionModel();
|
||||
// if (!selectionModel->hasSelection()) {
|
||||
// Base::Console().Log("\tNothing selected\n");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Base::Console().Log("\tSelected path '%s'\n", _selectedFull.toStdString().c_str());
|
||||
// int res = confirmDelete(this);
|
||||
// if (res == QMessageBox::Cancel) {
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
int MaterialsEditor::confirmSave(QWidget* parent)
|
||||
|
||||
Reference in New Issue
Block a user