use crate::geometry::Color;
use crate::layout::style::FlexStyle;
use crate::layout::types::FlexAlign;
use crate::theme::current;
use crate::view::node::ViewNode;
use crate::view::paint::PaintStyle;
use crate::widget::BuildContext;
use crate::widget::Widget;
use crate::widget::layout::LayoutAttr;
#[derive(Clone)]
pub struct Progress {
value: f64,
layout: LayoutAttr,
track_color: Color,
fill_color: Color,
}
impl Progress {
pub fn new(value: f64) -> Self {
Self {
value: value.clamp(0.0, 1.0),
layout: LayoutAttr::new().height(8.0),
track_color: current().background.secondary_default,
fill_color: current().background.brand_default,
}
}
pub fn value(mut self, v: f64) -> Self {
self.value = v.clamp(0.0, 1.0);
self
}
pub fn height(mut self, h: f32) -> Self {
self.layout = self.layout.height(h);
self
}
pub fn layout(mut self, l: LayoutAttr) -> Self {
self.layout = l;
self
}
pub fn track_color(mut self, c: Color) -> Self {
self.track_color = c;
self
}
pub fn fill_color(mut self, c: Color) -> Self {
self.fill_color = c;
self
}
}
impl Widget for Progress {
fn build(&self, _ctx: &mut BuildContext) -> ViewNode {
let v = self.value.clamp(0.0, 1.0) as f32;
let h = self.layout.height.unwrap_or(8.0);
let r = h / 2.0;
let track = FlexStyle::row().align_self(FlexAlign::Stretch).height(h);
let fill = FlexStyle::default().flex_grow(v.max(0.0)).height(h);
let spacer = FlexStyle::default().flex_grow((1.0 - v).max(0.0)).height(h);
ViewNode::Div {
layout: track,
paint: PaintStyle::new()
.background(self.track_color)
.radius(r)
.clip(true),
children: vec![
ViewNode::Div {
layout: fill,
paint: PaintStyle::new().background(self.fill_color),
children: vec![],
listeners: vec![],
key: None,
},
ViewNode::Div {
layout: spacer,
paint: PaintStyle::new(),
children: vec![],
listeners: vec![],
key: None,
},
],
listeners: vec![],
key: None,
}
}
}