use crate::core::{EventCtx, Widget};
use crate::event::Event;
use crate::geometry::{Rect, Size};
use crate::render::{Canvas, Paint};
use crate::signal::Signal;
use crate::style::Style;
use crate::text::TextEngine;
const BAR_H: i32 = 6;
const PERIOD_MS: u64 = 1100;
const SEG_FRAC: f32 = 0.35;
pub struct ProgressBar {
value: Option<Signal<f32>>,
}
impl ProgressBar {
pub fn determinate(value: Signal<f32>) -> Self {
Self { value: Some(value) }
}
pub fn indeterminate() -> Self {
Self { value: None }
}
}
impl Widget for ProgressBar {
fn measure(&self, _avail: Size, _style: &Style, _text: &mut dyn TextEngine) -> Size {
Size::new(160, BAR_H + 4)
}
fn paint(
&self,
bounds: Rect,
_content: Rect,
_focused: bool,
_enabled: bool,
canvas: &mut dyn Canvas,
_style: &Style,
) {
let th = crate::theme::current();
let (pal, pr) = (&th.palette, &th.progress);
let h = BAR_H.min(bounds.h) as f32;
let x = bounds.x as f32;
let y = bounds.y as f32 + (bounds.h as f32 - h) / 2.0;
let w = bounds.w as f32;
let r = h / 2.0;
canvas.fill_round_rect(x, y, w, h, r, &Paint::fill(pr.track(pal)));
let fill = Paint::fill(pr.fill(pal));
match &self.value {
Some(v) => {
let frac = v.get().clamp(0.0, 1.0);
let fw = w * frac;
if fw > 0.0 {
canvas.fill_round_rect(x, y, fw, h, r, &fill);
}
}
None => {
crate::anim::request_repaint();
let phase = (crate::anim::clock_ms() % PERIOD_MS) as f32 / PERIOD_MS as f32;
let seg = w * SEG_FRAC;
let travel = (w - seg).max(0.0);
let t = phase * 2.0;
let tri = if t < 1.0 { t } else { 2.0 - t }; let sx = tri * travel;
canvas.fill_round_rect(x + sx, y, seg, h, r, &fill);
}
}
}
fn on_event(&mut self, _ctx: &mut EventCtx, _ev: &Event) -> bool {
false
}
}