Skip to main content

rosin/widgets/
progressbar.rs

1use crate::{prelude::*, widgets::widget_styles};
2
3#[derive(Copy, Clone)]
4pub struct ProgressBarParams {
5    min: UIParam<f64>,
6    max: UIParam<f64>,
7}
8
9// TODO - use css transform so layout isn't needed
10impl Default for ProgressBarParams {
11    fn default() -> Self {
12        Self::new()
13    }
14}
15
16impl ProgressBarParams {
17    pub fn new() -> Self {
18        Self {
19            min: UIParam::Static(0.0),
20            max: UIParam::Static(1.0),
21        }
22    }
23
24    pub fn min(mut self, min: impl Into<UIParam<f64>>) -> Self {
25        self.min = min.into();
26        self
27    }
28
29    pub fn max(mut self, max: impl Into<UIParam<f64>>) -> Self {
30        self.max = max.into();
31        self
32    }
33
34    pub fn view<'a, S, H>(&self, ui: &'a mut Ui<S, H>, id: NodeId, value: WeakVar<f64>) -> &'a mut Ui<S, H> {
35        let min = self.min;
36        let max = self.max;
37
38        ui.node().id(id).style_sheet(widget_styles()).classes("progress-bar-bg").children(|ui| {
39            ui.node().id(id!(id)).classes("progress-bar-fg").on_style(move |_, style| {
40                let Some(value) = value.get() else { return };
41                let min = min.get().unwrap_or(0.0);
42                let max = max.get().unwrap_or(1.0);
43                if max <= min {
44                    return;
45                }
46                let normalized = ((value - min) / (max - min)).clamp(0.0, 1.0);
47                style.width = Unit::Percent(normalized as f32);
48            });
49        })
50    }
51}