From 9cb6327c98c74a61d28dc5e91ff4b5d83b31998c Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sun, 13 Apr 2025 19:19:52 +0200 Subject: [PATCH] feat(editor): support parsing vector3s --- core/src/datatypes/vector.cpp | 28 +++++++++++++++++++++++++++- core/src/datatypes/vector.h | 2 ++ core/src/objects/part.cpp | 2 +- editor/panes/propertiesview.cpp | 33 +++++++++++++++++++++------------ 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/core/src/datatypes/vector.cpp b/core/src/datatypes/vector.cpp index cf10504..a96de69 100644 --- a/core/src/datatypes/vector.cpp +++ b/core/src/datatypes/vector.cpp @@ -1,5 +1,6 @@ #include "vector.h" #include +#include #include "meta.h" // IWYU pragma: keep Data::Vector3::Vector3(const glm::vec3& src) : vector(src) {}; @@ -10,6 +11,7 @@ Data::Vector3::~Vector3() = default; const Data::TypeInfo Data::Vector3::TYPE = { .name = "Vector3", .deserializer = &Data::Vector3::Deserialize, + .fromString = &Data::Vector3::FromString, }; const Data::TypeInfo& Data::Vector3::GetType() const { return Data::Vector3::TYPE; }; @@ -18,7 +20,10 @@ Data::Vector3 Data::Vector3::ZERO(0, 0, 0); Data::Vector3 Data::Vector3::ONE(1, 1, 1); const Data::String Data::Vector3::ToString() const { - return std::to_string(X()) + ", " + std::to_string(Y()) + ", " + std::to_string(Z()); + // https://stackoverflow.com/a/46424921/16255372 + std::ostringstream stream; + stream << std::setprecision(8) << std::noshowpoint << X() << ", " << Y() << ", " << Z(); + return stream.str(); } Data::Vector3::operator glm::vec3() const { return vector; }; @@ -74,3 +79,24 @@ void Data::Vector3::Serialize(pugi::xml_node node) const { Data::Variant Data::Vector3::Deserialize(pugi::xml_node node) { return Data::Vector3(node.child("X").text().as_float(), node.child("Y").text().as_float(), node.child("Z").text().as_float()); } + +Data::Variant Data::Vector3::FromString(std::string string) { + float components[3]; + + for (int i = 0; i < 3; i++) { + if (string.length() == 0) return Data::Vector3(0, 0, 0); + while (string[0] == ' ' && string.length() > 0) string.erase(0, 1); + size_t nextPos = string.find(","); + if (nextPos == -1) nextPos = string.length(); + std::string term = string.substr(0, nextPos); + string.erase(0, nextPos+1); + + char* cpos; + float value = std::strtof(term.c_str(), &cpos); + if (cpos == term.c_str()) return Data::Vector3(0, 0, 0); + + components[i] = value; + } + + return Data::Vector3(components[0], components[1], components[2]); +} \ No newline at end of file diff --git a/core/src/datatypes/vector.h b/core/src/datatypes/vector.h index 23b79c9..c3587a0 100644 --- a/core/src/datatypes/vector.h +++ b/core/src/datatypes/vector.h @@ -25,7 +25,9 @@ namespace Data { virtual const Data::String ToString() const override; virtual void Serialize(pugi::xml_node node) const override; + static Data::Variant Deserialize(pugi::xml_node node); + static Data::Variant FromString(std::string); operator glm::vec3() const; operator rp::Vector3() const; diff --git a/core/src/objects/part.cpp b/core/src/objects/part.cpp index 73921f2..bb74e87 100644 --- a/core/src/objects/part.cpp +++ b/core/src/objects/part.cpp @@ -30,7 +30,7 @@ constexpr FieldCodec cframePositionCodec() { *cframe = cframe->Rotation() + source.get(); }, .read = [](void* source) -> Data::Variant { - return *static_cast(source); + return static_cast(source)->Position(); }, }; } diff --git a/editor/panes/propertiesview.cpp b/editor/panes/propertiesview.cpp index 41b3ac3..d75a001 100644 --- a/editor/panes/propertiesview.cpp +++ b/editor/panes/propertiesview.cpp @@ -69,6 +69,11 @@ public: QLineEdit* lineEdit = new QLineEdit(parent); lineEdit->setText(QString::fromStdString(currentValue.get())); + return lineEdit; + } else if (meta.type->fromString) { + QLineEdit* lineEdit = new QLineEdit(parent); + lineEdit->setText(QString::fromStdString(currentValue.ToString())); + return lineEdit; } @@ -100,6 +105,10 @@ public: QLineEdit* lineEdit = dynamic_cast(editor); inst->SetPropertyValue(propertyName, Data::String(lineEdit->text().toStdString())); + } else if (meta.type->fromString) { + QLineEdit* lineEdit = dynamic_cast(editor); + + inst->SetPropertyValue(propertyName, meta.type->fromString(lineEdit->text().toStdString())); } } }; @@ -127,8 +136,8 @@ PropertiesView::~PropertiesView() { } QStringList PROPERTY_CATEGORY_NAMES { - "Data", "Appearence", + "Data", "Behavior", "Part", "Surface" @@ -200,6 +209,8 @@ void PropertiesView::setSelected(std::optional instance) { PropertyMeta meta = inst->GetPropertyMeta(property).value(); Data::Variant currentValue = inst->GetPropertyValue(property).value(); + if (meta.type == &Data::CFrame::TYPE) continue; + QTreeWidgetItem* item = new QTreeWidgetItem; item->setFlags(item->flags() | Qt::ItemIsEditable | Qt::ItemIsSelectable); item->setData(0, Qt::DisplayRole, QString::fromStdString(property)); @@ -210,6 +221,10 @@ void PropertiesView::setSelected(std::optional instance) { item->setData(1, Qt::DisplayRole, QString::fromStdString(currentValue.ToString())); } + if (!meta.type->fromString || meta.flags & PROP_READONLY) { + item->setDisabled(true); + } + propertyCategories[meta.category]->addChild(item); propertyCategories[meta.category]->setExpanded(true); } @@ -228,16 +243,10 @@ void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) { if (!item->parent() || !currentInstance || currentInstance->expired()) return; InstanceRef inst = currentInstance->lock(); - // std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString(); - // PropertyMeta meta = inst->GetPropertyMeta(propertyName).value(); + std::string propertyName = item->data(0, Qt::DisplayRole).toString().toStdString(); + PropertyMeta meta = inst->GetPropertyMeta(propertyName).value(); - // if (meta.type == &Data::String::TYPE) { - // inst->SetPropertyValue(propertyName, Data::String(item->data(1, Qt::EditRole).toString().toStdString())); - // } else if (meta.type == &Data::Bool::TYPE) { - // inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1))); - // } else { - // inst->SetPropertyValue(propertyName, meta.type->fromString(item->data(1, Qt::EditRole).toString().toStdString())); - // } - - // update(indexFromItem(item, column)); + if (meta.type == &Data::Bool::TYPE) { + inst->SetPropertyValue(propertyName, Data::Bool(item->checkState(1))); + } } \ No newline at end of file