Add on_release message to Slider (#378)

* Add on_finish callback to Slider

* Fix formatting

* Rename Slider's on_finish to on_release, make the message simply an event without data

* Satisfy Clone impl requirement on Message in integration test

* Only call on_release after dragging a slider
This commit is contained in:
Duncan Freeman 2020-06-08 02:07:45 -07:00 committed by GitHub
parent 40750d9b36
commit 4960a8827e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 3 deletions

View File

@ -9,7 +9,7 @@ pub struct Controls {
sliders: [slider::State; 3], sliders: [slider::State; 3],
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Message { pub enum Message {
BackgroundColorChanged(Color), BackgroundColorChanged(Color),
} }

View File

@ -40,6 +40,7 @@ pub struct Slider<'a, Message, Renderer: self::Renderer> {
range: RangeInclusive<f32>, range: RangeInclusive<f32>,
value: f32, value: f32,
on_change: Box<dyn Fn(f32) -> Message>, on_change: Box<dyn Fn(f32) -> Message>,
on_release: Option<Message>,
width: Length, width: Length,
style: Renderer::Style, style: Renderer::Style,
} }
@ -71,11 +72,25 @@ impl<'a, Message, Renderer: self::Renderer> Slider<'a, Message, Renderer> {
value: value.max(*range.start()).min(*range.end()), value: value.max(*range.start()).min(*range.end()),
range, range,
on_change: Box::new(on_change), on_change: Box::new(on_change),
on_release: None,
width: Length::Fill, width: Length::Fill,
style: Renderer::Style::default(), style: Renderer::Style::default(),
} }
} }
/// Sets the release message of the [`Slider`].
/// This is called when the mouse is released from the slider.
///
/// Typically, the user's interaction with the slider is finished when this message is produced.
/// This is useful if you need to spawn a long-running task from the slider's result, where
/// the default on_change message could create too many events.
///
/// [`Slider`]: struct.Slider.html
pub fn on_release(mut self, on_release: Message) -> Self {
self.on_release = Some(on_release);
self
}
/// Sets the width of the [`Slider`]. /// Sets the width of the [`Slider`].
/// ///
/// [`Slider`]: struct.Slider.html /// [`Slider`]: struct.Slider.html
@ -114,6 +129,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer>
for Slider<'a, Message, Renderer> for Slider<'a, Message, Renderer>
where where
Renderer: self::Renderer, Renderer: self::Renderer,
Message: Clone,
{ {
fn width(&self) -> Length { fn width(&self) -> Length {
self.width self.width
@ -171,8 +187,13 @@ where
} }
} }
mouse::Event::ButtonReleased(mouse::Button::Left) => { mouse::Event::ButtonReleased(mouse::Button::Left) => {
if self.state.is_dragging {
if let Some(on_release) = self.on_release.clone() {
messages.push(on_release);
}
self.state.is_dragging = false; self.state.is_dragging = false;
} }
}
mouse::Event::CursorMoved { .. } => { mouse::Event::CursorMoved { .. } => {
if self.state.is_dragging { if self.state.is_dragging {
change(); change();
@ -252,7 +273,7 @@ impl<'a, Message, Renderer> From<Slider<'a, Message, Renderer>>
for Element<'a, Message, Renderer> for Element<'a, Message, Renderer>
where where
Renderer: 'a + self::Renderer, Renderer: 'a + self::Renderer,
Message: 'a, Message: 'a + Clone,
{ {
fn from( fn from(
slider: Slider<'a, Message, Renderer>, slider: Slider<'a, Message, Renderer>,