diff options
Diffstat (limited to '')
-rw-r--r-- | widget/src/slider.rs (renamed from native/src/widget/slider.rs) | 155 |
1 files changed, 76 insertions, 79 deletions
diff --git a/native/src/widget/slider.rs b/widget/src/slider.rs index d3715b1c..3ea4391b 100644 --- a/native/src/widget/slider.rs +++ b/widget/src/slider.rs @@ -1,20 +1,22 @@ //! Display an interactive selector of a single value from a range of values. //! //! A [`Slider`] has some local [`State`]. -use crate::event::{self, Event}; -use crate::layout; -use crate::mouse; -use crate::renderer; -use crate::touch; -use crate::widget::tree::{self, Tree}; -use crate::{ - Background, Clipboard, Color, Element, Layout, Length, Pixels, Point, - Rectangle, Shell, Size, Widget, +use crate::core::event::{self, Event}; +use crate::core::layout; +use crate::core::mouse; +use crate::core::renderer; +use crate::core::touch; +use crate::core::widget::tree::{self, Tree}; +use crate::core::{ + Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell, + Size, Widget, }; use std::ops::RangeInclusive; -pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet}; +pub use iced_style::slider::{ + Appearance, Handle, HandleShape, Rail, StyleSheet, +}; /// An horizontal bar and a handle that selects a single value from a range of /// values. @@ -25,11 +27,9 @@ pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet}; /// to 1 unit. /// /// # Example -/// ``` -/// # use iced_native::widget::slider; -/// # use iced_native::renderer::Null; -/// # -/// # type Slider<'a, T, Message> = slider::Slider<'a, T, Message, Null>; +/// ```no_run +/// # type Slider<'a, T, Message> = +/// # iced_widget::Slider<'a, Message, T, iced_widget::renderer::Renderer<iced_widget::style::Theme>>; /// # /// #[derive(Clone)] /// pub enum Message { @@ -43,9 +43,9 @@ pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet}; /// ///  #[allow(missing_debug_implementations)] -pub struct Slider<'a, T, Message, Renderer> +pub struct Slider<'a, T, Message, Renderer = crate::Renderer> where - Renderer: crate::Renderer, + Renderer: crate::core::Renderer, Renderer::Theme: StyleSheet, { range: RangeInclusive<T>, @@ -62,7 +62,7 @@ impl<'a, T, Message, Renderer> Slider<'a, T, Message, Renderer> where T: Copy + From<u8> + std::cmp::PartialOrd, Message: Clone, - Renderer: crate::Renderer, + Renderer: crate::core::Renderer, Renderer::Theme: StyleSheet, { /// The default height of a [`Slider`]. @@ -148,7 +148,7 @@ impl<'a, T, Message, Renderer> Widget<Message, Renderer> where T: Copy + Into<f64> + num_traits::FromPrimitive, Message: Clone, - Renderer: crate::Renderer, + Renderer: crate::core::Renderer, Renderer::Theme: StyleSheet, { fn tag(&self) -> tree::Tag { @@ -183,7 +183,7 @@ where tree: &mut Tree, event: Event, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, @@ -191,7 +191,7 @@ where update( event, layout, - cursor_position, + cursor, shell, tree.state.downcast_mut::<State>(), &mut self.value, @@ -209,13 +209,13 @@ where theme: &Renderer::Theme, _style: &renderer::Style, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, _viewport: &Rectangle, ) { draw( renderer, layout, - cursor_position, + cursor, tree.state.downcast_ref::<State>(), self.value, &self.range, @@ -228,15 +228,11 @@ where &self, tree: &Tree, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, _viewport: &Rectangle, _renderer: &Renderer, ) -> mouse::Interaction { - mouse_interaction( - layout, - cursor_position, - tree.state.downcast_ref::<State>(), - ) + mouse_interaction(layout, cursor, tree.state.downcast_ref::<State>()) } } @@ -245,7 +241,7 @@ impl<'a, T, Message, Renderer> From<Slider<'a, T, Message, Renderer>> where T: 'a + Copy + Into<f64> + num_traits::FromPrimitive, Message: 'a + Clone, - Renderer: 'a + crate::Renderer, + Renderer: 'a + crate::core::Renderer, Renderer::Theme: StyleSheet, { fn from( @@ -260,7 +256,7 @@ where pub fn update<Message, T>( event: Event, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, shell: &mut Shell<'_, Message>, state: &mut State, value: &mut T, @@ -275,7 +271,7 @@ where { let is_dragging = state.is_dragging; - let mut change = || { + let mut change = |cursor_position: Point| { let bounds = layout.bounds(); let new_value = if cursor_position.x <= bounds.x { *range.start() @@ -309,8 +305,9 @@ where match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { - if layout.bounds().contains(cursor_position) { - change(); + if let Some(cursor_position) = cursor.position_over(layout.bounds()) + { + change(cursor_position); state.is_dragging = true; return event::Status::Captured; @@ -331,7 +328,7 @@ where Event::Mouse(mouse::Event::CursorMoved { .. }) | Event::Touch(touch::Event::FingerMoved { .. }) => { if is_dragging { - change(); + let _ = cursor.position().map(change); return event::Status::Captured; } @@ -346,7 +343,7 @@ where pub fn draw<T, R>( renderer: &mut R, layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, state: &State, value: T, range: &RangeInclusive<T>, @@ -354,11 +351,11 @@ pub fn draw<T, R>( style: &<R::Theme as StyleSheet>::Style, ) where T: Into<f64> + Copy, - R: crate::Renderer, + R: crate::core::Renderer, R::Theme: StyleSheet, { let bounds = layout.bounds(); - let is_mouse_over = bounds.contains(cursor_position); + let is_mouse_over = cursor.is_over(bounds); let style = if state.is_dragging { style_sheet.dragging(style) @@ -368,72 +365,72 @@ pub fn draw<T, R>( style_sheet.active(style) }; - let rail_y = bounds.y + (bounds.height / 2.0).round(); + let (handle_width, handle_height, handle_border_radius) = + match style.handle.shape { + HandleShape::Circle { radius } => { + (radius * 2.0, radius * 2.0, radius.into()) + } + HandleShape::Rectangle { + width, + border_radius, + } => (f32::from(width), bounds.height, border_radius), + }; + + let value = value.into() as f32; + let (range_start, range_end) = { + let (start, end) = range.clone().into_inner(); + + (start.into() as f32, end.into() as f32) + }; + + let offset = if range_start >= range_end { + 0.0 + } else { + (bounds.width - handle_width) * (value - range_start) + / (range_end - range_start) + }; + + let rail_y = bounds.y + bounds.height / 2.0; renderer.fill_quad( renderer::Quad { bounds: Rectangle { x: bounds.x, - y: rail_y - 1.0, - width: bounds.width, - height: 2.0, + y: rail_y - style.rail.width / 2.0, + width: offset + handle_width / 2.0, + height: style.rail.width, }, - border_radius: 0.0.into(), + border_radius: style.rail.border_radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, - style.rail_colors.0, + style.rail.colors.0, ); renderer.fill_quad( renderer::Quad { bounds: Rectangle { - x: bounds.x, - y: rail_y + 1.0, - width: bounds.width, - height: 2.0, + x: bounds.x + offset + handle_width / 2.0, + y: rail_y - style.rail.width / 2.0, + width: bounds.width - offset - handle_width / 2.0, + height: style.rail.width, }, - border_radius: 0.0.into(), + border_radius: style.rail.border_radius, border_width: 0.0, border_color: Color::TRANSPARENT, }, - Background::Color(style.rail_colors.1), + style.rail.colors.1, ); - let (handle_width, handle_height, handle_border_radius) = match style - .handle - .shape - { - HandleShape::Circle { radius } => (radius * 2.0, radius * 2.0, radius), - HandleShape::Rectangle { - width, - border_radius, - } => (f32::from(width), bounds.height, border_radius), - }; - - let value = value.into() as f32; - let (range_start, range_end) = { - let (start, end) = range.clone().into_inner(); - - (start.into() as f32, end.into() as f32) - }; - - let handle_offset = if range_start >= range_end { - 0.0 - } else { - (bounds.width - handle_width) * (value - range_start) - / (range_end - range_start) - }; - renderer.fill_quad( renderer::Quad { bounds: Rectangle { - x: bounds.x + handle_offset.round(), + x: bounds.x + offset, y: rail_y - handle_height / 2.0, width: handle_width, height: handle_height, }, - border_radius: handle_border_radius.into(), + border_radius: handle_border_radius, border_width: style.handle.border_width, border_color: style.handle.border_color, }, @@ -444,11 +441,11 @@ pub fn draw<T, R>( /// Computes the current [`mouse::Interaction`] of a [`Slider`]. pub fn mouse_interaction( layout: Layout<'_>, - cursor_position: Point, + cursor: mouse::Cursor, state: &State, ) -> mouse::Interaction { let bounds = layout.bounds(); - let is_mouse_over = bounds.contains(cursor_position); + let is_mouse_over = cursor.is_over(bounds); if state.is_dragging { mouse::Interaction::Grabbing |