Skip to main content

rlvgl_widgets/
progress.rs

1//! Horizontal progress indicator.
2use rlvgl_core::draw::{draw_widget_bg, fill_rounded_rect};
3use rlvgl_core::event::Event;
4use rlvgl_core::renderer::Renderer;
5use rlvgl_core::style::Style;
6use rlvgl_core::widget::{Color, Rect, Widget};
7
8/// Simple progress bar widget.
9pub struct ProgressBar {
10    bounds: Rect,
11    /// Background and border style of the bar.
12    pub style: Style,
13    /// Color of the filled portion representing progress.
14    pub bar_color: Color,
15    min: i32,
16    max: i32,
17    value: i32,
18}
19
20impl ProgressBar {
21    /// Create a new progress bar with a value range.
22    pub fn new(bounds: Rect, min: i32, max: i32) -> Self {
23        Self {
24            bounds,
25            style: Style::default(),
26            bar_color: Color(0, 0, 0, 255),
27            min,
28            max,
29            value: min,
30        }
31    }
32
33    /// Current progress value.
34    pub fn value(&self) -> i32 {
35        self.value
36    }
37
38    /// Set the progress value, clamped to the configured range.
39    pub fn set_value(&mut self, val: i32) {
40        self.value = val.clamp(self.min, self.max);
41    }
42
43    /// Convert the current value to a filled width in pixels.
44    fn width_from_value(&self) -> i32 {
45        let range = self.max - self.min;
46        if range == 0 {
47            return 0;
48        }
49        let ratio = (self.value - self.min) as f32 / range as f32;
50        (ratio * self.bounds.width as f32) as i32
51    }
52}
53
54impl Widget for ProgressBar {
55    fn bounds(&self) -> Rect {
56        self.bounds
57    }
58
59    fn draw(&self, renderer: &mut dyn Renderer) {
60        let a = self.style.alpha;
61        let r = self.style.radius;
62        draw_widget_bg(renderer, self.bounds, &self.style);
63
64        let bar_width = self.width_from_value();
65        if bar_width > 0 {
66            let bar_rect = Rect {
67                x: self.bounds.x,
68                y: self.bounds.y,
69                width: bar_width,
70                height: self.bounds.height,
71            };
72            fill_rounded_rect(renderer, bar_rect, self.bar_color.with_alpha(a), r);
73        }
74    }
75
76    /// Progress bars are display only and ignore events.
77    fn handle_event(&mut self, _event: &Event) -> bool {
78        false
79    }
80}