NodeEditor class
This commit is contained in:
parent
14c677a0f5
commit
738ed42673
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ libs/
|
||||
.old*/
|
||||
current.config
|
||||
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_bg_window();
|
||||
|
||||
void node_editor_create(const char* title);
|
||||
void draw_node_editor();
|
||||
void node_editor_destroy();
|
||||
|
||||
//////////////////////////////////////
|
||||
// Macros //
|
||||
//////////////////////////////////////
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
#include "gui_internal.hpp"
|
||||
#include "NodeEditor.hpp"
|
||||
using namespace GraphC::gui;
|
||||
|
||||
#define default_font_name font_DroidSans
|
||||
const f32 default_font_size=14.0f;
|
||||
@ -7,6 +9,7 @@ bool loop_running=false;
|
||||
SDL_Window* sdl_window;
|
||||
SDL_GLContext gl_context;
|
||||
bool main_loop_wait_for_input=true;
|
||||
NodeEditor node_editor("new editor");
|
||||
|
||||
f32 getMainWindowDPI(){
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -119,7 +125,8 @@ Maybe draw_frame(){
|
||||
// Draw UI
|
||||
draw_bg_window();
|
||||
draw_debug_window(io, &main_loop_wait_for_input);
|
||||
draw_node_editor();
|
||||
node_editor.show();
|
||||
node_editor.draw();
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
@ -197,7 +204,7 @@ Maybe main_window_close(){
|
||||
}
|
||||
|
||||
void main_window_destroy(){
|
||||
node_editor_destroy();
|
||||
ImNodes::DestroyContext();
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
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