makepad_widgets/
multi_window.rs

1
2use {
3    crate::{
4        widget::*,
5        makepad_derive_widget::*,
6        window::*,
7        makepad_draw::*,
8    }
9};
10
11live_design!{
12    link widgets;
13    
14    pub MultiWindowBase = {{MultiWindow}} {}
15    pub MultiWindow = <MultiWindowBase> {}
16}
17
18#[derive(Live, LiveRegisterWidget, WidgetRef)]
19pub struct MultiWindow {
20    #[rust] draw_state: DrawStateWrap<DrawState>,
21    #[rust] windows: ComponentMap<LiveId, Window>,
22}
23
24impl LiveHook for MultiWindow {
25    fn apply_value_instance(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
26        let id = nodes[index].id;
27        match apply.from {
28            ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
29                if nodes[index].origin.has_prop_type(LivePropType::Instance) {
30                    if cx.os_type().is_single_window() && id != live_id!(mobile){
31                        return nodes.skip_node(index);
32                    }
33                    return self.windows.get_or_insert(cx, id, | cx | {Window::new(cx)})
34                        .apply(cx, apply, index, nodes);
35                }
36                else {
37                    cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
38                }
39            }
40            _ => ()
41        }
42        nodes.skip_node(index)
43    }
44}
45
46#[derive(Clone)]
47enum DrawState {
48    Window(usize),
49}
50
51impl WidgetNode for MultiWindow{
52    fn redraw(&mut self, cx: &mut Cx) {
53        for window in self.windows.values_mut() {
54            window.redraw(cx);
55        }
56    }
57    fn area(&self)->Area{Area::Empty}
58    
59    fn walk(&mut self, _cx:&mut Cx) -> Walk {Walk::default()}
60        
61    fn find_widgets(&self, path: &[LiveId], cached: WidgetCache, results:&mut WidgetSet){
62        for window in self.windows.values() {
63            window.find_widgets(path, cached, results);
64        }
65    }
66    
67    fn uid_to_widget(&self, uid:WidgetUid)->WidgetRef{
68        for window in self.windows.values() {
69            let x = window.uid_to_widget(uid);
70            if !x.is_empty(){return x}
71        }
72        WidgetRef::empty()
73    }
74}
75
76impl Widget for MultiWindow {
77    
78    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
79        for window in self.windows.values_mut() {
80            window.handle_event(cx, event, scope);
81        }
82    }
83    
84     fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, _walk: Walk) -> DrawStep {
85        self.draw_state.begin(cx, DrawState::Window(0));
86        if cx.os_type().is_single_window(){
87            if let Some(DrawState::Window(_)) = self.draw_state.get(){
88                if let Some(window) = self.windows.get_mut(&live_id!(mobile)){
89                    let walk = window.walk(cx);
90                    window.draw_walk(cx, scope, walk)?; 
91                    self.draw_state.end();
92                }
93            }
94            return DrawStep::done()
95        }
96        
97        while let Some(DrawState::Window(step)) = self.draw_state.get() {
98            
99            if let Some(window) = self.windows.values_mut().nth(step){
100                let walk = window.walk(cx);
101                window.draw_walk(cx, scope, walk)?; 
102                self.draw_state.set(DrawState::Window(step+1));
103            }
104            else{
105                self.draw_state.end();
106            }
107        }
108        DrawStep::done()
109    }
110}