use kas::prelude::*;
use kas::theme::Feature;
#[impl_self]
mod ProgressBar {
#[autoimpl(Debug ignore self.value_fn)]
#[widget]
pub struct ProgressBar<A, D: Directional = kas::dir::Right> {
core: widget_core!(),
direction: D,
value: f32,
value_fn: Box<dyn Fn(&ConfigCx, &A) -> f32>,
}
impl Self
where
D: Default,
{
#[inline]
pub fn new(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static) -> Self {
Self::new_dir(value_fn, D::default())
}
}
impl<A> ProgressBar<A, kas::dir::Right> {
#[inline]
pub fn right(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static) -> Self {
ProgressBar::new(value_fn)
}
}
impl Self {
#[inline]
pub fn new_dir(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static, direction: D) -> Self {
ProgressBar {
core: Default::default(),
direction,
value: 0.0,
value_fn: Box::new(value_fn),
}
}
#[inline]
pub fn direction(&self) -> Direction {
self.direction.as_direction()
}
}
impl Layout for Self {
fn size_rules(&mut self, cx: &mut SizeCx, axis: AxisInfo) -> SizeRules {
cx.feature(Feature::ProgressBar(self.direction()), axis)
}
fn set_rect(&mut self, cx: &mut SizeCx, rect: Rect, hints: AlignHints) {
let align = match self.direction.is_vertical() {
false => AlignPair::new(Align::Stretch, hints.vert.unwrap_or(Align::Center)),
true => AlignPair::new(hints.horiz.unwrap_or(Align::Center), Align::Stretch),
};
let rect = cx.align_feature(Feature::ProgressBar(self.direction()), rect, align);
self.core.set_rect(rect);
}
fn draw(&self, mut draw: DrawCx) {
let dir = self.direction.as_direction();
draw.progress_bar(self.rect(), dir, self.value);
}
}
impl Tile for Self {
fn role(&self, _: &mut dyn RoleCx) -> Role<'_> {
Role::ProgressBar {
fraction: self.value,
direction: self.direction.as_direction(),
}
}
}
impl Events for Self {
type Data = A;
fn update(&mut self, cx: &mut ConfigCx, data: &A) {
let value = (self.value_fn)(cx, data);
self.value = value.clamp(0.0, 1.0);
}
}
}