makepad_widgets/
nav_control.rs1use crate::makepad_draw::*;
2
3
4live_design!{
5 import makepad_draw::shader::std::*;
6
7 NavControlBase = {{NavControl}} {}
8}
9
10#[derive(Live, LiveHook)]
11pub struct NavControl {
12 #[live] draw_list: DrawList2d,
13 #[live] draw_focus: DrawQuad,
14 #[live] draw_text: DrawText,
15 #[rust] _recent_focus: Area,
16}
17
18impl NavControl {
19
20 pub fn send_trigger_to_scroll_stack(cx: &mut Cx, stack:Vec<Area>){
21 let mut prev_area = None;
22 for next_area in stack{
23 if let Some(prev_area) = prev_area{
24 cx.send_trigger(prev_area, Trigger{
25 id:live_id!(scroll_focus_nav),
26 from:next_area
27 });
28 }
29 prev_area = Some(next_area);
30 }
31 }
32
33 pub fn handle_event(&mut self, cx: &mut Cx, event: &Event, root: DrawListId) {
34 match event {
35 Event::KeyDown(ke) => match ke.key_code {
36 KeyCode::Tab => {
37 if ke.modifiers.shift {
38 let mut prev_area = Area::Empty;
39 if let Some((prev_area, scroll_stack)) = Cx2d::iterate_nav_stops(cx, root, | cx, stop | {
40 if cx.has_key_focus(stop.area) {
41 return Some(prev_area);
42 }
43 prev_area = stop.area;
44 None
45 }) {
46 if !prev_area.is_empty() {
47 Self::send_trigger_to_scroll_stack(cx, scroll_stack);
48 cx.set_key_focus(prev_area);
49 }
50 }
51 }
52 else {
53 let mut next_stop = false;
54 if let Some((next_area, scroll_stack)) = Cx2d::iterate_nav_stops(cx, root, | cx, stop | {
55 if next_stop {
56 return Some(stop.area)
57 }
58 if cx.has_key_focus(stop.area) {
59 next_stop = true;
60 }
61 None
62 }) {
63 Self::send_trigger_to_scroll_stack(cx, scroll_stack);
64 cx.set_key_focus(next_area);
65 }
66 }
67 }
68 _ => ()
69 },
70 _ => ()
71 }
72 }
73
74 pub fn draw(&mut self, cx: &mut Cx2d) {
75 if !self.draw_list.begin(cx, Walk::default()).is_redrawing() {
76 return
77 }
78
79 self.draw_list.end(cx);
80 }
81}
82
83