use crate::kurbo::{Point, RoundedRect, Size};
use crate::theme;
use crate::widget::Align;
use crate::{
BoxConstraints, Env, Event, EventCtx, LayoutCtx, LinearGradient, PaintCtx, RenderContext,
UnitPoint, UpdateCtx, Widget,
};
#[derive(Debug, Clone, Default)]
pub struct ProgressBar {}
impl ProgressBar {
pub fn new() -> impl Widget<f64> {
Align::vertical(UnitPoint::CENTER, Self::default())
}
}
impl Widget<f64> for ProgressBar {
fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut f64, _env: &Env) {}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: Option<&f64>, _data: &f64, _env: &Env) {
ctx.invalidate();
}
fn layout(
&mut self,
_layout_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
_data: &f64,
env: &Env,
) -> Size {
bc.debug_check("ProgressBar");
let default_width = 100.0;
if bc.is_width_bounded() {
bc.constrain(Size::new(
bc.max().width,
env.get(theme::BASIC_WIDGET_HEIGHT),
))
} else {
bc.constrain(Size::new(
default_width,
env.get(theme::BASIC_WIDGET_HEIGHT),
))
}
}
fn paint(&mut self, paint_ctx: &mut PaintCtx, data: &f64, env: &Env) {
let clamped = data.max(0.0).min(1.0);
let rounded_rect = RoundedRect::from_origin_size(
Point::ORIGIN,
(Size {
width: paint_ctx.size().width,
height: env.get(theme::BASIC_WIDGET_HEIGHT),
})
.to_vec2(),
4.,
);
paint_ctx.stroke(rounded_rect, &env.get(theme::BORDER), 2.0);
let background_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(
env.get(theme::BACKGROUND_LIGHT),
env.get(theme::BACKGROUND_DARK),
),
);
paint_ctx.fill(rounded_rect, &background_gradient);
let calculated_bar_width = clamped * rounded_rect.width();
let rounded_rect = RoundedRect::from_origin_size(
Point::ORIGIN,
(Size {
width: calculated_bar_width,
height: env.get(theme::BASIC_WIDGET_HEIGHT),
})
.to_vec2(),
4.,
);
let bar_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(env.get(theme::PRIMARY_LIGHT), env.get(theme::PRIMARY_DARK)),
);
paint_ctx.fill(rounded_rect, &bar_gradient);
}
}