Skip to content

feat(UI): separate theme settings, UI refactor, font support#1571

Merged
doodlum merged 42 commits into
community-shaders:devfrom
davo0411:ui-rework-pr1
Oct 13, 2025
Merged

feat(UI): separate theme settings, UI refactor, font support#1571
doodlum merged 42 commits into
community-shaders:devfrom
davo0411:ui-rework-pr1

Conversation

@davo0411
Copy link
Copy Markdown
Collaborator

@davo0411 davo0411 commented Oct 13, 2025

Adds the following:

  1. Full custom theme saving & loading via .json settings.
  2. Custom font loading with full font family support (bold, semibold... etc)
  3. Basic toggle (semi-iOS styled) replacing the "Enable at boot" button for features.
  4. Added icon for "Feature settings reset" button.
  5. Rework for many backend theme controls to mesh better. i.e. many elements were not controllable and hard-coded. This has been fixed.
  6. "Interface" UI tab reworked to flow better, added "Fonts" tab.
  7. Added theme controls for scrollbar and borders, allowing finer user control.
  8. Forced "Full" palette for themes.
  9. Cleaned up setting loading and filesystem code inconsistencies in state.cpp/h & filesystem.cpp/h. Added helpers for settingsthemes.json.

FOLLOW-UP PRS WILL COME. IF OTHERS ARE OPEN, MERGE THIS FIRST.

2054C2~1
203F1B~1
20D4AE~1

Summary by CodeRabbit

  • New Features

    • Full theme system with discoverable presets, load/save, Default Dark preset, create/preset management UI, and theme discovery at startup.
    • Per-role font management with font catalog, per-role selection, validation, and automatic/deferred font reloads.
  • Improvements

    • Unified, font-aware UI (headings, tabs, lists) with contrast-aware color controls and improved styling, spacing, and icons.
    • Fonts, Styling, and Themes tabs for granular scale, spacing, and palette adjustments.
  • Bug Fixes

    • Visual consistency fixes for borders, tab items, buttons, and control styling; improved restore/default actions.

davo0411 and others added 30 commits September 22, 2025 22:05
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
@github-actions
Copy link
Copy Markdown

Using provided base ref: 62fa347
Using base ref: 62fa347
Base commit date: 2025-10-12T14:53:26+01:00 (Sunday, October 12, 2025 02:53 PM)
No actionable suggestions for changed features.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (11)
src/Menu/SettingsTabRenderer.cpp (4)

297-304: Verify filesystem path exists before opening.

ShellExecuteA is called with a path from GetThemesRealPath(). While this internal helper should provide a safe path, the code doesn't verify the directory exists before attempting to open it, which could result in a confusing user experience if the folder hasn't been created yet.

 	ImGui::SameLine();
 	if (ImGui::Button("Open Themes Folder")) {
 		std::filesystem::path themesPath = Util::PathHelpers::GetThemesRealPath();
-		ShellExecuteA(NULL, "open", themesPath.string().c_str(), NULL, NULL, SW_SHOWNORMAL);
+		// Create directory if it doesn't exist
+		std::error_code ec;
+		std::filesystem::create_directories(themesPath, ec);
+		if (!ec) {
+			ShellExecuteA(NULL, "open", themesPath.string().c_str(), NULL, NULL, SW_SHOWNORMAL);
+		} else {
+			logger::error("Failed to create themes directory: {}", ec.message());
+		}
 	}

190-411: Consider refactoring for improved maintainability.

This function is quite long (~220 lines) and handles multiple concerns: theme selection UI, theme creation modal, theme management buttons. Breaking it into smaller helper functions would improve readability and testability.

Consider extracting:

  • RenderThemeSelectionCombo() (lines 203-295)
  • RenderThemeManagementButtons() (lines 287-342)
  • RenderCreateThemeModal() (lines 344-394)

This would make the main function orchestrate high-level flow while delegating details to focused helpers.


459-460: Display actual fonts path to user.

The warning message uses a hardcoded path string "Interface/CommunityShaders/Fonts/", which may not match the actual configured path. Showing the actual path would help users locate where to place their font files.

-		ImGui::TextColored(ImVec4(0.9f, 0.6f, 0.2f, 1.0f), "No fonts found. Place .ttf files in Interface/CommunityShaders/Fonts/");
+		std::filesystem::path fontsPath = Util::PathHelpers::GetFontsPath();
+		ImGui::TextColored(ImVec4(0.9f, 0.6f, 0.2f, 1.0f), 
+			"No fonts found. Place .ttf/.otf files in: %s", fontsPath.string().c_str());

413-592: Consider refactoring for improved maintainability.

This function is quite long (~180 lines) and handles multiple concerns: font size controls, font family/style selection for each role, and catalog management. Extracting the per-role rendering logic (lines 462-581) into a separate helper function would improve readability.

Consider extracting:

  • RenderFontRoleSettings(FontRole role, const FontRoleDescriptor& descriptor, FontRoleSettings& roleSettings, const Catalog& catalog) to handle lines 467-580

This would reduce the main function to orchestration and make the per-role logic easier to test and maintain.

src/Features/VR.cpp (1)

27-33: De-duplicate BeginTabItemWithFont wrapper

This anonymous-wrapper now exists in multiple TUs (here, SettingsTabRenderer.cpp, FeatureListRenderer.cpp). Prefer a single inline in a shared header (e.g., Menu/Fonts.h or a small Menu/FontHelpers.h) to avoid divergence.

src/Utils/UI.cpp (1)

1357-1413: Make ButtonWithFlash ID-collision proof

Keying by label string collides across windows/ID stacks. Prefer ImGuiID from ImGui::GetID(label) for uniqueness and faster lookup.

Apply this diff:

-bool ButtonWithFlash(const char* label, const ImVec2& size, int flashDurationMs)
+bool ButtonWithFlash(const char* label, const ImVec2& size, int flashDurationMs)
 {
-  static std::unordered_map<std::string, std::chrono::steady_clock::time_point> flashTimers;
+  static std::unordered_map<ImGuiID, std::chrono::steady_clock::time_point> flashTimers;
   static std::mutex flashTimersMutex;
 
-  std::string buttonId = std::string(label);
+  ImGuiID buttonId = ImGui::GetID(label);
   auto now = std::chrono::steady_clock::now();
   ...
 }
src/Utils/UI.h (1)

9-10: Unnecessary header dependency

This header doesn’t use anything from Menu/Fonts.h. Remove to reduce coupling and avoid potential include cycles.

-#include "../Menu/Fonts.h"
-
src/Menu/ThemeManager.cpp (2)

320-331: Avoid mutating a const Menu via const_cast; make the API non-const.

ReloadFont/SetupImGuiStyle modify Menu state in fallback paths. Passing const Menu and const_cast-ing is a code smell and can be UB if a truly-const object is passed.

Apply these diffs:

In ThemeManager.h:

-    static void SetupImGuiStyle(const class Menu& menu);
-    static void ReloadFont(const class Menu& menu, float& cachedFontSize);
+    static void SetupImGuiStyle(class Menu& menu);
+    static void ReloadFont(class Menu& menu, float& cachedFontSize);

In ThemeManager.cpp:

