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