summaryrefslogtreecommitdiffstats
path: root/native/src/widget/slider.rs
diff options
context:
space:
mode:
Diffstat (limited to 'native/src/widget/slider.rs')
-rw-r--r--native/src/widget/slider.rs109
1 files changed, 91 insertions, 18 deletions
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index 3a998c40..f91d3ac5 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -4,12 +4,79 @@
//!
//! [`Slider`]: struct.Slider.html
//! [`State`]: struct.State.html
-use std::hash::Hash;
-use crate::input::{mouse, ButtonState};
-use crate::{layout, Element, Event, Hasher, Layout, Length, Point, Widget};
+use crate::{
+ input::{mouse, ButtonState},
+ layout, Element, Event, Hasher, Layout, Length, Point, Rectangle, Size,
+ Widget,
+};
-pub use iced_core::slider::*;
+use std::{hash::Hash, ops::RangeInclusive};
+
+pub struct Slider<'a, Message> {
+ state: &'a mut State,
+ range: RangeInclusive<f32>,
+ value: f32,
+ on_change: Box<dyn Fn(f32) -> Message>,
+ width: Length,
+}
+
+impl<'a, Message> Slider<'a, Message> {
+ /// Creates a new [`Slider`].
+ ///
+ /// It expects:
+ /// * the local [`State`] of the [`Slider`]
+ /// * an inclusive range of possible values
+ /// * the current value of the [`Slider`]
+ /// * a function that will be called when the [`Slider`] is dragged.
+ /// It receives the new value of the [`Slider`] and must produce a
+ /// `Message`.
+ ///
+ /// [`Slider`]: struct.Slider.html
+ /// [`State`]: struct.State.html
+ pub fn new<F>(
+ state: &'a mut State,
+ range: RangeInclusive<f32>,
+ value: f32,
+ on_change: F,
+ ) -> Self
+ where
+ F: 'static + Fn(f32) -> Message,
+ {
+ Slider {
+ state,
+ value: value.max(*range.start()).min(*range.end()),
+ range,
+ on_change: Box::new(on_change),
+ width: Length::Fill,
+ }
+ }
+
+ /// Sets the width of the [`Slider`].
+ ///
+ /// [`Slider`]: struct.Slider.html
+ pub fn width(mut self, width: Length) -> Self {
+ self.width = width;
+ self
+ }
+}
+
+/// The local state of a [`Slider`].
+///
+/// [`Slider`]: struct.Slider.html
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
+pub struct State {
+ is_dragging: bool,
+}
+
+impl State {
+ /// Creates a new [`State`].
+ ///
+ /// [`State`]: struct.State.html
+ pub fn new() -> State {
+ State::default()
+ }
+}
impl<'a, Message, Renderer> Widget<Message, Renderer> for Slider<'a, Message>
where
@@ -24,7 +91,13 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
- renderer.layout(&self, limits)
+ let limits = limits
+ .width(self.width)
+ .height(Length::Units(renderer.height() as u16));
+
+ let size = limits.resolve(Size::ZERO);
+
+ layout::Node::new(size)
}
fn on_event(
@@ -81,7 +154,13 @@ where
layout: Layout<'_>,
cursor_position: Point,
) -> Renderer::Output {
- renderer.draw(&self, layout, cursor_position)
+ renderer.draw(
+ layout.bounds(),
+ cursor_position,
+ self.range.clone(),
+ self.value,
+ self.state.is_dragging,
+ )
}
fn hash_layout(&self, state: &mut Hasher) {
@@ -97,15 +176,7 @@ where
/// [`Slider`]: struct.Slider.html
/// [renderer]: ../../renderer/index.html
pub trait Renderer: crate::Renderer {
- /// Creates a [`Node`] for the provided [`Radio`].
- ///
- /// [`Node`]: ../../struct.Node.html
- /// [`Radio`]: struct.Radio.html
- fn layout<Message>(
- &self,
- slider: &Slider<'_, Message>,
- limits: &layout::Limits,
- ) -> layout::Node;
+ fn height(&self) -> u32;
/// Draws a [`Slider`].
///
@@ -119,11 +190,13 @@ pub trait Renderer: crate::Renderer {
/// [`Slider`]: struct.Slider.html
/// [`State`]: struct.State.html
/// [`Class`]: enum.Class.html
- fn draw<Message>(
+ fn draw(
&mut self,
- slider: &Slider<'_, Message>,
- layout: Layout<'_>,
+ bounds: Rectangle,
cursor_position: Point,
+ range: RangeInclusive<f32>,
+ value: f32,
+ is_dragging: bool,
) -> Self::Output;
}