180 lines
6.1 KiB
C++
180 lines
6.1 KiB
C++
#include "gui.hpp"
|
|
#include <algorithm>
|
|
#include "GraphEditor.hpp"
|
|
|
|
namespace GraphC::gui {
|
|
|
|
void GraphEditor::drawNode(const GraphModel::Node& node){
|
|
ImNodes::BeginNode(node.id);
|
|
ImNodes::BeginNodeTitleBar();
|
|
ImGui::TextUnformatted(node.title.c_str());
|
|
ImNodes::EndNodeTitleBar();
|
|
|
|
for(auto& a_p : node.getAttributes()){
|
|
auto&& a = *a_p.value;
|
|
switch (a.type){
|
|
case GraphModel::Attribute::Type::Input:
|
|
ImNodes::BeginInputAttribute(a.id);
|
|
ImGui::Text("%s", a.title.c_str());
|
|
ImNodes::EndInputAttribute();
|
|
break;
|
|
case GraphModel::Attribute::Type::Output:
|
|
ImNodes::BeginOutputAttribute(a.id);
|
|
ImGui::Text("%s", a.title.c_str());
|
|
ImGui::Indent(40);
|
|
ImNodes::EndOutputAttribute();
|
|
break;
|
|
case GraphModel::Attribute::Type::Static:
|
|
ImNodes::BeginStaticAttribute(a.id);
|
|
ImGui::Text("%s", a.title.c_str());
|
|
ImNodes::EndStaticAttribute();
|
|
break;
|
|
default:
|
|
throw "Node::draw() invalid type";
|
|
break;
|
|
}
|
|
}
|
|
|
|
static const char* items[]={
|
|
"static","input", "output"
|
|
};
|
|
static int selected_item_i = 0;
|
|
if(ImGui::Button("add attribute"))
|
|
ImGui::OpenPopup("new_attribute_popup");
|
|
|
|
if(ImGui::BeginPopup("new_attribute_popup")){
|
|
ImGui::SeparatorText("New attribute properties");
|
|
|
|
static char buf[256];
|
|
ImGui::InputText("label", buf, sizeof(buf));
|
|
|
|
if(ImGui::Button("select type"))
|
|
ImGui::OpenPopup("select_type_popup");
|
|
ImGui::SameLine();
|
|
ImGui::TextUnformatted(items[selected_item_i]);
|
|
|
|
if(ImGui::BeginPopup("select_type_popup")){
|
|
for (int i = 0; i < IM_ARRAYSIZE(items); i++)
|
|
if (ImGui::Selectable(items[i]))
|
|
selected_item_i = i;
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
if(ImGui::Button("Create attribute")){
|
|
graph.createAttribute(GraphModel::Attribute(
|
|
graph.id_gen.getNext(),
|
|
const_cast<GraphModel::Node*>(&node),
|
|
(GraphModel::Attribute::Type)selected_item_i,
|
|
std::string(buf)));
|
|
|
|
std::cout<<"ATTRIBUTES:\n";
|
|
std::cout<<graph.getAttributes().generateGraphVizCode()<<std::endl;
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
buf[0] = 0;
|
|
selected_item_i = 0;
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
ImNodes::EndNode();
|
|
}
|
|
|
|
|
|
GraphModel::Node* GraphEditor::CreateExampleNode(const std::string& node_title){
|
|
GraphModel::Node* n = graph.createNode(GraphModel::Node(graph.id_gen.getNext(), node_title));
|
|
graph.createAttribute(GraphModel::Attribute(graph.id_gen.getNext(), n, GraphModel::Attribute::Type::Input, "In"));
|
|
graph.createAttribute(GraphModel::Attribute(graph.id_gen.getNext(), n, GraphModel::Attribute::Type::Output, "Out"));
|
|
graph.createAttribute(GraphModel::Attribute(graph.id_gen.getNext(), n, GraphModel::Attribute::Type::Static, "Static"));
|
|
return n;
|
|
}
|
|
|
|
GraphEditor::GraphEditor(const std::string& _title)
|
|
: title(_title)
|
|
{
|
|
// CreateExampleNode("Node A");
|
|
// CreateExampleNode("Node B");
|
|
// CreateExampleNode("Node C");
|
|
// CreateExampleNode("Node D");
|
|
std::cout<<"NODES:\n";
|
|
std::cout<<graph.getNodes().generateGraphVizCode()<<std::endl;
|
|
std::cout<<"ATTRIBUTES:\n";
|
|
std::cout<<graph.getAttributes().generateGraphVizCode()<<std::endl;
|
|
}
|
|
|
|
void GraphEditor::show(){
|
|
editor_open = true;
|
|
}
|
|
|
|
void GraphEditor::hide(){
|
|
editor_open = false;
|
|
}
|
|
|
|
void GraphEditor::draw(){
|
|
if(!editor_open)
|
|
return;
|
|
|
|
ImGui::Begin(title.c_str(), &editor_open);
|
|
|
|
ImGui::SetWindowSizeMin(300,300);
|
|
|
|
if(ImGui::Button("create node")){
|
|
ImGui::OpenPopup("create_node_popup");
|
|
}
|
|
static char buf[256];
|
|
if(ImGui::BeginPopup("create_node_popup")){
|
|
ImGui::SeparatorText("New node properties");
|
|
ImGui::InputText("label", buf, sizeof(buf));
|
|
if(ImGui::Button("create node")){
|
|
graph.createNode(GraphModel::Node(graph.id_gen.getNext(), buf));
|
|
|
|
std::cout<<"NODES:\n";
|
|
std::cout<<graph.getNodes().generateGraphVizCode()<<std::endl;
|
|
|
|
buf[0] = 0;
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
ImNodes::BeginNodeEditor();
|
|
// draw nodes
|
|
for(auto& n_p : graph.getNodes()){
|
|
drawNode(n_p.value);
|
|
}
|
|
// draw edges
|
|
for(auto& p : graph.getEdges()){
|
|
ImNodes::Link(p.value.id, p.value.to_attr_id, p.value.from_attr_id);
|
|
}
|
|
|
|
ImNodes::EndNodeEditor();
|
|
|
|
// handle edge creation
|
|
GraphModel::id_t from_attr_id, to_attr_id;
|
|
if (ImNodes::IsLinkCreated(&from_attr_id, &to_attr_id))
|
|
{
|
|
if(!graph.tryCreateEdge(from_attr_id, to_attr_id, nullptr)){
|
|
ImGui::End();
|
|
throw UsefulException(format("can't create edge from attribute %i to attribute %i", from_attr_id, to_attr_id));
|
|
}
|
|
std::cout<<"EDGES:\n";
|
|
std::cout<<graph.getEdges().generateGraphVizCode()<<std::endl;
|
|
}
|
|
|
|
// handle edge destruction
|
|
GraphModel::id_t edge_id;
|
|
if (ImNodes::IsLinkDestroyed(&edge_id))
|
|
{
|
|
if(!graph.tryDeleteEdge(edge_id)){
|
|
ImGui::End();
|
|
throw UsefulException(format("can't delete edge with id %i", edge_id));
|
|
}
|
|
std::cout<<"EDGES:\n";
|
|
std::cout<<graph.getEdges().generateGraphVizCode()<<std::endl;
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
}
|