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}