freya_components/
progressbar.rs

1use freya_core::prelude::*;
2use torin::size::Size;
3
4use crate::{
5    get_theme,
6    theming::component_themes::ProgressBarThemePartial,
7};
8
9/// ProgressBar component.
10///
11/// # Example
12///
13/// ```rust
14/// # use freya::prelude::*;
15/// fn app() -> impl IntoElement {
16///     ProgressBar::new(50.)
17/// }
18///
19/// # use freya_testing::prelude::*;
20/// # launch_doc(|| {
21/// #   rect()
22///         .padding(8.).center().expanded().child(app())
23/// # }, (250., 250.).into(), "./images/gallery_progressbar.png");
24/// ```
25///
26/// # Preview
27/// ![Progressbar Preview][progressbar]
28#[cfg_attr(feature = "docs",
29    doc = embed_doc_image::embed_image!("progressbar", "images/gallery_progressbar.png")
30)]
31#[derive(Clone, PartialEq)]
32pub struct ProgressBar {
33    pub(crate) theme: Option<ProgressBarThemePartial>,
34    width: Size,
35    show_progress: bool,
36    progress: f32,
37    key: DiffKey,
38}
39
40impl KeyExt for ProgressBar {
41    fn write_key(&mut self) -> &mut DiffKey {
42        &mut self.key
43    }
44}
45
46impl ProgressBar {
47    pub fn new(progress: impl Into<f32>) -> Self {
48        Self {
49            width: Size::fill(),
50            theme: None,
51            show_progress: true,
52            progress: progress.into(),
53            key: DiffKey::None,
54        }
55    }
56
57    pub fn width(mut self, width: impl Into<Size>) -> Self {
58        self.width = width.into();
59        self
60    }
61
62    pub fn show_progress(mut self, show_progress: bool) -> Self {
63        self.show_progress = show_progress;
64        self
65    }
66}
67
68impl Render for ProgressBar {
69    fn render(&self) -> impl IntoElement {
70        let progressbar_theme = get_theme!(&self.theme, progressbar);
71
72        let progress = self.progress.clamp(0., 100.);
73
74        rect()
75            .horizontal()
76            .width(self.width.clone())
77            .height(Size::px(progressbar_theme.height))
78            .corner_radius(99.)
79            .background(progressbar_theme.background)
80            .border(
81                Border::new()
82                    .width(1.)
83                    .alignment(BorderAlignment::Outer)
84                    .fill(progressbar_theme.background),
85            )
86            .font_size(13.)
87            .child(
88                rect()
89                    .horizontal()
90                    .width(Size::percent(progress))
91                    .height(Size::fill())
92                    .corner_radius(99.)
93                    .background(progressbar_theme.progress_background)
94                    .child(
95                        label()
96                            .width(Size::fill())
97                            .color(progressbar_theme.color)
98                            .text_align(TextAlign::Center)
99                            .text(format!("{}%", self.progress))
100                            .max_lines(1),
101                    ),
102            )
103    }
104
105    fn render_key(&self) -> DiffKey {
106        self.key.clone().or(self.default_key())
107    }
108}