1use std::any::Any;
16
17use std::time::Instant;
18
19use druid_shell::kurbo::{Point, Rect, Size};
20use druid_shell::piet::{Color, Piet, RenderContext};
21
22use druid_shell::{Application, Region, WinHandler, WindowBuilder, WindowHandle};
23
24struct InvalidateTest {
25 handle: WindowHandle,
26 size: Size,
27 start_time: Instant,
28 color: Color,
29 rect: Rect,
30 cursor: Rect,
31}
32
33impl InvalidateTest {
34 fn update_color_and_rect(&mut self) {
35 let time_since_start = (Instant::now() - self.start_time).as_millis();
36 let (r, g, b, _) = self.color.as_rgba8();
37 self.color = match (time_since_start % 2, time_since_start % 3) {
38 (0, _) => Color::rgb8(r.wrapping_add(10), g, b),
39 (_, 0) => Color::rgb8(r, g.wrapping_add(10), b),
40 (_, _) => Color::rgb8(r, g, b.wrapping_add(10)),
41 };
42
43 self.rect.x0 = (self.rect.x0 + 5.0) % self.size.width;
44 self.rect.x1 = (self.rect.x1 + 5.5) % self.size.width;
45 self.rect.y0 = (self.rect.y0 + 3.0) % self.size.height;
46 self.rect.y1 = (self.rect.y1 + 3.5) % self.size.height;
47
48 self.handle.invalidate_rect(self.cursor);
50 self.cursor.x0 += 4.0;
51 self.cursor.x1 += 4.0;
52 if self.cursor.x0 > self.size.width {
53 self.cursor.x1 = self.cursor.width();
54 self.cursor.x0 = 0.0;
55 }
56 self.handle.invalidate_rect(self.cursor);
57 }
58}
59
60impl WinHandler for InvalidateTest {
61 fn connect(&mut self, handle: &WindowHandle) {
62 self.handle = handle.clone();
63 }
64
65 fn prepare_paint(&mut self) {
66 self.update_color_and_rect();
67 self.handle.invalidate_rect(self.rect);
68 }
69
70 fn paint(&mut self, piet: &mut Piet, region: &Region) {
71 piet.fill(region.bounding_box(), &self.color);
76 piet.fill(self.cursor, &Color::WHITE);
77 self.handle.request_anim_frame();
78 }
79
80 fn size(&mut self, size: Size) {
81 self.size = size;
82 }
83
84 fn command(&mut self, id: u32) {
85 match id {
86 0x100 => self.handle.close(),
87 _ => println!("unexpected id {id}"),
88 }
89 }
90
91 fn request_close(&mut self) {
92 self.handle.close();
93 }
94
95 fn destroy(&mut self) {
96 Application::global().quit()
97 }
98
99 fn as_any(&mut self) -> &mut dyn Any {
100 self
101 }
102}
103
104fn main() {
105 tracing_subscriber::fmt().init();
106 let app = Application::new().unwrap();
107 let mut builder = WindowBuilder::new(app.clone());
108 let inv_test = InvalidateTest {
109 size: Size::ZERO,
110 handle: Default::default(),
111 start_time: Instant::now(),
112 rect: Rect::from_origin_size(Point::ZERO, (10.0, 20.0)),
113 cursor: Rect::from_origin_size(Point::ZERO, (2.0, 100.0)),
114 color: Color::WHITE,
115 };
116 builder.set_handler(Box::new(inv_test));
117 builder.set_title("Invalidate tester");
118
119 let window = builder.build().unwrap();
120 window.show();
121 app.run(None);
122}