-void ThemeManager::SetupImGuiStyle(const Menu& menu)
+void ThemeManager::SetupImGuiStyle(Menu& menu)
@@
-        // Emergency recovery: const_cast is acceptable here to prevent total UI failure
-        if (const_cast<Menu*>(&menu)->LoadThemePreset("Default")) {
+        if (menu.LoadThemePreset("Default")) {
             ...
         }
-void ThemeManager::ReloadFont(const Menu& menu, float& cachedFontSize)
+void ThemeManager::ReloadFont(Menu& menu, float& cachedFontSize)
@@
-        auto& mutableRoleSettings = const_cast<Menu&>(menu).GetFontRoleSettings(role);
+        auto& mutableRoleSettings = menu.GetFontRoleSettings(role);
@@
-        const_cast<Menu&>(menu).GetFontRoleSettings(Menu::FontRole::Body) = defaults;
+        menu.GetFontRoleSettings(Menu::FontRole::Body) = defaults;
@@
-        const_cast<Menu&>(menu).GetFontRoleSettings(role) = defaults;
+        menu.GetFontRoleSettings(role) = defaults;
@@
-    menu.cachedFontName = const_cast<Menu&>(menu).GetFontRoleSettings(Menu::FontRole::Body).File;
+    menu.cachedFontName = menu.GetFontRoleSettings(Menu::FontRole::Body).File;
@@
-    const_cast<Menu&>(menu).GetSettings().Theme.FontName = menu.cachedFontName;
-    const_cast<Menu&>(menu).cachedFontSignature = const_cast<Menu&>(menu).BuildFontSignature(fontSize);
+    menu.GetSettings().Theme.FontName = menu.cachedFontName;
+    menu.cachedFontSignature = menu.BuildFontSignature(fontSize);

Also applies to: 399-404, 416-419, 426-431


191-196: Clamp scrollbar opacities to [0,1] to harden against malformed themes.

Prevents invalid alpha causing rendering artifacts.

Apply this diff:

-    colors[ImGuiCol_ScrollbarBg].w = themeSettings.ScrollbarOpacity.Background;
-    colors[ImGuiCol_ScrollbarGrab].w = themeSettings.ScrollbarOpacity.Thumb;
-    colors[ImGuiCol_ScrollbarGrabHovered].w = themeSettings.ScrollbarOpacity.ThumbHovered;
-    colors[ImGuiCol_ScrollbarGrabActive].w = themeSettings.ScrollbarOpacity.ThumbActive;
+    colors[ImGuiCol_ScrollbarBg].w = std::clamp(themeSettings.ScrollbarOpacity.Background, 0.0f, 1.0f);
+    colors[ImGuiCol_ScrollbarGrab].w = std::clamp(themeSettings.ScrollbarOpacity.Thumb, 0.0f, 1.0f);
+    colors[ImGuiCol_ScrollbarGrabHovered].w = std::clamp(themeSettings.ScrollbarOpacity.ThumbHovered, 0.0f, 1.0f);
+    colors[ImGuiCol_ScrollbarGrabActive].w = std::clamp(themeSettings.ScrollbarOpacity.ThumbActive, 0.0f, 1.0f);
src/Menu/ThemeManager.h (2)

3-11: Include for std::time_t in ThemeInfo.

Prevents reliance on transitive includes.

Apply this diff:

 #include <d3d11.h>
 #include <filesystem>
 #include <imgui.h>
 #include <mutex>
 #include <nlohmann/json.hpp>
+#include <ctime>
 #include <string>
 #include <vector>
 #include <winrt/base.h>

136-140: Make Menu parameters non-const (implementation mutates Menu on fallback).

Align header with implementation intent and remove const_casts.

Apply this diff:

-    static void SetupImGuiStyle(const class Menu& menu);
-    static void ReloadFont(const class Menu& menu, float& cachedFontSize);
+    static void SetupImGuiStyle(class Menu& menu);
+    static void ReloadFont(class Menu& menu, float& cachedFontSize);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62fa347 and ff94f2b.

⛔ Files ignored due to path filters (3)
  • package/Interface/CommunityShaders/Fonts/Jost/Jost-Light.ttf is excluded by !**/*.ttf
  • package/Interface/CommunityShaders/Fonts/Jost/Jost-Regular.ttf is excluded by !**/*.ttf
  • package/Interface/CommunityShaders/Fonts/Jost/Jost-SemiBold.ttf is excluded by !**/*.ttf
📒 Files selected for processing (24)
  • package/SKSE/Plugins/CommunityShaders/Themes/Default.json (1 hunks)
  • src/FeatureIssues.cpp (2 hunks)
  • src/Features/VR.cpp (5 hunks)
  • src/Menu.cpp (10 hunks)
  • src/Menu.h (8 hunks)
  • src/Menu/FeatureListRenderer.cpp (8 hunks)
  • src/Menu/Fonts.cpp (1 hunks)
  • src/Menu/Fonts.h (1 hunks)
  • src/Menu/HomePageRenderer.cpp (0 hunks)
  • src/Menu/MenuHeaderRenderer.cpp (5 hunks)
  • src/Menu/OverlayRenderer.cpp (2 hunks)
  • src/Menu/SettingsTabRenderer.cpp (10 hunks)
  • src/Menu/SettingsTabRenderer.h (1 hunks)
  • src/Menu/ThemeManager.cpp (2 hunks)
  • src/Menu/ThemeManager.h (3 hunks)
  • src/SettingsOverrideManager.cpp (3 hunks)
  • src/SettingsOverrideManager.h (0 hunks)
  • src/State.cpp (4 hunks)
  • src/State.h (2 hunks)
  • src/Utils/FileSystem.cpp (2 hunks)
  • src/Utils/FileSystem.h (2 hunks)
  • src/Utils/UI.cpp (11 hunks)
  • src/Utils/UI.h (3 hunks)
  • src/XSEPlugin.cpp (2 hunks)
💤 Files with no reviewable changes (2)
  • src/SettingsOverrideManager.h
  • src/Menu/HomePageRenderer.cpp
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Utils/FileSystem.h
  • src/Features/VR.cpp
  • src/FeatureIssues.cpp
  • src/Menu/SettingsTabRenderer.h
  • src/Utils/FileSystem.cpp
  • src/Menu/FeatureListRenderer.cpp
  • src/Utils/UI.h
  • src/Menu.h
  • src/Menu/MenuHeaderRenderer.cpp
  • src/SettingsOverrideManager.cpp
  • src/Menu/Fonts.cpp
  • src/Menu.cpp
  • src/Menu/SettingsTabRenderer.cpp
  • src/XSEPlugin.cpp
  • src/Menu/ThemeManager.h
  • src/State.h
  • src/Menu/OverlayRenderer.cpp
  • src/State.cpp
  • src/Menu/Fonts.h
  • src/Utils/UI.cpp
  • src/Menu/ThemeManager.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Utils/FileSystem.h
  • src/Features/VR.cpp
  • src/FeatureIssues.cpp
  • src/Menu/SettingsTabRenderer.h
  • src/Utils/FileSystem.cpp
  • src/Menu/FeatureListRenderer.cpp
  • src/Utils/UI.h
  • src/Menu.h
  • src/Menu/MenuHeaderRenderer.cpp
  • src/SettingsOverrideManager.cpp
  • src/Menu/Fonts.cpp
  • src/Menu.cpp
  • src/Menu/SettingsTabRenderer.cpp
  • src/XSEPlugin.cpp
  • src/Menu/ThemeManager.h
  • src/State.h
  • src/Menu/OverlayRenderer.cpp
  • src/State.cpp
  • src/Menu/Fonts.h
  • src/Utils/UI.cpp
  • src/Menu/ThemeManager.cpp
🧬 Code graph analysis (18)
src/Utils/FileSystem.h (1)
src/Utils/FileSystem.cpp (6)
  • GetSettingsThemePath (71-74)
  • GetSettingsThemePath (71-71)
  • GetThemesPath (76-79)
  • GetThemesPath (76-76)
  • GetThemesRealPath (149-152)
  • GetThemesRealPath (149-149)
src/Features/VR.cpp (3)
src/Menu/FeatureListRenderer.cpp (4)
  • label (283-292)
  • label (283-283)
  • BeginTabItemWithFont (41-44)
  • BeginTabItemWithFont (41-41)
src/Menu/Fonts.cpp (2)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
src/Menu/SettingsTabRenderer.cpp (2)
  • BeginTabItemWithFont (34-37)
  • BeginTabItemWithFont (34-34)
src/Menu/SettingsTabRenderer.h (1)
src/Menu/SettingsTabRenderer.cpp (6)
  • RenderThemesTab (190-411)
  • RenderThemesTab (190-190)
  • RenderFontsTab (413-592)
  • RenderFontsTab (413-413)
  • RenderStylingTab (594-674)
  • RenderStylingTab (594-594)
src/Menu/FeatureListRenderer.cpp (4)
src/Menu/Fonts.cpp (2)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
src/Utils/UI.cpp (8)
  • ContrastSelectable (1279-1315)
  • ContrastSelectable (1279-1279)
  • ContrastSelectableWithColor (1317-1354)
  • ContrastSelectableWithColor (1317-1317)
  • HoverTooltipWrapper (34-41)
  • HoverTooltipWrapper (43-49)
  • FeatureToggle (1415-1487)
  • FeatureToggle (1415-1415)
src/FeatureIssues.cpp (2)
  • IsObsoleteFeature (717-721)
  • IsObsoleteFeature (717-717)
src/SettingsOverrideManager.h (1)
  • GetSingleton (42-46)
src/Utils/UI.h (1)
src/Utils/UI.cpp (16)
  • ButtonWithFlash (1357-1413)
  • ButtonWithFlash (1357-1357)
  • FeatureToggle (1415-1487)
  • FeatureToggle (1415-1415)
  • CalculateLuminance (1221-1234)
  • CalculateLuminance (1221-1221)
  • GetContrastingTextColor (1236-1247)
  • GetContrastingTextColor (1236-1236)
  • CalculateContrastRatio (1249-1259)
  • CalculateContrastRatio (1249-1249)
  • AdjustBackgroundForTextContrast (1261-1277)
  • AdjustBackgroundForTextContrast (1261-1262)
  • ContrastSelectable (1279-1315)
  • ContrastSelectable (1279-1279)
  • ContrastSelectableWithColor (1317-1354)
  • ContrastSelectableWithColor (1317-1317)
src/Menu.h (4)
src/Menu.cpp (17)
  • Menu (171-196)
  • ResolveFontRole (151-159)
  • ResolveFontRole (151-151)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadThemePreset (277-314)
  • LoadThemePreset (277-277)
  • CreateDefaultThemes (316-321)
  • CreateDefaultThemes (316-316)
  • BuildFontSignature (161-164)
  • BuildFontSignature (161-161)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
src/Menu/ThemeManager.cpp (9)
  • LoadTheme (585-622)
  • LoadTheme (585-585)
  • SaveTheme (624-672)
  • SaveTheme (624-625)
  • DiscoverThemes (517-571)
  • DiscoverThemes (517-517)
  • file (653-653)
  • file (726-726)
  • file (772-772)
src/State.cpp (4)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu/Fonts.cpp (2)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
src/Menu/MenuHeaderRenderer.cpp (2)
src/Menu.h (1)
  • GetSingleton (105-109)
src/Utils/UI.cpp (6)
  • DrawAlignedTextWithLogo (298-335)
  • DrawAlignedTextWithLogo (298-298)
  • DrawSharpText (267-296)
  • DrawSharpText (267-267)
  • ButtonWithFlash (1357-1413)
  • ButtonWithFlash (1357-1357)
src/SettingsOverrideManager.cpp (1)
src/Utils/FileSystem.cpp (4)
  • GetOverridesPath (81-84)
  • GetOverridesPath (81-81)
  • GetAppliedOverridesPath (86-89)
  • GetAppliedOverridesPath (86-86)
src/Menu/Fonts.cpp (2)
src/Menu/Fonts.h (1)
  • FontRoleGuard (32-45)
src/Menu.h (1)
  • GetSingleton (105-109)
src/Menu.cpp (3)
src/Menu.h (4)
  • FontRoleSettings (382-382)
  • Style (286-304)
  • Menu (23-160)
  • GetSingleton (105-109)
src/State.cpp (7)
  • i (189-189)
  • Save (395-462)
  • Save (395-395)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu/Fonts.cpp (8)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
  • GetDefaultRole (118-121)
  • GetDefaultRole (118-118)
  • NormalizeFontRoles (90-116)
  • NormalizeFontRoles (90-90)
  • ValidateFont (570-625)
  • ValidateFont (570-570)
src/Menu/SettingsTabRenderer.cpp (4)
src/Menu/Fonts.cpp (6)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
  • DiscoverFontCatalog (447-549)
  • DiscoverFontCatalog (447-447)
  • DiscoverFontCatalog (552-555)
  • DiscoverFontCatalog (552-552)
src/Utils/UI.cpp (4)
  • HoverTooltipWrapper (34-41)
  • HoverTooltipWrapper (43-49)
  • ButtonWithFlash (1357-1413)
  • ButtonWithFlash (1357-1357)
src/Utils/FileSystem.cpp (2)
  • GetThemesRealPath (149-152)
  • GetThemesRealPath (149-149)
src/Menu/ThemeManager.cpp (2)
  • ResolveFontSize (821-839)
  • ResolveFontSize (821-821)
src/XSEPlugin.cpp (3)
src/Menu/FeatureListRenderer.cpp (4)
  • menu (264-281)
  • menu (264-264)
  • menu (349-355)
  • menu (349-349)
src/Menu.h (1)
  • GetSingleton (105-109)
src/Menu/ThemeManager.h (1)
  • GetSingleton (180-184)
src/Menu/ThemeManager.h (1)
src/Menu/ThemeManager.cpp (24)
  • ResolveFontSize (821-839)
  • ResolveFontSize (821-821)
  • SetupImGuiStyle (95-196)
  • SetupImGuiStyle (95-95)
  • ReloadFont (246-514)
  • ReloadFont (246-246)
  • ForceApplyDefaultTheme (198-244)
  • ForceApplyDefaultTheme (198-198)
  • DiscoverThemes (517-571)
  • DiscoverThemes (517-517)
  • GetThemeNames (573-583)
  • GetThemeNames (573-573)
  • LoadTheme (585-622)
  • LoadTheme (585-585)
  • SaveTheme (624-672)
  • SaveTheme (624-625)
  • GetThemeInfo (674-680)
  • GetThemeInfo (674-674)
  • RefreshThemes (682-686)
  • RefreshThemes (682-682)
  • GetThemesDirectory (688-691)
  • GetThemesDirectory (688-688)
  • CreateDefaultThemeFiles (693-755)
  • CreateDefaultThemeFiles (693-693)
src/State.h (2)
src/Menu.cpp (4)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
src/State.cpp (4)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/State.cpp (2)
src/Utils/FileSystem.cpp (10)
  • GetSettingsUserPath (56-59)
  • GetSettingsUserPath (56-56)
  • GetSettingsTestPath (61-64)
  • GetSettingsTestPath (61-61)
  • GetSettingsThemePath (71-74)
  • GetSettingsThemePath (71-71)
  • GetSettingsDefaultPath (66-69)
  • GetSettingsDefaultPath (66-66)
  • GetCommunityShaderPath (31-34)
  • GetCommunityShaderPath (31-31)
src/Menu.cpp (4)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
src/Menu/Fonts.h (2)
src/Menu.cpp (3)
  • Menu (171-196)
  • BuildFontSignature (161-164)
  • BuildFontSignature (161-161)
src/Menu/Fonts.cpp (22)
  • NormalizeFontRoles (90-116)
  • NormalizeFontRoles (90-90)
  • GetDefaultRole (118-121)
  • GetDefaultRole (118-118)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
  • FontRoleGuard (123-135)
  • FontRoleGuard (137-142)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
  • DiscoverFontCatalog (447-549)
  • DiscoverFontCatalog (447-447)
  • DiscoverFontCatalog (552-555)
  • DiscoverFontCatalog (552-552)
  • FormatFontDisplayName (376-400)
  • FormatFontDisplayName (376-376)
  • DiscoverFonts (558-568)
  • DiscoverFonts (558-558)
  • ValidateFont (570-625)
  • ValidateFont (570-570)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Utils/UI.cpp (1)
src/Menu/FeatureListRenderer.cpp (4)
  • menu (264-281)
  • menu (264-264)
  • menu (349-355)
  • menu (349-349)
src/Menu/ThemeManager.cpp (4)
src/Menu/Fonts.cpp (2)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Utils/UI.cpp (4)
  • CalculateLuminance (1221-1234)
  • CalculateLuminance (1221-1221)
  • AdjustBackgroundForTextContrast (1261-1277)
  • AdjustBackgroundForTextContrast (1261-1262)
src/Utils/FileSystem.cpp (4)
  • GetFontsPath (46-49)
  • GetFontsPath (46-46)
  • GetThemesPath (76-79)
  • GetThemesPath (76-76)
src/Menu.cpp (4)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (7)
src/FeatureIssues.cpp (2)

1460-1466: Theme palette alignment looks good.

Switching the button wrapper to FrameBorder matches the updated palette semantics; no issues spotted.


1483-1489: Consistent border usage confirmed.

Using FrameBorder here keeps the testing controls consistent with the rest of the UI theme.

src/Menu/SettingsTabRenderer.cpp (3)

21-44: LGTM!

The helper functions provide clean abstractions for applying font roles to ImGui widgets using RAII guards, ensuring fonts are properly restored after rendering.


594-674: LGTM!

The styling controls are well-organized with clear sections, helpful tooltips, and proper use of font roles for visual hierarchy. The new scrollbar opacity controls provide fine-grained user control as intended.


676-733: LGTM!

The color controls are well-structured with progressive disclosure (collapsing headers) to avoid overwhelming users. The "Simple" and "Advanced" sections provide appropriate access levels for different user needs.

src/Menu/SettingsTabRenderer.h (1)

32-35: New sub-tabs look good

RenderThemesTab, RenderFontsTab, and RenderStylingTab align with the refactor; signatures match usage in SettingsTabRenderer.cpp.

src/Features/VR.cpp (1)

208-208: LGTM on tab calls

Swapping ImGui::BeginTabItem to BeginTabItemWithFont applies role-aware fonts consistently.

Also applies to: 223-223, 232-232

Comment thread package/SKSE/Plugins/CommunityShaders/Themes/Default.json
Comment thread src/Menu.cpp
Comment thread src/Menu.h
Comment thread src/Menu/Fonts.h
Comment thread src/Menu/MenuHeaderRenderer.cpp
Comment thread src/Menu/SettingsTabRenderer.cpp Outdated
Comment thread src/Menu/ThemeManager.cpp Outdated
Comment thread src/State.cpp
Comment thread src/Utils/UI.cpp
Comment thread src/Utils/UI.cpp
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
src/Menu/SettingsTabRenderer.cpp (2)

351-360: Validate theme name for filesystem safety before creating.

Add a filename validator (reject separators, reserved device names, trailing dot/space) and gate the Create action on it.

@@
-		// Popup modal for creating new theme
+		// Popup modal for creating new theme
 		if (ImGui::BeginPopupModal("Create New Theme", &showCreateThemePopup, ImGuiWindowFlags_AlwaysAutoResize)) {
@@
 			ImGui::InputText("Theme Name", newThemeName, sizeof(newThemeName));
+			// Basic filename validation helper
+			static auto IsValidThemeName = [](std::string_view name) {
+				if (name.empty()) return false;
+				for (char c : name) {
+					if (c=='/'||c=='\\'||c==':'||c=='*'||c=='?'||c=='"'||c=='<'||c=='>'||c=='|') return false;
+				}
+				static constexpr const char* kReserved[] = {
+					"CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7","COM8","COM9",
+					"LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9"
+				};
+				for (auto* r : kReserved) {
+					size_t n = name.size(), m = std::char_traits<char>::length(r);
+					if (n==m && iequals(name, r)) return false;
+				}
+				if (name.back()==' ' || name.back()=='.') return false;
+				return true;
+			};
@@
-			// Buttons
-			if (Util::ButtonWithFlash("Create Theme") && strlen(newThemeName) > 0) {
+			// Buttons
+			if (Util::ButtonWithFlash("Create Theme") && IsValidThemeName(newThemeName)) {
 				// Use the existing SaveTheme method to serialize the theme settings
 				json currentThemeJson;
 				globals::menu->SaveTheme(currentThemeJson);
@@
-				if (themeManager->SaveTheme(std::string(newThemeName), currentThemeJson["Theme"], displayName, description)) {
+				if (themeManager->SaveTheme(std::string(newThemeName), currentThemeJson["Theme"], displayName, description)) {
 					// Theme created successfully, load it and exit create mode
 					globals::menu->LoadThemePreset(std::string(newThemeName));
 					isCreatingNewTheme = false;
 					showCreateThemePopup = false;
-				}
+				} else {
+					logger::error("Failed to create theme '{}'", newThemeName);
+				}
 			}
+			if (!IsValidThemeName(newThemeName)) {
+				ImGui::SameLine();
+				ImGui::TextColored(ImVec4(0.9f, 0.6f, 0.2f, 1.0f), "Invalid file name");
+			}

Based on learnings

Also applies to: 371-388


322-335: Add user-visible feedback when updating a theme.

Log success/failure to aid users diagnosing save issues. Mirror this for creation path (handled above).

-						// Overwrite the current theme with updated settings
-						if (themeManager->SaveTheme(currentThemePreset, currentThemeJson["Theme"],
-								currentThemeInfo->displayName, currentThemeInfo->description)) {
-							// Theme updated successfully
-						}
+						// Overwrite the current theme with updated settings
+						if (themeManager->SaveTheme(currentThemePreset, currentThemeJson["Theme"],
+								currentThemeInfo->displayName, currentThemeInfo->description)) {
+							logger::info("Theme '{}' updated successfully", currentThemePreset);
+						} else {
+							logger::error("Failed to update theme '{}'", currentThemePreset);
+						}

Based on learnings

src/Menu/ThemeManager.cpp (1)

184-189: Fix TextSelectedBg (use semi-transparent selection background, not opaque B/W).

Current code masks text. Use a tinted, semi-transparent selection like ImGui defaults.

-	// Apply contrast-aware text for selection states (TextSelectedBg is used when text is selected)
-	if (Util::ColorUtils::CalculateLuminance(colors[ImGuiCol_HeaderActive]) > LUMINANCE_THRESHOLD) {
-		colors[ImGuiCol_TextSelectedBg] = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);  // Black text on light selection
-	} else {
-		colors[ImGuiCol_TextSelectedBg] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);  // White text on dark selection
-	}
+	// TextSelectedBg is a background highlight. Use a semi‑transparent tint.
+	ImVec4 selBg = colors[ImGuiCol_HeaderActive];
+	selBg.w = 0.35f;
+	colors[ImGuiCol_TextSelectedBg] = selBg;
🧹 Nitpick comments (6)
src/Menu/SettingsTabRenderer.cpp (3)

3-6: Replace Windows-only _stricmp with a portable case-insensitive compare.

Use a local iequals to avoid platform-specific APIs and future-proof this UI code. Also add <cctype> for std::tolower.

@@
-#include <algorithm>
+#include <algorithm>
+#include <cctype>
@@
 namespace
 {
+	inline bool iequals(std::string_view a, std::string_view b) {
+		if (a.size() != b.size()) return false;
+		for (size_t i = 0; i < a.size(); ++i) {
+			if (std::tolower(static_cast<unsigned char>(a[i])) !=
+			    std::tolower(static_cast<unsigned char>(b[i])))
+				return false;
+		}
+		return true;
+	}
@@
-					if (_stricmp(fontCatalog.families[i].name.c_str(), roleSettings.Family.c_str()) == 0) {
+					if (iequals(fontCatalog.families[i].name, roleSettings.Family)) {
 						familyIndex = static_cast<int>(i);
 						break;
 					}
@@
-					if (_stricmp(selectedFamily->styles[s].style.c_str(), roleSettings.Style.c_str()) == 0) {
+					if (iequals(selectedFamily->styles[s].style, roleSettings.Style)) {
 						styleIndex = static_cast<int>(s);
 						break;
 					}

As per coding guidelines

Also applies to: 475-486, 530-536


390-394: Cancel should exit “create new theme” mode.

Without resetting, the UI stays in create-mode unintentionally.

-			if (ImGui::Button("Cancel")) {
-				showCreateThemePopup = false;
-			}
+			if (ImGui::Button("Cancel")) {
+				isCreatingNewTheme = false;
+				showCreateThemePopup = false;
+			}

289-297: After RefreshThemes invalidates selection, apply Default immediately.

Ensures UI uses a valid theme right away.

 			// Ensure a valid theme is still selected
 			const auto* themeInfo = themeManager->GetThemeInfo(globals::menu->GetSettings().SelectedThemePreset);
 			if (!themeInfo) {
 				globals::menu->GetSettings().SelectedThemePreset = "Default";
+				if (globals::menu->LoadThemePreset("Default")) {
+					themeSettings = globals::menu->GetSettings().Theme;
+				}
 			}
src/Menu/ThemeManager.cpp (2)

723-754: Include a FullPalette when creating Default.json to match “Full palette” enforcement.

SetupImGuiStyle prefers FullPalette; generate it programmatically for robust defaults.

-		file << R"({
-	"DisplayName": "Default Theme",
-	"Description": "Default community shaders theme",
-	"Version": "1.0",
-	"Author": "Community Shaders",
-	"Theme": {
-		"UseSimplePalette": true,
-		"Palette": {
-			"Background": [0.05, 0.05, 0.05, 1.0],
-			"Text": [1.0, 1.0, 1.0, 1.0],
-			"Border": [0.4, 0.4, 0.4, 1.0]
-		},
-		"FontSize": 27.0,
-		"GlobalScale": 0.0,
-		"TooltipHoverDelay": 0.5
-	}
-})";
+		{
+			json theme;
+			theme["UseSimplePalette"] = true;
+			theme["Palette"] = {
+				{ "Background", { 0.05f, 0.05f, 0.05f, 1.0f } },
+				{ "Text",       { 1.0f,  1.0f,  1.0f,  1.0f } },
+				{ "WindowBorder", { 0.4f, 0.4f, 0.4f, 1.0f } },
+				{ "FrameBorder",  { 0.4f, 0.4f, 0.4f, 0.7f } },
+				{ "Separator",    { 0.5f, 0.5f, 0.5f, 0.6f } },
+				{ "ResizeGrip",   { 0.6f, 0.6f, 0.6f, 0.8f } }
+			};
+			theme["FontSize"] = 27.0f;
+			theme["GlobalScale"] = 0.0f;
+			theme["TooltipHoverDelay"] = 0.5f;
+
+			// Seed FullPalette from current ImGui style so defaults are consistent
+			json fullPalette = json::array();
+			const auto& style = ImGui::GetStyle();
+			for (int i = 0; i < ImGuiCol_COUNT; ++i) {
+				const ImVec4& c = style.Colors[i];
+				fullPalette.push_back({ c.x, c.y, c.z, c.w });
+			}
+			theme["FullPalette"] = std::move(fullPalette);
+
+			json doc = {
+				{ "DisplayName", "Default Theme" },
+				{ "Description", "Default community shaders theme" },
+				{ "Version", "1.0" },
+				{ "Author", "Community Shaders" },
+				{ "Theme", theme }
+			};
+			file << doc.dump(4);
+		}

10-10: Remove unused include to reduce compile time.

<d3dcompiler.h> isn’t used in this TU.

-#include <d3dcompiler.h>
src/Menu/ThemeManager.h (1)

3-11: Avoid heavy platform headers in public headers.

Remove <d3d11.h> and <winrt/base.h> from the header to reduce transitive dependencies; include them in the .cpp where needed.

-#include <d3d11.h>
-#include <filesystem>
+#include <filesystem>
 #include <imgui.h>
-#include <mutex>
+#include <mutex>
 #include <nlohmann/json.hpp>
 #include <string>
 #include <vector>
-#include <winrt/base.h>
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ff94f2b and 4120387.

📒 Files selected for processing (3)
  • src/Menu/SettingsTabRenderer.cpp (10 hunks)
  • src/Menu/ThemeManager.cpp (2 hunks)
  • src/Menu/ThemeManager.h (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Menu/SettingsTabRenderer.cpp
  • src/Menu/ThemeManager.h
  • src/Menu/ThemeManager.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Menu/SettingsTabRenderer.cpp
  • src/Menu/ThemeManager.h
  • src/Menu/ThemeManager.cpp
🧬 Code graph analysis (3)
src/Menu/SettingsTabRenderer.cpp (6)
src/Menu/Fonts.cpp (4)
  • DiscoverFontCatalog (447-549)
  • DiscoverFontCatalog (447-447)
  • DiscoverFontCatalog (552-555)
  • DiscoverFontCatalog (552-552)
src/Menu/ThemeManager.h (1)
  • GetSingleton (180-184)
src/Menu.h (2)
  • GetSingleton (105-109)
  • GetFontRoleDefaultScale (94-97)
src/Utils/UI.cpp (4)
  • HoverTooltipWrapper (34-41)
  • HoverTooltipWrapper (43-49)
  • ButtonWithFlash (1357-1413)
  • ButtonWithFlash (1357-1357)
src/Utils/FileSystem.cpp (2)
  • GetThemesRealPath (149-152)
  • GetThemesRealPath (149-149)
src/Menu/ThemeManager.cpp (2)
  • ResolveFontSize (821-839)
  • ResolveFontSize (821-821)
src/Menu/ThemeManager.h (3)
src/Menu/ThemeManager.cpp (28)
  • ResolveFontSize (821-839)
  • ResolveFontSize (821-821)
  • SetupImGuiStyle (95-196)
  • SetupImGuiStyle (95-95)
  • ReloadFont (246-514)
  • ReloadFont (246-246)
  • ForceApplyDefaultTheme (198-244)
  • ForceApplyDefaultTheme (198-198)
  • DiscoverThemes (517-571)
  • DiscoverThemes (517-517)
  • GetThemeNames (573-583)
  • GetThemeNames (573-573)
  • LoadTheme (585-622)
  • LoadTheme (585-585)
  • SaveTheme (624-672)
  • SaveTheme (624-625)
  • GetThemeInfo (674-680)
  • GetThemeInfo (674-674)
  • RefreshThemes (682-686)
  • RefreshThemes (682-682)
  • GetThemesDirectory (688-691)
  • GetThemesDirectory (688-688)
  • CreateDefaultThemeFiles (693-755)
  • CreateDefaultThemeFiles (693-693)
  • LoadThemeFile (757-814)
  • LoadThemeFile (757-757)
  • ValidateThemeData (816-819)
  • ValidateThemeData (816-816)
src/Menu.h (2)
  • Menu (23-160)
  • GetSingleton (105-109)
src/Menu.cpp (7)
  • Menu (171-196)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
src/Menu/ThemeManager.cpp (5)
src/Menu/Fonts.cpp (2)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Utils/UI.cpp (4)
  • CalculateLuminance (1221-1234)
  • CalculateLuminance (1221-1221)
  • AdjustBackgroundForTextContrast (1261-1277)
  • AdjustBackgroundForTextContrast (1261-1262)
src/Menu/ThemeManager.h (1)
  • GetSingleton (180-184)
src/Utils/FileSystem.cpp (4)
  • GetFontsPath (46-49)
  • GetFontsPath (46-46)
  • GetThemesPath (76-79)
  • GetThemesPath (76-76)
src/Menu.cpp (6)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)

davo0411 and others added 2 commits October 13, 2025 22:04
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (4)
src/Utils/UI.cpp (1)

1219-1356: Still missing: AdjustColorForContrast implementation

The AdjustColorForContrast function declared in UI.h remains unimplemented in this file, which will cause linker errors when the function is called.

Add the implementation within the Util::ColorUtils namespace:

   void AdjustBackgroundForTextContrast(ImVec4& backgroundColor, float textLuminance,
       float luminanceThreshold, float darkenFactor, float lightenOffset)
   {
     float bgLuminance = CalculateLuminance(backgroundColor);

     if (bgLuminance > luminanceThreshold && textLuminance > luminanceThreshold) {
       // Both background and text are light - darken the background
       backgroundColor.x *= darkenFactor;
       backgroundColor.y *= darkenFactor;
       backgroundColor.z *= darkenFactor;
     } else if (bgLuminance < luminanceThreshold && textLuminance < luminanceThreshold) {
       // Both background and text are dark - lighten the background
       backgroundColor.x = std::min(1.0f, backgroundColor.x + lightenOffset);
       backgroundColor.y = std::min(1.0f, backgroundColor.y + lightenOffset);
       backgroundColor.z = std::min(1.0f, backgroundColor.z + lightenOffset);
     }
   }
+
+  ImVec4 AdjustColorForContrast(const ImVec4& textColor, const ImVec4& backgroundColor, float minimumRatio)
+  {
+    // If current contrast is sufficient, keep semantic color
+    float current = CalculateContrastRatio(textColor, backgroundColor);
+    if (current >= minimumRatio)
+      return textColor;
+
+    // Try black/white with original alpha to maximize contrast
+    ImVec4 black(0.f, 0.f, 0.f, textColor.w);
+    ImVec4 white(1.f, 1.f, 1.f, textColor.w);
+    float rb = CalculateContrastRatio(black, backgroundColor);
+    float rw = CalculateContrastRatio(white, backgroundColor);
+    return (rb >= rw) ? black : white;
+  }
src/Menu/MenuHeaderRenderer.cpp (1)

147-151: Guard globals::state before saving to prevent null deref.

Early frames may not have State initialized.

-            if (Util::ButtonWithFlash("Save Settings", { -1, 0 })) {
-                globals::state->Save();
-                globals::state->SaveTheme();
-            }
+            if (Util::ButtonWithFlash("Save Settings", { -1, 0 })) {
+                if (globals::state) {
+                    globals::state->Save();
+                    globals::state->SaveTheme();
+                } else {
+                    logger::warn("Save requested but globals::state is null (skipping).");
+                }
+            }
src/Menu/ThemeManager.cpp (1)

184-193: Use tinted selection background instead of black/white.

Prefer a semi‑transparent tint of HeaderActive to match theme hue and avoid harsh contrasts.

Apply:

-    // TextSelectedBg should be a tinted overlay, not opaque, so underlying text remains visible
-    float selectionLum = Util::ColorUtils::CalculateLuminance(colors[ImGuiCol_HeaderActive]);
-    if (selectionLum > LUMINANCE_THRESHOLD) {
-        // Light selection background - use semi-transparent dark tint
-        colors[ImGuiCol_TextSelectedBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.25f);
-    } else {
-        // Dark selection background - use semi-transparent light tint
-        colors[ImGuiCol_TextSelectedBg] = ImVec4(1.0f, 1.0f, 1.0f, 0.25f);
-    }
+    // TextSelectedBg is a background highlight: tint from HeaderActive with reduced alpha
+    ImVec4 selBg = colors[ImGuiCol_HeaderActive];
+    selBg.w = 0.35f;
+    colors[ImGuiCol_TextSelectedBg] = selBg;

Based on learnings

src/Menu/Fonts.h (1)

3-11: Header now self-contained with .

The missing include issue from prior review is fixed. LGTM.

🧹 Nitpick comments (8)
src/Utils/UI.cpp (1)

1416-1488: Consider extracting toggle drawing logic into helper functions.

The FeatureToggle function is well-implemented with proper null checks, theme integration, and correct toggle behavior. However, the function is lengthy and would benefit from extracting the knob drawing logic into a separate helper function to improve readability and maintainability.

For example, extract the knob drawing logic:

// Helper function to draw toggle knob
static void DrawToggleKnob(ImDrawList* drawList, const ImVec2& buttonMin, 
    const ImVec2& toggleSize, bool enabled) {
  float knobRadius = (toggleSize.y - 4.0f) * 0.5f;
  float knobPadding = 2.0f;
  float knobTravel = toggleSize.x - (knobRadius * 2.0f) - (knobPadding * 2.0f);
  float knobX = enabled ?
      buttonMin.x + knobPadding + knobRadius + knobTravel :
      buttonMin.x + knobPadding + knobRadius;
  float knobY = buttonMin.y + toggleSize.y * 0.5f;

  ImU32 knobColor = ImGui::ColorConvertFloat4ToU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
  drawList->AddCircleFilled(ImVec2(knobX, knobY), knobRadius, knobColor);
}

Then use it in FeatureToggle:

// Draw the toggle knob
DrawToggleKnob(drawList, buttonMin, toggleSize, *enabled);
src/Menu.h (1)

280-298: Remove redundant std::move on local return.

Returning a local by value already moves; std::move here inhibits NRVO and is unnecessary.

-            ImGuiStyle style = {};
+            ImGuiStyle style = {};
             style.WindowBorderSize = 2.0f;
             ...
-            return std::move(style);
+            return style;
src/Menu/MenuHeaderRenderer.cpp (1)

18-33: Reduce log severity to avoid spam when font missing.

RoleFontGuard logs per scope; this can flood logs. Prefer debug or once-only warn.

-                logger::error("RoleFontGuard: globals::menu is null, cannot retrieve font for role");
+                logger::debug("RoleFontGuard: globals::menu is null, cannot retrieve font for role");
...
-                logger::warn("RoleFontGuard: Failed to retrieve font for role {}", static_cast<int>(role));
+                logger::debug("RoleFontGuard: Failed to retrieve font for role {}", static_cast<int>(role));
package/SKSE/Plugins/CommunityShaders/Themes/Default.json (1)

39-39: Remove or wire BackgroundBlur (unused).

This field isn’t consumed by ThemeSettings; consider removing to avoid confusion.

src/Menu/SettingsTabRenderer.cpp (2)

340-345: Add user feedback on update failure (and success).

Currently silent; log outcome to help users.

-                        if (themeManager->SaveTheme(currentThemePreset, currentThemeJson["Theme"],
-                                currentThemeInfo->displayName, currentThemeInfo->description)) {
-                            // Theme updated successfully
-                        }
+                        if (themeManager->SaveTheme(currentThemePreset, currentThemeJson["Theme"],
+                                currentThemeInfo->displayName, currentThemeInfo->description)) {
+                            logger::info("Theme '{}' updated successfully", currentThemePreset);
+                        } else {
+                            logger::error("Failed to update theme '{}'", currentThemePreset);
+                        }

472-473: Fix fonts folder hint path.

Use the actual packaged path.

-            ImGui::TextColored(ImVec4(0.9f, 0.6f, 0.2f, 1.0f), "No fonts found. Place .ttf files in Interface/CommunityShaders/Fonts/");
+            ImGui::TextColored(ImVec4(0.9f, 0.6f, 0.2f, 1.0f), "No fonts found. Place .ttf files in Data/SKSE/Plugins/CommunityShaders/Fonts/");
src/Menu/ThemeManager.cpp (2)

147-152: Verify palette-to-role mapping (FrameBg vs FrameBorder).

You set:

  • FrameBg = Palette.FrameBorder
  • SliderGrab/Active = Palette.FrameBorder

This reads like border color being used for frame backgrounds and slider grabs. Confirm intent and data presence (WindowBorder, FrameBorder, ResizeGrip, Separator). If mismatched, map FrameBg to a proper frame background (e.g., Palette.Frame) and use an accent for grabs.


652-665: Save themes atomically to avoid partial/corrupt files.

Write to temp then rename, so readers never see half-written files.

Apply:

-        // Write the theme file
-        std::ofstream file(filePath);
+        // Write atomically: temp file then rename
+        auto tmpPath = filePath;
+        tmpPath += ".tmp";
+        std::ofstream file(tmpPath, std::ios::binary | std::ios::trunc);
         if (!file.is_open()) {
-            logger::warn("Failed to create theme file: {}", filePath.string());
+            logger::warn("Failed to create temp theme file: {}", tmpPath.string());
             return false;
         }
 
-        file << fullTheme.dump(4);  // Pretty print with 4-space indentation
-        file.close();
+        file << fullTheme.dump(4);
+        file.flush();
+        file.close();
+
+        std::error_code ec;
+        std::filesystem::rename(tmpPath, filePath, ec);
+        if (ec) {
+            // Fallback: replace if exists
+            std::filesystem::remove(filePath, ec);
+            ec.clear();
+            std::filesystem::rename(tmpPath, filePath, ec);
+            if (ec) {
+                logger::warn("Failed to finalize theme file '{}': {}", filePath.string(), ec.message());
+                return false;
+            }
+        }

Optional: also sanitize Windows reserved filenames (CON, NUL, PRN, etc.).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4120387 and 8a96c77.

📒 Files selected for processing (8)
  • package/SKSE/Plugins/CommunityShaders/Themes/Default.json (1 hunks)
  • src/Menu.h (8 hunks)
  • src/Menu/Fonts.h (1 hunks)
  • src/Menu/MenuHeaderRenderer.cpp (5 hunks)
  • src/Menu/SettingsTabRenderer.cpp (10 hunks)
  • src/Menu/ThemeManager.cpp (2 hunks)
  • src/Menu/ThemeManager.h (3 hunks)
  • src/Utils/UI.cpp (11 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Menu/MenuHeaderRenderer.cpp
  • src/Utils/UI.cpp
  • src/Menu/SettingsTabRenderer.cpp
  • src/Menu/ThemeManager.h
  • src/Menu/Fonts.h
  • src/Menu.h
  • src/Menu/ThemeManager.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Menu/MenuHeaderRenderer.cpp
  • src/Utils/UI.cpp
  • src/Menu/SettingsTabRenderer.cpp
  • src/Menu/ThemeManager.h
  • src/Menu/Fonts.h
  • src/Menu.h
  • src/Menu/ThemeManager.cpp
🧬 Code graph analysis (7)
src/Menu/MenuHeaderRenderer.cpp (1)
src/Utils/UI.cpp (6)
  • DrawAlignedTextWithLogo (299-336)
  • DrawAlignedTextWithLogo (299-299)
  • DrawSharpText (268-297)
  • DrawSharpText (268-268)
  • ButtonWithFlash (1358-1414)
  • ButtonWithFlash (1358-1358)
src/Utils/UI.cpp (1)
src/Menu/FeatureListRenderer.cpp (6)
  • menu (264-281)
  • menu (264-264)
  • menu (349-355)
  • menu (349-349)
  • label (283-292)
  • label (283-283)
src/Menu/SettingsTabRenderer.cpp (5)
src/Menu/Fonts.cpp (6)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
  • DiscoverFontCatalog (447-549)
  • DiscoverFontCatalog (447-447)
  • DiscoverFontCatalog (552-555)
  • DiscoverFontCatalog (552-552)
src/Menu.h (1)
  • GetFontRoleDefaultScale (88-91)
src/Utils/UI.cpp (4)
  • HoverTooltipWrapper (35-42)
  • HoverTooltipWrapper (44-50)
  • ButtonWithFlash (1358-1414)
  • ButtonWithFlash (1358-1358)
src/Utils/FileSystem.cpp (2)
  • GetThemesRealPath (149-152)
  • GetThemesRealPath (149-149)
src/Menu/ThemeManager.cpp (2)
  • ResolveFontSize (825-843)
  • ResolveFontSize (825-825)
src/Menu/ThemeManager.h (5)
src/Utils/Serialize.h (1)
  • nlohmann (2-18)
src/Menu/ThemeManager.cpp (28)
  • ResolveFontSize (825-843)
  • ResolveFontSize (825-825)
  • SetupImGuiStyle (95-200)
  • SetupImGuiStyle (95-95)
  • ReloadFont (250-518)
  • ReloadFont (250-250)
  • ForceApplyDefaultTheme (202-248)
  • ForceApplyDefaultTheme (202-202)
  • DiscoverThemes (521-575)
  • DiscoverThemes (521-521)
  • GetThemeNames (577-587)
  • GetThemeNames (577-577)
  • LoadTheme (589-626)
  • LoadTheme (589-589)
  • SaveTheme (628-676)
  • SaveTheme (628-629)
  • GetThemeInfo (678-684)
  • GetThemeInfo (678-678)
  • RefreshThemes (686-690)
  • RefreshThemes (686-686)
  • GetThemesDirectory (692-695)
  • GetThemesDirectory (692-692)
  • CreateDefaultThemeFiles (697-759)
  • CreateDefaultThemeFiles (697-697)
  • LoadThemeFile (761-818)
  • LoadThemeFile (761-761)
  • ValidateThemeData (820-823)
  • ValidateThemeData (820-820)
src/Menu.h (2)
  • Menu (23-154)
  • GetSingleton (99-103)
src/Menu.cpp (7)
  • Menu (171-196)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
src/State.cpp (4)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu/Fonts.h (3)
src/Menu.h (1)
  • Menu (23-154)
src/Menu.cpp (3)
  • Menu (171-196)
  • BuildFontSignature (161-164)
  • BuildFontSignature (161-161)
src/Menu/Fonts.cpp (20)
  • NormalizeFontRoles (90-116)
  • NormalizeFontRoles (90-90)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
  • FontRoleGuard (123-135)
  • FontRoleGuard (137-142)
  • BeginTabItemWithFont (144-148)
  • BeginTabItemWithFont (144-144)
  • DiscoverFontCatalog (447-549)
  • DiscoverFontCatalog (447-447)
  • DiscoverFontCatalog (552-555)
  • DiscoverFontCatalog (552-552)
  • FormatFontDisplayName (376-400)
  • FormatFontDisplayName (376-376)
  • DiscoverFonts (558-568)
  • DiscoverFonts (558-558)
  • ValidateFont (570-625)
  • ValidateFont (570-570)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Menu.h (6)
src/Utils/Serialize.h (1)
  • nlohmann (2-18)
src/Menu.cpp (17)
  • Menu (171-196)
  • ResolveFontRole (151-159)
  • ResolveFontRole (151-151)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadThemePreset (277-314)
  • LoadThemePreset (277-277)
  • CreateDefaultThemes (316-321)
  • CreateDefaultThemes (316-316)
  • BuildFontSignature (161-164)
  • BuildFontSignature (161-161)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
src/Menu/ThemeManager.cpp (9)
  • LoadTheme (589-626)
  • LoadTheme (589-589)
  • SaveTheme (628-676)
  • SaveTheme (628-629)
  • DiscoverThemes (521-575)
  • DiscoverThemes (521-521)
  • file (657-657)
  • file (730-730)
  • file (776-776)
src/State.cpp (4)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu/Fonts.cpp (2)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
src/Menu/ThemeManager.h (1)
  • ThemeManager (112-276)
src/Menu/ThemeManager.cpp (4)
src/Menu/Fonts.cpp (2)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Utils/UI.cpp (4)
  • CalculateLuminance (1222-1235)
  • CalculateLuminance (1222-1222)
  • AdjustBackgroundForTextContrast (1262-1278)
  • AdjustBackgroundForTextContrast (1262-1263)
src/Utils/FileSystem.cpp (4)
  • GetFontsPath (46-49)
  • GetFontsPath (46-46)
  • GetThemesPath (76-79)
  • GetThemesPath (76-76)
src/Menu.cpp (8)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (12)
src/Utils/UI.cpp (6)

180-197: LGTM!

The icon array expansion from 15 to 16 elements is correct, properly includes the new featureSettingRevert icon, and the count is updated consistently throughout the code.


318-320: LGTM!

The explicit spacing between logo and text improves visual separation and consistency in the UI layout.


452-463: LGTM!

The migration from hardcoded colors to theme-based Palette.Text with appropriate alpha adjustments for minimized (0.7) and hovered (0.8) states improves theme consistency and provides clear visual feedback.


514-516: LGTM!

Using theme Palette.Text instead of hardcoded white improves theme consistency and aligns with the overall theming approach.


756-789: LGTM!

The search bar now properly uses theme Palette.Text colors with appropriate alpha adjustment (0.7) for the icon, ensuring consistent theming throughout the interface.


1358-1414: LGTM!

The ButtonWithFlash implementation properly handles thread safety with a mutex-protected static map to track flash timers per button. The flash effect uses appropriate color brightening (±0.2 adjustment) and correctly manages the timer lifecycle.

src/Menu.h (1)

71-76: FontRole descriptors now match enum count (4).

Array length matches FontRole::Count. Resolves prior mismatch risk.

package/SKSE/Plugins/CommunityShaders/Themes/Default.json (1)

10-35: FontRoles length matches code (4).

Aligned with Menu::FontRoleDescriptors. Good.

src/Menu/SettingsTabRenderer.cpp (1)

26-35: Portable iequals helper looks good.

Simple ASCII-insensitive compare is sufficient here.

src/Menu/ThemeManager.h (1)

87-91: Confirm FullPalette size vs ImGuiCol_COUNT for your ImGui version.

Doc says “55 colors” but ImGuiCol_COUNT can change across versions; prefer referencing ImGuiCol_COUNT rather than a fixed number.

Based on learnings

src/Menu/ThemeManager.cpp (2)

768-775: Good: Path traversal protection when loading theme files.

Validating that filePath stays within the themes directory prevents directory traversal.


103-116: Remove unnecessary rebind of themeSettings: GetTheme() returns a const-reference to the same settings.Theme object, and LoadThemePreset’s assignment mutates it in-place—your original themeSettings remains valid and the proposed diff even breaks compilation.

Likely an incorrect or invalid review comment.

Comment thread package/SKSE/Plugins/CommunityShaders/Themes/Default.json
Comment thread src/Menu/MenuHeaderRenderer.cpp
Comment thread src/Menu/SettingsTabRenderer.cpp
Comment thread src/Menu/ThemeManager.cpp
Comment thread src/Menu/ThemeManager.cpp
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Oct 13, 2025

✅ A pre-release build is available for this PR:
Download

davo0411 and others added 2 commits October 13, 2025 22:29
Automated formatting by clang-format, prettier, and other hooks.
See https://pre-commit.ci for details.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Menu.cpp (1)

359-359: Consider checking ReloadFont return value during initialization.

The return value of ThemeManager::ReloadFont(*this, cachedFontSize) is not checked. If font loading fails during initialization, the UI continues with potentially missing or default fonts. While DrawOverlay() (lines 590-598) implements retry logic for deferred reloads, an initial failure here could degrade the user experience.

Consider logging the result:

-	ThemeManager::ReloadFont(*this, cachedFontSize);
+	if (!ThemeManager::ReloadFont(*this, cachedFontSize)) {
+		logger::warn("Menu::Init() - Initial font load failed, fonts may not be available");
+	}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a96c77 and 58c9cad.

📒 Files selected for processing (4)
  • src/Menu.cpp (10 hunks)
  • src/Menu/OverlayRenderer.cpp (2 hunks)
  • src/Menu/ThemeManager.cpp (2 hunks)
  • src/Menu/ThemeManager.h (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{cpp,cxx,cc,c,h,hpp,hxx,hlsl,hlsli,fx,fxh,py}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not include TODO/FIXME placeholders; provide complete, working solutions

Files:

  • src/Menu/OverlayRenderer.cpp
  • src/Menu/ThemeManager.cpp
  • src/Menu/ThemeManager.h
  • src/Menu.cpp
src/**/*.{cpp,cxx,cc,h,hpp,hxx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{cpp,cxx,cc,h,hpp,hxx}: Ensure SE/AE/VR runtime compatibility; use runtime detection patterns (e.g., REL::RelocateMember())
Include robust error handling and resource management with graceful degradation in the plugin code

Files:

  • src/Menu/OverlayRenderer.cpp
  • src/Menu/ThemeManager.cpp
  • src/Menu/ThemeManager.h
  • src/Menu.cpp
🧬 Code graph analysis (4)
src/Menu/OverlayRenderer.cpp (1)
src/Menu/ThemeManager.cpp (2)
  • ReloadFont (249-498)
  • ReloadFont (249-249)
src/Menu/ThemeManager.cpp (6)
src/Menu/Fonts.cpp (2)
  • IsPathWithinDirectory (170-187)
  • IsPathWithinDirectory (170-170)
src/Utils/UI.cpp (4)
  • CalculateLuminance (1222-1235)
  • CalculateLuminance (1222-1222)
  • AdjustBackgroundForTextContrast (1262-1278)
  • AdjustBackgroundForTextContrast (1262-1263)
src/Menu/ThemeManager.h (1)
  • GetSingleton (178-182)
src/Menu.h (1)
  • GetSingleton (99-103)
src/Utils/FileSystem.cpp (4)
  • GetFontsPath (46-49)
  • GetFontsPath (46-46)
  • GetThemesPath (76-79)
  • GetThemesPath (76-76)
src/Menu.cpp (4)
  • GetDefaultFontRole (166-169)
  • GetDefaultFontRole (166-166)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
src/Menu/ThemeManager.h (5)
src/Utils/Serialize.h (1)
  • nlohmann (2-18)
src/Menu/ThemeManager.cpp (28)
  • ResolveFontSize (805-823)
  • ResolveFontSize (805-805)
  • SetupImGuiStyle (94-199)
  • SetupImGuiStyle (94-94)
  • ReloadFont (249-498)
  • ReloadFont (249-249)
  • ForceApplyDefaultTheme (201-247)
  • ForceApplyDefaultTheme (201-201)
  • DiscoverThemes (501-555)
  • DiscoverThemes (501-501)
  • GetThemeNames (557-567)
  • GetThemeNames (557-557)
  • LoadTheme (569-606)
  • LoadTheme (569-569)
  • SaveTheme (608-656)
  • SaveTheme (608-609)
  • GetThemeInfo (658-664)
  • GetThemeInfo (658-658)
  • RefreshThemes (666-670)
  • RefreshThemes (666-666)
  • GetThemesDirectory (672-675)
  • GetThemesDirectory (672-672)
  • CreateDefaultThemeFiles (677-739)
  • CreateDefaultThemeFiles (677-677)
  • LoadThemeFile (741-798)
  • LoadThemeFile (741-741)
  • ValidateThemeData (800-803)
  • ValidateThemeData (800-800)
src/Menu.cpp (7)
  • Menu (171-196)
  • DiscoverThemes (267-275)
  • DiscoverThemes (267-267)
  • LoadTheme (234-250)
  • LoadTheme (234-234)
  • SaveTheme (252-265)
  • SaveTheme (252-252)
src/Menu.h (2)
  • Menu (23-154)
  • GetSingleton (99-103)
src/State.cpp (4)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu.cpp (3)
src/Menu.h (4)
  • FontRoleSettings (376-376)
  • Style (280-298)
  • Menu (23-154)
  • GetSingleton (99-103)
src/State.cpp (7)
  • i (189-189)
  • Save (395-462)
  • Save (395-395)
  • LoadTheme (831-864)
  • LoadTheme (831-831)
  • SaveTheme (866-890)
  • SaveTheme (866-866)
src/Menu/Fonts.cpp (8)
  • BuildFontSignature (150-164)
  • BuildFontSignature (150-150)
  • GetDefaultRole (118-121)
  • GetDefaultRole (118-118)
  • NormalizeFontRoles (90-116)
  • NormalizeFontRoles (90-90)
  • ValidateFont (570-625)
  • ValidateFont (570-570)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (3)
src/Menu/ThemeManager.cpp (1)

716-732: ...

src/Menu.cpp (2)

588-599: LGTM! Deferred font reload logic correctly implemented.

The font reload logic properly calls ThemeManager::ReloadFont before clearing the flag, ensuring the flag remains set if the reload fails. This allows automatic retry on the next frame, which addresses the issue raised in the previous review.


213-225: Fallback mechanism ensures Default theme load failures degrade gracefully
Init() retries loading Default.json and, on failure, invokes ThemeManager::ForceApplyDefaultTheme(), which applies a basic dark theme if needed.

@doodlum doodlum merged commit f02fe29 into community-shaders:dev Oct 13, 2025
15 checks passed
Pentalimbed pushed a commit to Pentalimbed/skyrim-community-shaders that referenced this pull request Dec 16, 2025
* chore(ui): update discord banner (community-shaders#1493)

* fix: use proper filename settingsuser.json (community-shaders#1491)

* chore(upscaling): increase fsr sharpness

* chore: rename d3d12interop to d3d12SwapChainActive (community-shaders#1494)

* feat(llf): remove particle lights (community-shaders#1495)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(llf): move llf to core (community-shaders#1496)

* fix: remove water clamp (community-shaders#1497)

* fix(upscaling): more upscaling fixes (community-shaders#1498)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix: fix some internal errors when debugging (community-shaders#1500)

* fix(ui): fix save settings conflicts & welcome screen (community-shaders#1501)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(ui): add constraints for discord banner size (community-shaders#1463)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(VR): fix exiting menu using controllers (community-shaders#1502)

* build: fix warnings (community-shaders#1505)

* feat(UI): allow tooltips for disabled elements (community-shaders#1503)

* feat(upscaling): add downscale percentages (community-shaders#1506)

* perf(ssgi): optimize  (community-shaders#1499)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(ui): font size and perf overlay improvements (community-shaders#1511)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: remove unused hooks (community-shaders#1510)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix: adjust IsInterior to consider kNoSky or kFixedDimensions flags (community-shaders#1512)

* fix(hair): correct hair indirect normal, marschner by default (community-shaders#1515)

Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: mostly revert ISHDR to 1.3.6 (community-shaders#1516)

* chore(upscaling): simplify interop and upscale methods (community-shaders#1514)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(hair): typo in code (community-shaders#1517)

* feat(ibl): lerp sky ibl using skylighting (community-shaders#1519)

* fix(sss): burley artifacts with effect blend (community-shaders#1518)

* fix(upscaling): fix screenshots when upscaling enabled (community-shaders#1520)

* fix(upscaling): fix mipbias sometimes being wrong (community-shaders#1521)

* fix: fix compile error if snow shader on (community-shaders#1522)

* chore(upscaling): revert fsr to typical settings (community-shaders#1523)

* fix: fix minor ui issues (community-shaders#1524)

* chore(grass collision): simpler grass collision (community-shaders#1525)

* fix: update skylighting and version

* fix(pbr): fix inconsistencies (community-shaders#1526)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: jiayev <l936249247@hotmail.com>

* feat(upscaling): sharpening slider (community-shaders#1527)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: bump versions

* fix(ibl): add ibl to reflection normalization (community-shaders#1528)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(hair): remove pbr lighting mult for hair (community-shaders#1531)

* chore(upscaling): add back upscale multiplier (community-shaders#1532)

* fix(upscaling): fix minor upscaling issues (community-shaders#1536)

* chore: gamma space normalisation (community-shaders#1535)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(grass collision): implement with texture and history (community-shaders#1539)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore(grass collision): less aggressive (community-shaders#1546)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(skylighting): fix cell id casting (community-shaders#1544)

* chore(emat): auto detect terrain parallax (community-shaders#1545)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: update versions

* feat(VR): enable upscaling (community-shaders#1507)

* fix(terrain shadows): fix brightened lods (community-shaders#1547)

* chore(upscaling): reduce ghosting near camera (community-shaders#1548)

* fix: fix grass not animating (community-shaders#1549)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix(grass collision): fix non-standard timescales (community-shaders#1550)

* build: deploy only updated files (community-shaders#1556)

* feat: add Clear Shader Cache to Advanced (community-shaders#1555)

* chore(featureissues): default collapse testing menu (community-shaders#1554)

* fix(VR): use only supported shaders from cache (community-shaders#1553)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* build: use gersemi cmake formatter (community-shaders#1557)

* fix(terrain): vanilla diffuse in pbr terrain cell too bright due to wrong color space (community-shaders#1558)

* docs: add new feature development template guide (community-shaders#1529)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* docs(UI): remove duplicate GPL license statement (community-shaders#1561)

* feat: add renderdoc for debugging (community-shaders#1560)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>

* fix(ui): welcome popup size issues (community-shaders#1573)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore(grass collision): minor tweaks (community-shaders#1568)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(terrain helper): fix conflicting bit (community-shaders#1566)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(UI): separate theme settings, UI refactor, font support (community-shaders#1571)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* chore: bump versions

* build: fix zipping aio (community-shaders#1579)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(grass collision): clamp maximum depth of grass (community-shaders#1578)

* feat(UI): enhance shader blocking (community-shaders#1564)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>

* fix: remove duplicate buffer setup (community-shaders#1586)

* feat: update shader compile elapsed time every second (community-shaders#1587)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* build: add cmake install commands (community-shaders#1372)

* feat(perf-overlay): add size controls (community-shaders#1591)

* fix(perf-overlay): fix infinite draw calls table height (community-shaders#1590)

* refactor(perf-overlay): remove collapsible headers (community-shaders#1572)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(perf-overlay): removed ImGuiTableFlags_ScrollX/Y for scroll bar issues (community-shaders#1594)

* build: fix shader copying to relative paths (community-shaders#1603)

* fix(ibl): apply ibl to cubemap normalisation for non deferred (community-shaders#1604)

* fix(grass): use correct light direction (community-shaders#1602)

* fix(welcome-popup): adjust font size & window spacing (community-shaders#1592)

* feat(lod): add gamma sliders (community-shaders#1588)

* build: correct CodeRabbit schema syntax (community-shaders#1608)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* build: add compile-time validation of GPU buffers (community-shaders#1427)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* ci: run shader validation on CMake and CI config changes (community-shaders#1606)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>

* feat: procedural sun

* limb darkening

* another darkening

* build(deps): remove orphaned Intel XeSS dependency (community-shaders#1611)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

* fix: accumulate sunlight color in pixel shader output

* fix(ui): enter key now behaves properly when first time popup is open (community-shaders#1615)

* feat(ui): add tabs to advanced settings & PBR search (community-shaders#1599)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* build: add HLSL intellisense (community-shaders#1614)

* refactor(UI): move light limit visualization into debug (community-shaders#1619)

* refactor(ui): add settings for shader block hotkeys (community-shaders#1624)

Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com>

* fix(ui): anchor reset settings button position  (community-shaders#1621)

Co-authored-by: Giovanni Correia <Gistix@users.noreply.github.com>

* fix(hair): use indirect normal for deferred marschner hair (community-shaders#1626)

* build: fix Package-AIO-Manual for fresh pulls (community-shaders#1625)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(snow): use world space vectors (community-shaders#1618)

* feat(UI): add gaussian blur shader core files (community-shaders#1595)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(ui): add test conditions button (community-shaders#1637)

* fix(ui): blocked shader info overflow in Shader Debug tab (community-shaders#1632)

* fix(upscaling): replace NIS with RCAS for DLSS (community-shaders#1620)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix(dynamic cubemaps): add a check for timeskip (community-shaders#1639)

* refactor: restructure lighting (community-shaders#1633)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* feat(ui): add themes & fonts (community-shaders#1596)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* feat(water): add flowmap parallax (community-shaders#1636)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* fix cloud shadow setting saving

---------

Co-authored-by: zxcvbn <66063766+zndxcvbn@users.noreply.github.com>
Co-authored-by: davo0411 <davidkehoe0411@outlook.com>
Co-authored-by: doodlum <15017472+doodlum@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@users.noreply.github.com>
Co-authored-by: soda <130315225+soda3000@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: ThePagi <32794457+ThePagi@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: alandtse <7086117+alandtse@users.noreply.github.com>
Co-authored-by: Alan Tse <alandtse@gmail.com>
Co-authored-by: Yupeng Zhang <ArcEarth@outlook.com>
Co-authored-by: kuplion <kuplion@hotmail.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Giovanni Correia <Gistix@users.noreply.github.com>
Co-authored-by: Bruce <44987693+brucenguyen@users.noreply.github.com>
Co-authored-by: Midona <106106405+midona-rhel@users.noreply.github.com>
@davo0411 davo0411 deleted the ui-rework-pr1 branch December 31, 2025 04:36
@coderabbitai coderabbitai Bot mentioned this pull request Feb 13, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants