makepad_widgets/
root.rs

1
2use {
3    crate::{
4        widget::*,
5        makepad_derive_widget::*,
6        makepad_draw::*,
7    }
8};
9
10live_design!{
11    link widgets;
12    
13    use link::widgets::*;
14    use link::designer::Designer;
15    
16    pub RootBase = {{Root}} {}
17    pub Root = <RootBase> {
18        design_window = <Designer> {}
19        xr_hands = <XrHands>{}
20    }
21}
22
23#[derive(Live, LiveRegisterWidget, WidgetRef)]
24pub struct Root {
25    #[rust] components: ComponentMap<LiveId, WidgetRef>,
26    #[rust(DrawList::new(cx))] xr_draw_list: DrawList,
27    #[live] xr_pass: Pass,
28    #[rust] draw_state: DrawStateWrap<DrawState>,
29}
30
31#[derive(Clone)]
32enum DrawState {
33    Component(usize),
34}
35
36impl LiveHook for Root {
37    fn apply_value_instance(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
38        let id = nodes[index].id;
39        match apply.from {
40            ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
41                if nodes[index].origin.has_prop_type(LivePropType::Instance) {
42                    // only open the design window 
43                    if id == live_id!(design_window) && !cx.in_makepad_studio(){
44                        return nodes.skip_node(index);
45                    }
46                    if id == live_id!(xr_hands) && !cx.os_type().has_xr_mode(){
47                        return nodes.skip_node(index);
48                    }
49                    return self.components.get_or_insert(cx, id, | cx | {WidgetRef::new(cx)})
50                        .apply(cx, apply, index, nodes);
51                }
52                else {
53                    cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
54                }
55            }
56            _ => ()
57        }
58        nodes.skip_node(index)
59    }
60}
61
62
63impl WidgetNode for Root{
64    fn redraw(&mut self, cx: &mut Cx) {
65        for component in self.components.values_mut() {
66            component.redraw(cx);
67        }
68    }
69    
70    fn area(&self)->Area{Area::Empty}
71    
72    fn walk(&mut self, _cx:&mut Cx) -> Walk {Walk::default()}
73        
74    fn find_widgets(&self, path: &[LiveId], cached: WidgetCache, results:&mut WidgetSet){
75        if path.len() != 0{
76            if let Some(component) = self.components.get(&path[0]) {
77                if path.len() == 1{
78                    results.push(component.clone());
79                }
80                else{
81                    component.find_widgets(&path[1..], cached, results);
82                }
83            }
84        }
85        for component in self.components.values() {
86            component.find_widgets(path, cached, results);
87        }
88    }
89    
90    fn uid_to_widget(&self, uid:WidgetUid)->WidgetRef{
91        for component in self.components.values() {
92            let x = component.uid_to_widget(uid);
93            if !x.is_empty(){return x}
94        }
95        WidgetRef::empty()
96    }
97        
98}
99
100impl Widget for Root {
101    
102    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
103        if let Event::Draw(e) = event {
104            if cx.in_xr_mode(){
105                if  !e.xr_state.is_some(){
106                    return
107                }
108                let mut cx_draw = CxDraw::new(cx, e);
109                let cx = &mut Cx3d::new(&mut cx_draw);
110                // lets begin a 3D drawlist in the global context
111                self.xr_pass.set_as_xr_pass(cx);
112                cx.begin_pass(&self.xr_pass, Some(4.0));
113                self.xr_draw_list.begin_always(cx);
114                self.draw_3d_all(cx, scope);
115                self.xr_draw_list.end(cx);
116                cx.end_pass(&self.xr_pass);
117                return
118            }
119            else{
120                let mut cx_draw = CxDraw::new(cx, e);
121                let cx = &mut Cx2d::new(&mut cx_draw);
122                self.draw_all(cx, scope);
123                return
124            }
125        }
126        
127        for component in self.components.values_mut() {
128            component.handle_event(cx, event, scope);
129        }
130    }
131    
132    fn draw_3d(&mut self, cx: &mut Cx3d, scope:&mut Scope)->DrawStep{
133        for component in self.components.values(){
134            component.draw_3d_all(cx, scope);
135        }
136        DrawStep::done()
137    }
138    
139    fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, _walk: Walk) -> DrawStep {
140        self.draw_state.begin(cx, DrawState::Component(0));
141                
142        while let Some(DrawState::Component(step)) = self.draw_state.get() {
143                        
144            if let Some(component) = self.components.values_mut().nth(step){
145                let walk = component.walk(cx);
146                component.draw_walk(cx, scope, walk)?; 
147                self.draw_state.set(DrawState::Component(step+1));
148            }
149            else{
150                self.draw_state.end();
151            }
152        }
153        DrawStep::done()
154    }
155}