feat(editor): edit composite values, such as individual components of vector3

This commit is contained in:
maelstrom 2025-04-14 01:12:48 +02:00
parent bfd5881ac8
commit ff1f9be5c5
2 changed files with 101 additions and 5 deletions

View file

@ -1,4 +1,5 @@
#include "panes/propertiesview.h" #include "panes/propertiesview.h"
#include "datatypes/base.h"
#include <QColorDialog> #include <QColorDialog>
#include <QLineEdit> #include <QLineEdit>
@ -31,11 +32,32 @@ public:
if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return nullptr; if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return nullptr;
InstanceRef inst = view->currentInstance->lock(); InstanceRef inst = view->currentInstance->lock();
std::string propertyName = view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString(); // If the property is deeper than 1 layer, then it is considered composite
// Handle specially
bool isComposite = index.parent().parent().isValid();
std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : "";
std::string propertyName = !isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value(); PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
Data::Variant currentValue = inst->GetPropertyValue(propertyName).value(); Data::Variant currentValue = inst->GetPropertyValue(propertyName).value();
if (isComposite) {
if (meta.type == &Data::Vector3::TYPE) {
Data::Vector3 vector = currentValue.get<Data::Vector3>();
float value = componentName == "X" ? vector.X() : componentName == "Y" ? vector.Y() : componentName == "Z" ? vector.Z() : 0;
QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
spinBox->setValue(value);
return spinBox;
}
return nullptr;
}
if (meta.type == &Data::Float::TYPE) { if (meta.type == &Data::Float::TYPE) {
QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
spinBox->setValue(currentValue.get<Data::Float>()); spinBox->setValue(currentValue.get<Data::Float>());
@ -80,9 +102,27 @@ public:
if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return; if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return;
InstanceRef inst = view->currentInstance->lock(); InstanceRef inst = view->currentInstance->lock();
std::string propertyName = view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString(); bool isComposite = index.parent().parent().isValid();
std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : "";
std::string propertyName = !index.parent().parent().isValid() ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value(); PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
Data::Variant currentValue = inst->GetPropertyValue(propertyName).value(); Data::Variant currentValue = inst->GetPropertyValue(propertyName).value();
if (isComposite) {
if (meta.type == &Data::Vector3::TYPE) {
Data::Vector3 vector = currentValue.get<Data::Vector3>();
float value = componentName == "X" ? vector.X() : componentName == "Y" ? vector.Y() : componentName == "Z" ? vector.Z() : 0;
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
spinBox->setValue(value);
return;
}
return;
}
if (meta.type == &Data::Float::TYPE) { if (meta.type == &Data::Float::TYPE) {
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor); QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
@ -114,9 +154,31 @@ public:
if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return; if (!index.parent().isValid() || !view->currentInstance || view->currentInstance->expired()) return;
InstanceRef inst = view->currentInstance->lock(); InstanceRef inst = view->currentInstance->lock();
std::string propertyName = view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString(); bool isComposite = index.parent().parent().isValid();
std::string componentName = isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString() : "";
std::string propertyName = !index.parent().parent().isValid() ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
PropertyMeta meta = inst->GetPropertyMeta(propertyName).value(); PropertyMeta meta = inst->GetPropertyMeta(propertyName).value();
if (isComposite) {
if (meta.type == &Data::Vector3::TYPE) {
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
float value = spinBox->value();
Data::Vector3 prev = inst->GetPropertyValue(propertyName).value().get<Data::Vector3>();
Data::Vector3 newVector = componentName == "X" ? Data::Vector3(value, prev.Y(), prev.Z())
: componentName == "Y" ? Data::Vector3(prev.X(), value, prev.Z())
: componentName == "Z" ? Data::Vector3(prev.X(), prev.Y(), value) : prev;
inst->SetPropertyValue(propertyName, newVector);
view->rebuildCompositeProperty(view->itemFromIndex(index.parent()), &Data::Vector3::TYPE, newVector);
return;
}
return;
}
if (meta.type == &Data::Float::TYPE) { if (meta.type == &Data::Float::TYPE) {
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor); QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
@ -147,6 +209,7 @@ public:
if (!parsedResult) return; if (!parsedResult) return;
inst->SetPropertyValue(propertyName, parsedResult.value()); inst->SetPropertyValue(propertyName, parsedResult.value());
model->setData(index, QString::fromStdString(parsedResult.value().ToString())); model->setData(index, QString::fromStdString(parsedResult.value().ToString()));
view->rebuildCompositeProperty(view->itemFromIndex(index), meta.type, parsedResult.value());
} }
} }
}; };
@ -235,6 +298,9 @@ void PropertiesView::setSelected(std::optional<InstanceRef> instance) {
Data::Color3 color = currentValue.get<Data::Color3>(); Data::Color3 color = currentValue.get<Data::Color3>();
item->setData(1, Qt::DecorationRole, QColor::fromRgbF(color.R(), color.G(), color.B())); item->setData(1, Qt::DecorationRole, QColor::fromRgbF(color.R(), color.G(), color.B()));
item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString())); item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString()));
} else if (meta.type == &Data::Vector3::TYPE) {
Data::Vector3 vector = currentValue.get<Data::Vector3>();
item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString()));
} else { } else {
item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString())); item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString()));
} }
@ -243,6 +309,8 @@ void PropertiesView::setSelected(std::optional<InstanceRef> instance) {
item->setDisabled(true); item->setDisabled(true);
} }
rebuildCompositeProperty(item, meta.type, currentValue);
propertyCategories[meta.category]->addChild(item); propertyCategories[meta.category]->addChild(item);
propertyCategories[meta.category]->setExpanded(true); propertyCategories[meta.category]->setExpanded(true);
} }
@ -258,7 +326,7 @@ void PropertiesView::setSelected(std::optional<InstanceRef> instance) {
} }
void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) { void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) {
if (!item->parent() || !currentInstance || currentInstance->expired()) return; if (!item->parent() || (item->parent() && item->parent()->parent()) || !currentInstance || currentInstance->expired()) return;
InstanceRef inst = currentInstance->lock(); InstanceRef inst = currentInstance->lock();
std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString(); std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString();
@ -267,4 +335,30 @@ void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) {
if (meta.type == &Data::Bool::TYPE) { if (meta.type == &Data::Bool::TYPE) {
inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1))); inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1)));
} }
}
void PropertiesView::rebuildCompositeProperty(QTreeWidgetItem *item, const Data::TypeInfo* type, Data::Variant value) {
if (type == &Data::Vector3::TYPE) {
// https://forum.qt.io/post/266837
foreach(auto i, item->takeChildren()) delete i;
Data::Vector3 vector = value.get<Data::Vector3>();
item->setData(1, Qt::DisplayRole, QString::fromStdString(value.ToString()));
QTreeWidgetItem* xItem = new QTreeWidgetItem;
xItem->setData(0, Qt::DisplayRole, "X");
xItem->setData(1, Qt::DisplayRole, vector.X());
QTreeWidgetItem* yItem = new QTreeWidgetItem;
yItem->setData(0, Qt::DisplayRole, "Y");
yItem->setData(1, Qt::DisplayRole, vector.Y());
QTreeWidgetItem* zItem = new QTreeWidgetItem;
zItem->setData(0, Qt::DisplayRole, "Z");
zItem->setData(1, Qt::DisplayRole, vector.Z());
item->addChild(xItem);
item->addChild(yItem);
item->addChild(zItem);
}
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <QTreeWidget> #include <QTreeWidget>
#include "datatypes/base.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
class Ui_MainWindow; class Ui_MainWindow;
@ -13,6 +14,7 @@ class PropertiesView : public QTreeWidget {
std::optional<InstanceRefWeak> currentInstance; std::optional<InstanceRefWeak> currentInstance;
void propertyChanged(QTreeWidgetItem *item, int column); void propertyChanged(QTreeWidgetItem *item, int column);
void activateProperty(QTreeWidgetItem *item, int column); void activateProperty(QTreeWidgetItem *item, int column);
void rebuildCompositeProperty(QTreeWidgetItem *item, const Data::TypeInfo*, Data::Variant);
friend PropertiesItemDelegate; friend PropertiesItemDelegate;
protected: protected: