makepad_widgets/
desktop_button.rs1use {
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}