makepad_widgets/
tab.rs

1use {
2    crate::{
3        tab_close_button::{TabCloseButtonAction, TabCloseButton},
4        makepad_draw::*,
5    }
6};
7
8live_design!{
9    TabBase = {{Tab}} {}
10}
11
12#[derive(Live, LiveHook)]
13pub struct Tab {
14    #[rust] is_selected: bool,
15    #[rust] is_dragging: bool,
16    
17    #[live] draw_bg: DrawQuad,
18    #[live] draw_name: DrawText,
19    //#[live] draw_drag: DrawColor,
20    
21    #[animator] animator: Animator,
22    
23    #[live] close_button: TabCloseButton,
24    
25    // height: f32,
26    
27    #[live] hover: f32,
28    #[live] selected: f32,
29    
30    #[live(10.0)] min_drag_dist: f64,
31    
32    #[walk] walk: Walk,
33    #[layout] layout: Layout,
34    
35}
36
37pub enum TabAction {
38    WasPressed,
39    CloseWasPressed,
40    ShouldTabStartDrag,
41    ShouldTabStopDrag
42    //DragHit(DragHit)
43}
44
45pub enum TabClosable{
46    Yes,
47    No
48}
49
50impl TabClosable{
51    pub fn as_bool(&self)->bool{
52        match self{
53            Self::Yes=>true,
54            Self::No=>false
55        }
56    }
57}
58
59impl Tab {
60    
61    pub fn is_selected(&self) -> bool {
62        self.is_selected
63    }
64    
65    pub fn set_is_selected(&mut self, cx: &mut Cx, is_selected: bool, animate: Animate) {
66        self.is_selected = is_selected;
67        self.animator_toggle(cx, is_selected, animate, id!(selected.on), id!(selected.off));
68    }
69    
70    pub fn draw(&mut self, cx: &mut Cx2d, name: &str, closable:TabClosable) {
71        //self.bg_quad.color = self.color(self.is_selected);
72        self.draw_bg.begin(cx, self.walk, self.layout);
73        //self.name_text.color = self.name_color(self.is_selected);
74        if let TabClosable::Yes = closable{
75            self.close_button.draw(cx);
76        }
77        //cx.turtle_align_y();
78        self.draw_name.draw_walk(cx, Walk::fit(), Align::default(), name);
79        //cx.turtle_align_y();
80        self.draw_bg.end(cx);
81        
82        //if self.is_dragged {
83        //    self.draw_drag.draw_abs(cx, self.draw_bg.area().get_clipped_rect(cx));
84        //}
85    }
86    
87    pub fn area(&self) -> Area {
88        self.draw_bg.area()
89    }
90    
91    pub fn handle_event_with(
92        &mut self,
93        cx: &mut Cx,
94        event: &Event,
95        dispatch_action: &mut dyn FnMut(&mut Cx, TabAction),
96    ) {
97        self.animator_handle_event(cx, event);
98        
99        let mut block_hover_out = false;
100        match self.close_button.handle_event(cx, event) {
101            TabCloseButtonAction::WasPressed => dispatch_action(cx, TabAction::CloseWasPressed),
102            TabCloseButtonAction::HoverIn => block_hover_out = true,
103            TabCloseButtonAction::HoverOut => self.animator_play(cx, id!(hover.off)),
104            _ => ()
105        };
106        
107        match event.hits(cx, self.draw_bg.area()) {
108            Hit::FingerHoverIn(_) => {
109                self.animator_play(cx, id!(hover.on));
110            }
111            Hit::FingerHoverOut(_) => if !block_hover_out {
112                self.animator_play(cx, id!(hover.off));
113            }
114            Hit::FingerMove(e) => {
115                if !self.is_dragging && (e.abs - e.abs_start).length() > self.min_drag_dist {
116                    self.is_dragging = true;
117                    dispatch_action(cx, TabAction::ShouldTabStartDrag);
118                }
119            }
120            Hit::FingerUp(_) => {
121                if self.is_dragging {
122                    dispatch_action(cx, TabAction::ShouldTabStopDrag);
123                    self.is_dragging = false;
124                }
125            }
126            Hit::FingerDown(_) => {
127                dispatch_action(cx, TabAction::WasPressed);
128            }
129            _ => {}
130        }
131    }
132}
133