From 8ea55a69a01069c93d37ee49342f8df6798855ff Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov <3209180+agavrilov@users.noreply.github.com> Date: Fri, 30 Nov 2018 14:34:17 -0800 Subject: [PATCH 1/2] Add on_change callback --- src/views/radio.rs | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/views/radio.rs b/src/views/radio.rs index 6e61078..4c48e3c 100644 --- a/src/views/radio.rs +++ b/src/views/radio.rs @@ -5,11 +5,14 @@ use std::rc::Rc; use theme::ColorStyle; use vec::Vec2; use view::View; +use Cursive; use {Printer, With}; struct SharedState { selection: usize, values: Vec>, + + on_change: Option>, } impl SharedState { @@ -31,19 +34,20 @@ pub struct RadioGroup { state: Rc>>, } -impl Default for RadioGroup { +impl Default for RadioGroup { fn default() -> Self { Self::new() } } -impl RadioGroup { +impl RadioGroup { /// Creates an empty group for radio buttons. pub fn new() -> Self { RadioGroup { state: Rc::new(RefCell::new(SharedState { selection: 0, values: Vec::new(), + on_change: None, })), } } @@ -70,6 +74,13 @@ impl RadioGroup { pub fn selection(&self) -> Rc { self.state.borrow().selection() } + + /// Sets a callback to be used when the selection changes. + pub fn set_on_change( + &mut self, on_change: F, + ) { + self.state.borrow_mut().on_change = Some(Rc::new(on_change)); + } } impl RadioGroup { @@ -100,7 +111,7 @@ pub struct RadioButton { label: String, } -impl RadioButton { +impl RadioButton { impl_enabled!(self.enabled); fn new( @@ -120,15 +131,25 @@ impl RadioButton { } /// Selects this button, un-selecting any other in the same group. - pub fn select(&mut self) { - self.state.borrow_mut().selection = self.id; + pub fn select(&mut self) -> EventResult { + let mut state = self.state.borrow_mut(); + state.selection = self.id; + if let Some(ref on_change) = state.on_change { + let on_change = Rc::clone(on_change); + let value = state.selection(); + EventResult::with_cb(move |s| on_change(s, &value)) + } else { + EventResult::Consumed(None) + } } /// Selects this button, un-selecting any other in the same group. /// /// Chainable variant. pub fn selected(self) -> Self { - self.with(Self::select) + self.with(|s| { + s.select(); + }) } fn draw_internal(&self, printer: &Printer) { @@ -177,16 +198,14 @@ impl View for RadioButton { fn on_event(&mut self, event: Event) -> EventResult { match event { Event::Key(Key::Enter) | Event::Char(' ') => { - self.select(); - EventResult::Consumed(None) + self.select() } Event::Mouse { event: MouseEvent::Release(MouseButton::Left), position, offset, } if position.fits_in_rect(offset, self.req_size()) => { - self.select(); - EventResult::Consumed(None) + self.select() } _ => EventResult::Ignored, } From fcfca86a3604963c7bfbf06c28a3967f2fa0f56b Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov <3209180+agavrilov@users.noreply.github.com> Date: Fri, 30 Nov 2018 15:44:56 -0800 Subject: [PATCH 2/2] Add chainable variant of on_change --- src/views/radio.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/views/radio.rs b/src/views/radio.rs index 4c48e3c..03d3421 100644 --- a/src/views/radio.rs +++ b/src/views/radio.rs @@ -81,6 +81,15 @@ impl RadioGroup { ) { self.state.borrow_mut().on_change = Some(Rc::new(on_change)); } + + /// Sets a callback to be used when the selection changes. + /// + /// Chainable variant. + pub fn on_change( + self, on_change: F, + ) -> Self { + self.with(|s| s.set_on_change(on_change)) + } } impl RadioGroup { @@ -148,6 +157,7 @@ impl RadioButton { /// Chainable variant. pub fn selected(self) -> Self { self.with(|s| { + // Ignore the potential callback here s.select(); }) }