diff options
-rw-r--r-- | examples/tour/src/main.rs | 2 | ||||
-rw-r--r-- | native/src/widget/slider.rs | 46 | ||||
-rw-r--r-- | pure/src/helpers.rs | 8 | ||||
-rw-r--r-- | pure/src/widget/slider.rs | 31 | ||||
-rw-r--r-- | style/src/slider.rs | 66 | ||||
-rw-r--r-- | style/src/theme.rs | 54 | ||||
-rw-r--r-- | style/src/theme/palette.rs | 2 |
7 files changed, 118 insertions, 91 deletions
diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 8bdc7f1d..c7ca8534 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -776,7 +776,7 @@ fn color_slider( state: &mut slider::State, component: f32, update: impl Fn(f32) -> Color + 'static, -) -> Slider<f64, StepMessage> { +) -> Slider<f64, StepMessage, iced::Renderer> { Slider::new(state, 0.0..=1.0, f64::from(component), move |c| { StepMessage::TextColorChanged(update(c as f32)) }) diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs index 3143aed9..f42bca28 100644 --- a/native/src/widget/slider.rs +++ b/native/src/widget/slider.rs @@ -40,7 +40,11 @@ pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; /// ///  #[allow(missing_debug_implementations)] -pub struct Slider<'a, T, Message> { +pub struct Slider<'a, T, Message, Renderer> +where + Renderer: crate::Renderer, + Renderer::Theme: StyleSheet, +{ state: &'a mut State, range: RangeInclusive<T>, step: T, @@ -49,13 +53,15 @@ pub struct Slider<'a, T, Message> { on_release: Option<Message>, width: Length, height: u16, - style_sheet: Box<dyn StyleSheet + 'a>, + variant: <Renderer::Theme as StyleSheet>::Variant, } -impl<'a, T, Message> Slider<'a, T, Message> +impl<'a, T, Message, Renderer> Slider<'a, T, Message, Renderer> where T: Copy + From<u8> + std::cmp::PartialOrd, Message: Clone, + Renderer: crate::Renderer, + Renderer::Theme: StyleSheet, { /// The default height of a [`Slider`]. pub const DEFAULT_HEIGHT: u16 = 22; @@ -99,7 +105,7 @@ where on_release: None, width: Length::Fill, height: Self::DEFAULT_HEIGHT, - style_sheet: Default::default(), + variant: Default::default(), } } @@ -129,9 +135,9 @@ where /// Sets the style of the [`Slider`]. pub fn style( mut self, - style_sheet: impl Into<Box<dyn StyleSheet + 'a>>, + variant: impl Into<<Renderer::Theme as StyleSheet>::Variant>, ) -> Self { - self.style_sheet = style_sheet.into(); + self.variant = variant.into(); self } @@ -230,26 +236,29 @@ where } /// Draws a [`Slider`]. -pub fn draw<T>( - renderer: &mut impl crate::Renderer, +pub fn draw<T, R>( + renderer: &mut R, layout: Layout<'_>, cursor_position: Point, state: &State, value: T, range: &RangeInclusive<T>, - style_sheet: &dyn StyleSheet, + style_sheet: &dyn StyleSheet<Variant = <R::Theme as StyleSheet>::Variant>, + variant: <R::Theme as StyleSheet>::Variant, ) where T: Into<f64> + Copy, + R: crate::Renderer, + R::Theme: StyleSheet, { let bounds = layout.bounds(); let is_mouse_over = bounds.contains(cursor_position); let style = if state.is_dragging { - style_sheet.dragging() + style_sheet.dragging(variant) } else if is_mouse_over { - style_sheet.hovered() + style_sheet.hovered(variant) } else { - style_sheet.active() + style_sheet.active(variant) }; let rail_y = bounds.y + (bounds.height / 2.0).round(); @@ -357,11 +366,12 @@ impl State { } impl<'a, T, Message, Renderer> Widget<Message, Renderer> - for Slider<'a, T, Message> + for Slider<'a, T, Message, Renderer> where T: Copy + Into<f64> + num_traits::FromPrimitive, Message: Clone, Renderer: crate::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { self.width @@ -423,7 +433,8 @@ where &self.state, self.value, &self.range, - self.style_sheet.as_ref(), + theme, + self.variant, ) } @@ -438,14 +449,17 @@ where } } -impl<'a, T, Message, Renderer> From<Slider<'a, T, Message>> +impl<'a, T, Message, Renderer> From<Slider<'a, T, Message, Renderer>> for Element<'a, Message, Renderer> where T: 'a + Copy + Into<f64> + num_traits::FromPrimitive, Message: 'a + Clone, Renderer: 'a + crate::Renderer, + Renderer::Theme: StyleSheet, { - fn from(slider: Slider<'a, T, Message>) -> Element<'a, Message, Renderer> { + fn from( + slider: Slider<'a, T, Message, Renderer>, + ) -> Element<'a, Message, Renderer> { Element::new(slider) } } diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index ad6f10b1..71ae7635 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -147,14 +147,16 @@ where /// Creates a new [`Slider`]. /// /// [`Slider`]: widget::Slider -pub fn slider<'a, Message, T>( +pub fn slider<'a, T, Message, Renderer>( range: std::ops::RangeInclusive<T>, value: T, on_change: impl Fn(T) -> Message + 'a, -) -> widget::Slider<'a, T, Message> +) -> widget::Slider<'a, T, Message, Renderer> where - Message: Clone, T: Copy + From<u8> + std::cmp::PartialOrd, + Message: Clone, + Renderer: iced_native::Renderer, + Renderer::Theme: widget::slider::StyleSheet, { widget::Slider::new(range, value, on_change) } diff --git a/pure/src/widget/slider.rs b/pure/src/widget/slider.rs index 2f934a48..a6deda41 100644 --- a/pure/src/widget/slider.rs +++ b/pure/src/widget/slider.rs @@ -37,7 +37,11 @@ pub use iced_style::slider::{Handle, HandleShape, Style, StyleSheet}; /// ///  #[allow(missing_debug_implementations)] -pub struct Slider<'a, T, Message> { +pub struct Slider<'a, T, Message, Renderer> +where + Renderer: iced_native::Renderer, + Renderer::Theme: StyleSheet, +{ range: RangeInclusive<T>, step: T, value: T, @@ -45,13 +49,15 @@ pub struct Slider<'a, T, Message> { on_release: Option<Message>, width: Length, height: u16, - style_sheet: Box<dyn StyleSheet + 'a>, + variant: <Renderer::Theme as StyleSheet>::Variant, } -impl<'a, T, Message> Slider<'a, T, Message> +impl<'a, T, Message, Renderer> Slider<'a, T, Message, Renderer> where T: Copy + From<u8> + std::cmp::PartialOrd, Message: Clone, + Renderer: iced_native::Renderer, + Renderer::Theme: StyleSheet, { /// The default height of a [`Slider`]. pub const DEFAULT_HEIGHT: u16 = 22; @@ -88,7 +94,7 @@ where on_release: None, width: Length::Fill, height: Self::DEFAULT_HEIGHT, - style_sheet: Default::default(), + variant: Default::default(), } } @@ -118,9 +124,9 @@ where /// Sets the style of the [`Slider`]. pub fn style( mut self, - style_sheet: impl Into<Box<dyn StyleSheet + 'a>>, + variant: impl Into<<Renderer::Theme as StyleSheet>::Variant>, ) -> Self { - self.style_sheet = style_sheet.into(); + self.variant = variant.into(); self } @@ -132,11 +138,12 @@ where } impl<'a, T, Message, Renderer> Widget<Message, Renderer> - for Slider<'a, T, Message> + for Slider<'a, T, Message, Renderer> where T: Copy + Into<f64> + num_traits::FromPrimitive, Message: Clone, Renderer: iced_native::Renderer, + Renderer::Theme: StyleSheet, { fn tag(&self) -> tree::Tag { tree::Tag::of::<slider::State>() @@ -208,7 +215,8 @@ where tree.state.downcast_ref::<slider::State>(), self.value, &self.range, - self.style_sheet.as_ref(), + theme, + self.variant, ) } @@ -228,14 +236,17 @@ where } } -impl<'a, T, Message, Renderer> From<Slider<'a, T, Message>> +impl<'a, T, Message, Renderer> From<Slider<'a, T, Message, Renderer>> for Element<'a, Message, Renderer> where T: 'a + Copy + Into<f64> + num_traits::FromPrimitive, Message: 'a + Clone, Renderer: 'a + iced_native::Renderer, + Renderer::Theme: StyleSheet, { - fn from(slider: Slider<'a, T, Message>) -> Element<'a, Message, Renderer> { + fn from( + slider: Slider<'a, T, Message, Renderer>, + ) -> Element<'a, Message, Renderer> { Element::new(slider) } } diff --git a/style/src/slider.rs b/style/src/slider.rs index 1bb28b09..2bf0de73 100644 --- a/style/src/slider.rs +++ b/style/src/slider.rs @@ -26,70 +26,14 @@ pub enum HandleShape { /// A set of rules that dictate the style of a slider. pub trait StyleSheet { + type Variant: Default + Copy; + /// Produces the style of an active slider. - fn active(&self) -> Style; + fn active(&self, variant: Self::Variant) -> Style; /// Produces the style of an hovered slider. - fn hovered(&self) -> Style; + fn hovered(&self, variant: Self::Variant) -> Style; /// Produces the style of a slider that is being dragged. - fn dragging(&self) -> Style; -} - -struct Default; - -impl StyleSheet for Default { - fn active(&self) -> Style { - Style { - rail_colors: ([0.6, 0.6, 0.6, 0.5].into(), Color::WHITE), - handle: Handle { - shape: HandleShape::Rectangle { - width: 8, - border_radius: 4.0, - }, - color: Color::from_rgb(0.95, 0.95, 0.95), - border_color: Color::from_rgb(0.6, 0.6, 0.6), - border_width: 1.0, - }, - } - } - - fn hovered(&self) -> Style { - let active = self.active(); - - Style { - handle: Handle { - color: Color::from_rgb(0.90, 0.90, 0.90), - ..active.handle - }, - ..active - } - } - - fn dragging(&self) -> Style { - let active = self.active(); - - Style { - handle: Handle { - color: Color::from_rgb(0.85, 0.85, 0.85), - ..active.handle - }, - ..active - } - } -} - -impl<'a> std::default::Default for Box<dyn StyleSheet + 'a> { - fn default() -> Self { - Box::new(Default) - } -} - -impl<'a, T> From<T> for Box<dyn StyleSheet + 'a> -where - T: StyleSheet + 'a, -{ - fn from(style_sheet: T) -> Self { - Box::new(style_sheet) - } + fn dragging(&self, variant: Self::Variant) -> Style; } diff --git a/style/src/theme.rs b/style/src/theme.rs index 16f24923..e3c0efc6 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -3,6 +3,7 @@ mod palette; pub use self::palette::Palette; use crate::button; +use crate::slider; use iced_core::{Background, Color}; @@ -118,3 +119,56 @@ impl button::StyleSheet for Theme { } } } + +impl slider::StyleSheet for Theme { + type Variant = (); + + fn active(&self, _variant: Self::Variant) -> slider::Style { + let palette = self.extended_palette(); + + let handle = slider::Handle { + shape: slider::HandleShape::Rectangle { + width: 8, + border_radius: 4.0, + }, + color: Color::WHITE, + border_color: Color::WHITE, + border_width: 1.0, + }; + + slider::Style { + rail_colors: (palette.background.strong, palette.background.base), + handle: slider::Handle { + color: palette.background.base, + border_color: palette.border, + ..handle + }, + } + } + + fn hovered(&self, variant: Self::Variant) -> slider::Style { + let active = self.active(variant); + let palette = self.extended_palette(); + + slider::Style { + handle: slider::Handle { + color: palette.background.weak, + ..active.handle + }, + ..active + } + } + + fn dragging(&self, variant: Self::Variant) -> slider::Style { + let active = self.active(variant); + let palette = self.extended_palette(); + + slider::Style { + handle: slider::Handle { + color: palette.background.strong, + ..active.handle + }, + ..active + } + } +} diff --git a/style/src/theme/palette.rs b/style/src/theme/palette.rs index 74139e6b..bbb122ef 100644 --- a/style/src/theme/palette.rs +++ b/style/src/theme/palette.rs @@ -59,6 +59,7 @@ pub struct Extended { pub primary: Group, pub success: Group, pub danger: Group, + pub border: Color, } lazy_static! { @@ -86,6 +87,7 @@ impl Extended { palette.background, palette.text, ), + border: mix(palette.background, palette.text, 0.7), } } } |