1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::makepad_draw::*;


live_design!{
    import makepad_draw::shader::std::*;
    
    NavControlBase = {{NavControl}} {}
}

#[derive(Live, LiveHook)]
pub struct NavControl {
    #[live] draw_list: DrawList2d,
    #[live] draw_focus: DrawQuad,
    #[live] draw_text: DrawText,
    #[rust] _recent_focus: Area,
}

impl NavControl {
    
    pub fn send_trigger_to_scroll_stack(cx: &mut Cx, stack:Vec<Area>){
        let mut prev_area = None;
        for next_area in stack{
            if let Some(prev_area) = prev_area{
                cx.send_trigger(prev_area, Trigger{
                    id:live_id!(scroll_focus_nav),
                    from:next_area
                });
            }
            prev_area = Some(next_area);
        }
    }
    
    pub fn handle_event(&mut self, cx: &mut Cx, event: &Event, root: DrawListId) {
        match event {
            Event::KeyDown(ke) => match ke.key_code {
                KeyCode::Tab => {
                    if ke.modifiers.shift {
                        let mut prev_area = Area::Empty;
                        if let Some((prev_area, scroll_stack)) = Cx2d::iterate_nav_stops(cx, root, | cx, stop | {
                            if cx.has_key_focus(stop.area) {
                                return Some(prev_area);
                            }
                            prev_area = stop.area;
                            None
                        }) {
                            if !prev_area.is_empty() {
                                Self::send_trigger_to_scroll_stack(cx, scroll_stack);
                                cx.set_key_focus(prev_area);
                            }
                        }
                    }
                    else {
                        let mut next_stop = false;
                        if let Some((next_area, scroll_stack)) = Cx2d::iterate_nav_stops(cx, root, | cx, stop | {
                            if next_stop {
                                return Some(stop.area)
                            }
                            if cx.has_key_focus(stop.area) {
                                next_stop = true;
                            }
                            None
                        }) {
                            Self::send_trigger_to_scroll_stack(cx, scroll_stack);
                            cx.set_key_focus(next_area);
                        }
                    }
                }
                _ => ()
            },
            _ => ()
        }
    }
    
    pub fn draw(&mut self, cx: &mut Cx2d) {
        if !self.draw_list.begin(cx, Walk::default()).is_redrawing() {
            return
        }
        
        self.draw_list.end(cx);
    }
}