makepad_widget/
tabclose.rs

1use makepad_render::*;
2use crate::buttonlogic::*;
3use crate::widgetstyle::*;
4
5#[derive(Clone)]
6pub struct TabClose {
7    pub bg: Quad,
8    pub animator: Animator,
9    pub _bg_area: Area,
10}
11
12impl TabClose {
13    pub fn proto(cx: &mut Cx) -> Self {
14        Self {
15            bg: Quad::proto(cx),
16            animator: Animator::default(),
17            _bg_area: Area::Empty,
18        }
19    }
20    
21    pub fn walk() -> WalkId {uid!()}
22    pub fn instance_hover() -> InstanceFloat {uid!()}
23    pub fn instance_down() -> InstanceFloat {uid!()}
24    pub fn anim_default() -> AnimId {uid!()}
25    pub fn anim_over() -> AnimId {uid!()}
26    pub fn anim_down() -> AnimId {uid!()}
27    pub fn shader_bg() -> ShaderId {uid!()}
28
29    pub fn style(cx: &mut Cx, opt: &StyleOptions) {
30        Self::walk().set(cx, Walk {
31            width: Width::Fix(10. * opt.scale),
32            height: Height::Fix(10. * opt.scale),
33            margin: Margin {l: -4., t: 0., r: 4., b: 0.}
34        });
35        
36        Self::anim_default().set(cx,Anim::new(Play::Cut {duration: 0.2}, vec![
37            Track::color(Quad::instance_color(), Ease::Lin, vec![(1.0, Theme::color_text_deselected_focus().get(cx))]),
38            Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 0.)]),
39            Track::float(Self::instance_down(), Ease::Lin, vec![(1.0, 0.)]),
40        ]));
41        
42        Self::anim_over().set(cx,Anim::new(Play::Cut {duration: 0.2}, vec![
43            Track::color(Quad::instance_color(), Ease::Lin, vec![
44                (0.0, Theme::color_text_selected_focus().get(cx)),
45                (1.0, Theme::color_text_selected_focus().get(cx))
46            ]),
47            Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 1.0)]),
48            Track::float(Self::instance_down(), Ease::Lin, vec![(1.0, 0.)]),
49        ]));
50        
51        Self::anim_down().set(cx, Anim::new(Play::Cut {duration: 0.2}, vec![
52            Track::color(Quad::instance_color(), Ease::Lin, vec![
53                (0.0, Theme::color_text_selected_focus().get(cx)),
54                (1.0, Theme::color_text_selected_focus().get(cx))
55            ]),
56            Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 1.0)]),
57            Track::float(Self::instance_down(), Ease::OutExp, vec![(0.0, 0.0), (1.0, 3.1415 * 0.5)]),
58        ]));
59        
60        Self::shader_bg().set(cx, Quad::def_quad_shader().compose(shader_ast!({
61            let hover: Self::instance_hover();
62            let down: Self::instance_down();
63            fn pixel() -> vec4 {
64                df_viewport(pos * vec2(w, h));
65                let hover_max: float = (hover * 0.2 + 0.8) * 0.5;
66                let hover_min: float = 1. - hover_max;
67                let c: vec2 = vec2(w, h) * 0.5;
68                df_rotate(down, c.x, c.y);
69                df_move_to(c.x * hover_min, c.y * hover_min);
70                df_line_to(c.x + c.x * hover_max, c.y + c.y * hover_max);
71                df_move_to(c.x + c.x * hover_max, c.y * hover_min);
72                df_line_to(c.x * hover_min, c.y + c.y * hover_max);
73                return df_stroke(color, 1. + down * 0.2);
74                //return df_fill(color);
75            }
76        })));
77    }
78    
79    
80    pub fn handle_tab_close(&mut self, cx: &mut Cx, event: &mut Event) -> ButtonEvent {
81        match event.hits(cx, self._bg_area, HitOpt {
82            margin: Some(Margin {l: 5., t: 5., r: 5., b: 5.}),
83            ..Default::default()
84        }) {
85            Event::Animate(ae) => self.animator.calc_area(cx, self._bg_area, ae.time),
86            Event::FingerDown(_fe) => {
87                self.animator.play_anim(cx, Self::anim_down().get(cx));
88                cx.set_down_mouse_cursor(MouseCursor::Hand);
89                return ButtonEvent::Down;
90            },
91            Event::FingerHover(fe) => {
92                cx.set_hover_mouse_cursor(MouseCursor::Hand);
93                match fe.hover_state {
94                    HoverState::In => if fe.any_down {
95                        self.animator.play_anim(cx, Self::anim_down().get(cx))
96                    }
97                    else {
98                        self.animator.play_anim(cx, Self::anim_over().get(cx))
99                    },
100                    HoverState::Out => self.animator.play_anim(cx, Self::anim_default().get(cx)),
101                    _ => ()
102                }
103            },
104            Event::FingerUp(fe) => if fe.is_over {
105                if !fe.is_touch {self.animator.play_anim(cx, Self::anim_over().get(cx))}
106                else {self.animator.play_anim(cx, Self::anim_default().get(cx))}
107                return ButtonEvent::Clicked;
108            }
109            else {
110                self.animator.play_anim(cx, Self::anim_default().get(cx));
111                return ButtonEvent::Up;
112            }
113            _ => ()
114        };
115        ButtonEvent::None
116    }
117    
118    pub fn draw_tab_close(&mut self, cx: &mut Cx) {
119        self.animator.init(cx, | cx | Self::anim_default().get(cx));
120        self.bg.shader = Self::shader_bg().get(cx);
121        self.bg.color = self.animator.last_color(cx, Quad::instance_color());
122        let bg_inst = self.bg.draw_quad(cx, Self::walk().get(cx));
123        bg_inst.push_last_float(cx, &self.animator, Self::instance_hover());
124        bg_inst.push_last_float(cx, &self.animator, Self::instance_down());
125        self._bg_area = bg_inst.into();
126        self.animator.set_area(cx, self._bg_area); // if our area changed, update animation
127    }
128}