Material: MaterialTreeWidget usability enhancements
Improves the MaterialTreeWidget beyond minimum viable product. - Filters can now be filter lists to allow a variety of filtering options. - User preferences allow the inclusion/exclusion of favorites and recents. - Widget state such as expansion, tree expansions, etc are saved and restored. - show current appearancee material when editing. - implements a python interface #fixes 13421: always opens full tree
This commit is contained in:
committed by
Chris Hennes
parent
9101454c4d
commit
9f43b0ff76
@@ -27,9 +27,7 @@
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/PyObjectBase.h>
|
||||
|
||||
// #include "Model.h"
|
||||
#include "MaterialFilter.h"
|
||||
|
||||
#include "MaterialFilterPy.h"
|
||||
#include "MaterialManagerPy.h"
|
||||
#include "MaterialPy.h"
|
||||
#include "ModelManagerPy.h"
|
||||
@@ -68,6 +66,7 @@ PyMOD_INIT_FUNC(Materials)
|
||||
Base::Console().Log("Loading Material module... done\n");
|
||||
|
||||
Base::Interpreter().addType(&Materials::MaterialManagerPy::Type, module, "MaterialManager");
|
||||
Base::Interpreter().addType(&Materials::MaterialFilterPy::Type, module, "MaterialFilter");
|
||||
Base::Interpreter().addType(&Materials::MaterialPy::Type, module, "Material");
|
||||
Base::Interpreter().addType(&Materials::ModelManagerPy::Type, module, "ModelManager");
|
||||
Base::Interpreter().addType(&Materials::ModelPropertyPy::Type, module, "ModelProperty");
|
||||
|
||||
@@ -33,12 +33,31 @@
|
||||
|
||||
using namespace Materials;
|
||||
|
||||
MaterialFilterOptions::MaterialFilterOptions()
|
||||
: _includeFavorites(true)
|
||||
, _includeRecent(true)
|
||||
, _includeFolders(true)
|
||||
, _includeLibraries(true)
|
||||
, _includeLegacy(false)
|
||||
{}
|
||||
|
||||
MaterialFilterTreeWidgetOptions::MaterialFilterTreeWidgetOptions()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/TreeWidget");
|
||||
_includeFavorites = param->GetBool("ShowFavorites", true);
|
||||
_includeRecent = param->GetBool("ShowRecent", true);
|
||||
_includeFolders = param->GetBool("ShowEmptyFolders", false);
|
||||
_includeLibraries = param->GetBool("ShowEmptyLibraries", true);
|
||||
_includeLegacy = param->GetBool("ShowLegacy", false);
|
||||
}
|
||||
|
||||
//===
|
||||
|
||||
TYPESYSTEM_SOURCE(Materials::MaterialFilter, Base::BaseClass)
|
||||
|
||||
MaterialFilter::MaterialFilter()
|
||||
: _includeFolders(true)
|
||||
, _includeLegacy(true)
|
||||
, _required()
|
||||
: _required()
|
||||
, _requiredComplete()
|
||||
{}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
@@ -36,6 +37,102 @@ namespace Materials
|
||||
|
||||
class Material;
|
||||
|
||||
/*
|
||||
* This class is used to set options for a material tree search
|
||||
*
|
||||
*/
|
||||
class MaterialsExport MaterialFilterOptions
|
||||
{
|
||||
|
||||
public:
|
||||
MaterialFilterOptions();
|
||||
virtual ~MaterialFilterOptions() = default;
|
||||
|
||||
/* Indicates if we should show favourite materials
|
||||
*
|
||||
* Default is to show favourite materials
|
||||
*/
|
||||
bool includeFavorites() const
|
||||
{
|
||||
return _includeFavorites;
|
||||
}
|
||||
void setIncludeFavorites(bool value)
|
||||
{
|
||||
_includeFavorites = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should show recent materials
|
||||
*
|
||||
* Default is to show recent materials
|
||||
*/
|
||||
bool includeRecent() const
|
||||
{
|
||||
return _includeRecent;
|
||||
}
|
||||
void setIncludeRecent(bool value)
|
||||
{
|
||||
_includeRecent = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should include empty folders
|
||||
*
|
||||
* Default is not to include empty folders
|
||||
*/
|
||||
bool includeEmptyFolders() const
|
||||
{
|
||||
return _includeFolders;
|
||||
}
|
||||
void setIncludeEmptyFolders(bool value)
|
||||
{
|
||||
_includeFolders = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should include empty libraries
|
||||
*
|
||||
* Default is to include empty libraries
|
||||
*/
|
||||
bool includeEmptyLibraries() const
|
||||
{
|
||||
return _includeLibraries;
|
||||
}
|
||||
void setIncludeEmptyLibraries(bool value)
|
||||
{
|
||||
_includeLibraries = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should include materials in the older format
|
||||
*
|
||||
* Default is not to include legacy format materials
|
||||
*/
|
||||
bool includeLegacy() const
|
||||
{
|
||||
return _includeLegacy;
|
||||
}
|
||||
void setIncludeLegacy(bool legacy)
|
||||
{
|
||||
_includeLegacy = legacy;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _includeFavorites;
|
||||
bool _includeRecent;
|
||||
bool _includeFolders;
|
||||
bool _includeLibraries;
|
||||
bool _includeLegacy;
|
||||
};
|
||||
|
||||
/*
|
||||
* The same class initialized with preferences for the MaterialTreeWidget
|
||||
*
|
||||
*/
|
||||
class MaterialsExport MaterialFilterTreeWidgetOptions: public MaterialFilterOptions
|
||||
{
|
||||
|
||||
public:
|
||||
MaterialFilterTreeWidgetOptions();
|
||||
~MaterialFilterTreeWidgetOptions() override = default;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class is used to filter materials during a material tree search
|
||||
*
|
||||
@@ -48,30 +145,17 @@ public:
|
||||
MaterialFilter();
|
||||
virtual ~MaterialFilter() = default;
|
||||
|
||||
/* Indicates if we should include empty folders
|
||||
*
|
||||
* Default is to include empty folders
|
||||
/*
|
||||
* Filter name when used in a list of filters. The name should be
|
||||
* unique within the list.
|
||||
*/
|
||||
bool includeEmptyFolders() const
|
||||
QString name() const
|
||||
{
|
||||
return _includeFolders;
|
||||
return _name;
|
||||
}
|
||||
void setIncludeEmptyFolders(bool value)
|
||||
void setName(const QString& name)
|
||||
{
|
||||
_includeFolders = value;
|
||||
}
|
||||
|
||||
/* Indicates if we should include materials in the older format
|
||||
*
|
||||
* Default is to include legacy format materials
|
||||
*/
|
||||
bool includeLegacy() const
|
||||
{
|
||||
return _includeLegacy;
|
||||
}
|
||||
void setIncludeLegacy(bool legacy)
|
||||
{
|
||||
_includeLegacy = legacy;
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/* Sets of model UUIDs that should be included. Optionally, we can
|
||||
@@ -101,12 +185,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool _includeFolders;
|
||||
bool _includeLegacy;
|
||||
QString _name;
|
||||
QSet<QString> _required;
|
||||
QSet<QString> _requiredComplete;
|
||||
};
|
||||
|
||||
} // namespace Materials
|
||||
|
||||
Q_DECLARE_METATYPE(Materials::MaterialFilter)
|
||||
|
||||
#endif // MATERIAL_MATERIALFILTER_H
|
||||
|
||||
@@ -15,17 +15,11 @@
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>Material filters.</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="IncludeEmptyFolders" ReadOnly="false">
|
||||
<Attribute Name="Name" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include empty folders in the material list.</UserDocu>
|
||||
<UserDocu>Name of the filter used to select a filter in a list</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeEmptyFolders" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeLegacy" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include legacy materials in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeLegacy" Type="Boolean"/>
|
||||
<Parameter Name="Name" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="RequiredModels" ReadOnly="false">
|
||||
<Documentation>
|
||||
|
||||
@@ -61,24 +61,15 @@ int MaterialFilterPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py::Boolean MaterialFilterPy::getIncludeEmptyFolders() const
|
||||
Py::String MaterialFilterPy::getName() const
|
||||
{
|
||||
return {getMaterialFilterPtr()->includeEmptyFolders()};
|
||||
auto filterName = getMaterialFilterPtr()->name();
|
||||
return {filterName.toStdString()};
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setIncludeEmptyFolders(const Py::Boolean value)
|
||||
void MaterialFilterPy::setName(const Py::String value)
|
||||
{
|
||||
getMaterialFilterPtr()->setIncludeEmptyFolders(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialFilterPy::getIncludeLegacy() const
|
||||
{
|
||||
return {getMaterialFilterPtr()->includeLegacy()};
|
||||
}
|
||||
|
||||
void MaterialFilterPy::setIncludeLegacy(const Py::Boolean value)
|
||||
{
|
||||
getMaterialFilterPtr()->setIncludeLegacy(value.isTrue());
|
||||
getMaterialFilterPtr()->setName(QString::fromStdString(value));
|
||||
}
|
||||
|
||||
Py::List MaterialFilterPy::getRequiredModels() const
|
||||
|
||||
@@ -266,7 +266,8 @@ QString MaterialLibrary::getUUIDFromPath(const QString& path) const
|
||||
}
|
||||
|
||||
bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
const Materials::MaterialFilterOptions& options) const
|
||||
{
|
||||
if (!filter) {
|
||||
// If there's no filter we always include
|
||||
@@ -274,7 +275,7 @@ bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
|
||||
}
|
||||
|
||||
// filter out old format files
|
||||
if (material->isOldFormat() && !filter->includeLegacy()) {
|
||||
if (material->isOldFormat() && !options.includeLegacy()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -283,7 +284,8 @@ bool MaterialLibrary::materialInTree(const std::shared_ptr<Material>& material,
|
||||
}
|
||||
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
const Materials::MaterialFilterOptions& options) const
|
||||
{
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>> materialTree =
|
||||
std::make_shared<std::map<QString, std::shared_ptr<MaterialTreeNode>>>();
|
||||
@@ -292,7 +294,7 @@ MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter
|
||||
auto filename = it.first;
|
||||
auto material = it.second;
|
||||
|
||||
if (materialInTree(material, filter)) {
|
||||
if (materialInTree(material, filter, options)) {
|
||||
QStringList list = filename.split(QString::fromStdString("/"));
|
||||
|
||||
// Start at the root
|
||||
@@ -325,7 +327,7 @@ MaterialLibrary::getMaterialTree(const std::shared_ptr<Materials::MaterialFilter
|
||||
|
||||
// Empty folders aren't included in _materialPathMap, so we add them by looking at the file
|
||||
// system
|
||||
if (!filter || filter->includeEmptyFolders()) {
|
||||
if (!filter || options.includeEmptyFolders()) {
|
||||
auto folderList = MaterialLoader::getMaterialFolders(*this);
|
||||
for (auto& folder : *folderList) {
|
||||
QStringList list = folder.split(QString::fromStdString("/"));
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace Materials
|
||||
class Material;
|
||||
class MaterialManager;
|
||||
class MaterialFilter;
|
||||
class MaterialFilterOptions;
|
||||
|
||||
class MaterialsExport MaterialLibrary: public LibraryBase,
|
||||
public std::enable_shared_from_this<MaterialLibrary>
|
||||
@@ -79,7 +80,8 @@ public:
|
||||
std::shared_ptr<Material> addMaterial(const std::shared_ptr<Material>& material,
|
||||
const QString& path);
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter) const;
|
||||
getMaterialTree(const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
const Materials::MaterialFilterOptions& options) const;
|
||||
|
||||
bool isReadOnly() const
|
||||
{
|
||||
@@ -99,7 +101,8 @@ protected:
|
||||
void updatePaths(const QString& oldPath, const QString& newPath);
|
||||
QString getUUIDFromPath(const QString& path) const;
|
||||
bool materialInTree(const std::shared_ptr<Material>& material,
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const;
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
const Materials::MaterialFilterOptions& options) const;
|
||||
|
||||
bool _readOnly;
|
||||
std::unique_ptr<std::map<QString, std::shared_ptr<Material>>> _materialPathMap;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
#include <QMutex>
|
||||
#include <QDirIterator>
|
||||
#include <QMutexLocker>
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QMutex>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <Mod/Material/MaterialGlobal.h>
|
||||
@@ -34,9 +32,12 @@
|
||||
#include "Materials.h"
|
||||
|
||||
#include "MaterialLibrary.h"
|
||||
#include "MaterialFilter.h"
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
class QMutex;
|
||||
|
||||
namespace App
|
||||
{
|
||||
class Material;
|
||||
@@ -45,8 +46,6 @@ class Material;
|
||||
namespace Materials
|
||||
{
|
||||
|
||||
class MaterialFilter;
|
||||
|
||||
class MaterialsExport MaterialManager: public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
@@ -77,13 +76,22 @@ public:
|
||||
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library,
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter) const
|
||||
{
|
||||
return library->getMaterialTree(filter);
|
||||
MaterialFilterOptions options;
|
||||
return library->getMaterialTree(filter, options);
|
||||
}
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library,
|
||||
const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
const MaterialFilterOptions& options) const
|
||||
{
|
||||
return library->getMaterialTree(filter, options);
|
||||
}
|
||||
std::shared_ptr<std::map<QString, std::shared_ptr<MaterialTreeNode>>>
|
||||
getMaterialTree(const std::shared_ptr<MaterialLibrary>& library) const
|
||||
{
|
||||
std::shared_ptr<Materials::MaterialFilter> filter;
|
||||
return library->getMaterialTree(filter);
|
||||
MaterialFilterOptions options;
|
||||
return library->getMaterialTree(filter, options);
|
||||
}
|
||||
std::shared_ptr<std::list<QString>>
|
||||
getMaterialFolders(const std::shared_ptr<MaterialLibrary>& library) const;
|
||||
|
||||
@@ -71,7 +71,7 @@ PyObject* MaterialManagerPy::getMaterial(PyObject* args)
|
||||
|
||||
PyObject* MaterialManagerPy::getMaterialByPath(PyObject* args)
|
||||
{
|
||||
char* path;
|
||||
char* path {};
|
||||
const char* lib = "";
|
||||
if (!PyArg_ParseTuple(args, "et|s", "utf-8", &path, &lib)) {
|
||||
return nullptr;
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "DlgSettingsMaterial.h"
|
||||
#include "Workbench.h"
|
||||
#include "WorkbenchManipulator.h"
|
||||
#include "MaterialTreeWidget.h"
|
||||
#include "MaterialTreeWidgetPy.h"
|
||||
|
||||
// use a different name to CreateCommand()
|
||||
void CreateMaterialCommands();
|
||||
@@ -78,7 +80,7 @@ PyMOD_INIT_FUNC(MatGui)
|
||||
|
||||
// load needed modules
|
||||
try {
|
||||
Base::Interpreter().runString("import Material");
|
||||
Base::Interpreter().runString("import Materials");
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
@@ -107,5 +109,18 @@ PyMOD_INIT_FUNC(MatGui)
|
||||
// add resources and reloads the translators
|
||||
loadMaterialResource();
|
||||
|
||||
Base::Interpreter().addType(&MatGui::MaterialTreeWidgetPy::Type,
|
||||
matGuiModule,
|
||||
"MaterialTreeWidget");
|
||||
|
||||
|
||||
// Initialize types
|
||||
|
||||
MatGui::MaterialTreeWidget::init();
|
||||
|
||||
// Add custom widgets
|
||||
new Gui::WidgetProducer<MatGui::MaterialTreeWidget>;
|
||||
|
||||
|
||||
PyMOD_Return(matGuiModule);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,14 @@ qt_find_and_add_translation(QM_SRCS "Resources/translations/*_*.ts"
|
||||
qt_create_resource_file(${Material_TR_QRC} ${QM_SRCS})
|
||||
qt_add_resources(MatGui_QRC_SRCS Resources/Material.qrc ${Material_TR_QRC})
|
||||
|
||||
generate_from_xml(MaterialTreeWidgetPy)
|
||||
|
||||
SET(Python_SRCS
|
||||
MaterialTreeWidgetPy.xml
|
||||
MaterialTreeWidgetPyImpl.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
set(MatGui_UIC_SRCS
|
||||
Array2D.ui
|
||||
Array3D.ui
|
||||
@@ -51,6 +59,7 @@ set(MatGui_UIC_SRCS
|
||||
)
|
||||
|
||||
SET(MatGui_SRCS
|
||||
${Python_SRCS}
|
||||
${MatGui_QRC_SRCS}
|
||||
${MatGui_UIC_HDRS}
|
||||
AppearancePreview.h
|
||||
|
||||
@@ -402,18 +402,6 @@
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="buttonUserDefinedMaterial">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>32767</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
|
||||
@@ -163,11 +163,7 @@ DlgDisplayPropertiesImp::DlgDisplayPropertiesImp(bool floating, QWidget* parent,
|
||||
|
||||
// Create a filter to only include current format materials
|
||||
// that contain the basic render model.
|
||||
auto filter = std::make_shared<Materials::MaterialFilter>();
|
||||
filter->setIncludeEmptyFolders(false);
|
||||
filter->setIncludeLegacy(false);
|
||||
filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Basic);
|
||||
d->ui.widgetMaterial->setFilter(filter);
|
||||
setupFilters();
|
||||
|
||||
std::vector<Gui::ViewProvider*> views = getSelection();
|
||||
setDisplayModes(views);
|
||||
@@ -209,6 +205,32 @@ DlgDisplayPropertiesImp::~DlgDisplayPropertiesImp()
|
||||
Gui::Selection().Detach(this);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setupFilters()
|
||||
{
|
||||
// Create a filter to only include current format materials
|
||||
// that contain the basic render model.
|
||||
auto filterList = std::make_shared<std::list<std::shared_ptr<Materials::MaterialFilter>>>();
|
||||
|
||||
auto filter = std::make_shared<Materials::MaterialFilter>();
|
||||
filter->setName(tr("Basic Appearance"));
|
||||
filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Basic);
|
||||
filterList->push_back(filter);
|
||||
|
||||
filter = std::make_shared<Materials::MaterialFilter>();
|
||||
filter->setName(tr("Texture Appearance"));
|
||||
filter->addRequiredComplete(Materials::ModelUUIDs::ModelUUID_Rendering_Texture);
|
||||
filterList->push_back(filter);
|
||||
|
||||
filter = std::make_shared<Materials::MaterialFilter>();
|
||||
filter->setName(tr("All Materials"));
|
||||
filterList->push_back(filter);
|
||||
|
||||
d->ui.widgetMaterial->setIncludeEmptyFolders(false);
|
||||
d->ui.widgetMaterial->setIncludeLegacy(false);
|
||||
|
||||
d->ui.widgetMaterial->setFilter(filterList);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setupConnections()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
@@ -337,6 +359,7 @@ void DlgDisplayPropertiesImp::slotChangedObject(const Gui::ViewProvider& obj,
|
||||
else if (prop.isDerivedFrom<App::PropertyMaterialList>()) {
|
||||
//auto& value = static_cast<const App::PropertyMaterialList&>(prop).getValue();
|
||||
if (prop_name == "ShapeAppearance") {
|
||||
// Base::Console().Log("slotChangeObject(ShapeAppearance)\n");
|
||||
// bool blocked = d->ui.buttonColor->blockSignals(true);
|
||||
// auto color = value.diffuseColor;
|
||||
// d->ui.buttonColor->setColor(QColor((int)(255.0f * color.r),
|
||||
@@ -565,17 +588,21 @@ void DlgDisplayPropertiesImp::setDisplayModes(const std::vector<Gui::ViewProvide
|
||||
|
||||
void DlgDisplayPropertiesImp::setMaterial(const std::vector<Gui::ViewProvider*>& views)
|
||||
{
|
||||
bool material = false;
|
||||
//App::Material::MaterialType matType = App::Material::DEFAULT;
|
||||
for (auto view : views) {
|
||||
if (auto* prop =
|
||||
dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeMaterial"))) {
|
||||
material = true;
|
||||
// matType = prop->getValue().getType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
d->ui.buttonUserDefinedMaterial->setEnabled(material);
|
||||
Q_UNUSED(views);
|
||||
// bool material = false;
|
||||
// App::Material mat = App::Material(App::Material::DEFAULT);
|
||||
// for (auto view : views) {
|
||||
// if (auto* prop =
|
||||
// dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeMaterial"))) {
|
||||
// mat = prop->getValue();
|
||||
// material = mat.uuid.empty();
|
||||
// if (!material) {
|
||||
// d->ui.widgetMaterial->setMaterial(QString::fromStdString(mat.uuid));
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// d->ui.buttonUserDefinedMaterial->setEnabled(material);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setColorPlot(const std::vector<Gui::ViewProvider*>& views)
|
||||
@@ -595,9 +622,21 @@ void DlgDisplayPropertiesImp::setColorPlot(const std::vector<Gui::ViewProvider*>
|
||||
|
||||
void DlgDisplayPropertiesImp::setShapeAppearance(const std::vector<Gui::ViewProvider*>& views)
|
||||
{
|
||||
Q_UNUSED(views)
|
||||
|
||||
// Private::setElementAppearance(views, "ShapeColor", d->ui.buttonColor);
|
||||
bool material = false;
|
||||
App::Material mat = App::Material(App::Material::DEFAULT);
|
||||
for (auto view : views) {
|
||||
if (auto* prop =
|
||||
dynamic_cast<App::PropertyMaterialList*>(view->getPropertyByName("ShapeAppearance"))) {
|
||||
mat = prop->getValues()[0];
|
||||
material = mat.uuid.empty();
|
||||
if (!material) {
|
||||
d->ui.widgetMaterial->setMaterial(QString::fromStdString(mat.uuid));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// d->ui.buttonUserDefinedMaterial->setEnabled(material);
|
||||
d->ui.buttonUserDefinedMaterial->setEnabled(true);
|
||||
}
|
||||
|
||||
void DlgDisplayPropertiesImp::setLineColor(const std::vector<Gui::ViewProvider*>& views)
|
||||
@@ -668,6 +707,7 @@ void DlgDisplayPropertiesImp::onMaterialSelected(
|
||||
material->getAppearanceProperty(QString::fromLatin1("Shininess"))->getFloat();
|
||||
mat.transparency =
|
||||
material->getAppearanceProperty(QString::fromLatin1("Transparency"))->getFloat();
|
||||
mat.uuid = material->getUUID().toStdString();
|
||||
prop->setValue(mat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ protected:
|
||||
|
||||
private:
|
||||
void setupConnections();
|
||||
void setupFilters();
|
||||
void slotChangedObject(const Gui::ViewProvider&, const App::Property& Prop);
|
||||
void setDisplayModes(const std::vector<Gui::ViewProvider*>&);
|
||||
void setMaterial(const std::vector<Gui::ViewProvider*>&);
|
||||
|
||||
@@ -43,6 +43,11 @@ void DlgSettingsMaterial::saveSettings()
|
||||
ui->fc_custom_mat_dir->onSave();
|
||||
ui->cb_delete_duplicates->onSave();
|
||||
ui->cb_sort_by_resources->onSave();
|
||||
ui->cb_show_favorites->onSave();
|
||||
ui->cb_show_recent->onSave();
|
||||
ui->cb_show_empty_libraries->onSave();
|
||||
ui->cb_show_empty_folders->onSave();
|
||||
ui->cb_show_legacy->onSave();
|
||||
|
||||
// Temporary for testing
|
||||
ui->cb_legacy_editor->onSave();
|
||||
@@ -57,6 +62,11 @@ void DlgSettingsMaterial::loadSettings()
|
||||
ui->fc_custom_mat_dir->onRestore();
|
||||
ui->cb_delete_duplicates->onRestore();
|
||||
ui->cb_sort_by_resources->onRestore();
|
||||
ui->cb_show_favorites->onRestore();
|
||||
ui->cb_show_recent->onRestore();
|
||||
ui->cb_show_empty_libraries->onRestore();
|
||||
ui->cb_show_empty_folders->onRestore();
|
||||
ui->cb_show_legacy->onRestore();
|
||||
|
||||
// Temporary for testing
|
||||
ui->cb_legacy_editor->onRestore();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>434</width>
|
||||
<height>341</height>
|
||||
<height>553</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -231,6 +231,89 @@ If unchecked, they will be sorted by their name.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gbMaterialSelector">
|
||||
<property name="title">
|
||||
<string>Material Selector</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_show_favorites">
|
||||
<property name="text">
|
||||
<string>Show favorites</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ShowFavorites</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/TreeWidget</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_show_recent">
|
||||
<property name="text">
|
||||
<string>Show recent</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ShowRecent</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/TreeWidget</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_show_empty_libraries">
|
||||
<property name="text">
|
||||
<string>Show empty libraries</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ShowEmptyLibraries</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/TreeWidget</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_show_empty_folders">
|
||||
<property name="text">
|
||||
<string>Show empty folders</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ShowEmptyFolders</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/TreeWidget</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_show_legacy">
|
||||
<property name="text">
|
||||
<string>Show legacy files</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ShowLegacy</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/TreeWidget</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -38,12 +38,14 @@
|
||||
|
||||
#include <Mod/Material/App/Exceptions.h>
|
||||
#include <Mod/Material/App/MaterialFilter.h>
|
||||
#include <Mod/Material/App/MaterialFilterPy.h>
|
||||
#include <Mod/Material/App/ModelUuids.h>
|
||||
|
||||
#include "MaterialTreeWidget.h"
|
||||
#include "MaterialsEditor.h"
|
||||
#include "ui_MaterialsEditor.h"
|
||||
|
||||
Q_DECLARE_METATYPE(Materials::MaterialFilterPy*)
|
||||
|
||||
using Base::Console;
|
||||
using namespace MatGui;
|
||||
@@ -51,7 +53,9 @@ using namespace MatGui;
|
||||
/** Constructs a Material tree widget.
|
||||
*/
|
||||
|
||||
MaterialTreeWidget::MaterialTreeWidget(std::shared_ptr<Materials::MaterialFilter> filter,
|
||||
TYPESYSTEM_SOURCE(MatGui::MaterialTreeWidget, Base::BaseClass)
|
||||
|
||||
MaterialTreeWidget::MaterialTreeWidget(const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_expanded(false)
|
||||
@@ -60,10 +64,21 @@ MaterialTreeWidget::MaterialTreeWidget(std::shared_ptr<Materials::MaterialFilter
|
||||
setup();
|
||||
}
|
||||
|
||||
MaterialTreeWidget::MaterialTreeWidget(
|
||||
const std::shared_ptr<std::list<std::shared_ptr<Materials::MaterialFilter>>>& filterList,
|
||||
QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_expanded(false)
|
||||
, _filter(std::make_shared<Materials::MaterialFilter>())
|
||||
, _filterList(filterList)
|
||||
{
|
||||
setup();
|
||||
}
|
||||
|
||||
MaterialTreeWidget::MaterialTreeWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_expanded(false)
|
||||
, _filter(nullptr)
|
||||
, _filter(std::make_shared<Materials::MaterialFilter>())
|
||||
{
|
||||
setup();
|
||||
}
|
||||
@@ -80,7 +95,12 @@ void MaterialTreeWidget::setup()
|
||||
/**
|
||||
* Destroys the widget and detaches it from its parameter group.
|
||||
*/
|
||||
MaterialTreeWidget::~MaterialTreeWidget() = default;
|
||||
MaterialTreeWidget::~MaterialTreeWidget()
|
||||
{
|
||||
addRecent(m_uuid);
|
||||
saveWidgetSettings();
|
||||
saveMaterialTree();
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::createLayout()
|
||||
{
|
||||
@@ -88,9 +108,9 @@ void MaterialTreeWidget::createLayout()
|
||||
m_expand = new QPushButton(this);
|
||||
m_expand->setIcon(style()->standardIcon(QStyle::SP_TitleBarUnshadeButton));
|
||||
m_materialTree = new QTreeView(this);
|
||||
m_filterCombo = new QComboBox(this);
|
||||
m_editor = new QPushButton(tr("Launch editor"), this);
|
||||
|
||||
// m_materialTree->setSelectionModel(QAbstractItemView::SingleSelection);
|
||||
m_materialTree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_materialTree->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
|
||||
@@ -102,6 +122,7 @@ void MaterialTreeWidget::createLayout()
|
||||
treeLayout->addWidget(m_materialTree);
|
||||
|
||||
auto buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addWidget(m_filterCombo);
|
||||
buttonLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Preferred));
|
||||
buttonLayout->addWidget(m_editor);
|
||||
|
||||
@@ -112,18 +133,34 @@ void MaterialTreeWidget::createLayout()
|
||||
layout->addItem(buttonLayout);
|
||||
setLayout(layout);
|
||||
|
||||
// Start in an unexpanded state. Store the state?
|
||||
openWidgetState(false);
|
||||
// Set the filter if using a filter list
|
||||
if (hasMultipleFilters()) {
|
||||
_filter = _filterList->front();
|
||||
}
|
||||
|
||||
fillFilterCombo();
|
||||
|
||||
// Start in the previous expanded state
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/TreeWidget");
|
||||
auto expanded = param->GetBool("WidgetExpanded", false);
|
||||
setExpanded(expanded);
|
||||
|
||||
connect(m_expand, &QPushButton::clicked, this, &MaterialTreeWidget::expandClicked);
|
||||
connect(m_editor, &QPushButton::clicked, this, &MaterialTreeWidget::editorClicked);
|
||||
connect(m_filterCombo,
|
||||
&QComboBox::currentTextChanged,
|
||||
this,
|
||||
&MaterialTreeWidget::onFilter);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::openWidgetState(bool open)
|
||||
void MaterialTreeWidget::setExpanded(bool open)
|
||||
{
|
||||
m_materialTree->setVisible(open);
|
||||
m_editor->setVisible(open);
|
||||
|
||||
setFilterVisible(open);
|
||||
|
||||
m_expanded = open;
|
||||
|
||||
if (open) {
|
||||
@@ -134,12 +171,33 @@ void MaterialTreeWidget::openWidgetState(bool open)
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::setFilterVisible(bool open)
|
||||
{
|
||||
if (open && hasMultipleFilters()) {
|
||||
m_filterCombo->setVisible(true);
|
||||
}
|
||||
else {
|
||||
m_filterCombo->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::fillFilterCombo()
|
||||
{
|
||||
m_filterCombo->clear();
|
||||
if (hasMultipleFilters()) {
|
||||
for (auto const& filter : *_filterList) {
|
||||
m_filterCombo->addItem(filter->name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MaterialTreeWidget::expandClicked(bool checked)
|
||||
{
|
||||
Q_UNUSED(checked)
|
||||
|
||||
// Toggle the open state
|
||||
openWidgetState(!m_expanded);
|
||||
setExpanded(!m_expanded);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::editorClicked(bool checked)
|
||||
@@ -160,7 +218,7 @@ void MaterialTreeWidget::editorClicked(bool checked)
|
||||
|
||||
// Gui::Application::Instance->commandManager().runCommandByName("Materials_Edit");
|
||||
// Toggle the open state
|
||||
// openWidgetState(!m_expanded);
|
||||
// setExpanded(!m_expanded);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::updateMaterial(const QString& uuid)
|
||||
@@ -212,8 +270,14 @@ QModelIndex MaterialTreeWidget::findInTree(const QString& uuid)
|
||||
auto root = model->invisibleRootItem();
|
||||
|
||||
QModelIndex index;
|
||||
if (findInTree(*root, &index, uuid)) {
|
||||
return index;
|
||||
// Find the original item, not the reference in favourites or recents
|
||||
for (int i = 0; i < root->rowCount(); i++) {
|
||||
auto child = root->child(i);
|
||||
if (child->text() != tr("Favorites") && child->text() != tr("Recent")) {
|
||||
if (findInTree(*child, &index, uuid)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -231,6 +295,7 @@ void MaterialTreeWidget::setMaterial(const QString& uuid)
|
||||
if (index.isValid()) {
|
||||
QItemSelectionModel* selectionModel = m_materialTree->selectionModel();
|
||||
selectionModel->select(index, QItemSelectionModel::SelectCurrent);
|
||||
m_materialTree->scrollTo(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,14 +304,61 @@ QString MaterialTreeWidget::getMaterialUUID() const
|
||||
return m_uuid;
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::setFilter(std::shared_ptr<Materials::MaterialFilter> filter)
|
||||
void MaterialTreeWidget::setFilter(const std::shared_ptr<Materials::MaterialFilter>& filter)
|
||||
{
|
||||
_filter.reset();
|
||||
if (_filter) {
|
||||
_filter.reset();
|
||||
}
|
||||
if (_filterList) {
|
||||
_filterList.reset();
|
||||
}
|
||||
|
||||
_filter = filter;
|
||||
|
||||
fillFilterCombo();
|
||||
setFilterVisible(m_expanded);
|
||||
|
||||
updateMaterialTree();
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::setFilter(
|
||||
const std::shared_ptr<std::list<std::shared_ptr<Materials::MaterialFilter>>>& filterList)
|
||||
{
|
||||
_filter.reset();
|
||||
if (_filterList) {
|
||||
_filterList.reset();
|
||||
}
|
||||
|
||||
_filterList = filterList;
|
||||
if (hasMultipleFilters()) {
|
||||
_filter = _filterList->front();
|
||||
}
|
||||
|
||||
fillFilterCombo();
|
||||
setFilterVisible(m_expanded);
|
||||
|
||||
updateMaterialTree();
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::setActiveFilter(const QString& name)
|
||||
{
|
||||
if (_filterList) {
|
||||
for (auto const& filter : *_filterList) {
|
||||
if (filter->name() == name) {
|
||||
_filter.reset();
|
||||
|
||||
_filter = filter;
|
||||
|
||||
// Save the library/folder expansion state
|
||||
saveMaterialTree();
|
||||
|
||||
updateMaterialTree();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::updateMaterialTree()
|
||||
{
|
||||
_favorites.clear();
|
||||
@@ -293,6 +405,70 @@ void MaterialTreeWidget::getRecents()
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::saveRecents()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/Recent");
|
||||
|
||||
// Clear out the existing favorites
|
||||
int count = param->GetInt("Recent", 0);
|
||||
for (int i = 0; static_cast<long>(i) < count; i++) {
|
||||
QString key = QString::fromLatin1("MRU%1").arg(i);
|
||||
param->RemoveASCII(key.toStdString().c_str());
|
||||
}
|
||||
|
||||
// Add the current values
|
||||
int size = _recents.size();
|
||||
if (size > _recentMax) {
|
||||
size = _recentMax;
|
||||
}
|
||||
param->SetInt("Recent", size);
|
||||
int j = 0;
|
||||
for (auto& recent : _recents) {
|
||||
QString key = QString::fromLatin1("MRU%1").arg(j);
|
||||
param->SetASCII(key.toStdString().c_str(), recent.toStdString());
|
||||
|
||||
j++;
|
||||
if (j >= size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::addRecent(const QString& uuid)
|
||||
{
|
||||
// Ensure it is a material. New, unsaved materials will not be
|
||||
try {
|
||||
auto material = _materialManager.getMaterial(uuid);
|
||||
Q_UNUSED(material)
|
||||
}
|
||||
catch (const Materials::MaterialNotFound&) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure no duplicates
|
||||
if (isRecent(uuid)) {
|
||||
_recents.remove(uuid);
|
||||
}
|
||||
|
||||
_recents.push_front(uuid);
|
||||
while (_recents.size() > static_cast<std::size_t>(_recentMax)) {
|
||||
_recents.pop_back();
|
||||
}
|
||||
|
||||
saveRecents();
|
||||
}
|
||||
|
||||
bool MaterialTreeWidget::isRecent(const QString& uuid) const
|
||||
{
|
||||
for (auto& it : _recents) {
|
||||
if (it == uuid) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::createMaterialTree()
|
||||
{
|
||||
auto model = new QStandardItemModel(this);
|
||||
@@ -312,36 +488,44 @@ void MaterialTreeWidget::createMaterialTree()
|
||||
|
||||
void MaterialTreeWidget::fillMaterialTree()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/TreeWidget/MaterialTree");
|
||||
|
||||
auto model = dynamic_cast<QStandardItemModel*>(m_materialTree->model());
|
||||
|
||||
auto lib = new QStandardItem(tr("Favorites"));
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib);
|
||||
addFavorites(lib);
|
||||
if (_filterOptions.includeFavorites()) {
|
||||
auto lib = new QStandardItem(tr("Favorites"));
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib, param);
|
||||
addFavorites(lib);
|
||||
}
|
||||
|
||||
lib = new QStandardItem(tr("Recent"));
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib);
|
||||
addRecents(lib);
|
||||
|
||||
// // Create a filter to only include current format materials
|
||||
// // that contain the basic render model.
|
||||
// Materials::MaterialFilter filter;
|
||||
// filter.setIncludeEmptyFolders(false);
|
||||
// filter.setIncludeLegacy(false);
|
||||
// filter.addRequired(Materials::ModelUUIDs::ModelUUID_Rendering_Basic);
|
||||
if (_filterOptions.includeRecent()) {
|
||||
auto lib = new QStandardItem(tr("Recent"));
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib, param);
|
||||
addRecents(lib);
|
||||
}
|
||||
|
||||
auto libraries = _materialManager.getMaterialLibraries();
|
||||
for (const auto& library : *libraries) {
|
||||
lib = new QStandardItem(library->getName());
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib);
|
||||
auto modelTree = _materialManager.getMaterialTree(library, _filter, _filterOptions);
|
||||
|
||||
QIcon icon(library->getIconPath());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
bool showLibraries = _filterOptions.includeEmptyLibraries();
|
||||
if (!_filterOptions.includeEmptyLibraries() && modelTree->size() > 0) {
|
||||
showLibraries = true;
|
||||
}
|
||||
|
||||
auto modelTree = _materialManager.getMaterialTree(library, _filter);
|
||||
addMaterials(*lib, modelTree, folderIcon, icon);
|
||||
if (showLibraries) {
|
||||
auto lib = new QStandardItem(library->getName());
|
||||
lib->setFlags(Qt::ItemIsEnabled);
|
||||
addExpanded(model, lib, param);
|
||||
|
||||
QIcon icon(library->getIconPath());
|
||||
QIcon folderIcon(QString::fromStdString(":/icons/folder.svg"));
|
||||
|
||||
addMaterials(*lib, modelTree, folderIcon, icon, param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,12 +535,34 @@ void MaterialTreeWidget::addExpanded(QStandardItem* parent, QStandardItem* child
|
||||
m_materialTree->setExpanded(child->index(), true);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::addExpanded(QStandardItem* parent,
|
||||
QStandardItem* child,
|
||||
const Base::Reference<ParameterGrp>& param)
|
||||
{
|
||||
parent->appendRow(child);
|
||||
|
||||
// Restore to any previous expansion state
|
||||
auto expand = param->GetBool(child->text().toStdString().c_str(), true);
|
||||
m_materialTree->setExpanded(child->index(), expand);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::addExpanded(QStandardItemModel* model, QStandardItem* child)
|
||||
{
|
||||
model->appendRow(child);
|
||||
m_materialTree->setExpanded(child->index(), true);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::addExpanded(QStandardItemModel* model,
|
||||
QStandardItem* child,
|
||||
const Base::Reference<ParameterGrp>& param)
|
||||
{
|
||||
model->appendRow(child);
|
||||
|
||||
// Restore to any previous expansion state
|
||||
auto expand = param->GetBool(child->text().toStdString().c_str(), true);
|
||||
m_materialTree->setExpanded(child->index(), expand);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::addRecents(QStandardItem* parent)
|
||||
{
|
||||
for (auto& uuid : _recents) {
|
||||
@@ -397,17 +603,16 @@ void MaterialTreeWidget::addMaterials(
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>&
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon)
|
||||
const QIcon& icon,
|
||||
const Base::Reference<ParameterGrp>& param)
|
||||
{
|
||||
auto childParam = param->GetGroup(parent.text().toStdString().c_str());
|
||||
for (auto& mat : *modelTree) {
|
||||
auto nodePtr = mat.second;
|
||||
if (nodePtr->getType() == Materials::MaterialTreeNode::DataNode) {
|
||||
auto material = nodePtr->getData();
|
||||
QString uuid = material->getUUID();
|
||||
// Base::Console().Log("Material path '%s'\n",
|
||||
// material->getDirectory().toStdString().c_str());
|
||||
|
||||
// auto card = new QStandardItem(icon, material->getName());
|
||||
auto card = new QStandardItem(icon, mat.first);
|
||||
card->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
card->setData(QVariant(uuid), Qt::UserRole);
|
||||
@@ -416,10 +621,10 @@ void MaterialTreeWidget::addMaterials(
|
||||
}
|
||||
else {
|
||||
auto node = new QStandardItem(folderIcon, mat.first);
|
||||
addExpanded(&parent, node);
|
||||
addExpanded(&parent, node, childParam);
|
||||
node->setFlags(Qt::ItemIsEnabled);
|
||||
auto treeMap = nodePtr->getFolder();
|
||||
addMaterials(*node, treeMap, folderIcon, icon);
|
||||
addMaterials(*node, treeMap, folderIcon, icon, childParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,6 +651,7 @@ void MaterialTreeWidget::onSelectMaterial(const QItemSelection& selected,
|
||||
std::string _uuid = uuid.toStdString();
|
||||
|
||||
Q_EMIT materialSelected(getMaterialManager().getMaterial(uuid));
|
||||
Q_EMIT onMaterial(uuid);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::onDoubleClick(const QModelIndex& index)
|
||||
@@ -458,3 +664,48 @@ void MaterialTreeWidget::onDoubleClick(const QModelIndex& index)
|
||||
updateMaterial(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::onFilter(const QString& text)
|
||||
{
|
||||
setActiveFilter(text);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::saveWidgetSettings()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/TreeWidget");
|
||||
param->SetBool("WidgetExpanded", m_expanded);
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::saveMaterialTree()
|
||||
{
|
||||
auto param = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/TreeWidget/MaterialTree");
|
||||
param->Clear();
|
||||
|
||||
auto tree = m_materialTree;
|
||||
auto model = dynamic_cast<QStandardItemModel*>(tree->model());
|
||||
|
||||
auto root = model->invisibleRootItem();
|
||||
for (int i = 0; i < root->rowCount(); i++) {
|
||||
auto child = root->child(i);
|
||||
saveMaterialTreeChildren(param, tree, model, child);
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialTreeWidget::saveMaterialTreeChildren(const Base::Reference<ParameterGrp>& param,
|
||||
QTreeView* tree,
|
||||
QStandardItemModel* model,
|
||||
QStandardItem* item)
|
||||
{
|
||||
if (item->hasChildren()) {
|
||||
param->SetBool(item->text().toStdString().c_str(), tree->isExpanded(item->index()));
|
||||
|
||||
auto treeParam = param->GetGroup(item->text().toStdString().c_str());
|
||||
for (int i = 0; i < item->rowCount(); i++) {
|
||||
auto child = item->child(i);
|
||||
|
||||
saveMaterialTreeChildren(treeParam, tree, model, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include <Mod/Material/App/MaterialFilter.h>
|
||||
#include <Mod/Material/App/MaterialFilterPy.h>
|
||||
#include <Mod/Material/App/MaterialManager.h>
|
||||
#include <Mod/Material/App/Materials.h>
|
||||
|
||||
@@ -48,6 +49,7 @@ namespace MatGui
|
||||
{
|
||||
class CommandManager;
|
||||
class WidgetFactoryInst;
|
||||
class MaterialTreeWidgetPy;
|
||||
|
||||
/** The Material Tree widget class
|
||||
* This widget is intended for use wherever materials are used. It is a light weight
|
||||
@@ -65,36 +67,21 @@ class WidgetFactoryInst;
|
||||
*
|
||||
* \author David Carter
|
||||
*/
|
||||
class MatGuiExport MaterialTreeWidget: public QWidget
|
||||
class MatGuiExport MaterialTreeWidget: public QWidget, public Base::BaseClass
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
explicit MaterialTreeWidget(std::shared_ptr<Materials::MaterialFilter> filter,
|
||||
explicit MaterialTreeWidget(const std::shared_ptr<Materials::MaterialFilter>& filter,
|
||||
QWidget* parent = nullptr);
|
||||
explicit MaterialTreeWidget(
|
||||
const std::shared_ptr<std::list<std::shared_ptr<Materials::MaterialFilter>>>& filterList,
|
||||
QWidget* parent = nullptr);
|
||||
explicit MaterialTreeWidget(QWidget* parent = nullptr);
|
||||
~MaterialTreeWidget() override;
|
||||
|
||||
// void setEntryName( const QByteArray& name );
|
||||
// QByteArray entryName() const;
|
||||
// /** Does the same as setEntryName().
|
||||
// * This function is added for convenience because the ui compiler
|
||||
// * will use this function if the attribute stdset isn't set to 0 in a .ui file.
|
||||
// */
|
||||
// void setPrefEntry(const QByteArray& name);
|
||||
|
||||
// void setParamGrpPath( const QByteArray& path );
|
||||
// QByteArray paramGrpPath() const;
|
||||
// /** Does the same as setParamGrpPath().
|
||||
// * This function is added for convenience because the ui compiler
|
||||
// * will use this function if the attribute stdset isn't set to 0 in a .ui file.
|
||||
// */
|
||||
// void setPrefPath(const QByteArray& name);
|
||||
|
||||
// void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
|
||||
// void onSave();
|
||||
// void onRestore();
|
||||
|
||||
/** Set the material by specifying its UUID
|
||||
*/
|
||||
void setMaterial(const QString& uuid);
|
||||
@@ -103,17 +90,84 @@ public:
|
||||
QString getMaterialUUID() const;
|
||||
/** Set the material filter
|
||||
*/
|
||||
void setFilter(std::shared_ptr<Materials::MaterialFilter> filter);
|
||||
void setFilter(const std::shared_ptr<Materials::MaterialFilter>& filter);
|
||||
void setFilter(
|
||||
const std::shared_ptr<std::list<std::shared_ptr<Materials::MaterialFilter>>>& filterList);
|
||||
void setActiveFilter(const QString &name);
|
||||
|
||||
void setExpanded(bool open);
|
||||
bool getExpanded()
|
||||
{
|
||||
return m_expanded;
|
||||
}
|
||||
|
||||
/* Indicates if we should show favourite materials
|
||||
*/
|
||||
bool includeFavorites() const
|
||||
{
|
||||
return _filterOptions.includeFavorites();
|
||||
}
|
||||
void setIncludeFavorites(bool value)
|
||||
{
|
||||
_filterOptions.setIncludeFavorites(value);
|
||||
}
|
||||
|
||||
/* Indicates if we should show recent materials
|
||||
*/
|
||||
bool includeRecent() const
|
||||
{
|
||||
return _filterOptions.includeRecent();
|
||||
}
|
||||
void setIncludeRecent(bool value)
|
||||
{
|
||||
_filterOptions.setIncludeRecent(value);
|
||||
}
|
||||
|
||||
/* Indicates if we should include empty folders
|
||||
*/
|
||||
bool includeEmptyFolders() const
|
||||
{
|
||||
return _filterOptions.includeEmptyFolders();
|
||||
}
|
||||
void setIncludeEmptyFolders(bool value)
|
||||
{
|
||||
_filterOptions.setIncludeEmptyFolders(value);
|
||||
}
|
||||
|
||||
/* Indicates if we should include empty libraries
|
||||
*/
|
||||
bool includeEmptyLibraries() const
|
||||
{
|
||||
return _filterOptions.includeEmptyLibraries();
|
||||
}
|
||||
void setIncludeEmptyLibraries(bool value)
|
||||
{
|
||||
Base::Console().Log("setIncludeEmptyLibraries(%s)\n", (value ? "true" : "false"));
|
||||
_filterOptions.setIncludeEmptyLibraries(value);
|
||||
}
|
||||
|
||||
/* Indicates if we should include materials in the older format
|
||||
*/
|
||||
bool includeLegacy() const
|
||||
{
|
||||
return _filterOptions.includeLegacy();
|
||||
}
|
||||
void setIncludeLegacy(bool legacy)
|
||||
{
|
||||
_filterOptions.setIncludeLegacy(legacy);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
/** Emits this signal when a material has been selected */
|
||||
void materialSelected(const std::shared_ptr<Materials::Material>& material);
|
||||
void onMaterial(const QString& uuid);
|
||||
|
||||
private Q_SLOTS:
|
||||
void expandClicked(bool checked);
|
||||
void editorClicked(bool checked);
|
||||
void onSelectMaterial(const QItemSelection& selected, const QItemSelection& deselected);
|
||||
void onDoubleClick(const QModelIndex& index);
|
||||
void onFilter(const QString& text);
|
||||
|
||||
private:
|
||||
void setup();
|
||||
@@ -122,6 +176,7 @@ private:
|
||||
QPushButton* m_expand;
|
||||
QTreeView* m_materialTree;
|
||||
QPushButton* m_editor;
|
||||
QComboBox* m_filterCombo;
|
||||
bool m_expanded;
|
||||
|
||||
QString m_materialDisplay;
|
||||
@@ -130,7 +185,10 @@ private:
|
||||
std::list<QString> _favorites;
|
||||
std::list<QString> _recents;
|
||||
std::shared_ptr<Materials::MaterialFilter> _filter;
|
||||
Materials::MaterialFilterTreeWidgetOptions _filterOptions;
|
||||
std::shared_ptr<std::list<std::shared_ptr<Materials::MaterialFilter>>> _filterList;
|
||||
int _recentMax;
|
||||
MaterialTreeWidgetPy* pyTreeWidget {nullptr};
|
||||
|
||||
Materials::MaterialManager _materialManager;
|
||||
|
||||
@@ -146,7 +204,17 @@ protected:
|
||||
}
|
||||
|
||||
void getFavorites();
|
||||
|
||||
void getRecents();
|
||||
void saveRecents();
|
||||
void addRecent(const QString& uuid);
|
||||
bool isRecent(const QString& uuid) const;
|
||||
void saveWidgetSettings();
|
||||
void saveMaterialTreeChildren(const Base::Reference<ParameterGrp>& param,
|
||||
QTreeView* tree,
|
||||
QStandardItemModel* model,
|
||||
QStandardItem* item);
|
||||
void saveMaterialTree();
|
||||
|
||||
/** Create the widgets UI objects
|
||||
*/
|
||||
@@ -159,7 +227,13 @@ protected:
|
||||
void fillMaterialTree();
|
||||
void updateMaterialTree();
|
||||
void addExpanded(QStandardItem* parent, QStandardItem* child);
|
||||
void addExpanded(QStandardItem* parent,
|
||||
QStandardItem* child,
|
||||
const Base::Reference<ParameterGrp>& param);
|
||||
void addExpanded(QStandardItemModel* model, QStandardItem* child);
|
||||
void addExpanded(QStandardItemModel* model,
|
||||
QStandardItem* child,
|
||||
const Base::Reference<ParameterGrp>& param);
|
||||
void addRecents(QStandardItem* parent);
|
||||
void addFavorites(QStandardItem* parent);
|
||||
void addMaterials(
|
||||
@@ -167,9 +241,13 @@ protected:
|
||||
const std::shared_ptr<std::map<QString, std::shared_ptr<Materials::MaterialTreeNode>>>&
|
||||
modelTree,
|
||||
const QIcon& folderIcon,
|
||||
const QIcon& icon);
|
||||
|
||||
void openWidgetState(bool open);
|
||||
const QIcon& icon,
|
||||
const Base::Reference<ParameterGrp>& param);
|
||||
void setFilterVisible(bool open);
|
||||
void fillFilterCombo();
|
||||
bool hasMultipleFilters() const {
|
||||
return (_filterList && _filterList->size() > 1);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace MatGui
|
||||
|
||||
71
src/Mod/Material/Gui/MaterialTreeWidgetPy.xml
Normal file
71
src/Mod/Material/Gui/MaterialTreeWidgetPy.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="BaseClassPy"
|
||||
Name="MaterialTreeWidgetPy"
|
||||
Twin="MaterialTreeWidget"
|
||||
TwinPointer="MaterialTreeWidget"
|
||||
Include="Mod/Material/Gui/MaterialTreeWidget.h"
|
||||
Namespace="MatGui"
|
||||
FatherInclude="Base/BaseClassPy.h"
|
||||
FatherNamespace="Base"
|
||||
Constructor="true"
|
||||
Delete="false">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="DavidCarter" EMail="dcarter@davidcarter.ca" />
|
||||
<UserDocu>Material tree widget.</UserDocu>
|
||||
</Documentation>
|
||||
<Attribute Name="UUID" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Material UUID.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="UUID" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="expanded" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Expand material tree.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="expanded" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeFavorites" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include favorites in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeFavorites" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeRecent" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include recently used materials in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeRecent" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeEmptyFolders" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include empty folders in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeEmptyFolders" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeEmptyLibraries" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include empty libraries in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeEmptyLibraries" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncludeLegacy" ReadOnly="false">
|
||||
<Documentation>
|
||||
<UserDocu>Include legacy materials in the material list.</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="IncludeLegacy" Type="Boolean"/>
|
||||
</Attribute>
|
||||
<Methode Name="setFilter">
|
||||
<Documentation>
|
||||
<UserDocu>Set the material filter or list of filters.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="selectFilter">
|
||||
<Documentation>
|
||||
<UserDocu>Set the current material filter.</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
238
src/Mod/Material/Gui/MaterialTreeWidgetPyImpl.cpp
Normal file
238
src/Mod/Material/Gui/MaterialTreeWidgetPyImpl.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 David Carter <dcarter@david.carter.ca> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Gui/PythonWrapper.h>
|
||||
|
||||
#include "MaterialTreeWidget.h"
|
||||
#include "MaterialTreeWidgetPy.h"
|
||||
|
||||
#include "MaterialTreeWidgetPy.cpp"
|
||||
|
||||
using namespace MatGui;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string MaterialTreeWidgetPy::representation() const
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << "<MaterialTreeWidget at " << getMaterialTreeWidgetPtr() << ">";
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject* MaterialTreeWidgetPy::PyMake(struct _typeobject*, PyObject*, PyObject*) // Python wrapper
|
||||
{
|
||||
// never create such objects with the constructor
|
||||
return new MaterialTreeWidgetPy(new MaterialTreeWidget());
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int MaterialTreeWidgetPy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
||||
{
|
||||
PyObject* obj {};
|
||||
if (PyArg_ParseTuple(args, "")) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O!", &(MatGui::MaterialTreeWidgetPy::Type), &obj)) {
|
||||
auto widget = static_cast<MatGui::MaterialTreeWidgetPy*>(obj)->getMaterialTreeWidgetPtr();
|
||||
_pcTwinPointer = widget;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// PyErr_Clear();
|
||||
// if (PyArg_ParseTuple(args, "O!", &(QWidget::Type), &obj)) {
|
||||
// auto widget = static_cast<MatGui::MaterialTreeWidget*>(obj);
|
||||
// _pcTwinPointer = widget;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
PyErr_Clear();
|
||||
if (PyArg_ParseTuple(args, "O", &obj)) {
|
||||
if (QLatin1String(obj->ob_type->tp_name) == QLatin1String("PySide2.QtWidgets.QWidget")) {
|
||||
Gui::PythonWrapper wrap;
|
||||
wrap.loadWidgetsModule();
|
||||
auto qObject = wrap.toQObject(Py::Object(obj));
|
||||
auto widget = static_cast<MatGui::MaterialTreeWidget*>(qObject);
|
||||
_pcTwinPointer = widget;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"empty parameter list, or MaterialTreeWidget expected not '%s'",
|
||||
obj->ob_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "empty parameter list, or MaterialTreeWidget expected");
|
||||
// PyErr_Format(PyExc_TypeError,
|
||||
// "empty parameter list, or MaterialTreeWidget expected not '%s'",
|
||||
// obj->ob_type->tp_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Py::String MaterialTreeWidgetPy::getUUID() const
|
||||
{
|
||||
return Py::String(getMaterialTreeWidgetPtr()->getMaterialUUID().toStdString());
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setUUID(const Py::String value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setMaterial(QString::fromStdString(value));
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getexpanded() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->getExpanded()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setexpanded(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setExpanded(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getIncludeFavorites() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->includeFavorites()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setIncludeFavorites(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setIncludeFavorites(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getIncludeRecent() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->includeRecent()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setIncludeRecent(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setIncludeRecent(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getIncludeEmptyFolders() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->includeEmptyFolders()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setIncludeEmptyFolders(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setIncludeEmptyFolders(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getIncludeEmptyLibraries() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->includeEmptyLibraries()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setIncludeEmptyLibraries(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setIncludeEmptyLibraries(value.isTrue());
|
||||
}
|
||||
|
||||
Py::Boolean MaterialTreeWidgetPy::getIncludeLegacy() const
|
||||
{
|
||||
return {getMaterialTreeWidgetPtr()->includeLegacy()};
|
||||
}
|
||||
|
||||
void MaterialTreeWidgetPy::setIncludeLegacy(const Py::Boolean value)
|
||||
{
|
||||
getMaterialTreeWidgetPtr()->setIncludeLegacy(value.isTrue());
|
||||
}
|
||||
|
||||
PyObject* MaterialTreeWidgetPy::setFilter(PyObject* args)
|
||||
{
|
||||
PyObject* obj;
|
||||
if (!PyArg_ParseTuple(args, "O", &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (PyObject_TypeCheck(obj, &(Materials::MaterialFilterPy::Type))) {
|
||||
auto filter = static_cast<Materials::MaterialFilterPy*>(obj)->getMaterialFilterPtr();
|
||||
Base::Console().Log("Filter '%s'\n", filter->name().toStdString().c_str());
|
||||
auto filterPtr = std::make_shared<Materials::MaterialFilter>(*filter);
|
||||
getMaterialTreeWidgetPtr()->setFilter(filterPtr);
|
||||
}
|
||||
else if (PyList_Check(obj)) {
|
||||
// The argument is a list of filters
|
||||
Base::Console().Log("Filter List\n");
|
||||
Py_ssize_t n = PyList_Size(obj);
|
||||
Base::Console().Log("n = %d\n", n);
|
||||
if (n < 0) {
|
||||
Py_Return;
|
||||
}
|
||||
PyObject* item;
|
||||
auto filterList = std::make_shared<std::list<std::shared_ptr<Materials::MaterialFilter>>>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
item = PyList_GetItem(obj, i);
|
||||
if (PyObject_TypeCheck(item, &(Materials::MaterialFilterPy::Type))) {
|
||||
auto filter =
|
||||
static_cast<Materials::MaterialFilterPy*>(item)->getMaterialFilterPtr();
|
||||
Base::Console().Log("\tFilter '%s'\n",
|
||||
filter->name().toStdString().c_str()); auto filterPtr =
|
||||
std::make_shared<Materials::MaterialFilter>(*filter);
|
||||
filterList->push_back(filterPtr);
|
||||
// getMaterialTreeWidgetPtr()->setFilter(
|
||||
//
|
||||
// *static_cast<Materials::MaterialFilterPy*>(obj)->getMaterialFilterPtr());
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"List entry must be of type 'MaterialFilter' not '%s'",
|
||||
obj->ob_type->tp_name);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
getMaterialTreeWidgetPtr()->setFilter(filterList);
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Type must be 'MaterialFilter' or list of 'MaterialFilter' not '%s'",
|
||||
obj->ob_type->tp_name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* MaterialTreeWidgetPy::selectFilter(PyObject* args)
|
||||
{
|
||||
char* name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Base::Console().Log("selectFilter(%s)\n", name);
|
||||
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* MaterialTreeWidgetPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int MaterialTreeWidgetPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user