From bbab4d8608c420abf13d52f11fccd0c99e8507f5 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 12 Feb 2022 12:06:25 +0100 Subject: [PATCH] Graph editor allows instantiation of different node types. --- src/AnimGraphEditor.cc | 88 ++++++++++++++++++++++++++++++---------- src/AnimGraphResource.cc | 3 +- 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/AnimGraphEditor.cc b/src/AnimGraphEditor.cc index e236b08..4b460b7 100644 --- a/src/AnimGraphEditor.cc +++ b/src/AnimGraphEditor.cc @@ -4,16 +4,14 @@ #include "AnimGraphEditor.h" -#include "imnodes.h" - #include "AnimGraphResource.h" +#include "imnodes.h" static AnimGraphResource gGraphResource; constexpr int NodeInputAttributeFlag = 2 << 16; constexpr int NodeOutputAttributeFlag = 2 << 17; - void AnimGraphEditorUpdate() { ImGui::BeginMenuBar(); if (ImGui::Button("Save")) { @@ -22,17 +20,22 @@ void AnimGraphEditorUpdate() { if (ImGui::Button("Load")) { gGraphResource.loadFromFile("editor_graph.json"); - for (size_t i = 0, n = gGraphResource.m_nodes.size(); i < n; i++) { + for (size_t i = 1, n = gGraphResource.m_nodes.size(); i < n; i++) { const AnimNodeResource& node_resource = gGraphResource.m_nodes[i]; - ImNodes::SetNodeGridSpacePos(i, ImVec2(node_resource.m_position[0], node_resource.m_position[1])); + ImNodes::SetNodeGridSpacePos( + i, + ImVec2(node_resource.m_position[0], node_resource.m_position[1])); } } if (ImGui::Button("Clear")) { gGraphResource.clear(); } char graph_name_buffer[256]; - memset (graph_name_buffer, 0, sizeof(graph_name_buffer)); - strncpy (graph_name_buffer, gGraphResource.m_name.c_str(), sizeof(graph_name_buffer)); + memset(graph_name_buffer, 0, sizeof(graph_name_buffer)); + strncpy( + graph_name_buffer, + gGraphResource.m_name.c_str(), + sizeof(graph_name_buffer)); if (ImGui::InputText("Name", graph_name_buffer, sizeof(graph_name_buffer))) { gGraphResource.m_name = graph_name_buffer; } @@ -41,15 +44,48 @@ void AnimGraphEditorUpdate() { ImNodes::BeginNodeEditor(); - if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImNodes::IsEditorHovered() - && ImGui::IsMouseReleased(ImGuiMouseButton_Right)) { - AnimNodeResource node_resource = AnimNodeResourceFactory("SpeedScale"); - size_t node_id = gGraphResource.m_nodes.size(); - ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos()); - gGraphResource.m_nodes.push_back(node_resource); + // Popup menu + { + const bool open_popup = + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) + && ImNodes::IsEditorHovered() + && ImGui::IsMouseReleased(ImGuiMouseButton_Right); + + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f)); + if (!ImGui::IsAnyItemHovered() && open_popup) { + ImGui::OpenPopup("add node"); + } + + if (ImGui::BeginPopup("add node")) { + const ImVec2 click_pos = ImGui::GetMousePosOnOpeningCurrentPopup(); + std::string node_type_name = ""; + if (ImGui::MenuItem("AnimSampler")) { + node_type_name = "AnimSampler"; + } + + if (ImGui::MenuItem("Blend2")) { + node_type_name = "Blend2"; + } + + if (ImGui::MenuItem("SpeedScale")) { + node_type_name = "SpeedScale"; + } + + if (node_type_name != "") { + AnimNodeResource node_resource = + AnimNodeResourceFactory(node_type_name); + size_t node_id = gGraphResource.m_nodes.size(); + ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos()); + gGraphResource.m_nodes.push_back(node_resource); + } + + ImGui::EndPopup(); + } + + ImGui::PopStyleVar(ImGuiStyleVar_WindowPadding); } - for (size_t i = 0, n = gGraphResource.m_nodes.size(); i < n; i++) { + for (size_t i = 1, n = gGraphResource.m_nodes.size(); i < n; i++) { AnimNodeResource& node_resource = gGraphResource.m_nodes[i]; ImNodes::BeginNode(i); @@ -60,7 +96,8 @@ void AnimGraphEditorUpdate() { ImNodes::EndNodeTitleBar(); // Inputs - const std::vector& node_inputs =node_resource.m_socket_accessor->m_inputs; + const std::vector& node_inputs = + node_resource.m_socket_accessor->m_inputs; for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) { const Socket& socket = node_inputs[j]; ImNodes::BeginInputAttribute(GenerateInputAttributeId(i, j)); @@ -69,7 +106,8 @@ void AnimGraphEditorUpdate() { } // Outputs - const std::vector& node_outputs =node_resource.m_socket_accessor->m_outputs; + const std::vector& node_outputs = + node_resource.m_socket_accessor->m_outputs; for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) { const Socket& socket = node_outputs[j]; ImNodes::BeginOutputAttribute(GenerateOutputAttributeId(i, j)); @@ -87,8 +125,12 @@ void AnimGraphEditorUpdate() { for (size_t i = 0, n = gGraphResource.m_connections.size(); i < n; i++) { const AnimGraphConnection& connection = gGraphResource.m_connections[i]; int start_attr, end_attr; - start_attr = GenerateOutputAttributeId(connection.m_source_node_index, connection.m_source_socket_index); - end_attr = GenerateInputAttributeId(connection.m_target_node_index, connection.m_target_socket_index); + start_attr = GenerateOutputAttributeId( + connection.m_source_node_index, + connection.m_source_socket_index); + end_attr = GenerateInputAttributeId( + connection.m_target_node_index, + connection.m_target_socket_index); ImNodes::Link(i, start_attr, end_attr); } @@ -98,14 +140,18 @@ void AnimGraphEditorUpdate() { if (ImNodes::IsLinkCreated(&start_attr, &end_attr)) { int node_start_id; int node_start_output_index; - SplitOutputAttributeId(start_attr, &node_start_id, &node_start_output_index); + SplitOutputAttributeId( + start_attr, + &node_start_id, + &node_start_output_index); int node_end_id; int node_end_input_index; SplitInputAttributeId(end_attr, &node_end_id, &node_end_input_index); - std::cout << "Link created: " << node_start_id << ", " << node_start_output_index << " -> " - << node_end_id << ", " << node_end_input_index << std::endl; + std::cout << "Link created: " << node_start_id << ", " + << node_start_output_index << " -> " << node_end_id << ", " + << node_end_input_index << std::endl; AnimGraphConnection connection; connection.m_source_node_index = node_start_id; diff --git a/src/AnimGraphResource.cc b/src/AnimGraphResource.cc index daaf88c..7e0b484 100644 --- a/src/AnimGraphResource.cc +++ b/src/AnimGraphResource.cc @@ -134,7 +134,8 @@ bool AnimGraphResource::loadFromFile (const char* filename) { std::cerr << "Invalid json object. Expected type 'AnimGraphResource' but got '" << json_data["type"] << "'." << std::endl; } - clear(); + m_nodes.clear(); + m_connections.clear(); m_name = json_data["name"]; for (size_t i = 0; i < json_data["nodes"].size(); i++) {