Try new approach to theming for Slider

This commit is contained in:
Héctor Ramón Jiménez 2024-03-04 03:57:03 +01:00
parent 1bb5a1b9a2
commit ce309db37b
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
5 changed files with 537 additions and 718 deletions

View file

@ -10,7 +10,7 @@
#![forbid(unsafe_code, rust_2018_idioms)]
#![deny(
unused_results,
missing_docs,
// missing_docs,
unused_results,
rustdoc::broken_intra_doc_links
)]

View file

@ -1,6 +1,6 @@
//! Change the apperance of a slider.
use crate::core::border;
use crate::core::Color;
use crate::core::{Color, Pixels};
/// The appearance of a slider.
#[derive(Debug, Clone, Copy)]
@ -11,6 +11,17 @@ pub struct Appearance {
pub handle: Handle,
}
impl Appearance {
/// Changes the [`HandleShape`] of the [`Appearance`] to a circle
/// with the given radius.
pub fn with_circular_handle(mut self, radius: impl Into<Pixels>) -> Self {
self.handle.shape = HandleShape::Circle {
radius: radius.into().0,
};
self
}
}
/// The appearance of a slider rail
#[derive(Debug, Clone, Copy)]
pub struct Rail {
@ -54,15 +65,11 @@ pub enum HandleShape {
/// A set of rules that dictate the style of a slider.
pub trait StyleSheet {
/// The supported style of the [`StyleSheet`].
type Style: Default;
/// Produces the style of an active slider.
fn active(&self, style: &Self::Style) -> Appearance;
/// Produces the style of an hovered slider.
fn hovered(&self, style: &Self::Style) -> Appearance;
/// Produces the style of a slider that is being dragged.
fn dragging(&self, style: &Self::Style) -> Appearance;
fn default() -> fn(&Self, Status) -> Appearance;
}
pub enum Status {
Active,
Hovered,
Dragging,
}

View file

@ -608,88 +608,40 @@ impl<T: Fn(&Theme) -> container::Appearance> container::StyleSheet for T {
}
}
/// The style of a slider.
#[derive(Default)]
pub enum Slider {
/// The default style.
#[default]
Default,
/// A custom style.
Custom(Box<dyn slider::StyleSheet<Style = Theme>>),
impl slider::StyleSheet for Theme {
fn default() -> fn(&Self, slider::Status) -> slider::Appearance {
slider
}
}
impl slider::StyleSheet for Theme {
type Style = Slider;
pub fn slider(theme: &Theme, status: slider::Status) -> slider::Appearance {
let palette = theme.extended_palette();
fn active(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let palette = self.extended_palette();
let handle = slider::Handle {
shape: slider::HandleShape::Rectangle {
width: 8,
border_radius: 4.0.into(),
},
color: Color::WHITE,
border_color: Color::WHITE,
border_width: 1.0,
};
let handle = slider::Handle {
shape: slider::HandleShape::Rectangle {
width: 8,
border_radius: 4.0.into(),
},
color: Color::WHITE,
border_color: Color::WHITE,
border_width: 1.0,
};
slider::Appearance {
rail: slider::Rail {
colors: (
palette.primary.base.color,
palette.secondary.base.color,
),
width: 4.0,
border_radius: 2.0.into(),
},
handle: slider::Handle {
color: palette.background.base.color,
border_color: palette.primary.base.color,
..handle
},
}
}
Slider::Custom(custom) => custom.active(self),
}
}
fn hovered(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let active = self.active(style);
let palette = self.extended_palette();
slider::Appearance {
handle: slider::Handle {
color: palette.primary.weak.color,
..active.handle
},
..active
}
}
Slider::Custom(custom) => custom.hovered(self),
}
}
fn dragging(&self, style: &Self::Style) -> slider::Appearance {
match style {
Slider::Default => {
let active = self.active(style);
let palette = self.extended_palette();
slider::Appearance {
handle: slider::Handle {
color: palette.primary.base.color,
..active.handle
},
..active
}
}
Slider::Custom(custom) => custom.dragging(self),
}
slider::Appearance {
rail: slider::Rail {
colors: (palette.primary.base.color, palette.secondary.base.color),
width: 4.0,
border_radius: 2.0.into(),
},
handle: slider::Handle {
color: match status {
slider::Status::Active => palette.background.base.color,
slider::Status::Hovered => palette.primary.weak.color,
slider::Status::Dragging => palette.primary.base.color,
},
border_color: palette.primary.base.color,
..handle
},
}
}