From 16a3bd7bbed765d2b5e476d2b470989baed2a90d Mon Sep 17 00:00:00 2001 From: Alexandre Bury Date: Thu, 15 Mar 2018 11:50:22 -0700 Subject: [PATCH] Return callbacks from `EditView::set_content` Just like for SelectView::select_up --- src/views/edit_view.rs | 53 +++++++++++++++++++++++++++++----------- src/views/select_view.rs | 4 +-- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/views/edit_view.rs b/src/views/edit_view.rs index 524132c..37bdc85 100644 --- a/src/views/edit_view.rs +++ b/src/views/edit_view.rs @@ -329,13 +329,19 @@ impl EditView { } /// Replace the entire content of the view with the given one. - pub fn set_content>(&mut self, content: S) { + /// + /// Returns a callback in response to content change. + /// + /// You should run this callback with a `&mut Cursive`. + pub fn set_content>(&mut self, content: S) -> Callback { let content = content.into(); let len = content.len(); self.content = Rc::new(content); self.offset = 0; self.set_cursor(len); + + self.make_edit_cb().unwrap_or_else(Callback::dummy) } /// Get the current text. @@ -346,6 +352,8 @@ impl EditView { /// Sets the current content to the given value. /// /// Convenient chainable method. + /// + /// Does not run the `on_edit` callback. pub fn content>(mut self, content: S) -> Self { self.set_content(content); self @@ -359,19 +367,43 @@ impl EditView { } /// Insert `ch` at the current cursor position. - pub fn insert(&mut self, ch: char) { + /// + /// Returns a callback in response to content change. + /// + /// You should run this callback with a `&mut Cursive`. + pub fn insert(&mut self, ch: char) -> Callback { // `make_mut` applies copy-on-write // It means it'll just return a ref if no one else has a ref, // and it will clone it into `self.content` otherwise. Rc::make_mut(&mut self.content).insert(self.cursor, ch); self.cursor += ch.len_utf8(); + + self.make_edit_cb().unwrap_or_else(Callback::dummy) } /// Remove the character at the current cursor position. - pub fn remove(&mut self, len: usize) { + /// + /// Returns a callback in response to content change. + /// + /// You should run this callback with a `&mut Cursive`. + pub fn remove(&mut self, len: usize) -> Callback { let start = self.cursor; let end = self.cursor + len; for _ in Rc::make_mut(&mut self.content).drain(start..end) {} + + self.make_edit_cb().unwrap_or_else(Callback::dummy) + } + + fn make_edit_cb(&self) -> Option { + self.on_edit.clone().map(|cb| { + // Get a new Rc on the content + let content = Rc::clone(&self.content); + let cursor = self.cursor; + + Callback::from_fn(move |s| { + cb(s, &content, cursor); + }) + }) } fn keep_cursor_in_view(&mut self) { @@ -536,7 +568,9 @@ impl View for EditView { fn on_event(&mut self, event: Event) -> EventResult { match event { - Event::Char(ch) => self.insert(ch), + Event::Char(ch) => { + self.insert(ch); + } // TODO: handle ctrl-key? Event::Key(Key::Home) => self.cursor = 0, Event::Key(Key::End) => self.cursor = self.content.len(), @@ -599,15 +633,6 @@ impl View for EditView { self.keep_cursor_in_view(); - let cb = self.on_edit.clone().map(|cb| { - // Get a new Rc on the content - let content = Rc::clone(&self.content); - let cursor = self.cursor; - - Callback::from_fn(move |s| { - cb(s, &content, cursor); - }) - }); - EventResult::Consumed(cb) + EventResult::Consumed(self.make_edit_cb()) } } diff --git a/src/views/select_view.rs b/src/views/select_view.rs index 6ecef23..de7e22f 100644 --- a/src/views/select_view.rs +++ b/src/views/select_view.rs @@ -249,7 +249,7 @@ impl SelectView { /// /// Returns a callback in response to the selection change. /// - /// You should run this callback with a `&mut Cursive`: + /// You should run this callback with a `&mut Cursive`. pub fn remove_item(&mut self, id: usize) -> Callback { self.items.remove(id); let focus = self.focus(); @@ -327,7 +327,7 @@ impl SelectView { /// /// Returns a callback in response to the selection change. /// - /// You should run this callback with a `&mut Cursive`: + /// You should run this callback with a `&mut Cursive`. pub fn set_selection(&mut self, i: usize) -> Callback { // TODO: Check if `i >= self.len()` ? // assert!(i < self.len(), "SelectView: trying to select out-of-bound");