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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#![windows_subsystem = "windows"]
use std::time::Duration;
use druid::widget::prelude::*;
use druid::widget::BackgroundBrush;
use druid::{AppLauncher, Color, LocalizedString, Point, TimerToken, WidgetPod, WindowDesc};
static TIMER_INTERVAL: Duration = Duration::from_millis(10);
struct TimerWidget {
timer_id: TimerToken,
simple_box: WidgetPod<u32, SimpleBox>,
pos: Point,
}
impl TimerWidget {
fn adjust_box_pos(&mut self, container_size: Size) {
let box_size = self.simple_box.layout_rect().size();
self.pos.x += 2.;
if self.pos.x + box_size.width > container_size.width {
self.pos.x = 0.;
self.pos.y += box_size.height;
if self.pos.y + box_size.height > container_size.height {
self.pos.y = 0.;
}
}
}
}
impl Widget<u32> for TimerWidget {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut u32, env: &Env) {
match event {
Event::WindowConnected => {
self.timer_id = ctx.request_timer(TIMER_INTERVAL);
}
Event::Timer(id) => {
if *id == self.timer_id {
self.adjust_box_pos(ctx.size());
ctx.request_layout();
self.timer_id = ctx.request_timer(TIMER_INTERVAL);
}
}
_ => (),
}
self.simple_box.event(ctx, event, data, env);
}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &u32, env: &Env) {
self.simple_box.lifecycle(ctx, event, data, env);
}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &u32, data: &u32, env: &Env) {
self.simple_box.update(ctx, data, env);
}
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &u32, env: &Env) -> Size {
self.simple_box.layout(ctx, &bc.loosen(), data, env);
self.simple_box.set_origin(ctx, data, env, self.pos);
bc.constrain((500.0, 500.0))
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &u32, env: &Env) {
self.simple_box.paint(ctx, data, env);
}
}
struct SimpleBox;
impl Widget<u32> for SimpleBox {
fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut u32, _env: &Env) {}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, _data: &u32, _env: &Env) {
if let LifeCycle::HotChanged(_) = event {
ctx.request_paint();
}
}
fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &u32, _data: &u32, _env: &Env) {}
fn layout(
&mut self,
_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
_data: &u32,
_env: &Env,
) -> Size {
bc.constrain((50.0, 50.0))
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &u32, env: &Env) {
let mut background = if ctx.is_hot() {
BackgroundBrush::Color(Color::rgb8(200, 55, 55))
} else {
BackgroundBrush::Color(Color::rgb8(30, 210, 170))
};
background.paint(ctx, data, env);
}
}
pub fn main() {
let window = WindowDesc::new(TimerWidget {
timer_id: TimerToken::INVALID,
simple_box: WidgetPod::new(SimpleBox),
pos: Point::ZERO,
})
.with_min_size((200., 200.))
.title(LocalizedString::new("timer-demo-window-title").with_placeholder("Look at it go!"));
AppLauncher::with_window(window)
.log_to_console()
.launch(0u32)
.expect("launch failed");
}