#include "Nodes_And_Connectors.hpp" #include "Json_Utilities.hpp" #include "imgui_internal.h" #include "Global_Variables.hpp" #include "DLT_Utilities.hpp" // 客制化圆形带X按钮 bool CircleButtonWithX(const char *id, float radius) { ImGuiWindow *window = ImGui::GetCurrentWindow(); if (window->SkipItems) return false; // 创建ID ImGuiID button_id = window->GetID(id); // 计算按钮位置和大小 ImVec2 pos = window->DC.CursorPos; ImVec2 size(radius * 2, radius * 2); ImRect bb(pos, ImVec2(pos.x + size.x, pos.y + size.y)); // 处理交互 ImGui::ItemSize(bb); if (!ImGui::ItemAdd(bb, button_id)) return false; bool hovered, held; bool pressed = ImGui::ButtonBehavior(bb, button_id, &hovered, &held); // 绘制 ImU32 col = ImGui::GetColorU32( held ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); // 获取绘制列表 ImDrawList *draw_list = ImGui::GetWindowDrawList(); ImVec2 center = ImVec2(pos.x + radius, pos.y + radius); // 绘制圆形 draw_list->AddCircleFilled(center, radius, col, 32); // 绘制边框(可选) draw_list->AddCircle(center, radius, ImGui::GetColorU32(ImGuiCol_Border), 32, 1.0f); // 计算X的线条 float cross_radius = radius * 0.5f; // X的大小 float thickness = radius * 0.15f; // X的粗细 // 绘制X的两条线 draw_list->AddLine( ImVec2(center.x - cross_radius, center.y - cross_radius), ImVec2(center.x + cross_radius, center.y + cross_radius), ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f)), // 白色X thickness); draw_list->AddLine( ImVec2(center.x + cross_radius, center.y - cross_radius), ImVec2(center.x - cross_radius, center.y + cross_radius), ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f)), // 白色X thickness); return pressed; } // ================================================================================================= // 必要构造 Abs_Connector::Abs_Connector(Independent_ID_Generator *ID_Generator, Connector_Type_Enum type, const char *socket_str) : ID_Generator(nullptr), id(-1), type(CONNECTOR_TYPE_UNKNOWN), socket_str(nullptr) { // 分配ID this->id = ID_Generator->Request_ID(); if (this->id != -1) { this->ID_Generator = ID_Generator; this->type = type; this->socket_str = socket_str; } }; // 析构 Abs_Connector::~Abs_Connector() { // 释放产物 if (this->pkg.p_content_mem != nullptr) free(this->pkg.p_content_mem); // 断开所有连接 this->Disconnect_All(); // 释放ID this->ID_Generator->Release_ID(this->id); } // 连接到目标连接点 bool Abs_Connector::Connect_To(Abs_Connector *target) { // 判定接口是否匹配 if (strcmp(target->socket_str, this->socket_str) == 0) { // 写连接关系 必须是一收一发 if (((this->type == CONNECTOR_TYPE_OUTPUT) && (target->type == CONNECTOR_TYPE_INPUT)) || // ((this->type == CONNECTOR_TYPE_INPUT) && (target->type == CONNECTOR_TYPE_OUTPUT)) || // ((this->type == CONNECTOR_TYPE_INPUT_EXCLUSIVE) && (target->type == CONNECTOR_TYPE_OUTPUT) && this->related_connector_list.empty()) || // ((this->type == CONNECTOR_TYPE_OUTPUT) && (target->type == CONNECTOR_TYPE_INPUT_EXCLUSIVE) && target->related_connector_list.empty())) // { // 向双方写入关联信息 target->related_connector_list.push_back(this); this->related_connector_list.push_back(target); return true; } } return false; } // 断开所有连接 void Abs_Connector::Disconnect_All(void) { for (auto target : this->related_connector_list) { // 删除连接点对自己的记录 for (auto iterator = target->related_connector_list.begin(); iterator != target->related_connector_list.end(); iterator++) if (*iterator == this) { iterator = target->related_connector_list.erase(iterator); break; } } // 清空自身列表 decltype(this->related_connector_list) empty_list; this->related_connector_list.swap(empty_list); } // 与指定的接口断开连接 bool Abs_Connector::Disconnect_To(Abs_Connector *target) { // 查找目标接口 for (auto iterator = this->related_connector_list.begin(); iterator != this->related_connector_list.end(); iterator++) { if (*iterator == target) { // 删除目标连接点对自己的记录 for (auto iterator = target->related_connector_list.begin(); iterator != target->related_connector_list.end(); iterator++) if (*iterator == this) { iterator = target->related_connector_list.erase(iterator); break; } // 自身删除对目标点的记录 iterator = this->related_connector_list.erase(iterator); return true; } } // 未成功查找 return false; } /** * 注册包 * @param p_content 目标容物指针 * @param content_size 容物大小 * @param count 当前包位置 * @param total_count 包流总长度 */ bool Abs_Connector::Register_Package(void *p_content, size_t content_size, size_t count, size_t total_count) { // 非输出类接口 if (this->type != CONNECTOR_TYPE_OUTPUT) return false; // 释放之前的产物 if (this->pkg.p_content_mem != nullptr) free(this->pkg.p_content_mem); // 分配空间 if (content_size > 0) { this->pkg.p_content_mem = malloc(content_size); if (this->pkg.p_content_mem == nullptr) return false; // 复制内容 memcpy(this->pkg.p_content_mem, p_content, content_size); } else this->pkg.p_content_mem = nullptr; // 包信息 this->pkg.package_count = count; this->pkg.total_count = total_count; this->pkg.content_size = content_size; return true; } // 获取上级节点 std::vector Abs_Connector::Get_Related_List(void) { return this->related_connector_list; } // 获取产物 const Abs_Connector::Package Abs_Connector::Get_Package(void) { // 输出节点返回直接产物 if (this->type == CONNECTOR_TYPE_OUTPUT) return this->pkg; // 其它情况返回空值 return {}; } // 获取ID int Abs_Connector::Get_ID(void) { return this->id; } // 获取接口类型 Abs_Connector::Connector_Type_Enum Abs_Connector::Get_Type(void) { return this->type; } // 获取套接字字符串 const char *Abs_Connector::Get_Socket_Str(void) { return this->socket_str; } // 默认风格连接点绘制 void Abs_Connector::Show(void) { switch (this->type) { case CONNECTOR_TYPE_OUTPUT: // 常规输出接口 ImNodes::BeginOutputAttribute(this->id, ImNodesPinShape_CircleFilled); ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight())); // 填充高度为字符高度 ImNodes::EndOutputAttribute(); break; case CONNECTOR_TYPE_INPUT: // 常规输入接口 ImNodes::BeginInputAttribute(this->id, ImNodesPinShape_CircleFilled); ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight())); // 填充高度为字符高度 ImNodes::EndInputAttribute(); break; case CONNECTOR_TYPE_INPUT_EXCLUSIVE: // 独占输入接口 ImNodes::PushColorStyle(ImNodesCol_Pin, IM_COL32(50, 120, 160, 160)); // 常规配色 ImNodes::PushColorStyle(ImNodesCol_PinHovered, IM_COL32(0, 110, 175, 255)); // Hover 配色 ImNodes::BeginInputAttribute(this->id, ImNodesPinShape_CircleFilled); ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight())); // 填充高度为字符高度 ImNodes::EndInputAttribute(); ImNodes::PopColorStyle(); ImNodes::PopColorStyle(); break; default: break; } } // ================================================================================================= // 必要构造 Abs_Node::Abs_Node(Independent_ID_Generator *Node_ID_Generator, Independent_ID_Generator *Connector_ID_Generator, Node_Type_Enum type, ImVec2 initial_position) : Node_ID_Generator(nullptr), Connector_ID_Generator(nullptr), id(-1), type(NODE_TYPE_UNKNOWN), initial_position(initial_position) { // 分配ID this->id = Node_ID_Generator->Request_ID(); if (this->id != -1) { this->Node_ID_Generator = Node_ID_Generator; this->Connector_ID_Generator = Connector_ID_Generator; this->type = type; } this->close_flag = false; } // 析构 Abs_Node::~Abs_Node() { // 释放ID this->Node_ID_Generator->Release_ID(this->id); } // 获取ID int Abs_Node::Get_ID(void) { return this->id; } // 获取节点类型 Abs_Node::Node_Type_Enum Abs_Node::Get_Type(void) { return this->type; } // 获取关闭信号 bool Abs_Node::Get_CloseFlag(void) { return this->close_flag; } // 获取节点配置参数 Json_Arry Abs_Node::Get_Arguments(void) { return Json_Arry(); } // 应用配置参数 bool Abs_Node::Apply_Arguments(Json_Arry Arg_Arry) { return true; } // 获取接口列表 std::vector> &Abs_Node::Get_Connector_List(void) { return this->Connector_List; } // ================================================================================================= // 必要构造 Connector_Test_Node::Connector_Test_Node(Independent_ID_Generator *Node_ID_Generator, Independent_ID_Generator *Connector_ID_Generator, ImVec2 initial_position) : Abs_Node(Node_ID_Generator, Connector_ID_Generator, NODE_TYPE_CONNECTOR_TEST, initial_position) { // 判定是否成功申请ID , 后加载测试用节点列表 if (this->id != -1) { // DLT MSG 相关接口 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [0] -> MSG this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [1] MSG -> // Boolean 相关接口 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [2] -> Boolean this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [3] Boolean -> // CSV 相关接口 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [4] -> Column this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [5] Column -> } } // 绘制节点 void Connector_Test_Node::Show(void) { if (this->close_flag == true) return; // 初始化位置设定 if ((this->initial_position.x != 0) || (this->initial_position.y != 0)) { ImNodes::SetNodeScreenSpacePos(this->id, this->initial_position); this->initial_position = ImVec2(0, 0); } // 全宽适配 bool all_width_fit = true; // 绘制节点 ImNodes::BeginNode(this->id); { // 获取节点当前长宽维度 ImVec2 dimension = ImNodes::GetNodeDimensions(this->id); // 标题部分 ImNodes::BeginNodeTitleBar(); { const char *title_str = u8"接口测试用节点"; ImGui::Text(title_str); ImGui::SameLine(); { ImGui::TextDisabled(u8"(?)"); // 上下边距为调整 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f)); if (ImGui::BeginItemTooltip()) { ImGui::Text("Node ID : %d\n", this->id); ImGui::Separator(); ImGui::Text(u8"注意!仅供接口测试使用!\n该节点不会进行任何处理操作\n有成对接口时会将输入接口连接的首个接口输入包转发到对应的出口"); ImGui::EndTooltip(); } ImGui::PopStyleVar(); } ImGui::SameLine(); // 节点宽度调整 auto button_diameter = ImGui::GetTextLineHeight(); auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x; auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2; // 宽度判定 if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x) all_width_fit = false; ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f)); ImGui::SameLine(); // 绘制关闭按钮 if (CircleButtonWithX("#X", ImGui::GetTextLineHeight() / 2)) this->close_flag = true; } ImNodes::EndNodeTitleBar(); // 节点主体绘制 { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y)); // 绘制DLT相关接口组 { // 宽度判定 auto text_width = ImGui::CalcTextSize("-> DLT-In").x + ImGui::CalcTextSize("DLT-Out ->").x; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2) all_width_fit = false; this->Connector_List[0]->Show(); ImGui::SameLine(); ImGui::Text("-> DLT-In"); ImGui::SameLine(); ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f)); ImGui::SameLine(); ImGui::Text("DLT-Out ->"); ImGui::SameLine(); this->Connector_List[1]->Show(); } // 绘制Boolean相关接口 { // 宽度判定 auto text_width = ImGui::CalcTextSize("-> Boolean-In").x + ImGui::CalcTextSize("Boolean-Out ->").x; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2) all_width_fit = false; this->Connector_List[2]->Show(); ImGui::SameLine(); ImGui::Text("-> Boolean-In"); ImGui::SameLine(); ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f)); ImGui::SameLine(); ImGui::Text("Boolean-Out ->"); ImGui::SameLine(); this->Connector_List[3]->Show(); } // 绘制CSV列相关接口组 { // 宽度判定 auto text_width = ImGui::CalcTextSize("-> CSV-Column-In").x + ImGui::CalcTextSize("CSV-Column-Out ->").x; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x) all_width_fit = false; if (this->node_width == 0) this->node_width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x; this->Connector_List[4]->Show(); ImGui::SameLine(); ImGui::Text("-> CSV-Column-In"); ImGui::SameLine(); ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f)); ImGui::SameLine(); ImGui::Text("CSV-Column-Out ->"); ImGui::SameLine(); this->Connector_List[5]->Show(); } ImGui::PopStyleVar(); } // 使用递进的方式自适应宽度 if (all_width_fit == false) this->node_width += 1.0f; } ImNodes::EndNode(); } // 执行处理流程 bool Connector_Test_Node::Execute_Process(void) { // DLT MSG 相关接口 if (!this->Connector_List[0]->Get_Related_List().empty()) { // [0] -> MSG // [1] MSG -> auto pkg = this->Connector_List[0]->Get_Related_List()[0]->Get_Package(); this->Connector_List[1]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count); } else this->Connector_List[1]->Register_Package(nullptr, 0, 0, 0); // Boolean 相关接口 if (!this->Connector_List[2]->Get_Related_List().empty()) { // [2] -> Boolean // [3] Boolean -> auto pkg = this->Connector_List[2]->Get_Related_List()[0]->Get_Package(); this->Connector_List[3]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count); } else this->Connector_List[3]->Register_Package(nullptr, 0, 0, 0); // CSV 相关接口 if (!this->Connector_List[4]->Get_Related_List().empty()) { // [4] -> Column // [5] Column -> auto pkg = this->Connector_List[4]->Get_Related_List()[0]->Get_Package(); this->Connector_List[5]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count); } else this->Connector_List[5]->Register_Package(nullptr, 0, 0, 0); return true; } // 必要构造 MSG_Input_Node::MSG_Input_Node(Independent_ID_Generator *Node_ID_Generator, Independent_ID_Generator *Connector_ID_Generator, ImVec2 initial_position) : Abs_Node(Node_ID_Generator, Connector_ID_Generator, NODE_TYPE_MSG_LINE_INPUT, initial_position) { // 判定是否成功申请ID if (this->id != -1) { // 消息输出节点 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [0] -> MSG } } // 绘制节点 void MSG_Input_Node::Show(void) { if (this->close_flag == true) return; // 初始化位置设定 if ((this->initial_position.x != 0) || (this->initial_position.y != 0)) { ImNodes::SetNodeScreenSpacePos(this->id, this->initial_position); this->initial_position = ImVec2(0, 0); } // 全宽适配 bool all_width_fit = true; // 绘制节点 ImNodes::BeginNode(this->id); { // 标题部分 ImNodes::BeginNodeTitleBar(); { const char *title_str = u8"DLT-信息输入节点"; ImGui::Text(title_str); ImGui::SameLine(); { ImGui::TextDisabled(u8"(?)"); // 上下边距为调整 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f)); if (ImGui::BeginItemTooltip()) { ImGui::Text("Node ID : %d\n", this->id); ImGui::Separator(); ImGui::Text(u8"每个处理流程开始时,输出一条DLT消息;\n每个此类节点输出的消息均会独立遍历所有输入文件;"); ImGui::EndTooltip(); } ImGui::PopStyleVar(); } ImGui::SameLine(); // 节点宽度调整 ImVec2 dimension = ImNodes::GetNodeDimensions(this->id); auto button_diameter = ImGui::GetTextLineHeight(); auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x; auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2; if (this->node_width == 0) this->node_width = Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x; if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x) all_width_fit = false; ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f)); ImGui::SameLine(); // 绘制关闭按钮 if (CircleButtonWithX("#X", button_diameter / 2)) this->close_flag = true; } ImNodes::EndNodeTitleBar(); // 节点主体部分 { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y)); // 靠右占位 ImVec2 dimension = ImNodes::GetNodeDimensions(this->id); auto text_width = ImGui::CalcTextSize(u8"DLT-Out ->").x; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2) all_width_fit = false; ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f)); ImGui::SameLine(); // 绘制DLT输出接口 ImGui::Text(u8"DLT-Out ->"); ImGui::SameLine(); this->Connector_List[0]->Show(); ImGui::PopStyleVar(); } // 使用递进的方式自适应宽度 if (all_width_fit == false) this->node_width += 1.0f; } ImNodes::EndNode(); } // 执行处理流程 bool MSG_Input_Node::Execute_Process(void) { // 未开始执行时 if (this->excute_flag == false) { private_finish_flag = false; // 错误信息 std::string err_str; const char *err_filename_str = nullptr; // 循环加载文件 Input_File_Node *p_file_list = input_dlt_file_list_head; while (p_file_list != nullptr) { err_str = this->log.Load_From_File(p_file_list->file_name_str); if (!err_str.empty()) { err_filename_str = p_file_list->file_name_str; break; } p_file_list = p_file_list->p_next; } // 输出错误信息 if (!err_str.empty()) { // 工具Lambda string 转 wstring auto Lambda_String_To_WString = [](const std::string &str) -> std::wstring { if (str.empty()) return std::wstring(); int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0); if (len <= 0) return std::wstring(); std::wstring wstr(len, L'\0'); MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstr[0], len); return wstr; }; // 输出错误信息 MessageBoxW(Main_Window_hWnd, (L"文件\"" + Lambda_String_To_WString(std::string(err_filename_str)) + L"\"读取失败\n" + Lambda_String_To_WString(err_str)).c_str(), L"", MB_OK | MB_ICONERROR); return false; } // 排序后消息处理 this->log.Sort(); this->excute_flag = true; this->private_excute_count = 0; this->private_excute_end_count = this->log.msg_list.size(); } // 注册接口包,执行期间不可以释放log,否则传入的产物中vector会虚空索引 if (this->private_excute_count < this->private_excute_end_count) { // [0] -> MSG this->Connector_List[0]->Register_Package((void *)&(this->log.msg_list[this->private_excute_count]), sizeof(this->log.msg_list[0]), this->private_excute_count + 1, this->excute_end_count); this->private_excute_count++; } else { this->log.Clear(); this->excute_flag = false; this->private_excute_count = 0; this->private_excute_end_count = 0; this->private_finish_flag = true; } return true; }; // 必要构造 Filter_Node::Filter_Node(Independent_ID_Generator *Node_ID_Generator, Independent_ID_Generator *Connector_ID_Generator, ImVec2 initial_position) : Abs_Node(Node_ID_Generator, Connector_ID_Generator, NODE_TYPE_FILTER, initial_position) { // 判定是否成功申请ID if (this->id != -1) { // Boolean 输入节点 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [0] -> Boolean // 消息输出节点 this->Connector_List.push_back(std::make_shared(Connector_ID_Generator, true)); // [1] -> MSG this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [2] MSG -> } } // 绘制节点 void Filter_Node::Show(void) { if (this->close_flag == true) return; // 初始化位置设定 if ((this->initial_position.x != 0) || (this->initial_position.y != 0)) { ImNodes::SetNodeScreenSpacePos(this->id, this->initial_position); this->initial_position = ImVec2(0, 0); } // 全宽适配 bool all_width_fit = true; // 绘制节点 ImNodes::BeginNode(this->id); { // 获取节点当前长宽维度 ImVec2 dimension = ImNodes::GetNodeDimensions(this->id); // 标题部分 ImNodes::BeginNodeTitleBar(); { const char *title_str = u8"消息筛选器"; ImGui::Text(title_str); ImGui::SameLine(); { ImGui::TextDisabled(u8"(?)"); // 上下边距为调整 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f)); if (ImGui::BeginItemTooltip()) { ImGui::Text("Node ID : %d\n", this->id); ImGui::Separator(); ImGui::Text(u8"对传入的MSG进行筛选\n不满足条件时将输出一个空包\n任意Boolean传入为真都会放行传入的MSG"); ImGui::EndTooltip(); } ImGui::PopStyleVar(); } ImGui::SameLine(); // 节点宽度调整 ImVec2 dimension = ImNodes::GetNodeDimensions(this->id); auto button_diameter = ImGui::GetTextLineHeight(); auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x; // auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2; auto Tittle_Str_Width = text_width + ImGui::GetStyle().ItemSpacing.x * 2; // 不知道为什么这里加上 NodePadding.x * 2 反而不对了 // 宽度判定 if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x) all_width_fit = false; ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f)); ImGui::SameLine(); // 绘制关闭按钮 if (CircleButtonWithX("#X", button_diameter / 2)) this->close_flag = true; } ImNodes::EndNodeTitleBar(); // 节点主体部分 { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y)); // 绘制Boolean 输入接口 { auto text_width = ImGui::CalcTextSize("-> Boolean [Pass allow]").x; // 宽度初始化 if (this->node_width == 0) this->node_width = text_width; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2) all_width_fit = false; this->Connector_List[0]->Show(); ImGui::SameLine(); ImGui::Text("-> Boolean "); ImGui::SameLine(); ImGui::TextDisabled(u8"[Pass allow]"); } // 绘制DLT相关接口组 { // 宽度判定 auto text_width = ImGui::CalcTextSize("-> DLT-In").x + ImGui::CalcTextSize("DLT-Out ->").x; if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x) all_width_fit = false; this->Connector_List[1]->Show(); ImGui::SameLine(); ImGui::Text("-> DLT-In"); ImGui::SameLine(); // ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f)); ImGui::Dummy(ImVec2(this->node_width - text_width, 0.0f)); // 不知道为什么这里加上 NodePadding.x * 2 反而不对了 ImGui::SameLine(); ImGui::Text("DLT-Out ->"); ImGui::SameLine(); this->Connector_List[2]->Show(); } ImGui::PopStyleVar(); } // 使用递进的方式自适应宽度 if (all_width_fit == false) this->node_width += 1.0f; } ImNodes::EndNode(); } // 执行处理流程 bool Filter_Node::Execute_Process(void) { bool pass_allow = false; for (auto input : this->Connector_List[0]->Get_Related_List()) { auto pkg = input->Get_Package(); if ((pkg.content_size != 0) && ((*((bool *)pkg.p_content_mem)) == true)) { pass_allow = true; break; } } if (pass_allow) { auto pkg = this->Connector_List[1]->Get_Package(); this->Connector_List[2]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count); } else this->Connector_List[2]->Register_Package(nullptr, 0, 0, 0); return true; } // END