1use kas::prelude::*;
9use kas::theme::Feature;
10
11impl_scope! {
12 #[autoimpl(Debug ignore self.value_fn)]
16 #[widget]
17 pub struct ProgressBar<A, D: Directional = kas::dir::Right> {
18 core: widget_core!(),
19 direction: D,
20 value: f32,
21 value_fn: Box<dyn Fn(&ConfigCx, &A) -> f32>,
22 }
23
24 impl Self
25 where
26 D: Default,
27 {
28 #[inline]
33 pub fn new(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static) -> Self {
34 Self::new_dir(value_fn, D::default())
35 }
36 }
37 impl<A> ProgressBar<A, kas::dir::Right> {
38 #[inline]
43 pub fn right(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static) -> Self {
44 ProgressBar::new(value_fn)
45 }
46 }
47
48 impl Self {
49 #[inline]
54 pub fn new_dir(value_fn: impl Fn(&ConfigCx, &A) -> f32 + 'static, direction: D) -> Self {
55 ProgressBar {
56 core: Default::default(),
57 direction,
58 value: 0.0,
59 value_fn: Box::new(value_fn),
60 }
61 }
62
63 #[inline]
65 pub fn direction(&self) -> Direction {
66 self.direction.as_direction()
67 }
68 }
69
70 impl Layout for Self {
71 fn size_rules(&mut self, sizer: SizeCx, axis: AxisInfo) -> SizeRules {
72 sizer.feature(Feature::ProgressBar(self.direction()), axis)
73 }
74
75 fn set_rect(&mut self, cx: &mut ConfigCx, rect: Rect, hints: AlignHints) {
76 let align = match self.direction.is_vertical() {
77 false => AlignPair::new(Align::Stretch, hints.vert.unwrap_or(Align::Center)),
78 true => AlignPair::new(hints.horiz.unwrap_or(Align::Center), Align::Stretch),
79 };
80 let rect = cx.align_feature(Feature::ProgressBar(self.direction()), rect, align);
81 self.core.rect = rect;
82 }
83
84 fn draw(&mut self, mut draw: DrawCx) {
85 let dir = self.direction.as_direction();
86 draw.progress_bar(self.rect(), dir, self.value);
87 }
88 }
89
90 impl Events for Self {
91 type Data = A;
92
93 fn update(&mut self, cx: &mut ConfigCx, data: &A) {
94 let value = (self.value_fn)(cx, data);
95 self.value = value.clamp(0.0, 1.0);
96 }
97 }
98}