NodeEditor class
This commit is contained in:
parent
14c677a0f5
commit
738ed42673
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ libs/
|
|||||||
.old*/
|
.old*/
|
||||||
current.config
|
current.config
|
||||||
src/generated/
|
src/generated/
|
||||||
|
imgui.ini
|
||||||
|
|||||||
118
src/gui/NodeEditor.cpp
Normal file
118
src/gui/NodeEditor.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "gui_internal.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "NodeEditor.hpp"
|
||||||
|
|
||||||
|
namespace GraphC::gui {
|
||||||
|
|
||||||
|
NodeAttribute::NodeAttribute(id_t _id, NodeAttributeType _type, std::string _title)
|
||||||
|
: id(_id), type(_type), title(_title) {}
|
||||||
|
|
||||||
|
NodeAttributeLink::NodeAttributeLink(id_t _id, id_t _in, id_t _out)
|
||||||
|
: id(_id), in_attr_id(_in), out_attr_id(_out) {}
|
||||||
|
|
||||||
|
Node::Node(id_t _id, std::string _title)
|
||||||
|
: id(_id), title(_title) {}
|
||||||
|
|
||||||
|
void Node::draw(){
|
||||||
|
ImNodes::BeginNode(id);
|
||||||
|
ImNodes::BeginNodeTitleBar();
|
||||||
|
ImGui::TextUnformatted(title.c_str());
|
||||||
|
ImNodes::EndNodeTitleBar();
|
||||||
|
|
||||||
|
for(NodeAttribute& a : attributes)
|
||||||
|
{
|
||||||
|
switch (a.type)
|
||||||
|
{
|
||||||
|
case NodeAttributeType::Input:
|
||||||
|
ImNodes::BeginInputAttribute(a.id);
|
||||||
|
ImGui::Text("%s", a.title.c_str());
|
||||||
|
ImNodes::EndInputAttribute();
|
||||||
|
break;
|
||||||
|
case NodeAttributeType::Output:
|
||||||
|
ImNodes::BeginOutputAttribute(a.id);
|
||||||
|
ImGui::Text("%s", a.title.c_str());
|
||||||
|
ImGui::Indent(40);
|
||||||
|
ImNodes::EndOutputAttribute();
|
||||||
|
break;
|
||||||
|
case NodeAttributeType::Static:
|
||||||
|
ImNodes::BeginStaticAttribute(a.id);
|
||||||
|
ImGui::Text("%s", a.title.c_str());
|
||||||
|
ImNodes::EndStaticAttribute();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Node::draw() invalid type";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImNodes::EndNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node CreateExampleNode(id_t* next_id, std::string title){
|
||||||
|
Node a = Node((*next_id)++, title);
|
||||||
|
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Input, "In"));
|
||||||
|
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Output, "Out"));
|
||||||
|
a.attributes.push_back(NodeAttribute((*next_id)++, NodeAttributeType::Static, "Static"));
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeEditor::NodeEditor(std::string _title) : title(_title) {
|
||||||
|
nodes.push_back(CreateExampleNode(&next_id, "node A"));
|
||||||
|
nodes.push_back(CreateExampleNode(&next_id, "node B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeEditor::show(){
|
||||||
|
editor_open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeEditor::hide(){
|
||||||
|
editor_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeEditor::draw(){
|
||||||
|
if(!editor_open)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui::Begin(title.c_str(), &editor_open);
|
||||||
|
|
||||||
|
ImGui::SetWindowSizeMin(300,300);
|
||||||
|
ImNodes::BeginNodeEditor();
|
||||||
|
// draw nodes
|
||||||
|
for(Node& n : nodes){
|
||||||
|
n.draw();
|
||||||
|
}
|
||||||
|
// draw links
|
||||||
|
for(const NodeAttributeLink& l : links){
|
||||||
|
ImNodes::Link(l.id, l.in_attr_id, l.out_attr_id);
|
||||||
|
}
|
||||||
|
ImNodes::EndNodeEditor();
|
||||||
|
|
||||||
|
// handle link creation
|
||||||
|
id_t in_attr_id;
|
||||||
|
id_t out_attr_id;
|
||||||
|
if (ImNodes::IsLinkCreated(&in_attr_id, &out_attr_id))
|
||||||
|
{
|
||||||
|
kprintf("new link id: %i\n", next_id);
|
||||||
|
NodeAttributeLink link(next_id++, in_attr_id, out_attr_id);
|
||||||
|
links.push_back(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle link destruction
|
||||||
|
id_t link_id;
|
||||||
|
if (ImNodes::IsLinkDestroyed(&link_id))
|
||||||
|
{
|
||||||
|
kprintf("link destroyed %i\n", link_id);
|
||||||
|
auto iter = std::find_if(links.begin(), links.end(),
|
||||||
|
[link_id](const NodeAttributeLink& link) -> bool {
|
||||||
|
kprintf("destroyed link found\n");
|
||||||
|
return link.id == link_id;
|
||||||
|
});
|
||||||
|
assert(iter != links.end());
|
||||||
|
links.erase(iter);
|
||||||
|
kprintf("destroyed link erased\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
57
src/gui/NodeEditor.hpp
Normal file
57
src/gui/NodeEditor.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../dependencies/imnodes/imnodes.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace GraphC::gui {
|
||||||
|
|
||||||
|
typedef i32 id_t;
|
||||||
|
|
||||||
|
enum class NodeAttributeType {
|
||||||
|
Input, Output, Static
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NodeAttribute {
|
||||||
|
id_t id;
|
||||||
|
NodeAttributeType type;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
NodeAttribute(id_t _id, NodeAttributeType _type, std::string _title);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
id_t id;
|
||||||
|
std::string title;
|
||||||
|
std::vector<NodeAttribute> attributes;
|
||||||
|
|
||||||
|
Node(id_t _id, std::string _title);
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NodeAttributeLink {
|
||||||
|
id_t id;
|
||||||
|
id_t in_attr_id;
|
||||||
|
id_t out_attr_id;
|
||||||
|
|
||||||
|
NodeAttributeLink(id_t _id, id_t _in, id_t _out);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NodeEditor {
|
||||||
|
std::string title=nullptr;
|
||||||
|
bool editor_open=false;
|
||||||
|
ImNodesContext* editor_context=nullptr;
|
||||||
|
id_t next_id=1;
|
||||||
|
std::vector<Node> nodes;
|
||||||
|
std::vector<NodeAttributeLink> links;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeEditor(std::string _title);
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -43,10 +43,6 @@ void main_window_destroy();
|
|||||||
void draw_debug_window(ImGuiIO& io, bool* main_loop_wait_for_input);
|
void draw_debug_window(ImGuiIO& io, bool* main_loop_wait_for_input);
|
||||||
void draw_bg_window();
|
void draw_bg_window();
|
||||||
|
|
||||||
void node_editor_create(const char* title);
|
|
||||||
void draw_node_editor();
|
|
||||||
void node_editor_destroy();
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
// Macros //
|
// Macros //
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
#include "gui_internal.hpp"
|
#include "gui_internal.hpp"
|
||||||
|
#include "NodeEditor.hpp"
|
||||||
|
using namespace GraphC::gui;
|
||||||
|
|
||||||
#define default_font_name font_DroidSans
|
#define default_font_name font_DroidSans
|
||||||
const f32 default_font_size=14.0f;
|
const f32 default_font_size=14.0f;
|
||||||
@ -7,6 +9,7 @@ bool loop_running=false;
|
|||||||
SDL_Window* sdl_window;
|
SDL_Window* sdl_window;
|
||||||
SDL_GLContext gl_context;
|
SDL_GLContext gl_context;
|
||||||
bool main_loop_wait_for_input=true;
|
bool main_loop_wait_for_input=true;
|
||||||
|
NodeEditor node_editor("new editor");
|
||||||
|
|
||||||
f32 getMainWindowDPI(){
|
f32 getMainWindowDPI(){
|
||||||
int w=0, h=0;
|
int w=0, h=0;
|
||||||
@ -75,7 +78,10 @@ Maybe main_window_open(const char* window_title){
|
|||||||
io.FontDefault=ImFont_LoadEmbedded(default_font_name, default_font_size);
|
io.FontDefault=ImFont_LoadEmbedded(default_font_name, default_font_size);
|
||||||
ImFont_LoadEmbedded(font_Cousine_Regular, default_font_size);
|
ImFont_LoadEmbedded(font_Cousine_Regular, default_font_size);
|
||||||
|
|
||||||
node_editor_create("node editor");
|
ImNodes::CreateContext();
|
||||||
|
ImNodes::StyleColorsDark();
|
||||||
|
ImNodes::PushAttributeFlag(ImNodesAttributeFlags_EnableLinkDetachWithDragClick);
|
||||||
|
node_editor=NodeEditor("node editor");
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +125,8 @@ Maybe draw_frame(){
|
|||||||
// Draw UI
|
// Draw UI
|
||||||
draw_bg_window();
|
draw_bg_window();
|
||||||
draw_debug_window(io, &main_loop_wait_for_input);
|
draw_debug_window(io, &main_loop_wait_for_input);
|
||||||
draw_node_editor();
|
node_editor.show();
|
||||||
|
node_editor.draw();
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
@ -197,7 +204,7 @@ Maybe main_window_close(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main_window_destroy(){
|
void main_window_destroy(){
|
||||||
node_editor_destroy();
|
ImNodes::DestroyContext();
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
#include "gui_internal.hpp"
|
|
||||||
#include "../../dependencies/imnodes/imnodes.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
struct Link {
|
|
||||||
int id;
|
|
||||||
int in_attr_id;
|
|
||||||
int out_attr_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
const char* editor_title=nullptr;
|
|
||||||
bool editor_open=false;
|
|
||||||
ImNodesContext* editor_context=nullptr;
|
|
||||||
int next_id=1;
|
|
||||||
std::vector<Link> links;
|
|
||||||
|
|
||||||
void node_editor_create(const char* title){
|
|
||||||
editor_title=title;
|
|
||||||
editor_open=true;
|
|
||||||
editor_context=ImNodes::CreateContext();
|
|
||||||
ImNodes::StyleColorsDark();
|
|
||||||
links=std::vector<Link>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void node_editor_destroy(){
|
|
||||||
editor_open=false;
|
|
||||||
ImNodes::DestroyContext(editor_context);
|
|
||||||
links.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_example_node(const char* node_title){
|
|
||||||
ImNodes::BeginNode(next_id++);
|
|
||||||
ImNodes::BeginNodeTitleBar();
|
|
||||||
ImGui::TextUnformatted(node_title);
|
|
||||||
ImNodes::EndNodeTitleBar();
|
|
||||||
ImNodes::BeginInputAttribute(next_id++);
|
|
||||||
ImGui::Text("input");
|
|
||||||
ImNodes::EndInputAttribute();
|
|
||||||
ImNodes::BeginOutputAttribute(next_id++);
|
|
||||||
ImGui::Indent(40);
|
|
||||||
ImGui::Text("output");
|
|
||||||
ImNodes::EndOutputAttribute();
|
|
||||||
ImNodes::EndNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_node_editor(){
|
|
||||||
if(!editor_open)
|
|
||||||
return;
|
|
||||||
next_id=1;
|
|
||||||
ImGui::Begin(editor_title, &editor_open);
|
|
||||||
ImGui::SetWindowSizeMin(300,300);
|
|
||||||
ImNodes::BeginNodeEditor();
|
|
||||||
draw_example_node("node A");
|
|
||||||
draw_example_node("node B");
|
|
||||||
for(const Link& link : links){
|
|
||||||
|
|
||||||
}
|
|
||||||
ImNodes::EndNodeEditor();
|
|
||||||
|
|
||||||
Link link;
|
|
||||||
if (ImNodes::IsLinkCreated(&link.in_attr_id, &link.out_attr_id))
|
|
||||||
{
|
|
||||||
link.id=next_id++;
|
|
||||||
links.push_back(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int link_id;
|
|
||||||
if (ImNodes::IsLinkDestroyed(&link_id))
|
|
||||||
{
|
|
||||||
auto iter = std::find_if(links.begin(), links.end(),
|
|
||||||
[link_id](const Link& link) -> bool {
|
|
||||||
return link.id == link_id;
|
|
||||||
});
|
|
||||||
assert(iter != links.end());
|
|
||||||
links.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user