From 63eacb180008a720cffabfb19d9dcd930c208f23 Mon Sep 17 00:00:00 2001 From: adrien <221212@umons.ac.be> Date: Wed, 24 Jun 2026 19:37:15 +0200 Subject: [PATCH] Renaming, comment & better default system --- crates/egui/src/context.rs | 27 ++- crates/egui/src/theme_plugin.rs | 219 +++++++++++++++--- crates/egui/src/widget_style.rs | 220 +------------------ crates/egui/src/widgets/button.rs | 1 - crates/egui/src/widgets/checkbox.rs | 2 +- crates/egui/src/widgets/separator.rs | 2 +- examples/styling_engine/src/custom_engine.rs | 16 +- examples/styling_engine/src/main.rs | 10 +- 8 files changed, 229 insertions(+), 268 deletions(-) diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 77ee51a87..76b03e881 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -38,7 +38,7 @@ use crate::{ resize, response, scroll_area, theme_plugin, util::IdTypeMap, viewport::ViewportClass, - widget_style::{Classes, StyleStruct, WidgetState}, + widget_style::{Classes, WidgetState, WidgetStyle}, }; use crate::IdMap; @@ -2031,37 +2031,36 @@ impl Context { } impl Context { - /// Register a [`ThemeStyle`](crate::theme_plugin::ThemeStyle) for the specified widget [`StyleStruct`](StyleStruct) `S` + /// Register a [`ThemeStyle`](crate::theme_plugin::ThemeStyle) for the specified widget type. /// /// A theme can only be added once for a specified widget. - /// This way it's convenient to add themes in `eframe::run_simple_native`. - /// If you want to add the theme anyway, use [`Self::replace_theme`] instead. - pub fn add_theme( + /// If a theme is already registered for this widget, this is a no-op (useful for `eframe::run_simple_native`). + /// + /// If you want to add the theme anyway, use [`Self::replace_widget_theme`] instead. + pub fn add_widget_theme( &self, theme: impl theme_plugin::ThemeStyle + Send + Sync + 'static, ) { self.write(|ctx| ctx.themes.register::(theme, false)); } - /// Register a [`ThemeStyle`](crate::theme_plugin::ThemeStyle) for the specified widget [`StyleStruct`](StyleStruct) `S` + /// Register a [`ThemeStyle`](crate::theme_plugin::ThemeStyle) for the specified widget. /// - /// Overwrite any theme already registered for the specified widget [`StyleStruct`](StyleStruct). - /// If you want to avoid overwriting existing theme, use [`Self::add_theme`] instead. - pub fn replace_theme( + /// Overwrite any theme already registered for the specified widget [`WidgetStyle`](WidgetStyle). + /// This allow to live edit a theme. + pub fn replace_widget_theme( &self, theme: impl theme_plugin::ThemeStyle + Send + Sync + 'static, ) { self.write(|ctx| ctx.themes.register::(theme, true)); } - /// Compute the [`StyleStruct`] using the registered theme if available. - /// - /// Return `None` if no theme was registered for the [`StyleStruct`] - pub fn get_style( + /// Compute the [`WidgetStyle`] using the registered theme. + pub(crate) fn get_widget_style( &self, classes: &Classes, state: WidgetState, - ) -> Option { + ) -> S { self.write(move |ctx| ctx.themes.get::(classes, state)) } } diff --git a/crates/egui/src/theme_plugin.rs b/crates/egui/src/theme_plugin.rs index 672dbf401..faa685248 100644 --- a/crates/egui/src/theme_plugin.rs +++ b/crates/egui/src/theme_plugin.rs @@ -1,11 +1,16 @@ -use std::sync::Arc; +use std::{any::TypeId, sync::Arc}; -use epaint::mutex::Mutex; +use emath::Vec2; +use epaint::{Shadow, Stroke, mutex::Mutex, text::TextWrapMode}; use crate::{ - Id, Ui, + Frame, Id, Spacing, Style, TextStyle, Ui, Visuals, + style::Widgets, util::IdTypeMap, - widget_style::{Classes, StyleStruct, WidgetState}, + widget_style::{ + BaseStyle, ButtonStyle, CheckboxStyle, Classes, HasClasses as _, LabelStyle, + SELECTED_CLASS, SeparatorStyle, TextVisuals, WidgetState, WidgetStyle, + }, }; /// A cache that can be implemented to reduce computation time of a `ThemeStyle` @@ -15,12 +20,12 @@ pub struct ThemeCache { } impl ThemeCache { - /// Access the cache for the requested [`StyleStruct`] based on the [`Classes`] and + /// Access the cache for the requested [`WidgetStyle`] based on the [`Classes`] and /// the [`WidgetState`] /// /// If no entry match the parameter then compute the fallback style and /// save the output for later. - pub fn get( + pub fn get( &mut self, classes: &Classes, state: WidgetState, @@ -37,45 +42,201 @@ impl ThemeCache { } } -/// A Theme plugin that implement a style computation for a defined `StyleStruct` +/// A Theme plugin that implement a style computation for a defined `WidgetStyle` pub trait ThemeStyle { /// The style according to the classes and state of the widget - fn style(&mut self, classes: &Classes, state: WidgetState) -> S; + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> S; + + /// Help to differ the different themes + fn theme_type_id(&self) -> TypeId + where + Self: 'static, + { + TypeId::of::() + } +} + +#[derive(Debug, Clone)] +struct DefaultStyle; + +impl ThemeStyle for DefaultStyle { + fn style(&mut self, _themes: &Themes, _classes: &Classes, state: WidgetState) -> BaseStyle { + let visuals = Widgets::dark(); + let spacing = Spacing::default(); + + let visuals = match state { + WidgetState::Noninteractive => visuals.noninteractive, + WidgetState::Inactive => visuals.inactive, + WidgetState::Hovered => visuals.hovered, + WidgetState::Active => visuals.active, + }; + + BaseStyle { + frame: Frame { + fill: visuals.bg_fill, + stroke: visuals.bg_stroke, + corner_radius: visuals.corner_radius, + inner_margin: spacing.button_padding.into(), + ..Default::default() + }, + stroke: visuals.fg_stroke, + text: TextVisuals { + color: visuals.text_color(), + font_id: TextStyle::Body.resolve(&Style::default()), + strikethrough: Stroke::NONE, + underline: Stroke::NONE, + }, + } + } +} + +impl ThemeStyle for DefaultStyle { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> ButtonStyle { + let widget_visuals = Widgets::dark(); + let spacing = Spacing::default(); + + let mut widget_visuals = match state { + WidgetState::Noninteractive => widget_visuals.noninteractive, + WidgetState::Inactive => widget_visuals.inactive, + WidgetState::Hovered => widget_visuals.hovered, + WidgetState::Active => widget_visuals.active, + }; + + let mut ws: BaseStyle = themes.get(classes, state); + + if classes.has(SELECTED_CLASS) { + let visuals = Visuals::default(); + widget_visuals.weak_bg_fill = visuals.selection.bg_fill; + widget_visuals.bg_fill = visuals.selection.bg_fill; + widget_visuals.fg_stroke = visuals.selection.stroke; + ws.text.color = visuals.selection.stroke.color; + } + + ButtonStyle { + frame: Frame { + fill: widget_visuals.weak_bg_fill, + stroke: widget_visuals.bg_stroke, + corner_radius: widget_visuals.corner_radius, + outer_margin: (-Vec2::splat(widget_visuals.expansion)).into(), + inner_margin: (spacing.button_padding + Vec2::splat(widget_visuals.expansion) + - Vec2::splat(widget_visuals.bg_stroke.width)) + .into(), + ..Default::default() + }, + text_style: ws.text, + } + } +} + +impl ThemeStyle for DefaultStyle { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> CheckboxStyle { + let widget_visuals = Widgets::dark(); + let spacing = Spacing::default(); + + let widget_visuals = match state { + WidgetState::Noninteractive => widget_visuals.noninteractive, + WidgetState::Inactive => widget_visuals.inactive, + WidgetState::Hovered => widget_visuals.hovered, + WidgetState::Active => widget_visuals.active, + }; + + let ws: BaseStyle = themes.get(classes, state); + + CheckboxStyle { + frame: Frame::new(), + checkbox_size: spacing.icon_width, + check_size: spacing.icon_width_inner, + checkbox_frame: Frame { + fill: widget_visuals.bg_fill, + corner_radius: widget_visuals.corner_radius, + stroke: widget_visuals.bg_stroke, + ..Default::default() + }, + text_style: ws.text, + check_stroke: ws.stroke, + } + } +} + +impl ThemeStyle for DefaultStyle { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> LabelStyle { + let ws: BaseStyle = themes.get(classes, state); + + LabelStyle { + frame: Frame { + fill: ws.frame.fill, + inner_margin: 0.0.into(), + outer_margin: 0.0.into(), + stroke: Stroke::NONE, + shadow: Shadow::NONE, + corner_radius: 0.into(), + }, + text: ws.text, + wrap_mode: TextWrapMode::Wrap, + } + } +} + +impl ThemeStyle for DefaultStyle { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> SeparatorStyle { + let ws: BaseStyle = themes.get(classes, state); + + SeparatorStyle { + spacing: 6.0, + stroke: ws.frame.stroke, + } + } } impl Ui { - /// Access the installed theme plugin if there is one and fetch the requested widget style if it exist. - /// Fallback to the default style if not found. + /// Access the register theme and fetch the requested [`WidgetStyle`]. /// - /// Requested widget style must implement [`StyleStruct`]. - pub fn widget_style( + /// Requested widget style must implement [`WidgetStyle`]. + pub fn widget_style( &self, id: crate::Id, classes: &Classes, ) -> S { // Fetch the current state of the widget let state = self - .ctx() .read_response(id) .map(|r| r.widget_state()) .unwrap_or_default(); - if let Some(style) = self.get_style::(classes, state) { - style - } else { - S::default_style(classes, state) - } + self.get_widget_style::(classes, state) } } -#[derive(Default)] -pub(crate) struct Themes { +pub struct Themes { themes: IdTypeMap, } +type ThemeWrap = Arc + Send + Sync>>>; + +impl Default for Themes { + /// Register the default egui theme + fn default() -> Self { + let mut themes = IdTypeMap::default(); + + themes.insert_temp::>( + Id::NULL, + Arc::new(Mutex::new(Box::new(DefaultStyle))), + ); + + themes.insert_temp::>( + Id::NULL, + Arc::new(Mutex::new(Box::new(DefaultStyle))), + ); + + Self { themes } + } +} + impl Themes { - /// Register a theme and the style associated - pub(crate) fn register( + /// Register a [`ThemeStyle`](crate::theme_plugin::ThemeStyle) for the specified widget [`WidgetStyle`](WidgetStyle) `S` + /// + /// Existing themes are overwritten if `force` is `true` or the new theme differs. + pub(crate) fn register( &mut self, theme: impl ThemeStyle + Send + Sync + 'static, force: bool, @@ -84,10 +245,11 @@ impl Themes { && self .themes .get_temp:: + Send + Sync>>>>(Id::NULL) - .is_some() + .is_some_and(|t| t.lock().theme_type_id() == theme.theme_type_id()) { return; } + self.themes .insert_temp:: + Send + Sync>>>>( Id::NULL, @@ -96,14 +258,13 @@ impl Themes { } /// Fetch the style of the current theme - pub(crate) fn get( - &self, - classes: &Classes, - state: WidgetState, - ) -> Option { + pub fn get(&self, classes: &Classes, state: WidgetState) -> S { let v = self .themes .get_temp:: + Send + Sync>>>>(Id::NULL); - v.map(|engine| engine.lock().style(classes, state)) + + v.unwrap_or_else(|| panic!("A style should be set for {:?}", std::any::type_name::())) + .lock() + .style(self, classes, state) } } diff --git a/crates/egui/src/widget_style.rs b/crates/egui/src/widget_style.rs index 5f8378510..4bb2a1c18 100644 --- a/crates/egui/src/widget_style.rs +++ b/crates/egui/src/widget_style.rs @@ -3,22 +3,16 @@ use std::{ fmt::{self, Debug}, }; -use emath::Vec2; -use epaint::{Color32, FontId, Shadow, Stroke, text::TextWrapMode}; +use epaint::{Color32, FontId, Stroke, text::TextWrapMode}; use smallvec::SmallVec; use crate::{ - Frame, Response, Spacing, Style, TextBuffer as _, TextStyle, Visuals, + Frame, Response, TextBuffer as _, style::{WidgetVisuals, Widgets}, }; /// Each dedicated style must implement this trait to be used in the theme plugin system -pub trait StyleStruct: Debug + Clone + Send + Sync + std::any::Any + 'static { - /// The default style for this struct based on classes and state of the widget. - fn default_style(classes: &Classes, state: WidgetState) -> Self - where - Self: Sized; -} +pub trait WidgetStyle: Debug + Clone + Send + Sync + std::any::Any + 'static {} /// General text style #[derive(Debug, Clone)] @@ -36,7 +30,7 @@ pub struct TextVisuals { /// General widget style #[derive(Debug, Clone)] -pub struct WidgetStyle { +pub struct BaseStyle { pub frame: Frame, pub text: TextVisuals, @@ -44,36 +38,7 @@ pub struct WidgetStyle { pub stroke: Stroke, } -impl StyleStruct for WidgetStyle { - fn default_style(_classes: &Classes, state: WidgetState) -> Self { - let visuals = Widgets::dark(); - let spacing = Spacing::default(); - - let visuals = match state { - WidgetState::Noninteractive => visuals.noninteractive, - WidgetState::Inactive => visuals.inactive, - WidgetState::Hovered => visuals.hovered, - WidgetState::Active => visuals.active, - }; - - Self { - frame: Frame { - fill: visuals.bg_fill, - stroke: visuals.bg_stroke, - corner_radius: visuals.corner_radius, - inner_margin: spacing.button_padding.into(), - ..Default::default() - }, - stroke: visuals.fg_stroke, - text: TextVisuals { - color: visuals.text_color(), - font_id: TextStyle::Button.resolve(&Style::default()), - strikethrough: Stroke::NONE, - underline: Stroke::NONE, - }, - } - } -} +impl WidgetStyle for BaseStyle {} /// Dedicated button style #[derive(Debug, Clone)] @@ -82,43 +47,7 @@ pub struct ButtonStyle { pub text_style: TextVisuals, } -impl StyleStruct for ButtonStyle { - fn default_style(classes: &Classes, state: WidgetState) -> Self { - let widget_visuals = Widgets::dark(); - let spacing = Spacing::default(); - - let mut widget_visuals = match state { - WidgetState::Noninteractive => widget_visuals.noninteractive, - WidgetState::Inactive => widget_visuals.inactive, - WidgetState::Hovered => widget_visuals.hovered, - WidgetState::Active => widget_visuals.active, - }; - - let mut ws = WidgetStyle::default_style(classes, state); - - if classes.has(SELECTED_CLASS) { - let visuals = Visuals::default(); - widget_visuals.weak_bg_fill = visuals.selection.bg_fill; - widget_visuals.bg_fill = visuals.selection.bg_fill; - widget_visuals.fg_stroke = visuals.selection.stroke; - ws.text.color = visuals.selection.stroke.color; - } - - Self { - frame: Frame { - fill: widget_visuals.weak_bg_fill, - stroke: widget_visuals.bg_stroke, - corner_radius: widget_visuals.corner_radius, - outer_margin: (-Vec2::splat(widget_visuals.expansion)).into(), - inner_margin: (spacing.button_padding + Vec2::splat(widget_visuals.expansion) - - Vec2::splat(widget_visuals.bg_stroke.width)) - .into(), - ..Default::default() - }, - text_style: ws.text, - } - } -} +impl WidgetStyle for ButtonStyle {} /// Dedicated checkbox style #[derive(Debug, Clone)] @@ -142,35 +71,7 @@ pub struct CheckboxStyle { pub check_stroke: Stroke, } -impl StyleStruct for CheckboxStyle { - fn default_style(classes: &Classes, state: WidgetState) -> Self { - let widget_visuals = Widgets::dark(); - let spacing = Spacing::default(); - - let widget_visuals = match state { - WidgetState::Noninteractive => widget_visuals.noninteractive, - WidgetState::Inactive => widget_visuals.inactive, - WidgetState::Hovered => widget_visuals.hovered, - WidgetState::Active => widget_visuals.active, - }; - - let ws = WidgetStyle::default_style(classes, state); - - Self { - frame: Frame::new(), - checkbox_size: spacing.icon_width, - check_size: spacing.icon_width_inner, - checkbox_frame: Frame { - fill: widget_visuals.bg_fill, - corner_radius: widget_visuals.corner_radius, - stroke: widget_visuals.bg_stroke, - ..Default::default() - }, - text_style: ws.text, - check_stroke: ws.stroke, - } - } -} +impl WidgetStyle for CheckboxStyle {} /// Dedicated label style #[derive(Debug, Clone)] @@ -185,6 +86,8 @@ pub struct LabelStyle { pub wrap_mode: TextWrapMode, } +impl WidgetStyle for LabelStyle {} + /// Dedicated separator style #[derive(Debug, Clone)] pub struct SeparatorStyle { @@ -195,6 +98,8 @@ pub struct SeparatorStyle { pub stroke: Stroke, } +impl WidgetStyle for SeparatorStyle {} + /// The different state of a widget can be #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum WidgetState { @@ -231,109 +136,6 @@ impl Response { } } -impl Style { - /// The general widget style. The style is computed according to the classes and state of the widget. - pub fn widget_style(&self, _classes: &Classes, state: WidgetState) -> WidgetStyle { - let visuals = self.visuals.widgets.state(state); - let font_id = self.override_font_id.clone(); - WidgetStyle { - frame: Frame { - fill: visuals.bg_fill, - stroke: visuals.bg_stroke, - corner_radius: visuals.corner_radius, - inner_margin: self.spacing.button_padding.into(), - ..Default::default() - }, - stroke: visuals.fg_stroke, - text: TextVisuals { - color: self - .visuals - .override_text_color - .unwrap_or_else(|| visuals.text_color()), - font_id: font_id.unwrap_or_else(|| TextStyle::Body.resolve(self)), - strikethrough: Stroke::NONE, - underline: Stroke::NONE, - }, - } - } - - /// The dedicated button style. The style is computed according to the classes and state of the widget. - /// It depend on the general widget style. - pub fn button_style(&self, classes: &Classes, state: WidgetState) -> ButtonStyle { - let mut visuals = *self.visuals.widgets.state(state); - let mut ws = self.widget_style(classes, state); - - if classes.has(SELECTED_CLASS) { - visuals.weak_bg_fill = self.visuals.selection.bg_fill; - visuals.bg_fill = self.visuals.selection.bg_fill; - visuals.fg_stroke = self.visuals.selection.stroke; - ws.text.color = self.visuals.selection.stroke.color; - } - - ButtonStyle { - frame: Frame { - fill: visuals.weak_bg_fill, - stroke: visuals.bg_stroke, - corner_radius: visuals.corner_radius, - outer_margin: (-Vec2::splat(visuals.expansion)).into(), - inner_margin: (self.spacing.button_padding + Vec2::splat(visuals.expansion) - - Vec2::splat(visuals.bg_stroke.width)) - .into(), - ..Default::default() - }, - text_style: ws.text, - } - } - - /// The dedicated checkbox style. The style is computed according to the classes and state of the widget. - /// It depend on the general widget style. - pub fn checkbox_style(&self, classes: &Classes, state: WidgetState) -> CheckboxStyle { - let visuals = self.visuals.widgets.state(state); - let ws = self.widget_style(classes, state); - CheckboxStyle { - frame: Frame::new(), - checkbox_size: self.spacing.icon_width, - check_size: self.spacing.icon_width_inner, - checkbox_frame: Frame { - fill: visuals.bg_fill, - corner_radius: visuals.corner_radius, - stroke: visuals.bg_stroke, - ..Default::default() - }, - text_style: ws.text, - check_stroke: ws.stroke, - } - } - - /// The dedicated label style. The style is computed according to the classes and state of the widget. - /// It depend on the general widget style. - pub fn label_style(&self, classes: &Classes, state: WidgetState) -> LabelStyle { - let ws = self.widget_style(classes, state); - LabelStyle { - frame: Frame { - fill: ws.frame.fill, - inner_margin: 0.0.into(), - outer_margin: 0.0.into(), - stroke: Stroke::NONE, - shadow: Shadow::NONE, - corner_radius: 0.into(), - }, - text: ws.text, - wrap_mode: TextWrapMode::Wrap, - } - } - - /// The dedicated separator style. The style is computed according to the classes and state of the widget. - /// It depend on the general widget style. - pub fn separator_style(&self, _classes: &Classes, _state: WidgetState) -> SeparatorStyle { - let visuals = self.visuals.noninteractive(); - SeparatorStyle { - spacing: 6.0, - stroke: visuals.bg_stroke, - } - } -} - /// The root class is a special class present on every top-level [`crate::Ui`]. pub const ROOT_CLASS: &str = "root"; diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index 011488399..d7f6c8a0c 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -328,7 +328,6 @@ impl<'a> Button<'a> { classes.add_class_if(SELECTED_CLASS, selected.unwrap_or(false)); - // let ButtonStyle { frame, text_style } = ui.style().button_style(&classes, state); let ButtonStyle { frame, text_style } = ui.widget_style(id, &classes); let mut button_padding = if has_frame_margin { diff --git a/crates/egui/src/widgets/checkbox.rs b/crates/egui/src/widgets/checkbox.rs index 0aaedec76..a9c0749fc 100644 --- a/crates/egui/src/widgets/checkbox.rs +++ b/crates/egui/src/widgets/checkbox.rs @@ -80,7 +80,7 @@ impl Widget for Checkbox<'_> { frame, check_stroke, text_style, - } = ui.style().checkbox_style(&classes, state); + } = ui.widget_style(id, &classes); let mut min_size = Vec2::splat(ui.spacing().interact_size.y); min_size.y = min_size.y.at_least(checkbox_size); diff --git a/crates/egui/src/widgets/separator.rs b/crates/egui/src/widgets/separator.rs index 48d02fe8e..bb4ae1ab9 100644 --- a/crates/egui/src/widgets/separator.rs +++ b/crates/egui/src/widgets/separator.rs @@ -106,7 +106,7 @@ impl Widget for Separator { let SeparatorStyle { spacing: spacing_style, stroke, - } = ui.style().separator_style(&classes, state); + } = ui.widget_style(id, &classes); // override the spacing if not set let spacing = spacing.unwrap_or(spacing_style); diff --git a/examples/styling_engine/src/custom_engine.rs b/examples/styling_engine/src/custom_engine.rs index 630a620f1..293b428a7 100644 --- a/examples/styling_engine/src/custom_engine.rs +++ b/examples/styling_engine/src/custom_engine.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; use eframe::egui::{ Color32, - theme_plugin::{ThemeCache, ThemeStyle}, + theme_plugin::{ThemeCache, ThemeStyle, Themes}, widget_style::{ - ButtonStyle, Classes, HasClasses as _, StyleStruct as _, WidgetState, WidgetStyle, + BaseStyle, ButtonStyle, Classes, HasClasses as _, WidgetState, WidgetStyle as _, }, }; use logos::Logos; @@ -79,16 +79,16 @@ impl ESSEngine { } /// This implementation basically do nothing. This is only the minimum requirement with caching. -impl ThemeStyle for ESSEngine { - fn style(&mut self, classes: &Classes, state: WidgetState) -> WidgetStyle { - self.cache.get(classes, state, || { - WidgetStyle::default_style(classes, state) - }) +impl ThemeStyle for ESSEngine { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> BaseStyle { + let current = themes.get::(classes, state); + self.cache + .get(classes, state, || BaseStyle::default_style(classes, state)) } } impl ThemeStyle for ESSEngine { - fn style(&mut self, classes: &Classes, state: WidgetState) -> ButtonStyle { + fn style(&mut self, themes: &Themes, classes: &Classes, state: WidgetState) -> ButtonStyle { self.cache.get(classes, state, || { let mut default = ButtonStyle::default_style(classes, state); for classe in classes.list() { diff --git a/examples/styling_engine/src/main.rs b/examples/styling_engine/src/main.rs index 7af3b131d..0eaff6e44 100644 --- a/examples/styling_engine/src/main.rs +++ b/examples/styling_engine/src/main.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release #![expect(rustdoc::missing_crate_level_docs)] // it's an example -use eframe::egui::widget_style::WidgetStyle; +use eframe::egui::widget_style::BaseStyle; use eframe::egui::{ self, Button, Frame, Margin, Panel, UiBuilder, widget_style::{ButtonStyle, HasClasses as _}, @@ -36,8 +36,8 @@ fn main() -> eframe::Result { eframe::run_ui_native("My egui App", options, move |ui, _frame| { // Register the theme plugin and which style they implement if let Ok(engine) = ESSEngine::try_parse(&style_code) { - ui.add_theme::(engine.clone()); - ui.add_theme::(engine); + ui.add_widget_theme::(engine.clone()); + ui.add_widget_theme::(engine); } ui.scope_builder(UiBuilder::new().with_class("body"), |ui| { @@ -54,8 +54,8 @@ fn main() -> eframe::Result { && let Ok(engine) = ESSEngine::try_parse(&style_code) { // Overwrite the current theme with the new one.clear - ui.replace_theme::(engine.clone()); - ui.replace_theme::(engine); + ui.replace_widget_theme::(engine.clone()); + ui.replace_widget_theme::(engine); } }); });