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    MultiWindowBase = {{MultiWindow}} {}
13}
14
15#[derive(Live)]
16pub struct MultiWindow {
17    #[rust] draw_state: DrawStateWrap<DrawState>,
18    #[rust] windows: ComponentMap<LiveId, Window>,
19}
20
21impl LiveHook for MultiWindow {
22    fn before_live_design(cx:&mut Cx){
23        register_widget!(cx,MultiWindow)
24    }
25    
26    fn apply_value_instance(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
27        let id = nodes[index].id;
28        match from {
29            ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
30                if nodes[index].origin.has_prop_type(LivePropType::Instance) {
31                    if cx.os_type().is_single_window() && id != live_id!(mobile){
32                        return nodes.skip_node(index);
33                    }
34                    return self.windows.get_or_insert(cx, id, | cx | {Window::new(cx)})
35                        .apply(cx, from, index, nodes);
36                }
37                else {
38                    cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
39                }
40            }
41            _ => ()
42        }
43        nodes.skip_node(index)
44    }
45}
46
47#[derive(Clone)]
48enum DrawState {
49    Window(usize),
50}
51
52impl Widget for MultiWindow {
53    fn redraw(&mut self, cx: &mut Cx) {
54        for window in self.windows.values_mut() {
55            window.redraw(cx);
56        }
57    }
58    
59    fn find_widgets(&mut self, path: &[LiveId], cached: WidgetCache, results:&mut WidgetSet){
60        for window in self.windows.values_mut() {
61            window.find_widgets(path, cached, results);
62        }
63    }
64    
65    fn handle_widget_event_with(&mut self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)) {
66        for window in self.windows.values_mut() {
67            window.handle_widget_event_with(cx, event, dispatch_action);
68        }
69    }
70    
71    fn walk(&mut self, _cx:&mut Cx) -> Walk {Walk::default()}
72    
73    fn draw_walk_widget(&mut self, cx: &mut Cx2d, _walk: Walk) -> WidgetDraw {
74        self.draw_state.begin(cx, DrawState::Window(0));
75        if cx.os_type().is_single_window(){
76            if let Some(DrawState::Window(_)) = self.draw_state.get(){
77                if let Some(window) = self.windows.get_mut(&live_id!(mobile)){
78                    window.draw_widget(cx)?; 
79                    self.draw_state.end();
80                }
81            }
82            return WidgetDraw::done()
83        }
84        
85        while let Some(DrawState::Window(step)) = self.draw_state.get() {
86            
87            if let Some(window) = self.windows.values_mut().nth(step){
88                window.draw_widget(cx)?; 
89                self.draw_state.set(DrawState::Window(step+1));
90            }
91            else{
92                self.draw_state.end();
93            }
94        }
95        WidgetDraw::done()
96    }
97}
98
99#[derive(Clone, Default, PartialEq, WidgetRef)]
100pub struct MultiWindowRef(WidgetRef);