use crate::kurbo::{Point, RoundedRect, Size};
use crate::theme;
use crate::{
BoxConstraints, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, LinearGradient,
PaintCtx, RenderContext, UnitPoint, UpdateCtx, Widget,
};
#[derive(Debug, Clone, Default)]
pub struct ProgressBar;
impl ProgressBar {
pub fn new() -> ProgressBar {
Self::default()
}
}
impl Widget<f64> for ProgressBar {
fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut f64, _env: &Env) {}
fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &f64, _env: &Env) {}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &f64, _data: &f64, _env: &Env) {
ctx.request_paint();
}
fn layout(
&mut self,
_layout_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
_data: &f64,
env: &Env,
) -> Size {
bc.debug_check("ProgressBar");
bc.constrain(Size::new(
env.get(theme::WIDE_WIDGET_WIDTH),
env.get(theme::BASIC_WIDGET_HEIGHT),
))
}
fn paint(&mut self, 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: ctx.size().width,
height: env.get(theme::BASIC_WIDGET_HEIGHT),
})
.to_vec2(),
4.,
);
ctx.stroke(rounded_rect, &env.get(theme::BORDER_DARK), 2.0);
let background_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(
env.get(theme::BACKGROUND_LIGHT),
env.get(theme::BACKGROUND_DARK),
),
);
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(),
env.get(theme::PROGRESS_BAR_RADIUS),
);
let bar_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(env.get(theme::PRIMARY_LIGHT), env.get(theme::PRIMARY_DARK)),
);
ctx.fill(rounded_rect, &bar_gradient);
}
}