Skip to main content

vizia_core/views/
progressbar.rs

1use crate::prelude::*;
2
3/// A simple progress bar that can be used to show the progress of something.
4///
5/// The input source should resolve to an [f32] in the range `0.0..1.0`.
6///
7/// # Example
8///
9/// ### Vertical progress bar bound to a value source
10/// ```ignore
11/// # use vizia_core::prelude::*;
12/// # let mut cx = &mut Context::default();
13/// # #[derive(Lens, Default)]
14/// # pub struct AppData {
15/// #     progress: f32,
16/// # }
17/// # impl Model for AppData {}
18/// # AppData::default().build(cx);
19/// ProgressBar::vertical(cx, AppData::progress);
20/// ```
21///
22/// ### Horizontal progress bar bound to a value source
23/// ```ignore
24/// # use vizia_core::prelude::*;
25/// # let mut cx = &mut Context::default();
26/// # #[derive(Lens, Default)]
27/// # pub struct AppData {
28/// #     progress: f32,
29/// # }
30/// # impl Model for AppData {}
31/// # AppData::default().build(cx);
32/// ProgressBar::horizontal(cx, AppData::progress);
33/// ```
34///
35/// ### A horizontal progress bar with a label beside it
36/// ```ignore
37/// # use vizia_core::prelude::*;
38/// # let mut cx = &mut Context::default();
39/// # #[derive(Lens, Default)]
40/// # pub struct AppData {
41/// #     progress: f32,
42/// # }
43/// # impl Model for AppData {}
44/// # AppData::default().build(cx);
45/// HStack::new(cx, |cx| {
46///     ProgressBar::horizontal(cx, AppData::progress);
47///     Label::new(cx, AppData::progress.map(|v| format!("{:.0}%", v * 100.0)));
48/// });
49/// ```
50pub struct ProgressBar;
51
52impl View for ProgressBar {
53    fn element(&self) -> Option<&'static str> {
54        Some("progressbar")
55    }
56
57    fn accessibility(&self, _cx: &mut AccessContext, node: &mut AccessNode) {
58        node.set_min_numeric_value(0.0);
59        node.set_max_numeric_value(1.0);
60    }
61}
62
63impl ProgressBar {
64    /// Creates a new progress bar bound to the provided value source.
65    ///
66    /// # Example
67    ///
68    /// ```ignore
69    /// # use vizia_core::prelude::*;
70    /// # let mut cx = &mut Context::default();
71    /// # #[derive(Lens, Default)]
72    /// # pub struct AppData {
73    /// #     value: f32,
74    /// # }
75    /// # impl Model for AppData {}
76    /// # AppData::default().build(cx);
77    /// ProgressBar::new(cx, AppData::value);
78    /// ```
79    pub fn new<L>(cx: &mut Context, signal: L) -> Handle<Self>
80    where
81        L: SignalGet<f32> + SignalMap<f32>,
82    {
83        Self::horizontal(cx, signal)
84    }
85
86    /// Creates a new horizontal progress bar bound to the provided value source.
87    pub fn horizontal<L>(cx: &mut Context, signal: L) -> Handle<Self>
88    where
89        L: SignalGet<f32> + SignalMap<f32>,
90    {
91        Self.build(cx, |cx| {
92            let progress = signal.map(|v| Units::Percentage(v * 100.0));
93            Element::new(cx).width(progress).class("progressbar-bar");
94        })
95        .role(Role::ProgressIndicator)
96        .numeric_value(signal.map(|val| *val as f64))
97        .orientation(Orientation::Horizontal)
98    }
99
100    /// Creates a new vertical progress bar bound to the provided value source.
101    pub fn vertical<L>(cx: &mut Context, signal: L) -> Handle<Self>
102    where
103        L: SignalGet<f32> + SignalMap<f32>,
104    {
105        Self.build(cx, |cx| {
106            let progress = signal.map(|v| Units::Percentage(v * 100.0));
107            Element::new(cx).top(Stretch(1.0)).height(progress).class("progressbar-bar");
108        })
109        .role(Role::ProgressIndicator)
110        .numeric_value(signal.map(|val| *val as f64))
111        .orientation(Orientation::Vertical)
112    }
113}