Make Slider
value type generic
This commit is contained in:
parent
f131969c47
commit
0b819de3e2
@ -13,4 +13,4 @@ pub use iced_native::slider::State;
|
|||||||
/// values.
|
/// values.
|
||||||
///
|
///
|
||||||
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
||||||
pub type Slider<'a, Message> = iced_native::Slider<'a, Message, Renderer>;
|
pub type Slider<'a, T, Message> = iced_native::Slider<'a, T, Message, Renderer>;
|
||||||
|
@ -16,8 +16,8 @@ pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet};
|
|||||||
/// values.
|
/// values.
|
||||||
///
|
///
|
||||||
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
||||||
pub type Slider<'a, Message, Backend> =
|
pub type Slider<'a, T, Message, Backend> =
|
||||||
iced_native::Slider<'a, Message, Renderer<Backend>>;
|
iced_native::Slider<'a, T, Message, Renderer<Backend>>;
|
||||||
|
|
||||||
const HANDLE_HEIGHT: f32 = 22.0;
|
const HANDLE_HEIGHT: f32 = 22.0;
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ debug = []
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
twox-hash = "1.5"
|
twox-hash = "1.5"
|
||||||
unicode-segmentation = "1.6"
|
unicode-segmentation = "1.6"
|
||||||
|
num-traits = "0.2"
|
||||||
|
|
||||||
[dependencies.iced_core]
|
[dependencies.iced_core]
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
|
@ -24,7 +24,7 @@ use std::{hash::Hash, ops::RangeInclusive};
|
|||||||
/// ```
|
/// ```
|
||||||
/// # use iced_native::{slider, renderer::Null};
|
/// # use iced_native::{slider, renderer::Null};
|
||||||
/// #
|
/// #
|
||||||
/// # pub type Slider<'a, Message> = iced_native::Slider<'a, Message, Null>;
|
/// # pub type Slider<'a, T, Message> = iced_native::Slider<'a, T, Message, Null>;
|
||||||
/// pub enum Message {
|
/// pub enum Message {
|
||||||
/// SliderChanged(f32),
|
/// SliderChanged(f32),
|
||||||
/// }
|
/// }
|
||||||
@ -37,18 +37,22 @@ use std::{hash::Hash, ops::RangeInclusive};
|
|||||||
///
|
///
|
||||||
/// 
|
/// 
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct Slider<'a, Message, Renderer: self::Renderer> {
|
pub struct Slider<'a, T, Message, Renderer: self::Renderer> {
|
||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
range: RangeInclusive<f32>,
|
range: RangeInclusive<T>,
|
||||||
step: f32,
|
step: T,
|
||||||
value: f32,
|
value: T,
|
||||||
on_change: Box<dyn Fn(f32) -> Message>,
|
on_change: Box<dyn Fn(T) -> Message>,
|
||||||
on_release: Option<Message>,
|
on_release: Option<Message>,
|
||||||
width: Length,
|
width: Length,
|
||||||
style: Renderer::Style,
|
style: Renderer::Style,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer: self::Renderer> Slider<'a, Message, Renderer> {
|
impl<'a, T, Message, Renderer> Slider<'a, T, Message, Renderer>
|
||||||
|
where
|
||||||
|
T: Copy + From<u8> + std::cmp::PartialOrd,
|
||||||
|
Renderer: self::Renderer,
|
||||||
|
{
|
||||||
/// Creates a new [`Slider`].
|
/// Creates a new [`Slider`].
|
||||||
///
|
///
|
||||||
/// It expects:
|
/// It expects:
|
||||||
@ -63,18 +67,30 @@ impl<'a, Message, Renderer: self::Renderer> Slider<'a, Message, Renderer> {
|
|||||||
/// [`State`]: struct.State.html
|
/// [`State`]: struct.State.html
|
||||||
pub fn new<F>(
|
pub fn new<F>(
|
||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
range: RangeInclusive<f32>,
|
range: RangeInclusive<T>,
|
||||||
value: f32,
|
value: T,
|
||||||
on_change: F,
|
on_change: F,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
F: 'static + Fn(f32) -> Message,
|
F: 'static + Fn(T) -> Message,
|
||||||
{
|
{
|
||||||
|
let value = if value >= *range.start() {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
*range.start()
|
||||||
|
};
|
||||||
|
|
||||||
|
let value = if value <= *range.end() {
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
*range.end()
|
||||||
|
};
|
||||||
|
|
||||||
Slider {
|
Slider {
|
||||||
state,
|
state,
|
||||||
value: value.max(*range.start()).min(*range.end()),
|
value,
|
||||||
range,
|
range,
|
||||||
step: 1.0,
|
step: T::from(1),
|
||||||
on_change: Box::new(on_change),
|
on_change: Box::new(on_change),
|
||||||
on_release: None,
|
on_release: None,
|
||||||
width: Length::Fill,
|
width: Length::Fill,
|
||||||
@ -114,7 +130,7 @@ impl<'a, Message, Renderer: self::Renderer> Slider<'a, Message, Renderer> {
|
|||||||
/// Sets the step size of the [`Slider`].
|
/// Sets the step size of the [`Slider`].
|
||||||
///
|
///
|
||||||
/// [`Slider`]: struct.Slider.html
|
/// [`Slider`]: struct.Slider.html
|
||||||
pub fn step(mut self, step: f32) -> Self {
|
pub fn step(mut self, step: T) -> Self {
|
||||||
self.step = step;
|
self.step = step;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@ -137,9 +153,10 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> Widget<Message, Renderer>
|
impl<'a, T, Message, Renderer> Widget<Message, Renderer>
|
||||||
for Slider<'a, Message, Renderer>
|
for Slider<'a, T, Message, Renderer>
|
||||||
where
|
where
|
||||||
|
T: Copy + Into<f64> + num_traits::FromPrimitive,
|
||||||
Renderer: self::Renderer,
|
Renderer: self::Renderer,
|
||||||
Message: Clone,
|
Message: Clone,
|
||||||
{
|
{
|
||||||
@ -181,13 +198,20 @@ where
|
|||||||
} else if cursor_position.x >= bounds.x + bounds.width {
|
} else if cursor_position.x >= bounds.x + bounds.width {
|
||||||
messages.push((self.on_change)(*self.range.end()));
|
messages.push((self.on_change)(*self.range.end()));
|
||||||
} else {
|
} else {
|
||||||
let percent = (cursor_position.x - bounds.x) / bounds.width;
|
let step: f64 = self.step.into();
|
||||||
let steps = (percent * (self.range.end() - self.range.start())
|
let start: f64 = (*self.range.start()).into();
|
||||||
/ self.step)
|
let end: f64 = (*self.range.end()).into();
|
||||||
.round();
|
|
||||||
let value = steps * self.step + self.range.start();
|
let percent = f64::from(cursor_position.x - bounds.x)
|
||||||
|
/ f64::from(bounds.width);
|
||||||
|
|
||||||
|
let steps = (percent * (end - start) / step).round();
|
||||||
|
let value = steps * step + start;
|
||||||
|
|
||||||
|
if let Some(value) = T::from_f64(value) {
|
||||||
messages.push((self.on_change)(value));
|
messages.push((self.on_change)(value));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
@ -224,11 +248,14 @@ where
|
|||||||
layout: Layout<'_>,
|
layout: Layout<'_>,
|
||||||
cursor_position: Point,
|
cursor_position: Point,
|
||||||
) -> Renderer::Output {
|
) -> Renderer::Output {
|
||||||
|
let start = *self.range.start();
|
||||||
|
let end = *self.range.end();
|
||||||
|
|
||||||
renderer.draw(
|
renderer.draw(
|
||||||
layout.bounds(),
|
layout.bounds(),
|
||||||
cursor_position,
|
cursor_position,
|
||||||
self.range.clone(),
|
start.into() as f32..=end.into() as f32,
|
||||||
self.value,
|
self.value.into() as f32,
|
||||||
self.state.is_dragging,
|
self.state.is_dragging,
|
||||||
&self.style,
|
&self.style,
|
||||||
)
|
)
|
||||||
@ -281,14 +308,15 @@ pub trait Renderer: crate::Renderer {
|
|||||||
) -> Self::Output;
|
) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Message, Renderer> From<Slider<'a, Message, Renderer>>
|
impl<'a, T, Message, Renderer> From<Slider<'a, T, Message, Renderer>>
|
||||||
for Element<'a, Message, Renderer>
|
for Element<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
|
T: 'a + Copy + Into<f64> + num_traits::FromPrimitive,
|
||||||
Renderer: 'a + self::Renderer,
|
Renderer: 'a + self::Renderer,
|
||||||
Message: 'a + Clone,
|
Message: 'a + Clone,
|
||||||
{
|
{
|
||||||
fn from(
|
fn from(
|
||||||
slider: Slider<'a, Message, Renderer>,
|
slider: Slider<'a, T, Message, Renderer>,
|
||||||
) -> Element<'a, Message, Renderer> {
|
) -> Element<'a, Message, Renderer> {
|
||||||
Element::new(slider)
|
Element::new(slider)
|
||||||
}
|
}
|
||||||
|
@ -13,4 +13,4 @@ pub use iced_native::slider::State;
|
|||||||
/// values.
|
/// values.
|
||||||
///
|
///
|
||||||
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
/// This is an alias of an `iced_native` slider with an `iced_wgpu::Renderer`.
|
||||||
pub type Slider<'a, Message> = iced_native::Slider<'a, Message, Renderer>;
|
pub type Slider<'a, T, Message> = iced_native::Slider<'a, T, Message, Renderer>;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user