makepad_widgets/
desktop_button.rs

1use {
2    crate::{
3        button::ButtonAction,
4        makepad_draw::*,
5        widget::*
6    }
7};
8
9live_design!{
10    import makepad_draw::shader::std::*;
11    
12    DrawDesktopButton = {{DrawDesktopButton}} {}
13    DesktopButtonBase = {{DesktopButton}} {}
14}
15
16#[derive(Live)]
17pub struct DesktopButton {
18    #[animator] animator: Animator,
19    #[walk] walk: Walk,
20    #[live] draw_bg: DrawDesktopButton,
21}
22
23impl Widget for DesktopButton{
24   fn handle_widget_event_with(
25        &mut self,
26        cx: &mut Cx,
27        event: &Event,
28        dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)
29    ) {
30        let uid = self.widget_uid();
31        self.handle_event_with(cx, event, &mut | cx, action | {
32            dispatch_action(cx, WidgetActionItem::new(action.into(),uid));
33        });
34    }
35
36    fn walk(&mut self, _cx:&mut Cx)->Walk{self.walk}
37    
38    fn redraw(&mut self, cx:&mut Cx){
39        self.draw_bg.redraw(cx)
40    }
41    
42    fn draw_walk_widget(&mut self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw {
43        let _ = self.draw_walk(cx, walk);
44        WidgetDraw::done()
45    }
46}
47
48#[derive(Live, LiveHook)]
49#[live_ignore]
50#[repr(u32)]
51pub enum DesktopButtonType {
52    WindowsMin = shader_enum(1),
53    WindowsMax = shader_enum(2),
54    WindowsMaxToggled = shader_enum(3),
55    WindowsClose = shader_enum(4),
56    XRMode = shader_enum(5),
57    #[pick] Fullscreen = shader_enum(6),
58}
59
60#[derive(Live, LiveHook)]
61#[repr(C)]
62pub struct DrawDesktopButton {
63    #[deref] draw_super: DrawQuad,
64    #[live] hover: f32,
65    #[live] pressed: f32,
66    #[live] button_type: DesktopButtonType
67}
68
69impl LiveHook for DesktopButton {
70    fn before_live_design(cx:&mut Cx){
71        register_widget!(cx, DesktopButton)
72    }
73    
74    fn after_new_from_doc(&mut self, _cx: &mut Cx) {
75        let (w, h) = match self.draw_bg.button_type {
76            DesktopButtonType::WindowsMin
77                | DesktopButtonType::WindowsMax
78                | DesktopButtonType::WindowsMaxToggled
79                | DesktopButtonType::WindowsClose => (46., 29.),
80            DesktopButtonType::XRMode => (50., 36.),
81            DesktopButtonType::Fullscreen => (50., 36.),
82        };
83        self.walk = Walk::fixed_size(dvec2(w, h))
84    }
85}
86
87impl DesktopButton {
88    pub fn handle_event_with(&mut self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, ButtonAction),) {
89        self.animator_handle_event(cx, event);
90
91        match event.hits(cx, self.draw_bg.area()) {
92            Hit::FingerDown(_fe) => {
93                dispatch_action(cx, ButtonAction::Pressed);
94                self.animator_play(cx, id!(hover.pressed));
95            },
96            Hit::FingerHoverIn(_) => {
97                cx.set_cursor(MouseCursor::Hand);
98                 self.animator_play(cx, id!(hover.on));
99            }
100            Hit::FingerHoverOut(_) => {
101                self.animator_play(cx, id!(hover.off));
102            }
103            Hit::FingerUp(fe) => if fe.is_over {
104                dispatch_action(cx, ButtonAction::Clicked);
105                if fe.device.has_hovers() {
106                    self.animator_play(cx, id!(hover.on));
107                }
108                else{
109                    self.animator_play(cx, id!(hover.off));
110                }
111            }
112            else {
113                dispatch_action(cx, ButtonAction::Released);
114                self.animator_play(cx, id!(hover.off));
115            }
116            _ => ()
117        };
118    }
119    
120    pub fn area(&mut self)->Area{
121        self.draw_bg.area()
122    }
123    pub fn get_widwalk(&self)->Walk{self.walk}
124    
125    pub fn draw_walk(&mut self, cx: &mut Cx2d, walk:Walk) {
126        self.draw_bg.draw_walk(cx, walk);
127    }
128}