diff --git a/core/src/theme.rs b/core/src/theme.rs index 1260bca8..22cf632a 100644 --- a/core/src/theme.rs +++ b/core/src/theme.rs @@ -168,31 +168,7 @@ impl Theme { impl fmt::Display for Theme { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Light => write!(f, "Light"), - Self::Dark => write!(f, "Dark"), - Self::Dracula => write!(f, "Dracula"), - Self::Nord => write!(f, "Nord"), - Self::SolarizedLight => write!(f, "Solarized Light"), - Self::SolarizedDark => write!(f, "Solarized Dark"), - Self::GruvboxLight => write!(f, "Gruvbox Light"), - Self::GruvboxDark => write!(f, "Gruvbox Dark"), - Self::CatppuccinLatte => write!(f, "Catppuccin Latte"), - Self::CatppuccinFrappe => write!(f, "Catppuccin Frappé"), - Self::CatppuccinMacchiato => write!(f, "Catppuccin Macchiato"), - Self::CatppuccinMocha => write!(f, "Catppuccin Mocha"), - Self::TokyoNight => write!(f, "Tokyo Night"), - Self::TokyoNightStorm => write!(f, "Tokyo Night Storm"), - Self::TokyoNightLight => write!(f, "Tokyo Night Light"), - Self::KanagawaWave => write!(f, "Kanagawa Wave"), - Self::KanagawaDragon => write!(f, "Kanagawa Dragon"), - Self::KanagawaLotus => write!(f, "Kanagawa Lotus"), - Self::Moonfly => write!(f, "Moonfly"), - Self::Nightfly => write!(f, "Nightfly"), - Self::Oxocarbon => write!(f, "Oxocarbon"), - Self::Ferra => write!(f, "Ferra"), - Self::Custom(custom) => custom.fmt(f), - } + f.write_str(self.name()) } } @@ -270,6 +246,12 @@ pub trait Base { /// debugging purposes; like displaying performance /// metrics or devtools. fn palette(&self) -> Option; + + /// Returns the unique name of the theme. + /// + /// This name may be used to efficiently detect theme + /// changes in some widgets. + fn name(&self) -> &str; } impl Base for Theme { @@ -313,6 +295,34 @@ impl Base for Theme { fn palette(&self) -> Option { Some(self.palette()) } + + fn name(&self) -> &str { + match self { + Self::Light => "Light", + Self::Dark => "Dark", + Self::Dracula => "Dracula", + Self::Nord => "Nord", + Self::SolarizedLight => "Solarized Light", + Self::SolarizedDark => "Solarized Dark", + Self::GruvboxLight => "Gruvbox Light", + Self::GruvboxDark => "Gruvbox Dark", + Self::CatppuccinLatte => "Catppuccin Latte", + Self::CatppuccinFrappe => "Catppuccin Frappé", + Self::CatppuccinMacchiato => "Catppuccin Macchiato", + Self::CatppuccinMocha => "Catppuccin Mocha", + Self::TokyoNight => "Tokyo Night", + Self::TokyoNightStorm => "Tokyo Night Storm", + Self::TokyoNightLight => "Tokyo Night Light", + Self::KanagawaWave => "Kanagawa Wave", + Self::KanagawaDragon => "Kanagawa Dragon", + Self::KanagawaLotus => "Kanagawa Lotus", + Self::Moonfly => "Moonfly", + Self::Nightfly => "Nightfly", + Self::Oxocarbon => "Oxocarbon", + Self::Ferra => "Ferra", + Self::Custom(custom) => &custom.name, + } + } } /// The default [`Style`] of a built-in [`Theme`]. diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index e0e5b510..6c5efb3f 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -42,6 +42,7 @@ use crate::core::renderer; use crate::core::text::editor::{Cursor, Editor as _}; use crate::core::text::highlighter::{self, Highlighter}; use crate::core::text::{self, LineHeight, Text, Wrapping}; +use crate::core::theme; use crate::core::time::{Duration, Instant}; use crate::core::widget::operation; use crate::core::widget::{self, Widget}; @@ -148,7 +149,7 @@ where max_height: f32::INFINITY, padding: Padding::new(5.0), wrapping: Wrapping::default(), - class: Theme::default(), + class: ::default(), key_binding: None, on_edit: None, highlighter_settings: (), @@ -514,6 +515,7 @@ pub struct State { last_click: Option, drag_click: Option, partial_scroll: f32, + last_theme: RefCell>, highlighter: RefCell, highlighter_settings: Highlighter::Settings, highlighter_format_address: usize, @@ -588,6 +590,7 @@ where last_click: None, drag_click: None, partial_scroll: 0.0, + last_theme: RefCell::default(), highlighter: RefCell::new(Highlighter::new( &self.highlighter_settings, )), @@ -938,6 +941,19 @@ where let font = self.font.unwrap_or_else(|| renderer.default_font()); + let theme_name = theme.name(); + + if state + .last_theme + .borrow() + .as_ref() + .is_none_or(|last_theme| last_theme != theme_name) + { + state.highlighter.borrow_mut().change_line(0); + let _ = + state.last_theme.borrow_mut().replace(theme_name.to_owned()); + } + internal.editor.highlight( font, state.highlighter.borrow_mut().deref_mut(), @@ -1391,7 +1407,7 @@ pub struct Style { } /// The theme catalog of a [`TextEditor`]. -pub trait Catalog { +pub trait Catalog: theme::Base { /// The item class of the [`Catalog`]. type Class<'a>;