Implement reactive-rendering for text_editor
This commit is contained in:
parent
d5a886dbcb
commit
3482ffecdc
1 changed files with 166 additions and 143 deletions
|
|
@ -119,6 +119,7 @@ pub struct TextEditor<
|
|||
&Highlighter::Highlight,
|
||||
&Theme,
|
||||
) -> highlighter::Format<Renderer::Font>,
|
||||
last_status: Option<Status>,
|
||||
}
|
||||
|
||||
impl<'a, Message, Theme, Renderer>
|
||||
|
|
@ -146,6 +147,7 @@ where
|
|||
highlighter_format: |_highlight, _theme| {
|
||||
highlighter::Format::default()
|
||||
},
|
||||
last_status: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -269,6 +271,7 @@ where
|
|||
on_edit: self.on_edit,
|
||||
highlighter_settings: settings,
|
||||
highlighter_format: to_format,
|
||||
last_status: self.last_status,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -611,6 +614,10 @@ where
|
|||
};
|
||||
|
||||
let state = tree.state.downcast_mut::<State<Highlighter>>();
|
||||
let is_redraw = matches!(
|
||||
event,
|
||||
Event::Window(window::Event::RedrawRequested(_now)),
|
||||
);
|
||||
|
||||
match event {
|
||||
Event::Window(window::Event::Unfocused) => {
|
||||
|
|
@ -647,16 +654,15 @@ where
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let Some(update) = Update::from_event(
|
||||
if let Some(update) = Update::from_event(
|
||||
event,
|
||||
state,
|
||||
layout.bounds(),
|
||||
self.padding,
|
||||
cursor,
|
||||
self.key_binding.as_deref(),
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
) {
|
||||
shell.capture_event();
|
||||
|
||||
match update {
|
||||
Update::Click(click) => {
|
||||
|
|
@ -707,7 +713,8 @@ where
|
|||
clipboard: &mut dyn Clipboard,
|
||||
shell: &mut Shell<'_, Message>,
|
||||
) {
|
||||
let mut publish = |action| shell.publish(on_edit(action));
|
||||
let mut publish =
|
||||
|action| shell.publish(on_edit(action));
|
||||
|
||||
match binding {
|
||||
Binding::Unfocus => {
|
||||
|
|
@ -736,9 +743,9 @@ where
|
|||
if let Some(contents) =
|
||||
clipboard.read(clipboard::Kind::Standard)
|
||||
{
|
||||
publish(Action::Edit(Edit::Paste(Arc::new(
|
||||
contents,
|
||||
))));
|
||||
publish(Action::Edit(Edit::Paste(
|
||||
Arc::new(contents),
|
||||
)));
|
||||
}
|
||||
}
|
||||
Binding::Move(motion) => {
|
||||
|
|
@ -796,8 +803,31 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shell.capture_event();
|
||||
let status = {
|
||||
let is_disabled = self.on_edit.is_none();
|
||||
let is_hovered = cursor.is_over(layout.bounds());
|
||||
|
||||
if is_disabled {
|
||||
Status::Disabled
|
||||
} else if state.focus.is_some() {
|
||||
Status::Focused { is_hovered }
|
||||
} else if is_hovered {
|
||||
Status::Hovered
|
||||
} else {
|
||||
Status::Active
|
||||
}
|
||||
};
|
||||
|
||||
if is_redraw {
|
||||
self.last_status = Some(status);
|
||||
} else if self
|
||||
.last_status
|
||||
.is_some_and(|last_status| status != last_status)
|
||||
{
|
||||
shell.request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
|
@ -807,7 +837,7 @@ where
|
|||
theme: &Theme,
|
||||
_defaults: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor: mouse::Cursor,
|
||||
_cursor: mouse::Cursor,
|
||||
_viewport: &Rectangle,
|
||||
) {
|
||||
let bounds = layout.bounds();
|
||||
|
|
@ -823,20 +853,8 @@ where
|
|||
|highlight| (self.highlighter_format)(highlight, theme),
|
||||
);
|
||||
|
||||
let is_disabled = self.on_edit.is_none();
|
||||
let is_mouse_over = cursor.is_over(bounds);
|
||||
|
||||
let status = if is_disabled {
|
||||
Status::Disabled
|
||||
} else if state.focus.is_some() {
|
||||
Status::Focused
|
||||
} else if is_mouse_over {
|
||||
Status::Hovered
|
||||
} else {
|
||||
Status::Active
|
||||
};
|
||||
|
||||
let style = theme.style(&self.class, status);
|
||||
let style = theme
|
||||
.style(&self.class, self.last_status.unwrap_or(Status::Active));
|
||||
|
||||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
|
|
@ -1035,7 +1053,7 @@ impl<Message> Binding<Message> {
|
|||
status,
|
||||
} = event;
|
||||
|
||||
if status != Status::Focused {
|
||||
if !matches!(status, Status::Focused { .. }) {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
@ -1175,7 +1193,9 @@ impl<Message> Update<Message> {
|
|||
..
|
||||
}) => {
|
||||
let status = if state.focus.is_some() {
|
||||
Status::Focused
|
||||
Status::Focused {
|
||||
is_hovered: cursor.is_over(bounds),
|
||||
}
|
||||
} else {
|
||||
Status::Active
|
||||
};
|
||||
|
|
@ -1221,7 +1241,10 @@ pub enum Status {
|
|||
/// The [`TextEditor`] is being hovered.
|
||||
Hovered,
|
||||
/// The [`TextEditor`] is focused.
|
||||
Focused,
|
||||
Focused {
|
||||
/// Whether the [`TextEditor`] is hovered, while focused.
|
||||
is_hovered: bool,
|
||||
},
|
||||
/// The [`TextEditor`] cannot be interacted with.
|
||||
Disabled,
|
||||
}
|
||||
|
|
@ -1296,7 +1319,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
|
|||
},
|
||||
..active
|
||||
},
|
||||
Status::Focused => Style {
|
||||
Status::Focused { .. } => Style {
|
||||
border: Border {
|
||||
color: palette.primary.strong.color,
|
||||
..active.border
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue