makepad_widgets/
page_flip.rs

1
2use crate::{
3    widget::*,
4    makepad_derive_widget::*,
5    makepad_draw::*,
6};
7
8live_design!{
9    PageFlipBase = {{PageFlip}} {}
10}
11
12#[derive(Live)]
13pub struct PageFlip {
14    #[rust] area: Area,
15    #[walk] walk: Walk,
16    #[layout] layout: Layout,
17    #[live(true)] on_demand: bool,
18    #[live] active_page: LiveId,
19    #[rust] draw_state: DrawStateWrap<Walk>,
20    #[rust] pointers: ComponentMap<LiveId, LivePtr>,
21    #[rust] pages: ComponentMap<LiveId, WidgetRef>,
22}
23
24impl LiveHook for PageFlip {
25    fn before_live_design(cx: &mut Cx) {
26        register_widget!(cx, PageFlip)
27    }
28    
29    fn before_apply(&mut self, _cx: &mut Cx, from: ApplyFrom, _index: usize, _nodes: &[LiveNode]) {
30        if let ApplyFrom::UpdateFromDoc {..} = from {
31            self.pointers.clear();
32        }
33    }
34    
35    // hook the apply flow to collect our templates and apply to instanced childnodes
36    fn apply_value_instance(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
37        let id = nodes[index].id;
38        match from {
39            ApplyFrom::NewFromDoc {file_id} | ApplyFrom::UpdateFromDoc {file_id} => {
40                if nodes[index].origin.has_prop_type(LivePropType::Instance) {
41                    let live_ptr = cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, index);
42                    self.pointers.insert(id, live_ptr);
43                    // find if we have the page and apply
44                    if let Some(node) = self.pages.get_mut(&id) {
45                        node.apply(cx, from, index, nodes);
46                    }
47                }
48                else {
49                    cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
50                }
51            }
52            _ => ()
53        }
54        nodes.skip_node(index)
55    }
56}
57
58impl PageFlip {
59    
60    pub fn page(&mut self, cx: &mut Cx, page_id: LiveId) -> Option<WidgetRef> {
61        if let Some(ptr) = self.pointers.get(&page_id) {
62            let entry = self.pages.get_or_insert(cx, page_id, | cx | {
63                WidgetRef::new_from_ptr(cx, Some(*ptr))
64            });
65            return Some(entry.clone())
66        }
67        None
68    }
69    
70    fn begin(&mut self, cx: &mut Cx2d, walk: Walk) {
71        cx.begin_turtle(walk, self.layout);
72    }
73    
74    fn end(&mut self, cx: &mut Cx2d) {
75        cx.end_turtle_with_area(&mut self.area);
76    }
77}
78
79
80impl Widget for PageFlip {
81    fn find_widgets(&mut self, path: &[LiveId], cached: WidgetCache, results: &mut WidgetSet) {
82        if let Some(page) = self.pages.get_mut(&self.active_page) {
83            page.find_widgets(path, cached, results);
84        }
85        for (key,page) in self.pages.iter_mut(){
86            if *key != self.active_page{
87                page.find_widgets(path, cached, results);
88            }
89        }
90    }
91    
92    fn redraw(&mut self, cx: &mut Cx) {
93        self.area.redraw(cx);
94    }
95    
96    fn handle_widget_event_with(&mut self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)) {
97        let uid = self.widget_uid();
98        
99        if let Some(page) = self.pages.get_mut(&self.active_page) {
100            let item_uid = page.widget_uid();
101            page.handle_widget_event_with(cx, event, &mut | cx, action | {
102                dispatch_action(cx, action.with_container(uid).with_item(item_uid))
103            });
104        }
105    }
106    
107    fn walk(&mut self, _cx: &mut Cx) -> Walk {
108        self.walk
109    }
110    
111    fn draw_walk_widget(&mut self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw {
112        if let Some(page) = self.page(cx, self.active_page) {
113            if self.draw_state.begin_with(cx, &(), | cx, _ | {
114                page.walk(cx)
115            }) {
116                self.begin(cx, walk);
117            }
118            if let Some(walk) = self.draw_state.get() {
119                page.draw_walk_widget(cx, walk) ?;
120            }
121            self.end(cx);
122        }
123        else {
124            self.begin(cx, walk);
125            self.end(cx);
126        }
127        WidgetDraw::done()
128    }
129}
130
131#[derive(Clone, Default, PartialEq, WidgetRef)]
132pub struct PageFlipRef(WidgetRef);
133
134impl PageFlipRef {
135    pub fn set_active_page(&self, page: LiveId) {
136        if let Some(mut inner) = self.borrow_mut() {
137            inner.active_page = page;
138        }
139    }
140    pub fn set_active_page_and_redraw(&self, cx: &mut Cx, page: LiveId) {
141        if let Some(mut inner) = self.borrow_mut() {
142            inner.redraw(cx);
143            inner.active_page = page;
144        }
145    }
146}
147
148#[derive(Clone, Default, WidgetSet)]
149pub struct PageFlipSet(WidgetSet);
150
151impl PageFlipSet {
152}