Skip to content

Commit eae40b6

Browse files
committed
feat: only rehighlight TextEditor when Theme changes
1 parent 0a34496 commit eae40b6

1 file changed

Lines changed: 31 additions & 16 deletions

File tree

widget/src/text_editor.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl<'a, Highlighter, Message, Theme, Renderer>
162162
TextEditor<'a, Highlighter, Message, Theme, Renderer>
163163
where
164164
Highlighter: text::Highlighter,
165-
Theme: Catalog,
165+
Theme: Catalog + 'static + PartialEq,
166166
Renderer: text::Renderer,
167167
{
168168
/// Sets the placeholder of the [`TextEditor`].
@@ -326,7 +326,7 @@ where
326326

327327
fn input_method<'b>(
328328
&self,
329-
state: &'b State<Highlighter>,
329+
state: &'b State<Highlighter, Theme>,
330330
renderer: &Renderer,
331331
layout: Layout<'_>,
332332
) -> InputMethod<&'b str> {
@@ -499,12 +499,13 @@ where
499499

500500
/// The state of a [`TextEditor`].
501501
#[derive(Debug)]
502-
pub struct State<Highlighter: text::Highlighter> {
502+
pub struct State<Highlighter: text::Highlighter, Theme: PartialEq> {
503503
focus: Option<Focus>,
504504
preedit: Option<input_method::Preedit>,
505505
last_click: Option<mouse::Click>,
506506
drag_click: Option<mouse::click::Kind>,
507507
partial_scroll: f32,
508+
last_theme: RefCell<Option<Theme>>,
508509
highlighter: RefCell<Highlighter>,
509510
highlighter_settings: Highlighter::Settings,
510511
highlighter_format_address: usize,
@@ -538,15 +539,17 @@ impl Focus {
538539
}
539540
}
540541

541-
impl<Highlighter: text::Highlighter> State<Highlighter> {
542+
impl<Highlighter: text::Highlighter, Theme: PartialEq + 'static>
543+
State<Highlighter, Theme>
544+
{
542545
/// Returns whether the [`TextEditor`] is currently focused or not.
543546
pub fn is_focused(&self) -> bool {
544547
self.focus.is_some()
545548
}
546549
}
547550

548-
impl<Highlighter: text::Highlighter> operation::Focusable
549-
for State<Highlighter>
551+
impl<Highlighter: text::Highlighter, Theme: PartialEq + 'static>
552+
operation::Focusable for State<Highlighter, Theme>
550553
{
551554
fn is_focused(&self) -> bool {
552555
self.focus.is_some()
@@ -565,11 +568,11 @@ impl<Highlighter, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
565568
for TextEditor<'_, Highlighter, Message, Theme, Renderer>
566569
where
567570
Highlighter: text::Highlighter,
568-
Theme: Catalog,
571+
Theme: Catalog + 'static + PartialEq + Clone,
569572
Renderer: text::Renderer,
570573
{
571574
fn tag(&self) -> widget::tree::Tag {
572-
widget::tree::Tag::of::<State<Highlighter>>()
575+
widget::tree::Tag::of::<State<Highlighter, Theme>>()
573576
}
574577

575578
fn state(&self) -> widget::tree::State {
@@ -579,6 +582,7 @@ where
579582
last_click: None,
580583
drag_click: None,
581584
partial_scroll: 0.0,
585+
last_theme: RefCell::<Option<Theme>>::default(),
582586
highlighter: RefCell::new(Highlighter::new(
583587
&self.highlighter_settings,
584588
)),
@@ -601,7 +605,7 @@ where
601605
limits: &layout::Limits,
602606
) -> iced_renderer::core::layout::Node {
603607
let mut internal = self.content.0.borrow_mut();
604-
let state = tree.state.downcast_mut::<State<Highlighter>>();
608+
let state = tree.state.downcast_mut::<State<Highlighter, Theme>>();
605609

606610
if state.highlighter_format_address != self.highlighter_format as usize
607611
{
@@ -666,7 +670,7 @@ where
666670
return;
667671
};
668672

669-
let state = tree.state.downcast_mut::<State<Highlighter>>();
673+
let state = tree.state.downcast_mut::<State<Highlighter, Theme>>();
670674
let is_redraw = matches!(
671675
event,
672676
Event::Window(window::Event::RedrawRequested(_now)),
@@ -776,13 +780,14 @@ where
776780
},
777781
Update::Binding(binding) => {
778782
fn apply_binding<
783+
T: PartialEq + 'static,
779784
H: text::Highlighter,
780785
R: text::Renderer,
781786
Message,
782787
>(
783788
binding: Binding<Message>,
784789
content: &Content<R>,
785-
state: &mut State<H>,
790+
state: &mut State<H, T>,
786791
on_edit: &dyn Fn(Action) -> Message,
787792
clipboard: &mut dyn Clipboard,
788793
shell: &mut Shell<'_, Message>,
@@ -925,10 +930,20 @@ where
925930
let bounds = layout.bounds();
926931

927932
let mut internal = self.content.0.borrow_mut();
928-
let state = tree.state.downcast_ref::<State<Highlighter>>();
933+
let state = tree.state.downcast_ref::<State<Highlighter, Theme>>();
929934

930935
let font = self.font.unwrap_or_else(|| renderer.default_font());
931936

937+
if state
938+
.last_theme
939+
.borrow()
940+
.as_ref()
941+
.is_none_or(|last_theme| last_theme != theme)
942+
{
943+
state.highlighter.borrow_mut().change_line(0);
944+
let _ = state.last_theme.borrow_mut().replace(theme.clone());
945+
}
946+
932947
internal.editor.highlight(
933948
font,
934949
state.highlighter.borrow_mut().deref_mut(),
@@ -1055,7 +1070,7 @@ where
10551070
_renderer: &Renderer,
10561071
operation: &mut dyn widget::Operation,
10571072
) {
1058-
let state = tree.state.downcast_mut::<State<Highlighter>>();
1073+
let state = tree.state.downcast_mut::<State<Highlighter, Theme>>();
10591074

10601075
operation.focusable(None, layout.bounds(), state);
10611076
}
@@ -1067,7 +1082,7 @@ impl<'a, Highlighter, Message, Theme, Renderer>
10671082
where
10681083
Highlighter: text::Highlighter,
10691084
Message: 'a,
1070-
Theme: Catalog + 'a,
1085+
Theme: Catalog + 'static + PartialEq + Clone,
10711086
Renderer: text::Renderer,
10721087
{
10731088
fn from(
@@ -1220,9 +1235,9 @@ enum Ime {
12201235
}
12211236

12221237
impl<Message> Update<Message> {
1223-
fn from_event<H: Highlighter>(
1238+
fn from_event<H: Highlighter, T: PartialEq + 'static>(
12241239
event: &Event,
1225-
state: &State<H>,
1240+
state: &State<H, T>,
12261241
bounds: Rectangle,
12271242
padding: Padding,
12281243
cursor: mouse::Cursor,

0 commit comments

Comments
 (0)