Theme plugin system#8153
Conversation
|
Preview available at https://egui-pr-preview.github.io/pr/8153-themeplugin View snapshot changes at kitdiff |
There was a problem hiding this comment.
I think it's trying to do a bit too much at once for now. We should try to start with a super minimal api.
The way it's set up with the single ThemePlugin that can be active at a time breaks extensibility. Say someone makes a EguiMaterial theme crate, and someone else makes a EguiSwitch component crate, and you want to use both in your project.
The way it's now, one would have to make a whole new ThemePlugin struct that wraps the EguiMaterialThemePlugin and adds support for the EguiSwitchStyle (since the rust orphan rules would prevent you from adding something like:
impl ThemeStyle<EguiSwitchStyle> for MeterialThemePlugin {.
So I would suggest we simplify the registration api to instead be per widget type. You could still have a single struct that impls the styles of all the different widget kinds, but they should be added indivudually. (Of course any theme plugin could offer a helper fn that registers them all).
Something like this:
let theme = EguiMaterialTheme::new();
let switch_theme = EguiSwitchTheme::new();
ctx.add_theme::<ButtonStyle>(theme);
ctx.add_theme::<SwitchStyle>(switch_theme);Both of these would be active at the same time, and there can only ever be a single registered theme per type.
Theme switching could still be implemented either by reregistering the different style types with different configs or by something internal to the theme plugin.
Caching could be reduced to some CachingThemePlugin that wraps some other plugin, so if someone doesn't want / need caching they could skip it.
| /// Change the current theme used by the system to compute the style | ||
| pub fn switch_theme(&self, theme_id: &impl ToString) { | ||
| self.write(|ctx| ctx.theme.set_current_theme(theme_id)); | ||
| } |
There was a problem hiding this comment.
Do we need a seperate api for this or could this be handled via classes? E.g. a dark_mode class on the root Ui to set the theme to dark mode. (Could even allow changing the theme within a part of the ui, by setting a different theme class there).
There was a problem hiding this comment.
Caching could be reduced to some CachingThemePlugin that wraps some other plugin, so if someone doesn't want / need caching they could skip it.
Why not use a flag in the ThemePlugin implementation ? That way if we don't find it in the cache, we compute the style and store it only if it's wanted.
Do we need a separate api for this or could this be handled via classes? E.g. a dark_mode class on the root Ui to set the theme to dark mode.
This is an idea, but we need to differentiate "theme" classes from regular classes. I also think that if many people design and share their own themes, their gonna need to share the same keyword like root and selected. Maybe I should create an enum with these keywords and one that take a Classname as a value.
Otherwise the change in how the theme are registered already allow to switch the theme.
What it does
Addition of a new system of theme plugins which allow the user to use different rules engine to compute the style for the available specialised widget style.
How to use
Create a engine implementing the trait
ThemePluginandThemeStyle<S: StyleStruct>and implement the necessary methods, then register this way (example forButtonStyle):ui.add_theme::<ButtonStyle>(&mycustomengine);Now all button will call the
ThemeStyle<ButtonStyle>method to compute the correct style and later use the cached value to avoid the costly computation.If no valid
ThemeStyle<S>or engine is available then it fallback to the default style.