diff --git a/src/core/text/build.rs b/src/core/text/build.rs index 3611918..f69b389 100644 --- a/src/core/text/build.rs +++ b/src/core/text/build.rs @@ -95,6 +95,7 @@ impl TextBuilderOutput for TextEditOutput { let mut text = TextEdit { view: TextView::new(buf, builder.attrs, builder.hint.get(ui)), selection: Default::default(), + history: Default::default(), }; let font_system = &mut ui.data.text.font_system; text.buf diff --git a/src/core/text/edit.rs b/src/core/text/edit.rs index dc43712..ade69f2 100644 --- a/src/core/text/edit.rs +++ b/src/core/text/edit.rs @@ -11,6 +11,7 @@ use winit::{ pub struct TextEdit { pub(super) view: TextView, pub(super) selection: TextSelection, + pub(super) history: Vec<(String, TextSelection)>, } impl TextEdit { @@ -180,6 +181,13 @@ impl<'a> TextEditCtx<'a> { text } + pub fn set(&mut self, text: &str) { + self.text + .buf + .set_text(self.font_system, text, &Attrs::new(), SHAPING, None); + self.text.selection.clear(); + } + pub fn motion(&mut self, motion: Motion) { if let TextSelection::Pos(cursor) = self.text.selection && let Some(cursor) = self.buf_motion(cursor, motion) @@ -372,6 +380,24 @@ impl<'a> TextEditCtx<'a> { } pub fn apply_event(&mut self, event: &KeyEvent, modifiers: &Modifiers) -> TextInputResult { + let old = (self.text.content(), self.text.selection); + let mut undo = false; + let res = self.apply_event_inner(event, modifiers, &mut undo); + if undo && let Some((old, selection)) = self.text.history.pop() { + self.set(&old); + self.text.selection = selection; + } else if self.text.content() != old.0 { + self.text.history.push(old); + } + res + } + + fn apply_event_inner( + &mut self, + event: &KeyEvent, + modifiers: &Modifiers, + undo: &mut bool, + ) -> TextInputResult { match &event.logical_key { Key::Named(named) => match named { NamedKey::Backspace => self.backspace(modifiers.control), @@ -429,6 +455,9 @@ impl<'a> TextEditCtx<'a> { }; } } + "z" => { + *undo = true; + } _ => self.insert(text), } } else { @@ -463,7 +492,7 @@ pub enum TextInputResult { Paste, } -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone, Copy)] pub enum TextSelection { #[default] None, diff --git a/src/layout/id.rs b/src/layout/id.rs index 1746bba..e0ff91c 100644 --- a/src/layout/id.rs +++ b/src/layout/id.rs @@ -9,7 +9,7 @@ use std::{ }; use crate::{ - layout::{FnTag, Ui, Widget, WidgetLike, WidgetTag}, + layout::{Ui, WidgetLike}, util::{Id, RefCounter}, }; @@ -141,49 +141,6 @@ pub struct IdFnTag; pub trait WidgetIdFn: FnOnce(&mut Ui) -> WidgetId {} impl WidgetId> WidgetIdFn for F {} -/// TODO: does this ever make sense to use? it allows for invalid ids -pub trait Idable { - type Widget: Widget; - fn set(self, ui: &mut Ui, id: &WidgetId); - fn id(self, id: &WidgetId) -> impl WidgetIdFn - where - Self: Sized, - { - let id = id.clone(); - move |ui| { - self.set(ui, &id); - id - } - } - fn id_static(self, id: StaticWidgetId) -> impl WidgetIdFn - where - Self: Sized, - { - move |ui| { - let id = id.id(&ui.send); - self.set(ui, &id); - id - } - } -} - -impl Idable for W { - type Widget = W; - - fn set(self, ui: &mut Ui, id: &WidgetId) { - ui.set(id, self); - } -} - -impl W, W: Widget> Idable for F { - type Widget = W; - - fn set(self, ui: &mut Ui, id: &WidgetId) { - let w = self(ui); - ui.set(id, w); - } -} - impl WidgetLike for WidgetId { type Widget = W; fn add(self, _: &mut Ui) -> WidgetId { diff --git a/src/layout/ui.rs b/src/layout/ui.rs index 08b26e5..e3aad4f 100644 --- a/src/layout/ui.rs +++ b/src/layout/ui.rs @@ -52,15 +52,11 @@ impl Ui { } pub fn push(&mut self, w: W) -> WidgetId { - let id = self.id(); + let id = self.new_id(); self.data.widgets.insert(id.id, w); id } - pub fn set(&mut self, id: &WidgetId, w: W) { - self.data.widgets.insert(id.id, w); - } - pub fn set_root(&mut self, w: impl WidgetLike) { self.root = Some(w.add(self).any()); self.full_redraw = true; @@ -78,7 +74,7 @@ impl Ui { self.data.widgets.get_mut(id) } - pub fn id(&mut self) -> WidgetId { + fn new_id(&mut self) -> WidgetId { WidgetId::new( self.data.widgets.reserve(), TypeId::of::(), @@ -87,11 +83,6 @@ impl Ui { ) } - pub fn id_static(&mut self) -> StaticWidgetId { - let id = self.id(); - id.into_static() - } - pub fn add_texture(&mut self, image: DynamicImage) -> TextureHandle { self.data.textures.add(image) }