settings_ui: Add dynamic settings UI item (#37331)

Closes #ISSUE

Adds a first draft of a way for "Dynamic" settings items to be added,
where Dynamic means settings where multiple sets of options are possible
(i.e. discriminated union, rust enum, etc). The implementation is very
similar to that of `Group`, except that instead of rendering all of it's
descendants, it contains a function to determine _which_ descendant to
render, whether that be a single item or a nested group of items.
Currently this is done in a type-unsafe way with indices, a future
improvement could be to make the API more type safe, and easier to
manually implement correctly.

An example of a "Dynamic" setting is `theme`, where it can either be a
string of the desired theme name, or an object with `mode: "light" |
"dark" | "system"` as well as theme names for `light` and `dark`. In the
system implemented by this PR, this would become a dynamic settings UI
item, where option `0` is a single item, the theme name selector, and
option `1` is a group, containing items for the `mode`, and
`light`/`dark` options.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle
2025-09-01 17:53:43 -04:00
committed by GitHub
parent 634a1343dd
commit 8a8a9a4f07
3 changed files with 93 additions and 35 deletions
+9
View File
@@ -29,6 +29,11 @@ pub enum SettingsUiEntryVariant {
path: &'static str,
item: SettingsUiItemSingle,
},
Dynamic {
path: &'static str,
options: Vec<SettingsUiEntry>,
determine_option: fn(&serde_json::Value, &mut App) -> usize,
},
// todo(settings_ui): remove
None,
}
@@ -90,6 +95,10 @@ pub enum SettingsUiItem {
items: Vec<SettingsUiEntry>,
},
Single(SettingsUiItemSingle),
Dynamic {
options: Vec<SettingsUiEntry>,
determine_option: fn(&serde_json::Value, &mut App) -> usize,
},
None,
}