makepad_widgets/
tab_close_button.rs

1use crate::makepad_draw::*;
2
3live_design!{
4    link widgets;
5    use link::theme::*;
6    use makepad_draw::shader::std::*;
7    
8    pub TabCloseButtonBase = {{TabCloseButton}} {}
9    
10    pub TabCloseButton = <TabCloseButtonBase> {
11        height: 10.0, width: 10.0,
12        margin: { right: (THEME_SPACE_2), left: -3.5 },
13        draw_button: {
14            instance hover: float;
15            instance active: float;
16
17            uniform size: 1.0
18
19            uniform color: (#8)
20            uniform color_hover: (#C)
21            uniform color_active: (#A)
22            
23            fn pixel(self) -> vec4 {
24                let sdf = Sdf2d::viewport(self.pos * self.rect_size);
25
26                let mid = self.rect_size / 2.0;
27                let size = (self.hover * 0.25 + 0.5) * 0.25 * length(self.rect_size) * self.size;
28                let min = mid - vec2(size);
29                let max = mid + vec2(size);
30                sdf.move_to(min.x, min.y);
31                sdf.line_to(max.x, max.y);
32                sdf.move_to(min.x, max.y);
33                sdf.line_to(max.x, min.y);
34
35                return sdf.stroke(
36                    mix(
37                        mix(self.color, self.color_hover, self.hover),
38                        mix(self.color_active, self.color_hover, self.hover),
39                        self.active
40                    ), 1.0
41                )
42            }
43        }
44        
45        animator: {
46            hover = {
47                default: off
48                off = {
49                    from: {all: Forward {duration: 0.1}}
50                    apply: {
51                        draw_button: {hover: 0.0}
52                    }
53                }
54                
55                on = {
56                    cursor: Hand,
57                    from: {all: Snap}
58                    apply: {
59                        draw_button: {hover: 1.0}
60                    }
61                }
62            }
63        }
64    }
65}
66
67#[derive(Live, LiveHook, LiveRegister)]
68pub struct TabCloseButton {
69    #[live] draw_button: DrawQuad,
70    #[animator] animator: Animator,
71
72    #[walk] walk: Walk
73}
74
75impl TabCloseButton {
76    
77    pub fn draw(&mut self, cx: &mut Cx2d) {
78        self.draw_button.draw_walk(
79            cx,
80            self.walk
81        );
82    }
83    
84    pub fn handle_event(
85        &mut self,
86        cx: &mut Cx,
87        event: &Event,
88    ) -> TabCloseButtonAction {
89        self.animator_handle_event(cx, event);
90        match event.hits(cx, self.draw_button.area()) {
91            Hit::FingerHoverIn(_) => {
92                self.animator_play(cx, id!(hover.on));
93                return TabCloseButtonAction::HoverIn;
94            }
95            Hit::FingerHoverOut(_)=>{
96                self.animator_play(cx, id!(hover.off));
97                return TabCloseButtonAction::HoverOut;
98            }
99            // Pressing the tab close button with a primary button/touch
100            // or the middle mouse button are both recognized as a close tab action.
101            Hit::FingerDown(fe) 
102                if fe.is_primary_hit() || fe.mouse_button().is_some_and(|b| b.is_middle()) =>
103            {
104                return TabCloseButtonAction::WasPressed;
105            }
106            _ => {}
107        }
108        TabCloseButtonAction::None
109    }
110}
111
112pub enum TabCloseButtonAction {
113    None,
114    WasPressed,
115    HoverIn,
116    HoverOut,
117}