1use std::any::Any;
16
17use druid_shell::kurbo::{Line, Size};
18use druid_shell::piet::{Color, RenderContext};
19
20use druid_shell::{
21 Application, HotKey, Menu, Region, SysMods, WinHandler, WindowBuilder, WindowHandle,
22};
23
24const BG_COLOR: Color = Color::rgb8(0x27, 0x28, 0x22);
25const FG_COLOR: Color = Color::rgb8(0xf0, 0xf0, 0xea);
26
27#[derive(Default)]
28struct QuitState {
29 quit_count: u32,
30 size: Size,
31 handle: WindowHandle,
32}
33
34impl WinHandler for QuitState {
35 fn connect(&mut self, handle: &WindowHandle) {
36 self.handle = handle.clone();
37 }
38
39 fn prepare_paint(&mut self) {}
40
41 fn paint(&mut self, piet: &mut piet_common::Piet, _: &Region) {
42 let rect = self.size.to_rect();
43 piet.fill(rect, &BG_COLOR);
44 piet.stroke(Line::new((10.0, 50.0), (90.0, 90.0)), &FG_COLOR, 1.0);
45 }
46
47 fn size(&mut self, size: Size) {
48 self.size = size;
49 }
50
51 fn request_close(&mut self) {
52 self.quit_count += 1;
53 if self.quit_count >= 5 {
54 self.handle.close();
55 } else {
56 tracing::info!("Don't wanna quit");
57 }
58 }
59
60 fn destroy(&mut self) {
61 Application::global().quit()
62 }
63
64 fn as_any(&mut self) -> &mut dyn Any {
65 self
66 }
67}
68
69fn main() {
70 tracing_subscriber::fmt().init();
71 let app = Application::new().unwrap();
72
73 let mut file_menu = Menu::new();
74 file_menu.add_item(
75 0x100,
76 "E&xit",
77 Some(&HotKey::new(SysMods::Cmd, "q")),
78 None,
79 true,
80 );
81
82 let mut menubar = Menu::new();
83 menubar.add_dropdown(file_menu, "Application", true);
84
85 let mut builder = WindowBuilder::new(app.clone());
86 builder.set_handler(Box::<QuitState>::default());
87 builder.set_title("Quit example");
88 builder.set_menu(menubar);
89
90 let window = builder.build().unwrap();
91 window.show();
92
93 app.run(None);
94}