2025-01-04 04:12:51 +00:00
|
|
|
#include "PropertyBrowser.h"
|
|
|
|
|
|
|
|
|
|
#include <QBoxLayout>
|
|
|
|
|
#include <QDebug>
|
2025-11-03 15:52:10 +00:00
|
|
|
#include <QSet>
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
|
#include "PropertyBrowser/qttreepropertybrowser.h"
|
|
|
|
|
#include "PropertyBrowser/qtpropertymanager.h"
|
|
|
|
|
#include "PropertyBrowser/qteditorfactory.h"
|
|
|
|
|
|
|
|
|
|
#include "DockTitleBar.h"
|
|
|
|
|
#include "DockWidget.h"
|
|
|
|
|
#include "workspace/WorkSpace.h"
|
|
|
|
|
#include "entities/Entity.h"
|
|
|
|
|
#include "entities/MeshComponent.h"
|
|
|
|
|
|
|
|
|
|
#include "common/SpdLogger.h"
|
|
|
|
|
|
|
|
|
|
PropertyBrowser::PropertyBrowser(QWidget *parent) :
|
|
|
|
|
QWidget(parent) {
|
|
|
|
|
|
|
|
|
|
InitUI();
|
|
|
|
|
|
|
|
|
|
//Test();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PropertyBrowser::~PropertyBrowser() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::AttachDock(DockWidget* dockWidget) {
|
|
|
|
|
if (nullptr == dockWidget) {
|
|
|
|
|
LOG_WARN("dockwidget is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dockWidget->SetDockWidgetTitleBar(nullptr);
|
|
|
|
|
dockWidget->setWidget(this);
|
|
|
|
|
|
|
|
|
|
DockTitleBar* dockTitleBar = new DockTitleBar;
|
|
|
|
|
dockTitleBar->SetTitle(tr("attribute"));
|
|
|
|
|
dockWidget->SetDockWidgetTitleBar(dockTitleBar);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::OnWorkSpaceChange(const QVariant& value) {
|
2025-11-03 16:23:24 +00:00
|
|
|
inFileEntryView_ = false;
|
2025-01-04 04:12:51 +00:00
|
|
|
WorkSpace* workspace = value.value<WorkSpace*>();
|
|
|
|
|
if (nullptr == workspace) {
|
|
|
|
|
LOG_WARN("workspace is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
browser_->clear();
|
2025-11-03 15:52:10 +00:00
|
|
|
// Reset local mappings when workspace changes
|
|
|
|
|
propertyToId_.clear();
|
|
|
|
|
idToProperty_.clear();
|
|
|
|
|
idToExpanded_.clear();
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
|
QtProperty* property;
|
|
|
|
|
|
|
|
|
|
property = workSpaceManager_->addProperty(tr("WorkSpace"));
|
|
|
|
|
QWorkspaceAttribute worksapceAttribute(workspace);
|
|
|
|
|
workSpaceManager_->setValue(property, worksapceAttribute);
|
|
|
|
|
addProperty(property, tr("WorkSpace"));
|
2025-10-12 14:14:16 +00:00
|
|
|
|
|
|
|
|
// Track and react to runtime workspace changes
|
|
|
|
|
if (currentWorkspace_) {
|
|
|
|
|
QObject::disconnect(currentWorkspace_, nullptr, this, nullptr);
|
|
|
|
|
}
|
|
|
|
|
currentWorkspace_ = workspace;
|
|
|
|
|
QObject::connect(currentWorkspace_, &WorkSpace::FilesChanged,
|
|
|
|
|
this, &PropertyBrowser::OnWorkspaceFilesChanged);
|
2025-11-02 16:36:16 +00:00
|
|
|
|
2025-11-03 16:23:24 +00:00
|
|
|
// No longer mount file entries under workspace; file entries are handled separately
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::OnEntityChange(const QVariant& value) {
|
2025-11-03 16:23:24 +00:00
|
|
|
inFileEntryView_ = false;
|
2025-01-04 04:12:51 +00:00
|
|
|
Entity* entity = value.value<Entity*>();
|
|
|
|
|
if (nullptr == entity) {
|
|
|
|
|
LOG_WARN("engity is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
browser_->clear();
|
|
|
|
|
|
|
|
|
|
QtProperty* property;
|
|
|
|
|
property = entityManager_->addProperty(tr("Entity"));
|
|
|
|
|
QEntityAttribute entityAttribute(entity);
|
|
|
|
|
entityManager_->setValue(property, entityAttribute);
|
|
|
|
|
addProperty(property, tr("Entity"));
|
|
|
|
|
|
|
|
|
|
SceneComponent* component = entity->GetRootComponent();
|
|
|
|
|
if (nullptr == component) {
|
|
|
|
|
LOG_WARN("component is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QtComponentPropertyManager* componentManager = GetCompononetPropertyManager(component->GetSelfTypeName().c_str());
|
|
|
|
|
if (nullptr == componentManager) {
|
|
|
|
|
LOG_WARN("component is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
property = componentManager->AddProperty();
|
|
|
|
|
componentManager->SetPropertyValue(property, component);
|
|
|
|
|
addProperty(property, componentManager->GetPropertyId());
|
|
|
|
|
|
|
|
|
|
std::vector<SceneComponent*> children = component->GetChildren();
|
|
|
|
|
for (auto child : children) {
|
|
|
|
|
componentManager = GetCompononetPropertyManager(child->GetSelfTypeName().c_str());
|
2025-06-22 08:27:44 +00:00
|
|
|
if (nullptr == componentManager) {
|
|
|
|
|
LOG_WARN("component is nullptr id {}", child->GetSelfTypeName());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
if (nullptr == child) {
|
|
|
|
|
LOG_WARN("component is nullptr id {}", child->GetSelfTypeName());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
property = componentManager->AddProperty();
|
|
|
|
|
componentManager->SetPropertyValue(property, child);
|
|
|
|
|
addProperty(property, componentManager->GetPropertyId());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-03 16:23:24 +00:00
|
|
|
void PropertyBrowser::OnFileEntryChange(const QVariant& value) {
|
|
|
|
|
FileEntry* entry = value.value<FileEntry*>();
|
|
|
|
|
if (!entry) {
|
|
|
|
|
LOG_WARN("file entry is nullptr");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Enter single FileEntry view mode and clear existing panels
|
|
|
|
|
inFileEntryView_ = true;
|
|
|
|
|
browser_->clear();
|
|
|
|
|
propertyToId_.clear();
|
|
|
|
|
idToProperty_.clear();
|
|
|
|
|
idToExpanded_.clear();
|
|
|
|
|
|
|
|
|
|
// Compute our id and ensure the property exists (create if missing)
|
|
|
|
|
const QString id = QString("CurveEntry:%1").arg(entry->GetFileName());
|
|
|
|
|
auto curve = entry->AsCurve();
|
|
|
|
|
if (!curve) {
|
|
|
|
|
LOG_WARN("file entry not a curve: %s", entry->GetFileName().toStdString().c_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const QString title = QString("CurveEntry - %1").arg(entry->GetName());
|
|
|
|
|
QtProperty* prop = curveEntryManager_->addProperty(title);
|
|
|
|
|
QCurveEntryAttribute attr(curve);
|
|
|
|
|
curveEntryManager_->setValue(prop, attr);
|
|
|
|
|
addProperty(prop, id);
|
|
|
|
|
|
|
|
|
|
// Focus the corresponding group: expand and select it
|
|
|
|
|
if (prop) {
|
|
|
|
|
QtBrowserItem* item = browser_->topLevelItem(prop);
|
|
|
|
|
if (item) {
|
|
|
|
|
browser_->setExpanded(item, true);
|
|
|
|
|
browser_->setCurrentItem(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
void PropertyBrowser::InitUI() {
|
|
|
|
|
QBoxLayout* layout = new QVBoxLayout(this);
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
browser_ = new QtTreePropertyBrowser;
|
|
|
|
|
layout->addWidget(browser_);
|
|
|
|
|
|
2025-02-11 17:54:16 +00:00
|
|
|
browser_->setHeaderVisible(true);
|
2025-02-12 14:04:02 +00:00
|
|
|
//browser_->setResizeMode(QtTreePropertyBrowser::Stretch);
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
|
InitPropertyManager();
|
|
|
|
|
InitComponentPropertyManager();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::InitPropertyManager() {
|
2025-06-27 16:23:58 +00:00
|
|
|
intManager_ = new QtIntPropertyManager(this);
|
|
|
|
|
boolManager_ = new QtBoolPropertyManager(this);
|
2025-01-04 04:12:51 +00:00
|
|
|
doubleManager_ = new QtDoublePropertyManager(this);
|
|
|
|
|
stringManager_ = new QtStringPropertyManager(this);
|
|
|
|
|
colorManager_ = new QtColorPropertyManager(this);
|
|
|
|
|
fontManager_ = new QtFontPropertyManager(this);
|
|
|
|
|
pointManager_ = new QtPointPropertyManager(this);
|
|
|
|
|
sizeManager_ = new QtSizePropertyManager(this);
|
|
|
|
|
modelBaseManager_ = new QtModelBasePropertyManager(this);
|
|
|
|
|
workSpaceManager_ = new QtWorkspacePropertyManager(this);
|
|
|
|
|
entityManager_ = new QtEntityPropertyManager(this);
|
2025-11-02 16:36:16 +00:00
|
|
|
curveEntryManager_ = new QtCurveEntryPropertyManager(this);
|
2025-01-04 04:12:51 +00:00
|
|
|
|
|
|
|
|
QtDoubleSpinBoxFactory* doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
|
|
|
|
|
QtCheckBoxFactory* checkBoxFactory = new QtCheckBoxFactory(this);
|
|
|
|
|
QtSpinBoxFactory* spinBoxFactory = new QtSpinBoxFactory(this);
|
|
|
|
|
QtLineEditFactory* lineEditFactory = new QtLineEditFactory(this);
|
|
|
|
|
QtEnumEditorFactory* comboBoxFactory = new QtEnumEditorFactory(this);
|
2025-01-04 16:11:29 +00:00
|
|
|
QtFilePathFactory* filePathFactory = new QtFilePathFactory(this);
|
2025-11-02 16:36:16 +00:00
|
|
|
QtColorEditorFactory* colorFactory = new QtColorEditorFactory(this);
|
2025-01-04 04:12:51 +00:00
|
|
|
//QtTransfromEditorFactory* transformFactory = new QtTransfromEditorFactory(this);
|
|
|
|
|
|
2025-06-27 16:23:58 +00:00
|
|
|
browser_->setFactoryForManager(intManager_, spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(boolManager_, checkBoxFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
browser_->setFactoryForManager(doubleManager_, doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(stringManager_, lineEditFactory);
|
|
|
|
|
browser_->setFactoryForManager(colorManager_->subIntPropertyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(fontManager_->subIntPropertyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(fontManager_->subBoolPropertyManager(), checkBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(fontManager_->subEnumPropertyManager(), comboBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(pointManager_->subIntPropertyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(sizeManager_->subIntPropertyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(workSpaceManager_->subStringProperyManager(), lineEditFactory);
|
2025-01-04 16:11:29 +00:00
|
|
|
browser_->setFactoryForManager(workSpaceManager_->subFilesProperyManager(), filePathFactory);
|
2025-10-12 14:14:16 +00:00
|
|
|
// Enable editing for grouped file entry counts
|
|
|
|
|
browser_->setFactoryForManager(workSpaceManager_->subIntProperyManager(), spinBoxFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
browser_->setFactoryForManager(entityManager_->subStringProperyManager(), lineEditFactory);
|
2025-07-02 14:43:23 +00:00
|
|
|
browser_->setFactoryForManager(entityManager_->subBoolProperyManager(), checkBoxFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
browser_->setFactoryForManager(
|
|
|
|
|
entityManager_->subTransfromProperyManager()->subVec3TPropertyManager()->subDoublePropertyManager(),
|
|
|
|
|
doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(
|
|
|
|
|
entityManager_->subTransfromProperyManager()->subVec3RPropertyManager()->subDoublePropertyManager(),
|
|
|
|
|
doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(
|
|
|
|
|
entityManager_->subTransfromProperyManager()->subVec3SPropertyManager()->subDoublePropertyManager(),
|
|
|
|
|
doubleSpinBoxFactory);
|
2025-11-02 16:36:16 +00:00
|
|
|
|
|
|
|
|
// Curve entry sub editors
|
|
|
|
|
browser_->setFactoryForManager(curveEntryManager_->subStringProperyManager(), lineEditFactory);
|
|
|
|
|
browser_->setFactoryForManager(curveEntryManager_->subEnumProperyManager(), comboBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(curveEntryManager_->subIntProperyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(curveEntryManager_->subDoubleProperyManager(), doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(curveEntryManager_->subColorProperyManager(), colorFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
}
|
|
|
|
|
|
2025-11-02 16:36:16 +00:00
|
|
|
void PropertyBrowser::OnWorkspaceFilesChanged(FileEntryType type, std::shared_ptr<FileEntry> fileEntry) {
|
2025-10-12 14:14:16 +00:00
|
|
|
if (!currentWorkspace_) return;
|
2025-11-03 16:23:24 +00:00
|
|
|
// In single FileEntry view, skip workspace-driven group refresh to keep panel clean
|
|
|
|
|
if (inFileEntryView_) return;
|
2025-11-02 16:36:16 +00:00
|
|
|
// Refresh workspace group
|
|
|
|
|
{
|
|
|
|
|
auto it = idToProperty_.find(tr("WorkSpace"));
|
|
|
|
|
if (it != idToProperty_.end()) {
|
|
|
|
|
QtProperty* property = it.value();
|
|
|
|
|
QWorkspaceAttribute worksapceAttribute(currentWorkspace_);
|
|
|
|
|
workSpaceManager_->setValue(property, worksapceAttribute);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-12 14:14:16 +00:00
|
|
|
}
|
|
|
|
|
|
2025-01-04 04:12:51 +00:00
|
|
|
void PropertyBrowser::InitComponentPropertyManager() {
|
|
|
|
|
QtDoubleSpinBoxFactory* doubleSpinBoxFactory = new QtDoubleSpinBoxFactory(this);
|
|
|
|
|
QtCheckBoxFactory* checkBoxFactory = new QtCheckBoxFactory(this);
|
|
|
|
|
QtSpinBoxFactory* spinBoxFactory = new QtSpinBoxFactory(this);
|
|
|
|
|
QtLineEditFactory* lineEditFactory = new QtLineEditFactory(this);
|
|
|
|
|
QtColorEditorFactory* colorFactory = new QtColorEditorFactory(this);
|
|
|
|
|
QtFilePathFactory* filePathFactory = new QtFilePathFactory(this);
|
2025-01-05 16:41:08 +00:00
|
|
|
QtModelFilePathFactory* modelFileFactory = new QtModelFilePathFactory(this);
|
2025-01-04 04:12:51 +00:00
|
|
|
QtEntityUUIDEditorFactory* entityUUIDFactory = new QtEntityUUIDEditorFactory(this);
|
|
|
|
|
|
|
|
|
|
QtMeshComponetManager* meshComponentManager = new QtMeshComponetManager(this);
|
2025-01-05 16:41:08 +00:00
|
|
|
browser_->setFactoryForManager(meshComponentManager->subModelFileProperyManager(), modelFileFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
componetManager_[meshComponentManager->GetPropertyId()] = meshComponentManager;
|
|
|
|
|
|
|
|
|
|
QtPathComponentManager* pathComponentManager = new QtPathComponentManager(this);
|
2025-01-04 16:11:29 +00:00
|
|
|
browser_->setFactoryForManager(pathComponentManager->subFilesProperyManager(), filePathFactory);
|
2025-01-04 04:12:51 +00:00
|
|
|
componetManager_[pathComponentManager->GetPropertyId()] = pathComponentManager;
|
|
|
|
|
|
|
|
|
|
QtConeWaveComponentManager* coneWaveComponentManager = new QtConeWaveComponentManager(this);
|
|
|
|
|
browser_->setFactoryForManager(coneWaveComponentManager->subDoubleProperyManager(), doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(coneWaveComponentManager->subIntProperyManager(), spinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(coneWaveComponentManager->subColorProperyManager(), colorFactory);
|
|
|
|
|
componetManager_[coneWaveComponentManager->GetPropertyId()] = coneWaveComponentManager;
|
|
|
|
|
|
|
|
|
|
QtDashedLineComponentManager* dashedLineComponentManager = new QtDashedLineComponentManager(this);
|
|
|
|
|
browser_->setFactoryForManager(dashedLineComponentManager->subEntityProperyManager(), entityUUIDFactory);
|
|
|
|
|
browser_->setFactoryForManager(dashedLineComponentManager->subDoubleProperyManager(), doubleSpinBoxFactory);
|
|
|
|
|
browser_->setFactoryForManager(dashedLineComponentManager->subColorProperyManager(), colorFactory);
|
|
|
|
|
componetManager_[dashedLineComponentManager->GetPropertyId()] = dashedLineComponentManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::addProperty(QtProperty* property, const QString& id) {
|
|
|
|
|
propertyToId_[property] = id;
|
|
|
|
|
idToProperty_[id] = property;
|
|
|
|
|
QtBrowserItem* item = browser_->addProperty(property);
|
|
|
|
|
if (idToExpanded_.contains(id))
|
|
|
|
|
browser_->setExpanded(item, idToExpanded_[id]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QtComponentPropertyManager* PropertyBrowser::GetCompononetPropertyManager(const QString& id) {
|
|
|
|
|
if (!componetManager_.contains(id)) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return componetManager_[id];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PropertyBrowser::Test() {
|
|
|
|
|
QtProperty* property;
|
|
|
|
|
|
|
|
|
|
property = modelBaseManager_->addProperty(tr("ModelBase"));
|
2025-06-27 16:23:58 +00:00
|
|
|
QModelAttbute modelAttr(QString("test"), QString("test222"), true, 1.0 , true);
|
2025-01-04 04:12:51 +00:00
|
|
|
modelBaseManager_->setValue(property, modelAttr);
|
|
|
|
|
addProperty(property, QLatin1String("brush"));
|
|
|
|
|
|
|
|
|
|
property = colorManager_->addProperty(tr("color base"));
|
|
|
|
|
colorManager_->setValue(property, QColor(255, 12, 231, 252));
|
|
|
|
|
addProperty(property, QLatin1String("bda"));
|
|
|
|
|
}
|