Gary Talent e773d6f0ee
All checks were successful
Build / build (push) Successful in 1m16s
[studio] Rename StudioContext to Context
2025-05-06 22:37:21 -05:00

176 lines
5.5 KiB
C++

/*
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <imgui.h>
#include "clawviewer.hpp"
namespace studio {
ClawEditor::ClawEditor(Context &sctx, ox::StringParam path):
Editor(sctx, std::move(path)),
m_obj(sctx.project->loadObj<ox::ModelObject>(itemPath()).unwrapThrow()) {
}
void ClawEditor::draw(Context&) noexcept {
ImGui::BeginChild("PaletteEditor");
static constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
if (ImGui::BeginTable("ObjTree", 3, flags)) {
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 100);
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, 250);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_NoHide);
ImGui::TableHeadersRow();
ObjPath objPath;
drawTree(objPath, m_obj);
ImGui::EndTable();
}
ImGui::EndChild();
}
void ClawEditor::drawRow(ox::ModelValue const&value) noexcept {
using Str = ox::BasicString<100>;
Str val, type;
switch (value.type()) {
case ox::ModelValue::Type::Undefined:
val = "undefined";
type = "undefined";
break;
case ox::ModelValue::Type::Bool:
val = value.get<bool>() ? "true" : "false";
type = "bool";
break;
case ox::ModelValue::Type::UnsignedInteger8:
val = ox::sfmt<Str>("{}", value.get<uint8_t>());
type = "uint8";
break;
case ox::ModelValue::Type::UnsignedInteger16:
val = ox::sfmt<Str>("{}", value.get<uint16_t>());
type = "uint16";
break;
case ox::ModelValue::Type::UnsignedInteger32:
val = ox::sfmt<Str>("{}", value.get<uint32_t>());
type = "uint32";
break;
case ox::ModelValue::Type::UnsignedInteger64:
val = ox::sfmt<Str>("{}", value.get<uint64_t>());
type = "uint64";
break;
case ox::ModelValue::Type::SignedInteger8:
val = ox::sfmt<Str>("{}", value.get<int8_t>());
type = "int8";
break;
case ox::ModelValue::Type::SignedInteger16:
val = ox::sfmt<Str>("{}", value.get<int16_t>());
type = "int16";
break;
case ox::ModelValue::Type::SignedInteger32:
val = ox::sfmt<Str>("{}", value.get<int32_t>());
type = "int32";
break;
case ox::ModelValue::Type::SignedInteger64:
val = ox::sfmt<Str>("{}", value.get<int64_t>());
type = "int64";
break;
case ox::ModelValue::Type::String:
val = ox::sfmt<Str>("\"{}\"", value.get<ox::String>());
type = "string";
break;
case ox::ModelValue::Type::Object:
type = value.get<ox::ModelObject>().type()->typeName.c_str();
break;
case ox::ModelValue::Type::Union:
type = "union";
break;
case ox::ModelValue::Type::InlineArray:
case ox::ModelValue::Type::Vector:
type = "list";
break;
}
ImGui::TableNextColumn();
ImGui::Text("%s", type.c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", val.c_str());
}
void ClawEditor::drawVar(ObjPath &path, ox::StringViewCR name, ox::ModelValue const&value) noexcept {
using Str = ox::BasicString<100>;
path.push_back(name);
if (value.type() == ox::ModelValue::Type::Object) {
drawTree(path, value.get<ox::ModelObject>());
} else if (value.type() == ox::ModelValue::Type::Vector) {
auto const&vec = value.get<ox::ModelValueVector>();
auto const pathStr = ox::join<Str>("##", path).unwrap();
auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr);
auto const flags = ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_OpenOnArrow
| (vec.size() ? 0 : ImGuiTreeNodeFlags_Leaf)
| (false ? ImGuiTreeNodeFlags_Selected : 0);
auto const open = ImGui::TreeNodeEx(lbl.c_str(), flags);
ImGui::SameLine();
drawRow(value);
if (open) {
for (auto i = 0lu; auto const&e: vec) {
auto const iStr = ox::sfmt<Str>("{}", i);
path.push_back(iStr);
ImGui::TableNextRow(0, 5);
ImGui::TableNextColumn();
drawVar(path, ox::sfmt<Str>("[{}]", i), e);
path.pop_back();
++i;
}
ImGui::TreePop();
}
} else {
auto const pathStr = ox::join<Str>("##", path).unwrap();
auto const lbl = ox::sfmt<Str>("{}##{}", name, pathStr);
auto const flags = ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_OpenOnArrow
| ImGuiTreeNodeFlags_Leaf
| (false ? ImGuiTreeNodeFlags_Selected : 0);
auto const open = ImGui::TreeNodeEx(lbl.c_str(), flags);
ImGui::SameLine();
drawRow(value);
if (open) {
ImGui::TreePop();
}
}
path.pop_back();
}
void ClawEditor::drawTree(ObjPath &path, ox::ModelObject const&obj) noexcept {
using Str = ox::BasicString<100>;
for (const auto &c : obj) {
ImGui::TableNextRow(0, 5);
auto pathStr = ox::join<Str>("##", path).unwrap();
auto lbl = ox::sfmt<Str>("{}##{}", c->name, pathStr);
const auto rowSelected = false;
const auto hasChildren = c->value.type() == ox::ModelValue::Type::Object
|| c->value.type() == ox::ModelValue::Type::Vector;
const auto flags = ImGuiTreeNodeFlags_SpanFullWidth
| ImGuiTreeNodeFlags_OpenOnArrow
| (hasChildren ? 0 : ImGuiTreeNodeFlags_Leaf)
| (rowSelected ? ImGuiTreeNodeFlags_Selected : 0);
ImGui::TableNextColumn();
//if (ImGui::IsItemClicked()) {
//}
//if (ImGui::IsMouseDoubleClicked(0) && ImGui::IsItemHovered()) {
//}
path.push_back(c->name);
if (c->value.type() == ox::ModelValue::Type::Object) {
const auto open = ImGui::TreeNodeEx(lbl.c_str(), flags);
ImGui::SameLine();
drawRow(c->value);
if (open) {
drawTree(path, c->value.get<ox::ModelObject>());
ImGui::TreePop();
}
} else {
drawVar(path, c->name, c->value);
}
path.pop_back();
}
}
}