From 59e2ba20033e3d114d80b703105a81cdb15501ae Mon Sep 17 00:00:00 2001 From: soda3000 Date: Mon, 22 Sep 2025 15:54:27 -0300 Subject: [PATCH 1/2] feat(ui): font size and perf overlay improvements --- src/Features/PerformanceOverlay.cpp | 43 +++++++++++++++++++++++++++++ src/Features/PerformanceOverlay.h | 4 +++ src/Menu.cpp | 32 +++++++++------------ src/Menu.h | 2 +- src/Menu/OverlayRenderer.cpp | 2 +- src/Menu/OverlayRenderer.h | 2 +- src/Menu/SettingsTabRenderer.cpp | 36 ++++++++++++++++++++++++ src/Menu/ThemeManager.cpp | 28 +++++++++++++++++-- src/Menu/ThemeManager.h | 3 ++ 9 files changed, 127 insertions(+), 25 deletions(-) diff --git a/src/Features/PerformanceOverlay.cpp b/src/Features/PerformanceOverlay.cpp index 0cbc489e83..e15d049192 100644 --- a/src/Features/PerformanceOverlay.cpp +++ b/src/Features/PerformanceOverlay.cpp @@ -204,6 +204,13 @@ void PerformanceOverlay::DrawSettings() if (ImGui::Button("Reset Position")) { this->settings.PositionSet = false; } + ImGui::SameLine(); + if (ImGui::Button("Restore Defaults")) { + RestoreDefaultSettings(); + } + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::TextUnformatted("Restores Performance Overlay settings to defaults, including graphs, appearance, and update intervals."); + } ImGui::Unindent(); } @@ -211,6 +218,42 @@ void PerformanceOverlay::DrawSettings() } } +void PerformanceOverlay::SaveSettings(json& j) +{ + // Persist all overlay settings to JSON + j = this->settings; // uses NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT +} + +void PerformanceOverlay::LoadSettings(json& j) +{ + try { + // Load all settings from JSON (missing fields use defaults) + this->settings = j.get(); + } catch (...) { + // Fallback to defaults if JSON is invalid + this->settings = PerformanceOverlay::Settings{}; + } + // Ensure history buffers match loaded size + this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); +} + +void PerformanceOverlay::RestoreDefaultSettings() +{ + this->settings = PerformanceOverlay::Settings{}; + // Reset runtime buffers/state to match defaults + this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.smoothFps = 0.0f; + this->state.smoothFrameTimeMs = 0.0f; + this->state.postFGSmoothFps = 0.0f; + this->state.postFGSmoothFrameTimeMs = 0.0f; + this->state.minFrameTime = 1000.0f; + this->state.maxFrameTime = 0.0f; + this->state.smoothedMinFrameTime = 0.0f; + this->state.smoothedMaxFrameTime = 50.0f; +} + void PerformanceOverlay::DataLoaded() { // Initialize performance overlay state diff --git a/src/Features/PerformanceOverlay.h b/src/Features/PerformanceOverlay.h index 083d1724fd..a86fb5a052 100644 --- a/src/Features/PerformanceOverlay.h +++ b/src/Features/PerformanceOverlay.h @@ -129,6 +129,10 @@ struct PerformanceOverlay : OverlayFeature virtual void DrawSettings() override; virtual void DataLoaded() override; void DrawOverlay() override; + // Settings persistence and defaults + void SaveSettings(json& j) override; + void LoadSettings(json& j) override; + void RestoreDefaultSettings() override; // ============================================================================ // CORE PERFORMANCE DISPLAY FUNCTIONS diff --git a/src/Menu.cpp b/src/Menu.cpp index 0f93d51913..d7968d19b5 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -176,17 +176,8 @@ void Menu::Init() DXGI_SWAP_CHAIN_DESC desc{}; globals::d3d::swapChain->GetDesc(&desc); - float fontSize = settings.Theme.FontSize; - - if (std::round(fontSize) != std::round(ThemeManager::Constants::DEFAULT_FONT_SIZE)) { - if (globals::state->screenSize.y > 0) { - fontSize = globals::state->screenSize.y * ThemeManager::Constants::DEFAULT_FONT_RATIO; - } else { - logger::warn("Menu::Init() - Failed to get game resolution from globals::state->screenSize."); - } - } - - fontSize = std::clamp(fontSize, ThemeManager::Constants::MIN_FONT_SIZE, ThemeManager::Constants::MAX_FONT_SIZE); + // Determine effective font size: user setting when >0, otherwise dynamic default by resolution + float fontSize = ThemeManager::ResolveFontSize(*this); auto fontPath = Util::PathHelpers::GetFontsPath() / "Jost-Regular.ttf"; if (!imgui_io.Fonts->AddFontFromFileTTF(fontPath.string().c_str(), @@ -195,7 +186,10 @@ void Menu::Init() imgui_io.Fonts->AddFontDefault(); } - imgui_io.FontGlobalScale = exp2(settings.Theme.GlobalScale); + imgui_io.FontGlobalScale = exp2(settings.Theme.GlobalScale); + + // Initialize cached font size to effective size to prevent redundant reload on first frame + cachedFontSize = fontSize; // Setup Platform/Renderer backends ImGui_ImplWin32_Init(desc.OutputWindow); @@ -417,13 +411,13 @@ void Menu::DrawFooter() */ void Menu::DrawOverlay() { - OverlayRenderer::RenderOverlay( - *this, - [this]() { ProcessInputEventQueue(); }, - [this]() { DrawSettings(); }, - [](uint32_t key) { return Util::Input::KeyIdToString(key); }, - cachedFontSize, - settings.Theme.FontSize); + OverlayRenderer::RenderOverlay( + *this, + [this]() { ProcessInputEventQueue(); }, + [this]() { DrawSettings(); }, + [](uint32_t key) { return Util::Input::KeyIdToString(key); }, + cachedFontSize, + ThemeManager::ResolveFontSize(*this)); } /** diff --git a/src/Menu.h b/src/Menu.h index ca9c31e6a5..a165f6a0d8 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -99,7 +99,7 @@ class Menu struct ThemeSettings { - float FontSize = ThemeManager::Constants::DEFAULT_FONT_SIZE; + float FontSize = 0.0f; // When 0, dynamic default (resolution-based) is used float GlobalScale = REL::Module::IsVR() ? -0.5f : 0.f; // exponential bool UseSimplePalette = true; // simple palette or full customization diff --git a/src/Menu/OverlayRenderer.cpp b/src/Menu/OverlayRenderer.cpp index ac0c73dda8..e08abca32f 100644 --- a/src/Menu/OverlayRenderer.cpp +++ b/src/Menu/OverlayRenderer.cpp @@ -21,7 +21,7 @@ void OverlayRenderer::RenderOverlay( const std::function& processInputEventQueue, const std::function& drawSettings, const std::function& keyIdToString, - float cachedFontSize, + float& cachedFontSize, float currentFontSize) { HandleVRSetup(); diff --git a/src/Menu/OverlayRenderer.h b/src/Menu/OverlayRenderer.h index e5010395af..99b6157c97 100644 --- a/src/Menu/OverlayRenderer.h +++ b/src/Menu/OverlayRenderer.h @@ -40,7 +40,7 @@ class OverlayRenderer const std::function& processInputEventQueue, const std::function& drawSettings, const std::function& keyIdToString, - float cachedFontSize, + float& cachedFontSize, float currentFontSize); private: diff --git a/src/Menu/SettingsTabRenderer.cpp b/src/Menu/SettingsTabRenderer.cpp index 9dc95ff51e..5cd10ab5da 100644 --- a/src/Menu/SettingsTabRenderer.cpp +++ b/src/Menu/SettingsTabRenderer.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "Menu.h" +#include "ThemeManager.h" #include "ShaderCache.h" #include "Util.h" @@ -141,6 +142,17 @@ void SettingsTabRenderer::RenderKeybindingsTab( void SettingsTabRenderer::RenderInterfaceTab() { if (ImGui::BeginTabItem("Interface")) { + // Restore theme defaults button + if (ImGui::Button("Restore Theme Defaults")) { + auto& settings = globals::menu->GetSettings(); + settings.Theme = Menu::ThemeSettings{}; // reset to default-initialized theme + // Apply global font scale immediately + ImGui::GetIO().FontGlobalScale = exp2(settings.Theme.GlobalScale); + } + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::TextUnformatted("Resets UI sizes, colors and options to their defaults (including resolution-based font size)."); + } + if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None)) { RenderUIOptionsTab(); RenderSizesTab(); @@ -186,7 +198,31 @@ void SettingsTabRenderer::RenderSizesTab() auto& io = ImGui::GetIO(); io.FontGlobalScale = trueScale; } + // Font size controls: Auto (resolution-based) or Manual + bool useAutoFont = (themeSettings.FontSize <= 0.0f); + if (ImGui::Checkbox("Use resolution-based font size", &useAutoFont)) { + if (useAutoFont) { + // Enable auto: set sentinel 0.0f + themeSettings.FontSize = 0.0f; + } else { + // Disable auto: seed manual size with current effective (what user sees now) + float effective = ThemeManager::ResolveFontSize(*globals::menu); + themeSettings.FontSize = std::clamp(effective, ThemeManager::Constants::MIN_FONT_SIZE, ThemeManager::Constants::MAX_FONT_SIZE); + } + } + if (auto _tt = Util::HoverTooltipWrapper()) { + ImGui::TextUnformatted("When enabled, the UI font size scales with your screen resolution. Disable to set a fixed size."); + } + + // Show current effective size for clarity + float effectiveNow = ThemeManager::ResolveFontSize(*globals::menu); + ImGui::Text("Effective size: %.0f px", std::round(effectiveNow)); + + // Manual font size slider (disabled in auto mode) + ImGui::BeginDisabled(useAutoFont); ImGui::SliderFloat("Font Size", &themeSettings.FontSize, ThemeManager::Constants::MIN_FONT_SIZE, ThemeManager::Constants::MAX_FONT_SIZE, "%.0f"); + ImGui::EndDisabled(); + ImGui::SliderFloat2("Window Padding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("Frame Padding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderFloat2("Item Spacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); diff --git a/src/Menu/ThemeManager.cpp b/src/Menu/ThemeManager.cpp index 787899ba3c..3cfd96eb57 100644 --- a/src/Menu/ThemeManager.cpp +++ b/src/Menu/ThemeManager.cpp @@ -7,6 +7,7 @@ #include "RE/Skyrim.h" #include "Util.h" +#include "State.h" void ThemeManager::SetupImGuiStyle(const Menu& menu) { @@ -124,8 +125,8 @@ void ThemeManager::ReloadFont(const Menu& menu, float& cachedFontSize) font_config.PixelSnapH = Constants::FCONF_PIXELSNAP_H; font_config.RasterizerMultiply = Constants::FCONF_RASTERIZER_MULTIPLY; - float fontSize = themeSettings.FontSize; - fontSize = std::clamp(fontSize, Constants::MIN_FONT_SIZE, Constants::MAX_FONT_SIZE); + // Compute effective font size (user value or dynamic default) + float fontSize = ResolveFontSize(menu); auto fontPath = Util::PathHelpers::GetFontsPath() / "Jost-Regular.ttf"; if (!io.Fonts->AddFontFromFileTTF(fontPath.string().c_str(), @@ -140,5 +141,26 @@ void ThemeManager::ReloadFont(const Menu& menu, float& cachedFontSize) io.FontGlobalScale = exp2(themeSettings.GlobalScale); - cachedFontSize = themeSettings.FontSize; + // Cache the effective size so we can detect changes accurately + cachedFontSize = fontSize; +} + +float ThemeManager::ResolveFontSize(const Menu& menu) +{ + const auto& themeSettings = menu.GetTheme(); + float configured = themeSettings.FontSize; + + // If user configured a positive size, use it (clamped) + if (std::round(configured) > 0) { + return std::clamp(configured, Constants::MIN_FONT_SIZE, Constants::MAX_FONT_SIZE); + } + + // Otherwise, compute dynamic default based on current screen resolution + float dynamicSize = Constants::DEFAULT_FONT_SIZE; + if (globals::state && globals::state->screenSize.y > 0) { + dynamicSize = globals::state->screenSize.y * Constants::DEFAULT_FONT_RATIO; + } else { + logger::warn("ThemeManager::ResolveFontSize() - Falling back to DEFAULT_FONT_SIZE due to missing screen height."); + } + return std::clamp(dynamicSize, Constants::MIN_FONT_SIZE, Constants::MAX_FONT_SIZE); } \ No newline at end of file diff --git a/src/Menu/ThemeManager.h b/src/Menu/ThemeManager.h index e002719473..e55b6b06c9 100644 --- a/src/Menu/ThemeManager.h +++ b/src/Menu/ThemeManager.h @@ -7,6 +7,9 @@ class ThemeManager public: static void SetupImGuiStyle(const class Menu& menu); static void ReloadFont(const class Menu& menu, float& cachedFontSize); + // Returns the effective font size to use. If the user setting is <= 0, a dynamic + // default based on current screen resolution is returned; otherwise the user value. + static float ResolveFontSize(const class Menu& menu); struct Constants { From 93c5adf65f5a40ad188628dbc006a13429cca0b5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 18:57:13 +0000 Subject: [PATCH 2/2] =?UTF-8?q?style:=20=F0=9F=8E=A8=20apply=20pre-commit.?= =?UTF-8?q?ci=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automated formatting by clang-format, prettier, and other hooks. See https://pre-commit.ci for details. --- src/Features/PerformanceOverlay.cpp | 48 ++++++++++++++--------------- src/Menu.cpp | 24 +++++++-------- src/Menu.h | 2 +- src/Menu/SettingsTabRenderer.cpp | 4 +-- src/Menu/ThemeManager.cpp | 2 +- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Features/PerformanceOverlay.cpp b/src/Features/PerformanceOverlay.cpp index e15d049192..4ab6688840 100644 --- a/src/Features/PerformanceOverlay.cpp +++ b/src/Features/PerformanceOverlay.cpp @@ -220,38 +220,38 @@ void PerformanceOverlay::DrawSettings() void PerformanceOverlay::SaveSettings(json& j) { - // Persist all overlay settings to JSON - j = this->settings; // uses NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT + // Persist all overlay settings to JSON + j = this->settings; // uses NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT } void PerformanceOverlay::LoadSettings(json& j) { - try { - // Load all settings from JSON (missing fields use defaults) - this->settings = j.get(); - } catch (...) { - // Fallback to defaults if JSON is invalid - this->settings = PerformanceOverlay::Settings{}; - } - // Ensure history buffers match loaded size - this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); - this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); + try { + // Load all settings from JSON (missing fields use defaults) + this->settings = j.get(); + } catch (...) { + // Fallback to defaults if JSON is invalid + this->settings = PerformanceOverlay::Settings{}; + } + // Ensure history buffers match loaded size + this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); } void PerformanceOverlay::RestoreDefaultSettings() { - this->settings = PerformanceOverlay::Settings{}; - // Reset runtime buffers/state to match defaults - this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); - this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); - this->state.smoothFps = 0.0f; - this->state.smoothFrameTimeMs = 0.0f; - this->state.postFGSmoothFps = 0.0f; - this->state.postFGSmoothFrameTimeMs = 0.0f; - this->state.minFrameTime = 1000.0f; - this->state.maxFrameTime = 0.0f; - this->state.smoothedMinFrameTime = 0.0f; - this->state.smoothedMaxFrameTime = 50.0f; + this->settings = PerformanceOverlay::Settings{}; + // Reset runtime buffers/state to match defaults + this->state.frameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.postFGFrameTimeHistory.Resize(this->settings.FrameHistorySize); + this->state.smoothFps = 0.0f; + this->state.smoothFrameTimeMs = 0.0f; + this->state.postFGSmoothFps = 0.0f; + this->state.postFGSmoothFrameTimeMs = 0.0f; + this->state.minFrameTime = 1000.0f; + this->state.maxFrameTime = 0.0f; + this->state.smoothedMinFrameTime = 0.0f; + this->state.smoothedMaxFrameTime = 50.0f; } void PerformanceOverlay::DataLoaded() diff --git a/src/Menu.cpp b/src/Menu.cpp index d7968d19b5..768cb12b39 100644 --- a/src/Menu.cpp +++ b/src/Menu.cpp @@ -176,8 +176,8 @@ void Menu::Init() DXGI_SWAP_CHAIN_DESC desc{}; globals::d3d::swapChain->GetDesc(&desc); - // Determine effective font size: user setting when >0, otherwise dynamic default by resolution - float fontSize = ThemeManager::ResolveFontSize(*this); + // Determine effective font size: user setting when >0, otherwise dynamic default by resolution + float fontSize = ThemeManager::ResolveFontSize(*this); auto fontPath = Util::PathHelpers::GetFontsPath() / "Jost-Regular.ttf"; if (!imgui_io.Fonts->AddFontFromFileTTF(fontPath.string().c_str(), @@ -186,10 +186,10 @@ void Menu::Init() imgui_io.Fonts->AddFontDefault(); } - imgui_io.FontGlobalScale = exp2(settings.Theme.GlobalScale); + imgui_io.FontGlobalScale = exp2(settings.Theme.GlobalScale); - // Initialize cached font size to effective size to prevent redundant reload on first frame - cachedFontSize = fontSize; + // Initialize cached font size to effective size to prevent redundant reload on first frame + cachedFontSize = fontSize; // Setup Platform/Renderer backends ImGui_ImplWin32_Init(desc.OutputWindow); @@ -411,13 +411,13 @@ void Menu::DrawFooter() */ void Menu::DrawOverlay() { - OverlayRenderer::RenderOverlay( - *this, - [this]() { ProcessInputEventQueue(); }, - [this]() { DrawSettings(); }, - [](uint32_t key) { return Util::Input::KeyIdToString(key); }, - cachedFontSize, - ThemeManager::ResolveFontSize(*this)); + OverlayRenderer::RenderOverlay( + *this, + [this]() { ProcessInputEventQueue(); }, + [this]() { DrawSettings(); }, + [](uint32_t key) { return Util::Input::KeyIdToString(key); }, + cachedFontSize, + ThemeManager::ResolveFontSize(*this)); } /** diff --git a/src/Menu.h b/src/Menu.h index a165f6a0d8..d889f1d225 100644 --- a/src/Menu.h +++ b/src/Menu.h @@ -99,7 +99,7 @@ class Menu struct ThemeSettings { - float FontSize = 0.0f; // When 0, dynamic default (resolution-based) is used + float FontSize = 0.0f; // When 0, dynamic default (resolution-based) is used float GlobalScale = REL::Module::IsVR() ? -0.5f : 0.f; // exponential bool UseSimplePalette = true; // simple palette or full customization diff --git a/src/Menu/SettingsTabRenderer.cpp b/src/Menu/SettingsTabRenderer.cpp index 5cd10ab5da..778ccefccc 100644 --- a/src/Menu/SettingsTabRenderer.cpp +++ b/src/Menu/SettingsTabRenderer.cpp @@ -5,8 +5,8 @@ #include "Globals.h" #include "Menu.h" -#include "ThemeManager.h" #include "ShaderCache.h" +#include "ThemeManager.h" #include "Util.h" void SettingsTabRenderer::RenderGeneralSettings( @@ -145,7 +145,7 @@ void SettingsTabRenderer::RenderInterfaceTab() // Restore theme defaults button if (ImGui::Button("Restore Theme Defaults")) { auto& settings = globals::menu->GetSettings(); - settings.Theme = Menu::ThemeSettings{}; // reset to default-initialized theme + settings.Theme = Menu::ThemeSettings{}; // reset to default-initialized theme // Apply global font scale immediately ImGui::GetIO().FontGlobalScale = exp2(settings.Theme.GlobalScale); } diff --git a/src/Menu/ThemeManager.cpp b/src/Menu/ThemeManager.cpp index 3cfd96eb57..9903786933 100644 --- a/src/Menu/ThemeManager.cpp +++ b/src/Menu/ThemeManager.cpp @@ -6,8 +6,8 @@ #include #include "RE/Skyrim.h" -#include "Util.h" #include "State.h" +#include "Util.h" void ThemeManager::SetupImGuiStyle(const Menu& menu) {