Skip to main content

cosmic/widget/progress_bar/
style.rs

1use iced::Color;
2use palette::WithAlpha;
3
4#[derive(Clone, Copy, Debug)]
5pub struct Style {
6    /// The track [`Color`] of the progress indicator.
7    pub track_color: Color,
8    /// The bar [`Color`] of the progress indicator.
9    pub bar_color: Color,
10    /// The border [`Color`] of the progress indicator.
11    pub border_color: Option<Color>,
12    /// The border radius of the progress indicator.
13    pub border_radius: f32,
14}
15
16/// [`Style`] field overrides
17#[derive(Clone, Copy, Debug, Default)]
18pub struct Class {
19    pub track_color: Option<Color>,
20    pub bar_color: Option<Color>,
21    pub border_color: Option<Color>,
22    pub border_radius: Option<f32>,
23}
24
25impl Class {
26    pub fn track_color(mut self, color: impl Into<Color>) -> Self {
27        self.track_color = Some(color.into());
28        self
29    }
30
31    pub fn bar_color(mut self, color: impl Into<Color>) -> Self {
32        self.bar_color = Some(color.into());
33        self
34    }
35
36    pub fn border_color(mut self, color: impl Into<Color>) -> Self {
37        self.border_color = Some(color.into());
38        self
39    }
40
41    pub fn border_radius(mut self, radius: f32) -> Self {
42        self.border_radius = Some(radius);
43        self
44    }
45
46    fn resolve(&self, base: Style) -> Style {
47        Style {
48            track_color: self.track_color.unwrap_or(base.track_color),
49            bar_color: self.bar_color.unwrap_or(base.bar_color),
50            border_color: self.border_color.or(base.border_color),
51            border_radius: self.border_radius.unwrap_or(base.border_radius),
52        }
53    }
54}
55
56/// A set of rules that dictate the style of an indicator.
57pub trait Catalog: Sized {
58    /// The supported class of the [`Catalog`].
59    type Class: Default;
60
61    /// Produces the active [`Style`] of an indicator.
62    fn style(&self, class: &Self::Class, is_determinate: bool, is_circular: bool) -> Style;
63}
64
65impl Catalog for iced::Theme {
66    type Class = Class;
67
68    fn style(&self, class: &Self::Class, _is_determinate: bool, _is_circular: bool) -> Style {
69        let palette = self.extended_palette();
70        class.resolve(Style {
71            track_color: palette.background.weak.color,
72            bar_color: palette.primary.base.color,
73            border_color: None,
74            border_radius: 0.0,
75        })
76    }
77}
78
79impl Catalog for crate::Theme {
80    type Class = Class;
81
82    fn style(&self, class: &Self::Class, is_determinate: bool, is_circular: bool) -> Style {
83        let theme = self.cosmic();
84
85        let (mut track_color, bar_color) = match (theme.is_dark, theme.is_high_contrast) {
86            (true, true) => (
87                theme.palette.neutral_6.into(),
88                theme.accent_text_color().into(),
89            ),
90            (true, false) => (theme.palette.neutral_5.into(), theme.accent_color().into()),
91            (false, true) => (
92                theme.palette.neutral_4.into(),
93                theme.accent_text_color().into(),
94            ),
95            (false, false) => (theme.palette.neutral_3.into(), theme.accent_color().into()),
96        };
97
98        if !is_determinate && is_circular {
99            track_color = Color::TRANSPARENT;
100        }
101
102        class.resolve(Style {
103            track_color,
104            bar_color,
105            border_color: if is_determinate && theme.is_high_contrast {
106                Some(self.current_container().divider.with_alpha(0.5).into())
107            } else {
108                None
109            },
110            border_radius: theme.corner_radii.radius_xl[0],
111        })
112    }
113}