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 #[animator] animator: Animator,
22
23 #[live] close_button: TabCloseButton,
24
25 #[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 }
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.draw_bg.begin(cx, self.walk, self.layout);
73 if let TabClosable::Yes = closable{
75 self.close_button.draw(cx);
76 }
77 self.draw_name.draw_walk(cx, Walk::fit(), Align::default(), name);
79 self.draw_bg.end(cx);
81
82 }
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