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 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 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}