From bb4161c1aec0a2a76de39ff2e5ed65f7acbad471 Mon Sep 17 00:00:00 2001 From: Casper Storm Date: Tue, 13 Dec 2022 10:05:52 +0100 Subject: Split vertical orientation into VerticalSlider --- native/src/widget.rs | 3 + native/src/widget/helpers.rs | 17 ++ native/src/widget/slider.rs | 199 +++------------ native/src/widget/vertical_slider.rs | 470 +++++++++++++++++++++++++++++++++++ 4 files changed, 531 insertions(+), 158 deletions(-) create mode 100644 native/src/widget/vertical_slider.rs (limited to 'native/src') diff --git a/native/src/widget.rs b/native/src/widget.rs index a4b46ed4..efe26fc7 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -33,6 +33,7 @@ pub mod text_input; pub mod toggler; pub mod tooltip; pub mod tree; +pub mod vertical_slider; mod action; mod id; @@ -79,6 +80,8 @@ pub use toggler::Toggler; pub use tooltip::Tooltip; #[doc(no_inline)] pub use tree::Tree; +#[doc(no_inline)] +pub use vertical_slider::VerticalSlider; pub use action::Action; pub use id::Id; diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs index 0bde288f..8cc1ae82 100644 --- a/native/src/widget/helpers.rs +++ b/native/src/widget/helpers.rs @@ -198,6 +198,23 @@ where widget::Slider::new(range, value, on_change) } +/// Creates a new [`VerticalSlider`]. +/// +/// [`VerticalSlider`]: widget::VerticalSlider +pub fn vertical_slider<'a, T, Message, Renderer>( + range: std::ops::RangeInclusive, + value: T, + on_change: impl Fn(T) -> Message + 'a, +) -> widget::VerticalSlider<'a, T, Message, Renderer> +where + T: Copy + From + std::cmp::PartialOrd, + Message: Clone, + Renderer: crate::Renderer, + Renderer::Theme: widget::slider::StyleSheet, +{ + widget::VerticalSlider::new(range, value, on_change) +} + /// Creates a new [`PickList`]. /// /// [`PickList`]: widget::PickList diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index bf3383d9..87030a4d 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -16,9 +16,10 @@ use std::ops::RangeInclusive; pub use iced_style::slider::{Appearance, Handle, HandleShape, StyleSheet}; -/// A bar and a handle that selects a single value from a range of values. +/// An horizontal bar and a handle that selects a single value from a range of +/// values. /// -/// A [`Slider`] will try to fill the space of its container, based on its orientation. +/// A [`Slider`] will try to fill the horizontal space of its container. /// /// The [`Slider`] range of numeric values is generic and its step size defaults /// to 1 unit. @@ -52,9 +53,8 @@ where value: T, on_change: Box Message + 'a>, on_release: Option, - width: Option, - height: Option, - orientation: Orientation, + width: Length, + height: u16, style: ::Style, } @@ -65,6 +65,9 @@ where Renderer: crate::Renderer, Renderer::Theme: StyleSheet, { + /// The default height of a [`Slider`]. + pub const DEFAULT_HEIGHT: u16 = 22; + /// Creates a new [`Slider`]. /// /// It expects: @@ -95,9 +98,8 @@ where step: T::from(1), on_change: Box::new(on_change), on_release: None, - width: None, - height: None, - orientation: Default::default(), + width: Length::Fill, + height: Self::DEFAULT_HEIGHT, style: Default::default(), } } @@ -115,13 +117,13 @@ where /// Sets the width of the [`Slider`]. pub fn width(mut self, width: Length) -> Self { - self.width = Some(width); + self.width = width; self } /// Sets the height of the [`Slider`]. - pub fn height(mut self, height: Length) -> Self { - self.height = Some(height); + pub fn height(mut self, height: u16) -> Self { + self.height = height; self } @@ -139,12 +141,6 @@ where self.step = step; self } - - /// Sets the orientation of the [`Slider`]. - pub fn orientation(mut self, orientation: Orientation) -> Self { - self.orientation = orientation; - self - } } impl<'a, T, Message, Renderer> Widget @@ -164,17 +160,11 @@ where } fn width(&self) -> Length { - match self.orientation { - Orientation::Horizontal => self.width.unwrap_or(Length::Fill), - Orientation::Vertical => Length::Shrink, - } + self.width } fn height(&self) -> Length { - match self.orientation { - Orientation::Horizontal => Length::Shrink, - Orientation::Vertical => self.height.unwrap_or(Length::Fill), - } + Length::Shrink } fn layout( @@ -182,14 +172,9 @@ where _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let width = self - .width - .unwrap_or_else(|| self.orientation.default_width()); - let height = self - .height - .unwrap_or_else(|| self.orientation.default_height()); - - let limits = limits.width(width).height(height); + let limits = + limits.width(self.width).height(Length::Units(self.height)); + let size = limits.resolve(Size::ZERO); layout::Node::new(size) @@ -216,7 +201,6 @@ where self.step, self.on_change.as_ref(), &self.on_release, - self.orientation, ) } @@ -239,7 +223,6 @@ where &self.range, theme, &self.style, - self.orientation, ) } @@ -287,7 +270,6 @@ pub fn update( step: T, on_change: &dyn Fn(T) -> Message, on_release: &Option, - orientation: Orientation, ) -> event::Status where T: Copy + Into + num_traits::FromPrimitive, @@ -297,40 +279,17 @@ where let mut change = || { let bounds = layout.bounds(); - - let cursor_below_bounds = match orientation { - Orientation::Horizontal => cursor_position.x <= bounds.x, - Orientation::Vertical => { - cursor_position.y >= bounds.y + bounds.height - } - }; - - let cursor_above_bounds = match orientation { - Orientation::Horizontal => { - cursor_position.x >= bounds.x + bounds.width - } - Orientation::Vertical => cursor_position.y <= bounds.y, - }; - - let new_value = if cursor_below_bounds { + let new_value = if cursor_position.x <= bounds.x { *range.start() - } else if cursor_above_bounds { + } else if cursor_position.x >= bounds.x + bounds.width { *range.end() } else { let step = step.into(); let start = (*range.start()).into(); let end = (*range.end()).into(); - let percent = match orientation { - Orientation::Horizontal => { - f64::from(cursor_position.x - bounds.x) - / f64::from(bounds.width) - } - Orientation::Vertical => { - 1.00 - (f64::from(cursor_position.y - bounds.y) - / f64::from(bounds.height)) - } - }; + 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; @@ -395,7 +354,6 @@ pub fn draw( range: &RangeInclusive, style_sheet: &dyn StyleSheet