makepad_widgets/
multi_window.rs1
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}