1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::draw::Primitive;
use crate::layout::{Direction, Rectangle, Size};
use crate::stylesheet::Stylesheet;
use crate::widget::{Dummy, IntoNode, Node, Widget};
pub struct Progress<'a, T> {
progress: f32,
fill: Node<'a, T>,
}
impl<'a, T: 'a> Progress<'a, T> {
pub fn new(progress: f32) -> Self {
Self {
progress,
fill: Dummy::new("bar").into_node(),
}
}
}
impl<'a, T: 'a> Widget<'a, T> for Progress<'a, T> {
fn widget(&self) -> &'static str {
"progress"
}
fn len(&self) -> usize {
1
}
fn visit_children(&mut self, visitor: &mut dyn FnMut(&mut Node<'a, T>)) {
visitor(&mut self.fill);
}
fn size(&self, style: &Stylesheet) -> (Size, Size) {
(style.width, style.height)
}
fn draw(&mut self, layout: Rectangle, clip: Rectangle, style: &Stylesheet) -> Vec<Primitive<'a>> {
let mut result = Vec::new();
result.extend(style.background.render(layout));
let fill = layout.after_padding(style.padding);
let fill = match style.direction {
Direction::LeftToRight => Rectangle {
right: fill.left + fill.width() * self.progress,
..fill
},
Direction::RightToLeft => Rectangle {
left: fill.right - fill.width() * self.progress,
..fill
},
Direction::TopToBottom => Rectangle {
bottom: fill.top + fill.height() * self.progress,
..fill
},
Direction::BottomToTop => Rectangle {
top: fill.bottom - fill.height() * self.progress,
..fill
},
};
if self.progress > 0.0 {
if style.contains("clip-bar") {
if let Some(clip) = clip.intersect(&fill) {
result.push(Primitive::PushClip(clip));
result.extend(self.fill.draw(layout.after_padding(style.padding), clip));
result.push(Primitive::PopClip);
}
} else {
result.extend(self.fill.draw(fill, clip));
}
}
result
}
}
impl<'a, T: 'a> IntoNode<'a, T> for Progress<'a, T> {
fn into_node(self) -> Node<'a, T> {
Node::new(self)
}
}