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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::kurbo::{Point, Rect, Size};
use crate::theme;
use crate::{
BoxConstraints, Env, Event, EventCtx, LayoutCtx, LifeCycle, LifeCycleCtx, LinearGradient,
PaintCtx, RenderContext, UnitPoint, UpdateCtx, Widget,
};
#[derive(Debug, Clone, Default)]
pub struct ProgressBar;
impl ProgressBar {
pub fn new() -> ProgressBar {
Self::default()
}
}
impl Widget<f64> for ProgressBar {
fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut f64, _env: &Env) {}
fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &f64, _env: &Env) {}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &f64, _data: &f64, _env: &Env) {
ctx.request_paint();
}
fn layout(
&mut self,
_layout_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
_data: &f64,
env: &Env,
) -> Size {
bc.debug_check("ProgressBar");
bc.constrain(Size::new(
env.get(theme::WIDE_WIDGET_WIDTH),
env.get(theme::BASIC_WIDGET_HEIGHT),
))
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &f64, env: &Env) {
let clamped = data.max(0.0).min(1.0);
let stroke_width = 2.0;
let inset = -stroke_width / 2.0;
let rounded_rect = Rect::from_origin_size(
Point::ORIGIN,
(Size {
width: ctx.size().width,
height: env.get(theme::BASIC_WIDGET_HEIGHT),
})
.to_vec2(),
)
.inset(inset)
.to_rounded_rect(4.0);
ctx.stroke(rounded_rect, &env.get(theme::BORDER_DARK), stroke_width);
let background_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(
env.get(theme::BACKGROUND_LIGHT),
env.get(theme::BACKGROUND_DARK),
),
);
ctx.fill(rounded_rect, &background_gradient);
let calculated_bar_width = clamped * rounded_rect.width();
let rounded_rect = Rect::from_origin_size(
Point::new(-inset, 0.),
(Size {
width: calculated_bar_width,
height: env.get(theme::BASIC_WIDGET_HEIGHT),
})
.to_vec2(),
)
.inset((0.0, inset))
.to_rounded_rect(env.get(theme::PROGRESS_BAR_RADIUS));
let bar_gradient = LinearGradient::new(
UnitPoint::TOP,
UnitPoint::BOTTOM,
(env.get(theme::PRIMARY_LIGHT), env.get(theme::PRIMARY_DARK)),
);
ctx.fill(rounded_rect, &bar_gradient);
}
}