makepad_widgets/
slides_view.rs1use crate::{
2 makepad_derive_widget::*,
3 makepad_draw::*,
4 widget::*,
5};
6
7live_design!{
8 SlidesViewBase = {{SlidesView}} {
9 }
10}
11
12#[derive(Live)]
13pub struct SlidesView {
14 #[layout] layout: Layout,
15 #[rust] area: Area,
16 #[walk] walk: Walk,
17 #[rust] children: ComponentMap<LiveId, WidgetRef>,
18 #[rust] draw_order: Vec<LiveId>,
19 #[rust] next_frame: NextFrame,
20 #[live] current_slide: f64,
21 #[live] goal_slide: f64,
22 #[live] anim_speed: f64,
23 #[rust] _draw_state: DrawStateWrap<DrawState>,
24}
25
26#[derive(Clone)]
27enum DrawState {
28 _Drawing(usize),
29}
30
31impl LiveHook for SlidesView {
32 fn before_live_design(cx: &mut Cx) {
33 register_widget!(cx, SlidesView)
34 }
35
36 fn before_apply(&mut self, _cx: &mut Cx, from: ApplyFrom, _index: usize, _nodes: &[LiveNode]) {
37 if let ApplyFrom::UpdateFromDoc {..} = from {
38 self.draw_order.clear();
40 }
41 }
42
43 fn apply_value_instance(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
44 let id = nodes[index].id;
45 match from {
46 ApplyFrom::Animate | ApplyFrom::ApplyOver => {
47 if let Some(component) = self.children.get_mut(&nodes[index].id) {
48 component.apply(cx, from, index, nodes)
49 }
50 else {
51 nodes.skip_node(index)
52 }
53 }
54 ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
55 if nodes[index].origin.has_prop_type(LivePropType::Instance) {
56 self.draw_order.push(id);
57 return self.children.get_or_insert(cx, id, | cx | {
58 WidgetRef::new(cx)
59 }).apply(cx, from, index, nodes);
60 }
61 else {
62 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
63 nodes.skip_node(index)
64 }
65 }
66 _ => {
67 nodes.skip_node(index)
68 }
69 }
70 }
71}
72
73#[derive(Clone, WidgetAction)]
74pub enum SlidesViewAction {
75 None,
76}
77
78impl Widget for SlidesView {
79 fn handle_widget_event_with(
80 &mut self,
81 cx: &mut Cx,
82 event: &Event,
83 dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)
84 ) {
85 let uid = self.widget_uid();
86 let current = self.current_slide.floor() as usize;
88 if let Some(current) = self.draw_order.get(current){
89 if let Some(current) = self.children.get(¤t){
90 current.handle_widget_event_with(cx, event, dispatch_action);
91 }
92 }
93 if self.current_slide.fract() >0.0{
94 let next = current + 1;
95 if let Some(next) = self.draw_order.get(next){
96 if let Some(next) = self.children.get(&next){
97 next.handle_widget_event_with(cx, event, dispatch_action);
98 }
99 }
100 }
101 self.handle_event_with(cx, event, &mut | cx, action | {
102 dispatch_action(cx, WidgetActionItem::new(action.into(), uid));
103 });
104 }
105
106 fn walk(&mut self, _cx: &mut Cx) -> Walk {
107 self.walk
108 }
109
110 fn redraw(&mut self, cx: &mut Cx) {
111 self.area.redraw(cx)
112 }
113
114 fn find_widgets(&mut self, path: &[LiveId], cached: WidgetCache, results: &mut WidgetSet) {
115 for child in self.children.values_mut() {
116 child.find_widgets(path, cached, results);
117 }
118 }
119
120 fn draw_walk_widget(&mut self, _cx: &mut Cx2d, _walk: Walk) -> WidgetDraw {
121 WidgetDraw::done()
128 }
129}
130
131impl SlidesView {
132 fn next_frame(&mut self, cx: &mut Cx) {
133 self.next_frame = cx.new_next_frame();
134 }
135
136 pub fn next_slide(&mut self, cx: &mut Cx) {
137 self.goal_slide += 1.0;
138 let max_goal_slide = (self.draw_order.len().max(1) - 1) as f64;
140 if self.goal_slide > max_goal_slide {
141 self.goal_slide = max_goal_slide
142 }
143 self.next_frame(cx);
144 }
145
146 pub fn prev_slide(&mut self, cx: &mut Cx) {
147 self.goal_slide -= 1.0;
148 if self.goal_slide < 0.0 {
149 self.goal_slide = 0.0;
150 }
151 self.next_frame(cx);
152 }
153
154 pub fn handle_event_with(&mut self, cx: &mut Cx, event: &Event, _dispatch_action: &mut dyn FnMut(&mut Cx, SlidesViewAction)) {
155 match event {
157 Event::Construct => {
158 self.next_frame(cx);
159 }
160 Event::NextFrame(ne) if ne.set.contains(&self.next_frame) => {
161 self.current_slide = self.current_slide * self.anim_speed + self.goal_slide * (1.0 - self.anim_speed);
162 if (self.current_slide - self.goal_slide).abs()>0.00001 {
163 self.next_frame(cx);
164 self.area.redraw(cx);
165 }
166 else{
167 self.current_slide = self.current_slide.round();
168 }
169
170 }
171 _ => ()
172 }
173 match event.hits(cx, self.area) {
174 Hit::KeyDown(KeyEvent {key_code: KeyCode::ArrowRight, ..}) => {
175 self.next_slide(cx);
176 }
177 Hit::KeyDown(KeyEvent {key_code: KeyCode::ArrowLeft, ..}) => {
178 self.prev_slide(cx);
179 }
180 Hit::FingerDown(_fe) => {
181 cx.set_key_focus(self.area);
182 },
183 _ => ()
184 }
185 }
186
187 pub fn redraw(&mut self, cx: &mut Cx) {
188 self.area.redraw(cx);
189 }
190
191 pub fn draw_walk(&mut self, _cx: &mut Cx2d, _walk: Walk) {
192 }
195}
196
197#[derive(Clone, PartialEq, WidgetRef)]
199pub struct SlidesViewRef(WidgetRef);
200
201impl SlidesViewRef {
202 pub fn next_slide(&self, cx: &mut Cx) {
203 if let Some(mut inner) = self.borrow_mut() {
204 inner.next_slide(cx);
205 }
206 }
207 pub fn prev_slide(&self, cx: &mut Cx) {
208 if let Some(mut inner) = self.borrow_mut() {
209 inner.prev_slide(cx);
210 }
211 }
212}
213
214#[derive(Clone, WidgetSet)]
215pub struct SlidesViewSet(WidgetSet);
216
217impl SlidesViewSet {
218 pub fn next_slide(&self, cx: &mut Cx) {
219 for item in self.iter() {
220 item.next_slide(cx);
221 }
222 }
223 pub fn prev_slide(&self, cx: &mut Cx) {
224 for item in self.iter() {
225 item.prev_slide(cx);
226 }
227 }
228}
229