From ee6a8eb29a68166cfe4399b96ce0a9c5a41e13a3 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Fri, 18 Feb 2022 22:24:19 +0100 Subject: [PATCH] Basic node properties editor. --- src/AnimGraphEditor.cc | 89 ++++++++++++++++++++++++++++++++++++---- src/AnimGraphResource.cc | 13 +++++- src/AnimGraphResource.h | 2 + 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/AnimGraphEditor.cc b/src/AnimGraphEditor.cc index de8cb42..bef8d62 100644 --- a/src/AnimGraphEditor.cc +++ b/src/AnimGraphEditor.cc @@ -26,6 +26,52 @@ ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) { return ImNodesPinShape_Quad; } +void AnimGraphEditorRenderSidebar(AnimNodeResource& node_resource) { + ImGui::Text("[%s]", node_resource.m_type_name.c_str()); + + char node_name_buffer[256]; + memset(node_name_buffer, 0, sizeof(node_name_buffer)); + strncpy( + node_name_buffer, + node_resource.m_name.c_str(), + std::min(node_resource.m_name.size(), sizeof(node_name_buffer))); + + if (ImGui::InputText("Name", node_name_buffer, sizeof(node_name_buffer))) { + node_resource.m_name = node_name_buffer; + } + + int num_properties = node_resource.m_socket_accessor->m_properties.size(); + for (int i = 0; i < num_properties; i++) { + Socket& property = node_resource.m_socket_accessor->m_properties[i]; + if (property.m_type == SocketType::SocketTypeFloat) { + ImGui::SliderFloat( + property.m_name.c_str(), + reinterpret_cast(property.m_value.ptr), + -100.f, + 100.f); + } else if (property.m_type == SocketType::SocketTypeBool) { + ImGui::Checkbox( + property.m_name.c_str(), + reinterpret_cast(property.m_value.ptr)); + } else if (property.m_type == SocketType::SocketTypeString) { + std::string* property_string = + reinterpret_cast(property.m_value.ptr); + char string_buf[256]; + memset(string_buf, 0, sizeof(string_buf)); + strncpy( + string_buf, + property_string->c_str(), + std::min(property_string->size(), sizeof(string_buf))); + if (ImGui::InputText( + property.m_name.c_str(), + string_buf, + sizeof(string_buf))) { + (*property_string) = string_buf; + } + } + } +} + void AnimGraphEditorUpdate() { static AnimGraphResource graph_resource = AnimGraphResource(); @@ -58,6 +104,11 @@ void AnimGraphEditorUpdate() { ImGui::EndMenuBar(); + ImGui::Columns(2); + + // + // Node editor canvas + // ImNodes::BeginNodeEditor(); // Popup menu @@ -128,7 +179,8 @@ void AnimGraphEditorUpdate() { ImColor(255, 255, 255, 255)); ImGui::Text(socket.m_name.c_str()); - ImNodes::PushAttributeFlag(ImNodesAttributeFlags_EnableLinkDetachWithDragClick); + ImNodes::PushAttributeFlag( + ImNodesAttributeFlags_EnableLinkDetachWithDragClick); ImNodes::EndInputAttribute(); } @@ -142,19 +194,21 @@ void AnimGraphEditorUpdate() { sGetSocketShapeFromSocketType(socket.m_type), ImColor(255, 255, 255, 255)); ImGui::Text(socket.m_name.c_str()); - ImNodes::PushAttributeFlag(ImNodesAttributeFlags_EnableLinkDetachWithDragClick); + ImNodes::PushAttributeFlag( + ImNodesAttributeFlags_EnableLinkDetachWithDragClick); ImNodes::EndInputAttribute(); } // Graph output node if (i == 0) { if (ImGui::Button("+Output")) { - AnimNodeResource& graph_output_node = graph_resource.getGraphOutputNode(); + AnimNodeResource& graph_output_node = + graph_resource.getGraphOutputNode(); static float bla = 0.f; std::string socket_name = "Output"; - socket_name += - std::to_string(graph_output_node.m_socket_accessor->m_inputs.size()); + socket_name += std::to_string( + graph_output_node.m_socket_accessor->m_inputs.size()); graph_output_node.m_socket_accessor->RegisterInput( socket_name, nullptr); @@ -165,8 +219,8 @@ void AnimGraphEditorUpdate() { static float bla = 0.f; std::string socket_name = "Input"; - socket_name += - std::to_string(graph_input_node.m_socket_accessor->m_outputs.size()); + socket_name += std::to_string( + graph_input_node.m_socket_accessor->m_outputs.size()); graph_input_node.m_socket_accessor->RegisterOutput( socket_name, nullptr); @@ -220,6 +274,25 @@ void AnimGraphEditorUpdate() { // Handle link detachements. int link_id = 0; if (ImNodes::IsLinkDestroyed(&link_id)) { - graph_resource.m_connections.erase(graph_resource.m_connections.begin() + link_id); + graph_resource.m_connections.erase( + graph_resource.m_connections.begin() + link_id); } + + int selected_nodes[ImNodes::NumSelectedNodes()]; + ImNodes::GetSelectedNodes(selected_nodes); + + // + // Sidebar + // + ImGui::NextColumn(); + + if (ImNodes::NumSelectedNodes() == 1) { + if (selected_nodes[0] < graph_resource.m_nodes.size()) { + AnimNodeResource& selected_node = + graph_resource.m_nodes[selected_nodes[0]]; + AnimGraphEditorRenderSidebar(selected_node); + } + } + + ImGui::Columns(1); } \ No newline at end of file diff --git a/src/AnimGraphResource.cc b/src/AnimGraphResource.cc index 0a5c1b1..3eb407e 100644 --- a/src/AnimGraphResource.cc +++ b/src/AnimGraphResource.cc @@ -144,6 +144,14 @@ AnimGraphConnection sAnimGraphConnectionFromJson(const json& json_node) { void AnimGraphResource::clear() { m_name = ""; + + clearNodes(); + m_connections.clear(); + + initGraphConnectors(); +} + +void AnimGraphResource::clearNodes() { for (size_t i = 0; i < m_nodes.size(); i++) { delete m_nodes[i].m_socket_accessor; m_nodes[i].m_socket_accessor = nullptr; @@ -151,13 +159,13 @@ void AnimGraphResource::clear() { m_nodes[i].m_anim_node = nullptr; } m_nodes.clear(); +} +void AnimGraphResource::initGraphConnectors() { m_nodes.push_back(AnimNodeResourceFactory("BlendTree")); m_nodes[0].m_name = "Outputs"; m_nodes.push_back(AnimNodeResourceFactory("BlendTree")); m_nodes[1].m_name = "Inputs"; - - m_connections.clear(); } bool AnimGraphResource::saveToFile(const char* filename) const { @@ -220,6 +228,7 @@ bool AnimGraphResource::loadFromFile(const char* filename) { } clear(); + clearNodes(); m_name = json_data["name"]; for (size_t i = 0; i < json_data["nodes"].size(); i++) { diff --git a/src/AnimGraphResource.h b/src/AnimGraphResource.h index 08be856..41ebdc7 100644 --- a/src/AnimGraphResource.h +++ b/src/AnimGraphResource.h @@ -337,6 +337,8 @@ struct AnimGraphResource { AnimGraphResource() { clear(); } void clear(); + void clearNodes(); + void initGraphConnectors(); bool saveToFile(const char* filename) const; bool loadFromFile(const char* filename);