#include "../include/SerialApp.h" #include "imgui.h" #include #include #include #include SerialApp::SerialApp() : should_close(false) {} void SerialApp::Initialize() { connection_window.Initialize(); // Загружаем тему при старте. Если лежит в корне сборки — просто имя файла. if (!LoadTheme("dracula.theme")) { // Если файла нет, оставляем стандартную тему ImGui, чтобы приложение не упало ImGui::StyleColorsDark(); } } // Вспомогательная функция перевода HEX строки (например, "282a36ff") в ImVec4 static ImVec4 HexToImVec4(const std::string& hex_str) { if (hex_str.length() < 8) return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); unsigned int r, g, b, a; std::stringstream ss; ss << std::hex << hex_str.substr(0, 2); ss >> r; ss.clear(); ss << std::hex << hex_str.substr(2, 2); ss >> g; ss.clear(); ss << std::hex << hex_str.substr(4, 2); ss >> b; ss.clear(); ss << std::hex << hex_str.substr(6, 2); ss >> a; return ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); } bool SerialApp::LoadTheme(const std::string& filepath) { std::ifstream file(filepath); if (!file.is_open()) { std::cerr << "[THEME ERROR] Файл темы не найден: " << filepath << std::endl; return false; } ImGuiStyle& style = ImGui::GetStyle(); // Карта сопоставления строк из файла конфигурации и индексов цветов ImGui std::unordered_map color_map = { {"Color_Text", ImGuiCol_Text}, {"Color_WindowBg", ImGuiCol_WindowBg}, {"Color_ChildBg", ImGuiCol_ChildBg}, {"Color_PopupBg", ImGuiCol_PopupBg}, {"Color_Border", ImGuiCol_Border}, {"Color_FrameBg", ImGuiCol_FrameBg}, {"Color_FrameBgHovered", ImGuiCol_FrameBgHovered}, {"Color_FrameBgActive", ImGuiCol_FrameBgActive}, {"Color_TitleBg", ImGuiCol_TitleBg}, {"Color_TitleBgActive", ImGuiCol_TitleBgActive}, {"Color_MenuBarBg", ImGuiCol_MenuBarBg}, {"Color_ScrollbarBg", ImGuiCol_ScrollbarBg}, {"Color_ScrollbarGrab", ImGuiCol_ScrollbarGrab}, {"Color_ScrollbarGrabHovered", ImGuiCol_ScrollbarGrabHovered}, {"Color_ScrollbarGrabActive", ImGuiCol_ScrollbarGrabActive}, {"Color_CheckMark", ImGuiCol_CheckMark}, {"Color_SliderGrab", ImGuiCol_SliderGrab}, {"Color_SliderGrabActive", ImGuiCol_SliderGrabActive}, {"Color_Button", ImGuiCol_Button}, {"Color_ButtonHovered", ImGuiCol_ButtonHovered}, {"Color_ButtonActive", ImGuiCol_ButtonActive}, {"Color_Header", ImGuiCol_Header}, {"Color_HeaderHovered", ImGuiCol_HeaderHovered}, {"Color_HeaderActive", ImGuiCol_HeaderActive}, {"Color_Separator", ImGuiCol_Separator} }; std::string line; while (std::getline(file, line)) { // Пропускаем пустые строки и комментарии if (line.empty() || line[0] == '#') continue; std::stringstream ss(line); std::string key; ss >> key; if (key.rfind("Color_", 0) == 0) { // Читаем HEX цвета std::string hex_val; ss >> hex_val; if (color_map.find(key) != color_map.end()) { style.Colors[color_map[key]] = HexToImVec4(hex_val); } } else { // Читаем размеры скруглений float val; ss >> val; if (key == "WindowRounding") style.WindowRounding = val; else if (key == "FrameRounding") style.FrameRounding = val; else if (key == "PopupRounding") style.PopupRounding = val; else if (key == "GrabRounding") style.GrabRounding = val; } } file.close(); return true; } void SerialApp::RenderUI() { RenderMainMenuBar(); if (show_connection_window) { connection_window.Render(&show_connection_window); } if (show_payload_window) { payload_window.Render(&show_payload_window, connection_window); } if (show_log_window) { log_window.Render(&show_log_window, connection_window); } } void SerialApp::RenderMainMenuBar() { if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Exit", "Alt+F4")) { should_close = true; } ImGui::EndMenu(); } if (ImGui::BeginMenu("Windows")) { ImGui::MenuItem("1. Connection Settings", nullptr, &show_connection_window); ImGui::MenuItem("2. Raw Payload Terminal", nullptr, &show_payload_window); ImGui::MenuItem("3. Transaction Log", nullptr, &show_log_window); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); } }