269 lines
12 KiB
C++
269 lines
12 KiB
C++
#include "UI_Layout.hpp"
|
|
#include "imgui_impl_win32.h"
|
|
#include "Global_Variables.hpp"
|
|
#include "Config.hpp"
|
|
|
|
extern "C"
|
|
{
|
|
#include "windows.h"
|
|
#include "stdio.h"
|
|
}
|
|
|
|
// UI布局
|
|
void UI_Layout()
|
|
{
|
|
// 配置窗口绘制位置为Dear ImGUI生成的主窗口
|
|
const ImGuiViewport *viewport = ImGui::GetMainViewport();
|
|
// 下一个窗体绘制到主窗体位置
|
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
|
// 下一个窗体绘制为主窗体大小
|
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
|
// 设置下一个焦点窗体为主窗体
|
|
ImGui::SetNextWindowViewport(viewport->ID);
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); // 绘制风格栈压入窗口圆角为0
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); // 绘制风格栈压入窗体边框宽度为0
|
|
|
|
// 窗体选项配置
|
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_None;
|
|
// 设置窗体相关属性,无标题栏,无折叠标志,不可重塑大小,不可移动
|
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
|
// 设置窗体相关属性,收到焦点时不移动到前台,禁用焦点事件
|
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
|
// 设置窗体相关属性,不允许停靠
|
|
window_flags |= ImGuiWindowFlags_NoDocking;
|
|
|
|
ImGui::Begin("Main Panel", NULL, window_flags); // 创建主面板
|
|
ImGui::PopStyleVar(2); // 退出绘制风格栈中的设置项
|
|
{
|
|
|
|
// 拖拽输入区域
|
|
Widgets::Drag_Input_Area(ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().x / 2));
|
|
|
|
// 文件列表组件
|
|
Widgets::File_List_Area();
|
|
}
|
|
ImGui::End();
|
|
|
|
ImGui::ShowDemoWindow(nullptr);
|
|
}
|
|
|
|
void Widgets::Drag_Input_Area(const ImVec2 &size)
|
|
{
|
|
ImGui::BeginChild("Drag_Drop_Area", size);
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 10.0f); // 绘制风格栈压入窗口圆角为0
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
|
|
// 显示一个按钮,作为拖拽源
|
|
static bool pressed_hover = false;
|
|
|
|
if (ImGui::Button(pressed_hover ? u8"松开左键以添加" : u8"单击选择文件或拖拽文件到此处", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y)))
|
|
{
|
|
OPENFILENAMEW ofn; // common dialog box structure
|
|
wchar_t szFile[MAX_PATH * MAX_SINGLE_SELECT_FILE_COUNT] = {L'\0'}; // buffer for file name
|
|
|
|
// Initialize OPENFILENAME
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = Main_Window_hWnd;
|
|
ofn.lpstrFile = szFile;
|
|
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
|
|
// use the contents of szFile to initialize itself.
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFilter = L"(.dlt)\0*.dlt\0";
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.nMaxFileTitle = 0;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
|
|
|
|
// Display the Open dialog box.
|
|
|
|
// 处理文件输入
|
|
if (GetOpenFileNameW(&ofn) == TRUE)
|
|
{
|
|
// 重复输入检测
|
|
bool with_duplicated_input = false;
|
|
|
|
wchar_t *p_first_str = ofn.lpstrFile;
|
|
// 单文件
|
|
if ((p_first_str[wcslen(p_first_str)] == L'\0') && (p_first_str[wcslen(p_first_str) + 1] == L'\0'))
|
|
{
|
|
char file_path_multi_byte[MAX_PATH] = {'\0'};
|
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, NULL, 0, NULL, NULL);
|
|
WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, file_path_multi_byte, size_needed, NULL, NULL);
|
|
|
|
for (Input_File_Node *p_file_node = input_dlt_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
|
|
if (!strcmp(p_file_node->file_name_str, file_path_multi_byte))
|
|
{
|
|
with_duplicated_input = true;
|
|
break;
|
|
}
|
|
if (with_duplicated_input)
|
|
{
|
|
MessageBoxW(Main_Window_hWnd, L"存在重复输入", L"", MB_OK);
|
|
}
|
|
else
|
|
{
|
|
|
|
// 开辟新文件节点
|
|
Input_File_Node *p_new_file_node = (Input_File_Node *)malloc(sizeof(Input_File_Node));
|
|
p_new_file_node->file_name_str = (char *)malloc(strlen(file_path_multi_byte) + 1);
|
|
memset(p_new_file_node->file_name_str, '\0', strlen(file_path_multi_byte) + 1);
|
|
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte) + 1);
|
|
p_new_file_node->p_next = nullptr;
|
|
|
|
// 插入文件列表
|
|
if (input_dlt_file_list_head == nullptr)
|
|
input_dlt_file_list_head = p_new_file_node;
|
|
else
|
|
{
|
|
Input_File_Node *p_target_node = input_dlt_file_list_head;
|
|
for (size_t count = 1; count < input_dlt_file_count; count++)
|
|
p_target_node = p_target_node->p_next;
|
|
|
|
p_target_node->p_next = p_new_file_node;
|
|
}
|
|
|
|
input_dlt_file_count++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 多文件输入时
|
|
char public_path_multi_byte[MAX_PATH] = {'\0'};
|
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, NULL, 0, NULL, NULL);
|
|
WideCharToMultiByte(CP_UTF8, 0, p_first_str, -1, public_path_multi_byte, size_needed, NULL, NULL);
|
|
|
|
for (wchar_t *p_file_name_str = ofn.lpstrFile + wcslen(ofn.lpstrFile) + 1; *p_file_name_str != L'\0'; p_file_name_str += (wcslen(p_file_name_str) + 1))
|
|
{
|
|
char file_name_multi_byte[MAX_PATH] = {'\0'};
|
|
char file_path_multi_byte[MAX_PATH] = {'\0'};
|
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, p_file_name_str, -1, NULL, 0, NULL, NULL);
|
|
WideCharToMultiByte(CP_UTF8, 0, p_file_name_str, -1, file_name_multi_byte, size_needed, NULL, NULL);
|
|
|
|
// 拼接完整路径
|
|
sprintf(file_path_multi_byte, "%s\\%s", public_path_multi_byte, file_name_multi_byte);
|
|
|
|
for (Input_File_Node *p_file_node = input_dlt_file_list_head; p_file_node != nullptr; p_file_node = p_file_node->p_next)
|
|
if (!strcmp(p_file_node->file_name_str, file_path_multi_byte))
|
|
{
|
|
with_duplicated_input = true;
|
|
break;
|
|
}
|
|
if (with_duplicated_input)
|
|
continue;
|
|
|
|
// 开辟新文件节点
|
|
Input_File_Node *p_new_file_node = (Input_File_Node *)malloc(sizeof(Input_File_Node));
|
|
p_new_file_node->file_name_str = (char *)malloc(strlen(file_path_multi_byte) + 1);
|
|
memset(p_new_file_node->file_name_str, '\0', strlen(file_path_multi_byte) + 1);
|
|
memcpy(p_new_file_node->file_name_str, file_path_multi_byte, strlen(file_path_multi_byte) + 1);
|
|
p_new_file_node->p_next = nullptr;
|
|
|
|
// 插入文件列表
|
|
if (input_dlt_file_list_head == nullptr)
|
|
input_dlt_file_list_head = p_new_file_node;
|
|
else
|
|
{
|
|
Input_File_Node *p_target_node = input_dlt_file_list_head;
|
|
for (size_t count = 1; count < input_dlt_file_count; count++)
|
|
p_target_node = p_target_node->p_next;
|
|
|
|
p_target_node->p_next = p_new_file_node;
|
|
}
|
|
|
|
input_dlt_file_count++;
|
|
}
|
|
|
|
if (with_duplicated_input)
|
|
{
|
|
MessageBoxW(Main_Window_hWnd, L"存在重复输入", L"", MB_OK);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// 仅在外部拖拽入内时触发,内部拖拽不触发
|
|
pressed_hover = (ImGui::IsItemHovered() && (GetAsyncKeyState(VK_LBUTTON) < 0) && (!ImGui::IsMouseDown(ImGuiMouseButton_Left)));
|
|
|
|
ImGui::PopStyleVar(2);
|
|
}
|
|
ImGui::EndChild();
|
|
}
|
|
|
|
void Widgets::File_List_Area(const ImVec2 &size)
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 10.0f);
|
|
ImGui::BeginChild("File_List_Area_Wrapper", ImVec2(size.x, size.y), ImGuiChildFlags_Border);
|
|
ImGui::PopStyleVar();
|
|
{
|
|
|
|
int element_id = 0;
|
|
Input_File_Node *p_file_node_pre = nullptr;
|
|
Input_File_Node *p_file_node = input_dlt_file_list_head;
|
|
for (size_t count = 0; count < input_dlt_file_count; count++)
|
|
{
|
|
ImGui::PushID(element_id++);
|
|
|
|
// 点击了删除
|
|
if (ImGui::Button("X"))
|
|
{
|
|
if (p_file_node == input_dlt_file_list_head)
|
|
{
|
|
free(input_dlt_file_list_head->file_name_str);
|
|
input_dlt_file_list_head = input_dlt_file_list_head->p_next;
|
|
free(p_file_node);
|
|
p_file_node = input_dlt_file_list_head;
|
|
}
|
|
else
|
|
{
|
|
p_file_node_pre->p_next = p_file_node->p_next;
|
|
free(p_file_node->file_name_str);
|
|
free(p_file_node);
|
|
}
|
|
input_dlt_file_count--;
|
|
count--;
|
|
ImGui::PopID();
|
|
continue;
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
|
ImGui::InputText("##Text_Show", p_file_node->file_name_str, strlen(p_file_node->file_name_str) + 1, ImGuiInputTextFlags_ElideLeft | ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_NoUndoRedo);
|
|
|
|
ImGui::PopID();
|
|
|
|
p_file_node = p_file_node->p_next;
|
|
if (count == 0)
|
|
p_file_node_pre = input_dlt_file_list_head;
|
|
else
|
|
p_file_node_pre = p_file_node_pre->p_next;
|
|
}
|
|
}
|
|
ImGui::EndChild();
|
|
}
|
|
|
|
void Widgets::Workflow_Area(const ImVec2 &size)
|
|
{
|
|
ImNodes::BeginNodeEditor();
|
|
{
|
|
|
|
ImNodes::BeginNode(1);
|
|
|
|
ImNodes::BeginNodeTitleBar();
|
|
ImGui::TextUnformatted("output node");
|
|
ImNodes::EndNodeTitleBar();
|
|
|
|
ImGui::Text("Test Format %%d :%d", 123);
|
|
|
|
ImGui::Button("Click");
|
|
|
|
ImGui::SameLine();
|
|
static bool check = false;
|
|
ImGui::Checkbox("", &check);
|
|
|
|
ImNodes::EndNode();
|
|
}
|
|
ImNodes::EndNodeEditor();
|
|
} |