218 lines
8.0 KiB
C++
218 lines
8.0 KiB
C++
#include "Workflow_Editor.hpp"
|
|
#include "imgui_internal.h"
|
|
|
|
// 新增节点
|
|
bool Workflow_Editor::Add_Node(Node_Type_Enum type, ImVec2 initial_position)
|
|
{
|
|
// 新节点
|
|
std::shared_ptr<Abs_Node> p_New_Node;
|
|
|
|
// 记录节点
|
|
switch (type)
|
|
{
|
|
case NODE_TYPE_MSG_LINE_INPUT: // 消息行输入 (头节点)
|
|
|
|
// 创建节点
|
|
p_New_Node = std::make_shared<MSG_Input_Node>(&this->Node_ID_Generator,
|
|
&this->Connector_ID_Generator,
|
|
initial_position);
|
|
break;
|
|
|
|
// // 记录到节点池和接口池
|
|
// this->Node_Pool.push_back(p_New_Node);
|
|
// for (auto p_Connector : p_New_Node->Get_Connector_List())
|
|
// this->Connector_Pool.push_back(p_Connector);
|
|
|
|
// // 编辑工作路由
|
|
// {
|
|
// // 起始层级只有起始节点
|
|
// std::vector<std::shared_ptr<Abs_Node>> Begin_Layer;
|
|
// Begin_Layer.push_back(p_New_Node);
|
|
|
|
// // 层级列表仅有起始层级
|
|
// std::vector<std::vector<std::shared_ptr<Abs_Node>>> Layer_List;
|
|
// Layer_List.push_back(Begin_Layer);
|
|
|
|
// // 插入工作路由表
|
|
// this->Process_Route.push_back(Layer_List);
|
|
// }
|
|
// return true;
|
|
|
|
case NODE_TYPE_CSV_EXPORTER: // CSV输出器
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
if (p_New_Node.get() != nullptr)
|
|
{
|
|
// 将新增的节点及其接口记录到对应的池
|
|
this->Node_Pool.push_back(p_New_Node);
|
|
for (auto p_Connector : p_New_Node->Get_Connector_List())
|
|
this->Connector_Pool.push_back(p_Connector);
|
|
|
|
// 记录到散点池
|
|
this->Separate_Node_List.push_back(p_New_Node);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 绘制节点编辑器
|
|
void Workflow_Editor::Show(void)
|
|
{
|
|
// 浅色主题节点编辑器窗体
|
|
ImNodes::StyleColorsLight();
|
|
ImNodes::BeginNodeEditor();
|
|
{
|
|
// 显示所有节点
|
|
for (auto iterator = this->Node_Pool.begin(); iterator != this->Node_Pool.end(); iterator++)
|
|
{
|
|
auto Connector_List = (*iterator)->Get_Connector_List();
|
|
if ((*iterator)->Get_CloseFlag() == true)
|
|
{
|
|
// 删除列表中所有与该节点接口相关的边并从接口池中删除
|
|
for (auto pConnector : Connector_List)
|
|
{
|
|
int connector_id = pConnector->Get_ID();
|
|
// 遍历边池
|
|
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++)
|
|
{
|
|
if ((iterator->source_connector_id == connector_id) || (iterator->target_connector_id == connector_id))
|
|
{
|
|
// 注销边ID
|
|
this->Edge_ID_Generator.Release_ID(connector_id);
|
|
// 注销边记录,迭代器删除后会返回下一个位置的迭代器
|
|
iterator = this->Edge_Pool.erase(iterator);
|
|
iterator--;
|
|
}
|
|
}
|
|
|
|
// 从接口池中移除
|
|
for (auto iterator = this->Connector_Pool.begin(); iterator != this->Connector_Pool.end(); iterator++)
|
|
{
|
|
if (*iterator == pConnector)
|
|
{
|
|
// 注销节点记录
|
|
iterator = this->Connector_Pool.erase(iterator);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @todo 从工作路由中删除该节点并调整工作路由层级顺序
|
|
* @todo 可能不需要对外暴露接口池
|
|
*/
|
|
|
|
// 从节点池中删除该节点,迭代器删除后会返回下一个位置的迭代器
|
|
iterator = this->Node_Pool.erase(iterator);
|
|
iterator--;
|
|
}
|
|
else
|
|
// 绘制节点
|
|
(*iterator)->Show();
|
|
}
|
|
|
|
// 右键菜单
|
|
{
|
|
const bool open_popup = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) &&
|
|
ImNodes::IsEditorHovered() &&
|
|
ImGui::IsMouseReleased(ImGuiMouseButton_Right);
|
|
|
|
// 设置弹窗周边Padding
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
|
|
|
|
// if (!ImGui::IsAnyItemHovered() && open_popup)
|
|
if (open_popup)
|
|
{
|
|
ImGui::OpenPopup("RightClick_Popup");
|
|
}
|
|
|
|
if (ImGui::BeginPopup("RightClick_Popup"))
|
|
{
|
|
ImVec2 click_pos = ImGui::GetMousePosOnOpeningCurrentPopup();
|
|
// 节点添加菜单
|
|
if (ImGui::BeginMenu(u8"创建节点"))
|
|
{
|
|
if (ImGui::MenuItem(u8"DLT信息输入节点"))
|
|
this->Add_Node(NODE_TYPE_MSG_LINE_INPUT, click_pos);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
ImGui::EndPopup();
|
|
}
|
|
ImGui::PopStyleVar();
|
|
}
|
|
|
|
// 显示所有的连线
|
|
for (auto Edge : this->Edge_Pool)
|
|
ImNodes::Link(Edge.id, Edge.source_connector_id, Edge.target_connector_id);
|
|
|
|
// 缩略图
|
|
ImNodes::MiniMap(0.2f, ImNodesMiniMapLocation_TopRight);
|
|
}
|
|
ImNodes::EndNodeEditor();
|
|
|
|
// 处理连线
|
|
{
|
|
int source_id = -1, target_id = -1;
|
|
if (ImNodes::IsLinkCreated(&source_id, &target_id))
|
|
{
|
|
|
|
// 查找接口
|
|
bool find = false;
|
|
std::shared_ptr<Abs_Connector> p_source_connector;
|
|
std::shared_ptr<Abs_Connector> p_target_connector;
|
|
for (auto pNode : this->Node_Pool)
|
|
{
|
|
for (auto pConnector : pNode->Get_Connector_List())
|
|
{
|
|
if (pConnector->Get_ID() == source_id)
|
|
p_source_connector = pConnector;
|
|
if (pConnector->Get_ID() == target_id)
|
|
p_target_connector = pConnector;
|
|
if ((p_source_connector.get() != nullptr) && (p_target_connector.get() != nullptr))
|
|
{
|
|
find = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (find)
|
|
break;
|
|
}
|
|
|
|
// 判定查找结果
|
|
if (find)
|
|
{
|
|
// 输入类型节点只允许一个父接口,输出类型节点可以有多个子接口
|
|
if (p_target_connector->Get_Provider() != nullptr)
|
|
{
|
|
int origin_source_id = p_target_connector->Get_Provider()->Get_ID();
|
|
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++)
|
|
{
|
|
if (iterator->source_connector_id == origin_source_id && iterator->target_connector_id == target_id)
|
|
{
|
|
this->Edge_ID_Generator.Release_ID(iterator->id);
|
|
this->Edge_Pool.erase(iterator);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 尝试连接
|
|
if (p_source_connector->Connect_To(p_target_connector.get()) == true)
|
|
{
|
|
// 记录到边池
|
|
this->Edge_Pool.push_back({this->Edge_ID_Generator.Request_ID(), source_id, target_id});
|
|
|
|
/**
|
|
* @todo 调整工作路由层级
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|