From e20fee79564a977c1d4a1f15073fc00eab31719e Mon Sep 17 00:00:00 2001 From: pml68 Date: Tue, 25 Feb 2025 23:41:27 +0100 Subject: [PATCH] feat: only rehighlight `TextEditor` when `Theme` changes --- widget/src/text_editor.rs | 47 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index e0e5b510..ae3b7087 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -170,7 +170,7 @@ impl<'a, Highlighter, Message, Theme, Renderer> TextEditor<'a, Highlighter, Message, Theme, Renderer> where Highlighter: text::Highlighter, - Theme: Catalog, + Theme: Catalog + 'static + PartialEq, Renderer: text::Renderer, { /// Sets the placeholder of the [`TextEditor`]. @@ -335,7 +335,7 @@ where fn input_method<'b>( &self, - state: &'b State, + state: &'b State, renderer: &Renderer, layout: Layout<'_>, ) -> InputMethod<&'b str> { @@ -508,12 +508,13 @@ where /// The state of a [`TextEditor`]. #[derive(Debug)] -pub struct State { +pub struct State { focus: Option, preedit: Option, last_click: Option, drag_click: Option, partial_scroll: f32, + last_theme: RefCell>, highlighter: RefCell, highlighter_settings: Highlighter::Settings, highlighter_format_address: usize, @@ -547,15 +548,17 @@ impl Focus { } } -impl State { +impl + State +{ /// Returns whether the [`TextEditor`] is currently focused or not. pub fn is_focused(&self) -> bool { self.focus.is_some() } } -impl operation::Focusable - for State +impl + operation::Focusable for State { fn is_focused(&self) -> bool { self.focus.is_some() @@ -574,11 +577,11 @@ impl Widget for TextEditor<'_, Highlighter, Message, Theme, Renderer> where Highlighter: text::Highlighter, - Theme: Catalog, + Theme: Catalog + 'static + PartialEq + Clone, Renderer: text::Renderer, { fn tag(&self) -> widget::tree::Tag { - widget::tree::Tag::of::>() + widget::tree::Tag::of::>() } fn state(&self) -> widget::tree::State { @@ -588,6 +591,7 @@ where last_click: None, drag_click: None, partial_scroll: 0.0, + last_theme: RefCell::>::default(), highlighter: RefCell::new(Highlighter::new( &self.highlighter_settings, )), @@ -610,7 +614,7 @@ where limits: &layout::Limits, ) -> iced_renderer::core::layout::Node { let mut internal = self.content.0.borrow_mut(); - let state = tree.state.downcast_mut::>(); + let state = tree.state.downcast_mut::>(); if state.highlighter_format_address != self.highlighter_format as usize { @@ -675,7 +679,7 @@ where return; }; - let state = tree.state.downcast_mut::>(); + let state = tree.state.downcast_mut::>(); let is_redraw = matches!( event, Event::Window(window::Event::RedrawRequested(_now)), @@ -785,13 +789,14 @@ where }, Update::Binding(binding) => { fn apply_binding< + T: PartialEq + 'static, H: text::Highlighter, R: text::Renderer, Message, >( binding: Binding, content: &Content, - state: &mut State, + state: &mut State, on_edit: &dyn Fn(Action) -> Message, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, @@ -934,10 +939,20 @@ where let bounds = layout.bounds(); let mut internal = self.content.0.borrow_mut(); - let state = tree.state.downcast_ref::>(); + let state = tree.state.downcast_ref::>(); let font = self.font.unwrap_or_else(|| renderer.default_font()); + if state + .last_theme + .borrow() + .as_ref() + .is_none_or(|last_theme| last_theme != theme) + { + state.highlighter.borrow_mut().change_line(0); + let _ = state.last_theme.borrow_mut().replace(theme.clone()); + } + internal.editor.highlight( font, state.highlighter.borrow_mut().deref_mut(), @@ -1064,7 +1079,7 @@ where _renderer: &Renderer, operation: &mut dyn widget::Operation, ) { - let state = tree.state.downcast_mut::>(); + let state = tree.state.downcast_mut::>(); operation.focusable(self.id.as_ref(), layout.bounds(), state); } @@ -1076,7 +1091,7 @@ impl<'a, Highlighter, Message, Theme, Renderer> where Highlighter: text::Highlighter, Message: 'a, - Theme: Catalog + 'a, + Theme: Catalog + 'static + PartialEq + Clone, Renderer: text::Renderer, { fn from( @@ -1232,9 +1247,9 @@ enum Ime { } impl Update { - fn from_event( + fn from_event( event: &Event, - state: &State, + state: &State, bounds: Rectangle, padding: Padding, cursor: mouse::Cursor,