Skip to content

feat(ui): add subheading organisation to the features panel#1155

Merged
alandtse merged 4 commits into
community-shaders:devfrom
davo0411:Feature-headings
Jun 18, 2025
Merged

feat(ui): add subheading organisation to the features panel#1155
alandtse merged 4 commits into
community-shaders:devfrom
davo0411:Feature-headings

Conversation

@davo0411
Copy link
Copy Markdown
Collaborator

@davo0411 davo0411 commented Jun 16, 2025

20C2B1~1
200F6B~1
(ignore image 2 having duplicate terrain / Landscape & textures panels, the final code is only "Landscape & Textures", "Terrain" is gone.
Adds expandable subheadings to the left-hand features pane for better organisation.

Part of my ongoing UI changes.

Summary by CodeRabbit

  • New Features
    • Features in the menu are now grouped into collapsible categories with improved visual headers.
    • Categories have persistent expansion states, making navigation more intuitive.
    • Each feature now displays a category label such as "Lighting", "Sky", "Characters", "Grass", "Water", or "Landscape & Textures".
  • UI Improvements
    • Added custom-styled headers for both categories and sections, enhancing menu readability and organization.
    • Features are sorted alphabetically within each category for easier browsing.
  • Theme Enhancements
    • Introduced new color palette options for UI elements, including success and informational status colors and dedicated feature heading colors, improving visual consistency and clarity.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 16, 2025

"""

Walkthrough

A category system for features was introduced, adding a virtual GetCategory() method to all feature classes and grouping features by category in the UI. The menu now displays collapsible, stylized category headers using new UI utility functions, improving feature organization and navigation.

Changes

File(s) Change Summary
src/Feature.h Added virtual GetCategory() method to base Feature struct, defaulting to "Other".
src/Features/CloudShadows.h
src/Features/DynamicCubemaps.h
src/Features/ExtendedMaterials.h
src/Features/GrassCollision.h
src/Features/GrassLighting.h
src/Features/HairSpecular.h
src/Features/IBL.h
src/Features/InteriorSunShadows.h
src/Features/InverseSquareLighting.h
src/Features/LODBlending.h
src/Features/LightLimitFix.h
src/Features/ScreenSpaceGI.h
src/Features/ScreenSpaceShadows.h
src/Features/SkySync.h
src/Features/Skylighting.h
src/Features/SubsurfaceScattering.h
src/Features/TerrainBlending.h
src/Features/TerrainHelper.h
src/Features/TerrainShadows.h
src/Features/TerrainVariation.h
src/Features/VolumetricLighting.h
src/Features/WaterEffects.h
src/Features/WetnessEffects.h
Each feature struct/class now overrides GetCategory() to return its specific category string.
src/Menu.cpp Refactored menu to group features by category, added collapsible category headers, and persistent expansion.
src/Utils/UI.cpp Added DrawCategoryHeader and DrawSectionHeader functions for custom header rendering with ImGui.
src/Utils/UI.h Declared DrawCategoryHeader and DrawSectionHeader in the Util namespace.
src/Menu.h Added new color members to StatusPaletteColors and introduced FeatureHeadingColors struct inside ThemeSettings.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Menu
    participant Feature
    participant Util

    User->>Menu: Open feature menu
    Menu->>Feature: Query GetCategory() for each feature
    Menu->>Menu: Group features by category
    Menu->>Util: DrawCategoryHeader(categoryName, isExpanded)
    alt Category expanded
        Menu->>Util: Render features under category
    end
    Note over Menu: Category expansion state persists
Loading

Suggested reviewers

  • alandtse

Poem

🐇 Hopping through code, I found a way,
To sort features bright as day.
Categories bloom in menus wide,
Collapsible headers, a joyful ride!
From sky to grass, and water's gleam,
A rabbit's dream in UI theme.
🌿✨
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 1

♻️ Duplicate comments (7)
src/Features/SubsurfaceScattering.h (1)

69-69: Same centralisation concern as raised in InteriorSunShadows.h

See earlier comment about consolidating category literals.

src/Features/WetnessEffects.h (1)

19-19: Same centralisation concern as raised in InteriorSunShadows.h

See earlier comment about consolidating category literals.

src/Features/GrassCollision.h (1)

19-19: Same centralisation concern as raised in InteriorSunShadows.h

See earlier comment about consolidating category literals.

src/Features/GrassLighting.h (1)

19-19: Same centralisation concern as raised in InteriorSunShadows.h

See earlier comment about consolidating category literals.

src/Features/TerrainHelper.h (1)

18-18: Same “string-literal category” duplication as noted in HairSpecular

Please see the earlier comment about centralising category values to prevent drift.

src/Features/ScreenSpaceShadows.h (1)

19-19: Same “string-literal category” duplication as noted previously

Refer to the suggestion in HairSpecular.h.

src/Features/TerrainShadows.h (1)

21-21: Same “string-literal category” duplication as noted previously

Refer to the suggestion in HairSpecular.h.

🧹 Nitpick comments (10)
src/Feature.h (1)

47-52: Consider centralising category literals and marking the accessor as [[nodiscard]].

Having every feature return a raw string literal is safe but error-prone: a single typo in one override produces an extra, empty header in the menu.
A lightweight enum → string map, or at minimum constexpr std::string_view constants collected in one header (e.g. Categories.h) would give compile-time checking and auto-completion support.

While touching the signature, adding [[nodiscard]] signals callers that the value is meant to be used.

-	virtual std::string_view GetCategory() const { return "Other"; }
+	[[nodiscard]] virtual std::string_view GetCategory() const { return CATEGORY_OTHER; }

(where CATEGORY_OTHER would be defined in the proposed common header).

src/Features/LODBlending.h (1)

14-14: Add inline (or a shared constant) for header-defined GetCategory() to keep ODR hygiene and avoid string typos

All other small methods in this header are declared inline; omitting it here is an inconsistency that can trigger multiple-definition linker errors if the header is included in more than one TU without -fvisibility-inlines-hidden.

-	virtual std::string_view GetCategory() const override { return "Landscape & Textures"; }
+	virtual inline std::string_view GetCategory() const override { return "Landscape & Textures"; }

Long-term, consider centralising category strings in a constexpr std::string_view (or enum → lookup) to prevent typos and make refactors trivial.

src/Features/TerrainBlending.h (1)

15-15: Consistency: mark the header-defined override inline

Same rationale as for LODBlending: keep style uniform and eliminate the tiny risk of ODR violations.

-	virtual std::string_view GetCategory() const override { return "Landscape & Textures"; }
+	virtual inline std::string_view GetCategory() const override { return "Landscape & Textures"; }
src/Features/InverseSquareLighting.h (1)

19-19: Inline qualifier missing

For uniformity with neighbouring one-liners (GetName(), GetShortName() …) and safer linkage, add inline.

-	virtual std::string_view GetCategory() const override { return "Lighting"; }
+	virtual inline std::string_view GetCategory() const override { return "Lighting"; }
src/Features/ScreenSpaceGI.h (1)

21-21: Inline qualifier

Same minor consistency issue—worth fixing while the file is touched.

-	virtual std::string_view GetCategory() const override { return "Lighting"; }
+	virtual inline std::string_view GetCategory() const override { return "Lighting"; }
src/Features/VolumetricLighting.h (1)

35-35: Inline for header method

Keep all tiny accessors marked inline to avoid redundant symbol emission.

-	virtual std::string_view GetCategory() const override { return "Lighting"; }
+	virtual inline std::string_view GetCategory() const override { return "Lighting"; }
src/Features/InteriorSunShadows.h (1)

14-14: Category string is hard-coded; consider centralising to avoid drift

Every feature now embeds its own string literal for the category. Typos or later renames will require touching dozens of files. A small enum class FeatureCategory { Lighting, Grass, … } or at least a header with constexpr std::string_view constants would eliminate that risk and simplify refactors.

No action is strictly required for this PR, but worth tracking before more features are added.

src/Utils/UI.cpp (1)

103-157: Well-implemented custom category header rendering.

The function correctly handles interaction, dynamic sizing, and edge cases. Consider extracting the magic numbers (padding: 20.0f, vertical spacing: 8.0f) as named constants for better maintainability.

src/Menu.cpp (2)

366-367: Consider persisting category expansion states.

The static map maintains expansion states only during the current session. Users might expect these UI preferences to persist across application restarts. Consider saving/loading these states as part of the menu settings.


614-614: Consider making category order configurable.

The hardcoded category order works well but could be made configurable to allow users or modders to customize the menu organization according to their preferences.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b9e1401 and 59ac141.

📒 Files selected for processing (27)
  • src/Feature.h (1 hunks)
  • src/Features/CloudShadows.h (1 hunks)
  • src/Features/DynamicCubemaps.h (1 hunks)
  • src/Features/ExtendedMaterials.h (1 hunks)
  • src/Features/GrassCollision.h (1 hunks)
  • src/Features/GrassLighting.h (1 hunks)
  • src/Features/HairSpecular.h (1 hunks)
  • src/Features/IBL.h (1 hunks)
  • src/Features/InteriorSunShadows.h (1 hunks)
  • src/Features/InverseSquareLighting.h (1 hunks)
  • src/Features/LODBlending.h (1 hunks)
  • src/Features/LightLimitFix.h (1 hunks)
  • src/Features/ScreenSpaceGI.h (1 hunks)
  • src/Features/ScreenSpaceShadows.h (1 hunks)
  • src/Features/SkySync.h (1 hunks)
  • src/Features/Skylighting.h (1 hunks)
  • src/Features/SubsurfaceScattering.h (1 hunks)
  • src/Features/TerrainBlending.h (1 hunks)
  • src/Features/TerrainHelper.h (1 hunks)
  • src/Features/TerrainShadows.h (1 hunks)
  • src/Features/TerrainVariation.h (1 hunks)
  • src/Features/VolumetricLighting.h (1 hunks)
  • src/Features/WaterEffects.h (1 hunks)
  • src/Features/WetnessEffects.h (1 hunks)
  • src/Menu.cpp (5 hunks)
  • src/Utils/UI.cpp (2 hunks)
  • src/Utils/UI.h (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/Menu.cpp (2)
src/Utils/UI.cpp (4)
  • DrawSectionHeader (159-192)
  • DrawSectionHeader (159-159)
  • DrawCategoryHeader (103-157)
  • DrawCategoryHeader (103-103)
src/Utils/UI.h (2)
  • DrawSectionHeader (126-126)
  • DrawCategoryHeader (119-119)
src/Utils/UI.cpp (1)
src/Utils/UI.h (1)
  • hovered (22-22)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (15)
src/Features/SkySync.h (1)

14-15: Category override looks good.

The override matches the new base signature (const, override) and uses a safe string literal. No issues spotted.

src/Features/TerrainVariation.h (1)

21-22: Category override looks good.

Consistent with the rest of the codebase and the UI grouping strategy.

src/Features/LightLimitFix.h (1)

21-22: Category override looks good.

The "Lighting" literal is concise and will group correctly.

src/Features/ExtendedMaterials.h (1)

14-15: Category override looks good.

No further comments.

src/Features/WaterEffects.h (1)

22-22: Override GetCategory() for UI grouping
Correctly introduces the GetCategory() override returning "Water", aligning this feature with the new collapsible “Water” section in the UI.

src/Features/IBL.h (1)

17-17: Override GetCategory() for UI grouping
The GetCategory() override returns "Lighting", ensuring this feature appears under the Lighting section in the feature panel.

src/Features/DynamicCubemaps.h (1)

105-105: Override GetCategory() for UI grouping
The GetCategory() override returning "Lighting" is correct and will group this feature under the Lighting header.

src/Features/CloudShadows.h (1)

26-26: Override GetCategory() for UI grouping
This override returns "Sky", which aligns CloudShadows with the Sky category in the collapsible UI menu.

src/Features/Skylighting.h (1)

21-21: Override GetCategory() for UI grouping
The GetCategory() override here returns "Sky", correctly grouping Skylighting under the Sky section of the features panel.

src/Utils/UI.h (2)

3-3: Good call including <imgui.h> directly

This makes UI.h self-contained and prevents order-dependent build breaks.


113-126: Add UTIL_API / IMGUI_API visibility decorators (or inline) to new helpers

DrawCategoryHeader / DrawSectionHeader will be defined in UI.cpp.
Without a visibility/export macro they will have default internal linkage on MSVC-DLL builds, causing unresolved externals when the header is included from other translation units in a DLL.
If the project already uses an export macro (e.g., UTIL_API), mark them:

-bool DrawCategoryHeader(const char* categoryName, bool& isExpanded);
-void DrawSectionHeader(const char* sectionName, bool useWhiteText = false);
+UTIL_API bool DrawCategoryHeader(const char* categoryName, bool& isExpanded);
+UTIL_API void DrawSectionHeader(const char* sectionName, bool useWhiteText = false);

If you intend them to be header-only, add inline instead.

src/Utils/UI.cpp (2)

2-2: LGTM!

The ImGui header include is necessary for the new UI utility functions.


159-192: Clean implementation of non-interactive section headers.

The function appropriately reuses the visual style from DrawCategoryHeader while removing interaction logic. The conditional text coloring provides good flexibility.

src/Menu.cpp (2)

24-24: LGTM!

Required include for the new UI utility functions.


393-410: Good integration of the new UI utilities.

The visitor implementation properly handles both special section headers and interactive category headers, maintaining consistent styling across the UI.

Comment thread src/Features/HairSpecular.h
@davo0411 davo0411 changed the title feat(ui): Add subheading organisation to the features panel. feat(ui): add subheading organisation to the features panel. Jun 16, 2025
@davo0411 davo0411 changed the title feat(ui): add subheading organisation to the features panel. feat(ui): add subheading organisation to the features panel Jun 16, 2025
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 16, 2025

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

Comment thread src/Utils/UI.cpp Outdated
Comment thread src/Utils/UI.cpp Outdated
@davo0411 davo0411 requested a review from alandtse June 17, 2025 13:51
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.h (1)

69-80: Make the new color palette immutable & avoid per-instance memory overhead

UITemplateColors is instantiated as a mutable data member (UITemplate).
Because Menu::Settings::Theme already lives as a data member inside every Menu
instance, every copy incurs ~84 bytes for this palette. The values are compile-time
constants and should never be mutated at runtime, so you can both:

  1. Prevent accidental modification.
  2. Have the data emitted only once in the binary.
-       struct UITemplateColors
+       struct UITemplateColors
        {
            …
-       } UITemplate;
+       };
+
+       // One read-only instance shared by all ThemeSettings
+       inline static constexpr UITemplateColors UITemplate{};

This keeps call-sites unchanged (theme.UITemplate.*) while making the
palette constexpr, deduplicating storage and improving clarity that the
colors are part of the theme’s constant definition rather than user-editable.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59ac141 and ea15a9b.

📒 Files selected for processing (2)
  • src/Menu.h (1 hunks)
  • src/Utils/UI.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Utils/UI.cpp
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build plugin and addons

Comment thread src/Menu.h Outdated
@davo0411 davo0411 requested a review from alandtse June 18, 2025 00:31
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: 1

🔭 Outside diff range comments (1)
src/Menu.cpp (1)

108-115: ThemeSettings JSON layout now out of sync with previous saves

Adding FeatureHeading in the middle of the aggregate struct changes the serialized order.
Old settings.json files will silently read the new field as Style, shifting everything that follows.
Either:

  1. Add the new member at the end of the struct, or
  2. Bump the settings version and perform migration.

Failing to do so will corrupt all stored user themes.

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

36-41: Naming inconsistency in StatusPaletteColors

SuccessColor / InfoColor are the only palette entries with the redundant “Color” suffix, while peer fields are simply Disable, Error, etc. This breaks the otherwise consistent naming scheme and will read oddly at all call-sites (StatusPalette.SuccessColor). Consider dropping the suffix to keep the API uniform.

-   SuccessColor,
-   InfoColor
+   Success,
+   Info

42-48: Implicit default construction may hide bugs

Both LineColorHovered and TextColorHovered default-construct to black/zero if the JSON omits them.
That makes the header unreadable in the UI yet fails silently. Provide sane defaults or validate the JSON when loading.

+   LineColorHovered   = { 1.0f, 1.0f, 1.0f, 0.25f },
+   TextColorHovered   = { 1.0f, 1.0f, 1.0f, 1.0f },

367-381: Static map for expansion state is fine, but std::map is over-kill

A dozen categories are stored; unordered_map gives O(1) and smaller codegen.
Also, no locking is required because rendering is single-threaded.

- static std::map<std::string, bool> categoryExpansionStates;
+ static std::unordered_map<std::string, bool> categoryExpansionStates;

884-896: Color editor exposes new fields that are not consumed anywhere

FeatureHeading.* colors are editable but never applied in SetupImGuiStyle(). If they are only used inside Util::DrawCategoryHeader, ensure that helper reads them; otherwise users will think the setting is broken.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea15a9b and 8db5813.

📒 Files selected for processing (3)
  • src/Menu.cpp (8 hunks)
  • src/Menu.h (1 hunks)
  • src/Utils/UI.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Utils/UI.cpp
  • src/Menu.h
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build plugin and addons
🔇 Additional comments (1)
src/Menu.cpp (1)

602-646: Category collapse takes one frame to propagate

menuList is rebuilt before the header is drawn, so toggling a category hides/shows its contents only on the next frame, causing a perceptible flicker.
Consider rebuilding the list immediately after the toggle or, more simply, draw feature rows unconditionally and rely on ImGui::BeginDisabled/spacing to hide them—avoiding the rebuild altogether.

Comment thread src/Menu.cpp
Copy link
Copy Markdown
Collaborator

@alandtse alandtse left a comment

Choose a reason for hiding this comment

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

Merge able once ci passes. Thanks.

@alandtse alandtse merged commit 20709fa into community-shaders:dev Jun 18, 2025
12 checks passed
@davo0411 davo0411 deleted the Feature-headings branch June 19, 2025 10:52
alandtse pushed a commit that referenced this pull request Jun 20, 2025
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
davo0411 added a commit to davo0411/skyrim-community-shaders that referenced this pull request Jun 21, 2025
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
alandtse pushed a commit to alandtse/open-shaders that referenced this pull request Jul 20, 2025
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
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