#pragma once #include "BaseTheme.h" #include #include #include namespace XCEngine { namespace Editor { namespace UI { class ImGuiSession { public: void Initialize(const std::string& projectPath, float mainDpiScale = 1.0f) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.ConfigDpiScaleFonts = true; io.ConfigDpiScaleViewports = true; ConfigureIniFile(projectPath, io); ConfigureStyle(ImGui::GetStyle(), mainDpiScale); ConfigureFonts(io); } void Shutdown() { SaveSettings(); if (ImGui::GetCurrentContext() != nullptr) { ImGui::DestroyContext(); } m_iniPath.clear(); } void SaveSettings() const { if (m_iniPath.empty() || ImGui::GetCurrentContext() == nullptr) { return; } ImGui::SaveIniSettingsToDisk(m_iniPath.c_str()); } const std::string& GetIniPath() const { return m_iniPath; } void SetProjectPath(const std::string& projectPath) { if (ImGui::GetCurrentContext() == nullptr) { return; } SaveSettings(); ImGuiIO& io = ImGui::GetIO(); ConfigureIniFile(projectPath, io); ImGui::LoadIniSettingsFromDisk(m_iniPath.c_str()); } private: static constexpr float kUiFontSize = 18.0f; static constexpr const char* kPrimaryUiFontPath = "C:/Windows/Fonts/segoeui.ttf"; static constexpr const char* kChineseFallbackFontPath = "C:/Windows/Fonts/msyh.ttc"; void ConfigureIniFile(const std::string& projectPath, ImGuiIO& io) { const std::filesystem::path configDir = std::filesystem::path(projectPath) / ".xceditor"; std::error_code ec; std::filesystem::create_directories(configDir, ec); m_iniPath = (configDir / "imgui_layout.ini").string(); io.IniFilename = m_iniPath.c_str(); } void ConfigureStyle(ImGuiStyle& style, float mainDpiScale) const { ApplyBaseTheme(style); const float dpiScale = mainDpiScale < 1.0f ? 1.0f : (mainDpiScale > 4.0f ? 4.0f : mainDpiScale); style.ScaleAllSizes(dpiScale); style.FontScaleDpi = dpiScale; } void ConfigureFonts(ImGuiIO& io) const { ImFontAtlas* atlas = io.Fonts; atlas->Clear(); ImFontConfig baseConfig; baseConfig.OversampleH = 2; baseConfig.OversampleV = 1; baseConfig.PixelSnapH = true; ImFont* uiFont = atlas->AddFontFromFileTTF( kPrimaryUiFontPath, kUiFontSize, &baseConfig, atlas->GetGlyphRangesDefault()); if (uiFont) { ImFontConfig mergeConfig = baseConfig; mergeConfig.MergeMode = true; mergeConfig.PixelSnapH = true; atlas->AddFontFromFileTTF( kChineseFallbackFontPath, kUiFontSize, &mergeConfig, atlas->GetGlyphRangesChineseSimplifiedCommon()); } else { uiFont = atlas->AddFontFromFileTTF( kChineseFallbackFontPath, kUiFontSize, &baseConfig, atlas->GetGlyphRangesChineseSimplifiedCommon()); } if (!uiFont) { ImFontConfig fallbackConfig = baseConfig; fallbackConfig.SizePixels = kUiFontSize; uiFont = atlas->AddFontDefault(&fallbackConfig); } io.FontDefault = uiFont; } std::string m_iniPath; }; } // namespace UI } // namespace Editor } // namespace XCEngine