makepad_widgets/
page_flip.rs1
2use crate::{
3 widget::*,
4 makepad_derive_widget::*,
5 makepad_draw::*,
6};
7
8live_design!{
9 link widgets;
10 pub PageFlipBase = {{PageFlip}} {}
11 pub PageFlip = <PageFlipBase>{
12 }
13}
14
15#[derive(Live, LiveRegisterWidget, WidgetRef, WidgetSet)]
16pub struct PageFlip {
17 #[rust] area: Area,
18 #[walk] walk: Walk,
19 #[layout] layout: Layout,
20 #[live(false)] lazy_init: bool,
21 #[live] active_page: LiveId,
22 #[rust] draw_state: DrawStateWrap<Walk>,
23 #[rust] pointers: ComponentMap<LiveId, LivePtr>,
24 #[rust] pages: ComponentMap<LiveId, WidgetRef>,
25}
26
27impl LiveHook for PageFlip {
28
29 fn before_apply(&mut self, _cx: &mut Cx, apply: &mut Apply, _index: usize, _nodes: &[LiveNode]) {
30 if let ApplyFrom::UpdateFromDoc {..} = apply.from {
31 self.pointers.clear();
32 }
33 }
34
35 fn after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, _index: usize, _nodes: &[LiveNode]) {
36 match apply.from {
37 ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
38 if !self.lazy_init{
39 for (page_id, ptr) in self.pointers.iter(){
40 self.pages.get_or_insert(cx, *page_id, | cx | {
41 WidgetRef::new_from_ptr(cx, Some(*ptr))
42 });
43 }
44 }
45 }
46 _=>()
47 }
48 }
49
50
51 fn apply_value_instance(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
53 let id = nodes[index].id;
54 match apply.from {
55 ApplyFrom::NewFromDoc {file_id} | ApplyFrom::UpdateFromDoc {file_id,..} => {
56 if nodes[index].origin.has_prop_type(LivePropType::Instance) {
57 let live_ptr = cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, index);
58 self.pointers.insert(id, live_ptr);
59 if let Some(node) = self.pages.get_mut(&id) {
61 node.apply(cx, apply, index, nodes);
62 }
63 }
64 else {
65 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
66 }
67 }
68 _ => ()
69 }
70 nodes.skip_node(index)
71 }
72}
73
74impl PageFlip {
75
76 pub fn page(&mut self, cx: &mut Cx, page_id: LiveId) -> Option<WidgetRef> {
77 if let Some(ptr) = self.pointers.get(&page_id) {
78 let entry = self.pages.get_or_insert(cx, page_id, | cx | {
79 WidgetRef::new_from_ptr(cx, Some(*ptr))
80 });
81 return Some(entry.clone())
82 }
83 None
84 }
85
86 fn begin(&mut self, cx: &mut Cx2d, walk: Walk) {
87 cx.begin_turtle(walk, self.layout);
88 }
89
90 fn end(&mut self, cx: &mut Cx2d) {
91 cx.end_turtle_with_area(&mut self.area);
92 }
93}
94
95impl WidgetNode for PageFlip{
96 fn walk(&mut self, _cx:&mut Cx) -> Walk{
97 self.walk
98 }
99 fn area(&self)->Area{self.area}
100
101 fn redraw(&mut self, cx: &mut Cx){
102 self.area.redraw(cx)
103 }
104
105 fn find_widgets(&self, path: &[LiveId], cached: WidgetCache, results: &mut WidgetSet) {
106 if let Some(page) = self.pages.get(&path[0]) {
107 if path.len() == 1{
108 results.push(page.clone());
109 }
110 else{
111 page.find_widgets(&path[1..], cached, results);
112 }
113 }
114 for page in self.pages.values() {
115 page.find_widgets(path, cached, results);
116 }
117 }
118
119 fn uid_to_widget(&self, uid:WidgetUid)->WidgetRef{
120 for page in self.pages.values() {
121 let x = page.uid_to_widget(uid);
122 if !x.is_empty(){return x}
123 }
124 WidgetRef::empty()
125 }
126}
127
128impl Widget for PageFlip {
129
130 fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
131 let uid = self.widget_uid();
132 if event.requires_visibility(){
133 if let Some(page) = self.pages.get_mut(&self.active_page) {
134 let item_uid = page.widget_uid();
135 cx.group_widget_actions(uid, item_uid, |cx|{
136 page.handle_event(cx, event, scope)
137 });
138 }
139 }
140 else{
141 for page in self.pages.values(){
142 let item_uid = page.widget_uid();
143 cx.group_widget_actions(uid, item_uid, |cx|{
144 page.handle_event(cx, event, scope)
145 });
146 }
147 }
148 }
149
150 fn draw_walk(&mut self, cx: &mut Cx2d, scope:&mut Scope, walk: Walk) -> DrawStep {
151 if let Some(page) = self.page(cx, self.active_page) {
152 if self.draw_state.begin_with(cx, &(), | cx, _ | {
153 page.walk(cx)
154 }) {
155 self.begin(cx, walk);
156 }
157 if let Some(walk) = self.draw_state.get() {
158 page.draw_walk(cx, scope, walk) ?;
159 }
160 self.end(cx);
161 }
162 else {
163 self.begin(cx, walk);
164 self.end(cx);
165 }
166 DrawStep::done()
167 }
168}
169
170impl PageFlipRef {
171 pub fn set_active_page(&self, cx: &mut Cx, page: LiveId) {
172 if let Some(mut inner) = self.borrow_mut() {
173 inner.redraw(cx);
174 inner.active_page = page;
175 }
176 }
177}
178
179impl PageFlipSet {
180}