1
2use {
3 std::f64::consts::PI,
4 crate::{
5 makepad_live_compiler::{
6 LiveRef,
7 LiveNodeReader,
8 LiveNodeOrigin,
9 LiveValue,
10 LiveTypeInfo,
11 LiveTypeField,
12 LivePropType,
13 LiveFieldKind,
14 LiveModuleId,
15 LiveType,
16 LiveId,
17 LiveNode,
18 LiveIdAsProp,
19 LiveNodeSliceApi,
20 LiveNodeVecApi
21 },
22 live_traits::{LiveNew},
23 makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
24 makepad_error_log::*,
25 makepad_live_id::*,
26 makepad_derive_live::*,
27 makepad_math::*,
28 cursor::MouseCursor,
29 event::{Event, NextFrame},
30 cx::Cx,
31 live_traits::*,
32 },
33};
34
35pub trait AnimatorImpl {
36
37 fn animator_cut(&mut self, cx: &mut Cx, state: &[LiveId; 2]);
38 fn animator_play(&mut self, cx: &mut Cx, state: &[LiveId; 2]);
39 fn animator_toggle(&mut self, cx: &mut Cx, is_state_1: bool, animate: Animate, state1: &[LiveId; 2], state2: &[LiveId; 2]) {
40 if is_state_1 {
41 if let Animate::Yes = animate {
42 self.animator_play(cx, state1)
43 }
44 else {
45 self.animator_cut(cx, state1)
46 }
47 }
48 else {
49 if let Animate::Yes = animate {
50 self.animator_play(cx, state2)
51 }
52 else {
53 self.animator_cut(cx, state2)
54 }
55 }
56 }
57 fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool;
58 fn animator_apply_state(&mut self, cx: &mut Cx);
59 fn animator_after_apply(&mut self, cx: &mut Cx, apply_from: ApplyFrom, index: usize, nodes: &[LiveNode]);
60 fn animator_handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction;
61}
62
63#[derive(Debug, Clone, Copy)]
64pub enum Animate {
65 Yes,
66 No
67}
68
69#[derive(Debug, Clone, Live, LiveHook)]
71pub struct KeyFrame {
72 #[live(Ease::Linear)]
73 pub ease: Ease,
74
75 #[live(1.0)]
76 pub time: f64,
77
78 #[live(LiveValue::None)]
79 pub value: LiveValue,
80}
81
82#[derive(Copy, Clone, Debug, PartialEq, Live, LiveHook)]
83pub enum Play {
84 #[pick {duration: 1.0}]
85 Forward {duration: f64},
86
87 Snap,
88
89 #[live {duration: 1.0, end: 1.0}]
90 Reverse {duration: f64, end: f64},
91
92 #[live {duration: 1.0, end: 1.0}]
93 Loop {duration: f64, end: f64},
94
95 #[live {duration: 1.0, end: 1.0}]
96 ReverseLoop {duration: f64, end: f64},
97
98 #[live {duration: 1.0, end: 1.0}]
99 BounceLoop {duration: f64, end: f64},
100}
101impl Play {
104 pub fn get_ended_time(&self, time: f64) -> (bool, f64) {
116 match self {
117 Self::Snap => (true, 1.0),
118 Self::Forward {duration} => {
119 if *duration == 0.0 {return (true, 1.0)}
120 (time > *duration, time.min(*duration) / duration)
121 },
122 Self::Reverse {duration, end} => {
123 if *duration == 0.0 {return (true, 1.0)}
124 (time > *duration, end - (time.min(*duration) / duration))
125 },
126 Self::Loop {duration, end} => {
127 if *duration == 0.0 {return (true, 1.0)}
128 (false, (time / duration) % end)
129 },
130 Self::ReverseLoop {end, duration} => {
131 if *duration == 0.0 {return (true, 1.0)}
132 (false, end - (time / duration) % end)
133 },
134 Self::BounceLoop {end, duration} => {
135 if *duration == 0.0 {return (true, 1.0)}
136 let mut local_time = (time / duration) % (end * 2.0);
137 if local_time > *end {
138 local_time = 2.0 * end - local_time;
139 };
140 (false, local_time)
141 },
142 }
143 }
144}
145
146
147#[derive(Clone, Copy, Debug, PartialEq, Live, LiveHook)]
148pub enum Ease {
149 #[pick] Linear,
150 #[live] None,
151 #[live(1.0)] Constant(f64),
152 #[live] InQuad,
153 #[live] OutQuad,
154 #[live] InOutQuad,
155 #[live] InCubic,
156 #[live] OutCubic,
157 #[live] InOutCubic,
158 #[live] InQuart,
159 #[live] OutQuart,
160 #[live] InOutQuart,
161 #[live] InQuint,
162 #[live] OutQuint,
163 #[live] InOutQuint,
164 #[live] InSine,
165 #[live] OutSine,
166 #[live] InOutSine,
167 #[live] InExp,
168 #[live] OutExp,
169 #[live] InOutExp,
170 #[live] InCirc,
171 #[live] OutCirc,
172 #[live] InOutCirc,
173 #[live] InElastic,
174 #[live] OutElastic,
175 #[live] InOutElastic,
176 #[live] InBack,
177 #[live] OutBack,
178 #[live] InOutBack,
179 #[live] InBounce,
180 #[live] OutBounce,
181 #[live] InOutBounce,
182 #[live {d1: 0.82, d2: 0.97, max: 100}] ExpDecay {d1: f64, d2: f64, max: usize},
183
184 #[live {begin: 0.0, end: 1.0}] Pow {begin: f64, end: f64},
185 #[live {cp0: 0.0, cp1: 0.0, cp2: 1.0, cp3: 1.0}] Bezier {cp0: f64, cp1: f64, cp2: f64, cp3: f64}
186}
187
188impl Ease {
189 pub fn map(&self, t: f64) -> f64 {
190 match self {
191 Self::ExpDecay {d1, d2, max} => { let mut di = *d1;
194 let mut dt = 1.0;
195 let max_steps = (*max).min(1000);
196 let mut steps = 0;
197 while dt > 0.001 && steps < max_steps {
199 steps = steps + 1;
200 dt = dt * di;
201 di *= d2;
202 }
203 let step = t * (steps as f64);
205 let mut di = *d1;
206 let mut dt = 1.0;
207 let max_steps = max_steps as f64;
208 let mut steps = 0.0;
209 while dt > 0.001 && steps < max_steps {
210 steps += 1.0;
211 if steps >= step { let fac = steps - step;
213 return 1.0 - (dt * fac + (dt * di) * (1.0 - fac))
214 }
215 dt = dt * di;
216 di *= d2;
217 }
218 1.0
219 }
220 Self::Linear => {
221 return t.max(0.0).min(1.0);
222 },
223 Self::Constant(t) => {
224 return t.max(0.0).min(1.0);
225 },
226 Self::None => {
227 return 1.0;
228 },
229 Self::Pow {begin, end} => {
230 if t < 0. {
231 return 0.;
232 }
233 if t > 1. {
234 return 1.;
235 }
236 let a = -1. / (begin * begin).max(1.0);
237 let b = 1. + 1. / (end * end).max(1.0);
238 let t2 = (((a - 1.) * -b) / (a * (1. - b))).powf(t);
239 return (-a * b + b * a * t2) / (a * t2 - b);
240 },
241
242 Self::InQuad => {
243 return t * t;
244 },
245 Self::OutQuad => {
246 return t * (2.0 - t);
247 },
248 Self::InOutQuad => {
249 let t = t * 2.0;
250 if t < 1. {
251 return 0.5 * t * t;
252 }
253 else {
254 let t = t - 1.;
255 return -0.5 * (t * (t - 2.) - 1.);
256 }
257 },
258 Self::InCubic => {
259 return t * t * t;
260 },
261 Self::OutCubic => {
262 let t2 = t - 1.0;
263 return t2 * t2 * t2 + 1.0;
264 },
265 Self::InOutCubic => {
266 let t = t * 2.0;
267 if t < 1. {
268 return 0.5 * t * t * t;
269 }
270 else {
271 let t = t - 2.;
272 return 1. / 2. * (t * t * t + 2.);
273 }
274 },
275 Self::InQuart => {
276 return t * t * t * t
277 },
278 Self::OutQuart => {
279 let t = t - 1.;
280 return -(t * t * t * t - 1.);
281 },
282 Self::InOutQuart => {
283 let t = t * 2.0;
284 if t < 1. {
285 return 0.5 * t * t * t * t;
286 }
287 else {
288 let t = t - 2.;
289 return -0.5 * (t * t * t * t - 2.);
290 }
291 },
292 Self::InQuint => {
293 return t * t * t * t * t;
294 },
295 Self::OutQuint => {
296 let t = t - 1.;
297 return t * t * t * t * t + 1.;
298 },
299 Self::InOutQuint => {
300 let t = t * 2.0;
301 if t < 1. {
302 return 0.5 * t * t * t * t * t;
303 }
304 else {
305 let t = t - 2.;
306 return 0.5 * (t * t * t * t * t + 2.);
307 }
308 },
309 Self::InSine => {
310 return -(t * PI * 0.5).cos() + 1.;
311 },
312 Self::OutSine => {
313 return (t * PI * 0.5).sin();
314 },
315 Self::InOutSine => {
316 return -0.5 * ((t * PI).cos() - 1.);
317 },
318 Self::InExp => {
319 if t < 0.001 {
320 return 0.;
321 }
322 else {
323 return 2.0f64.powf(10. * (t - 1.));
324 }
325 },
326 Self::OutExp => {
327 if t > 0.999 {
328 return 1.;
329 }
330 else {
331 return -(2.0f64.powf(-10. * t)) + 1.;
332 }
333 },
334 Self::InOutExp => {
335 if t<0.001 {
336 return 0.;
337 }
338 if t>0.999 {
339 return 1.;
340 }
341 let t = t * 2.0;
342 if t < 1. {
343 return 0.5 * 2.0f64.powf(10. * (t - 1.));
344 }
345 else {
346 let t = t - 1.;
347 return 0.5 * (-(2.0f64.powf(-10. * t)) + 2.);
348 }
349 },
350 Self::InCirc => {
351 return -((1. - t * t).sqrt() - 1.);
352 },
353 Self::OutCirc => {
354 let t = t - 1.;
355 return (1. - t * t).sqrt();
356 },
357 Self::InOutCirc => {
358 let t = t * 2.;
359 if t < 1. {
360 return -0.5 * ((1. - t * t).sqrt() - 1.);
361 }
362 else {
363 let t = t - 2.;
364 return 0.5 * ((1. - t * t).sqrt() + 1.);
365 }
366 },
367 Self::InElastic => {
368 let p = 0.3;
369 let s = p / 4.0; if t < 0.001 {
371 return 0.;
372 }
373 if t > 0.999 {
374 return 1.;
375 }
376 let t = t - 1.0;
377 return -(2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
378 },
379 Self::OutElastic => {
380 let p = 0.3;
381 let s = p / 4.0; if t < 0.001 {
384 return 0.;
385 }
386 if t > 0.999 {
387 return 1.;
388 }
389 return 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
390 },
391 Self::InOutElastic => {
392 let p = 0.3;
393 let s = p / 4.0; if t < 0.001 {
395 return 0.;
396 }
397 if t > 0.999 {
398 return 1.;
399 }
400 let t = t * 2.0;
401 if t < 1. {
402 let t = t - 1.0;
403 return -0.5 * (2.0f64.powf(10.0 * t) * ((t - s) * (2.0 * PI) / p).sin());
404 }
405 else {
406 let t = t - 1.0;
407 return 0.5 * 2.0f64.powf(-10.0 * t) * ((t - s) * (2.0 * PI) / p).sin() + 1.0;
408 }
409 },
410 Self::InBack => {
411 let s = 1.70158;
412 return t * t * ((s + 1.) * t - s);
413 },
414 Self::OutBack => {
415 let s = 1.70158;
416 let t = t - 1.;
417 return t * t * ((s + 1.) * t + s) + 1.;
418 },
419 Self::InOutBack => {
420 let s = 1.70158;
421 let t = t * 2.0;
422 if t < 1. {
423 let s = s * 1.525;
424 return 0.5 * (t * t * ((s + 1.) * t - s));
425 }
426 else {
427 let t = t - 2.;
428 return 0.5 * (t * t * ((s + 1.) * t + s) + 2.);
429 }
430 },
431 Self::InBounce => {
432 return 1.0 - Self::OutBounce.map(1.0 - t);
433 },
434 Self::OutBounce => {
435 if t < (1. / 2.75) {
436 return 7.5625 * t * t;
437 }
438 if t < (2. / 2.75) {
439 let t = t - (1.5 / 2.75);
440 return 7.5625 * t * t + 0.75;
441 }
442 if t < (2.5 / 2.75) {
443 let t = t - (2.25 / 2.75);
444 return 7.5625 * t * t + 0.9375;
445 }
446 let t = t - (2.625 / 2.75);
447 return 7.5625 * t * t + 0.984375;
448 },
449 Self::InOutBounce => {
450 if t <0.5 {
451 return Self::InBounce.map(t * 2.) * 0.5;
452 }
453 else {
454 return Self::OutBounce.map(t * 2. - 1.) * 0.5 + 0.5;
455 }
456 },
457 Self::Bezier {cp0, cp1, cp2, cp3} => {
458 if t < 0. {
459 return 0.;
460 }
461 if t > 1. {
462 return 1.;
463 }
464
465 if (cp0 - cp1).abs() < 0.001 && (cp2 - cp3).abs() < 0.001 {
466 return t;
467 }
468
469 let epsilon = 1.0 / 200.0 * t;
470 let cx = 3.0 * cp0;
471 let bx = 3.0 * (cp2 - cp0) - cx;
472 let ax = 1.0 - cx - bx;
473 let cy = 3.0 * cp1;
474 let by = 3.0 * (cp3 - cp1) - cy;
475 let ay = 1.0 - cy - by;
476 let mut u = t;
477
478 for _i in 0..6 {
479 let x = ((ax * u + bx) * u + cx) * u - t;
480 if x.abs() < epsilon {
481 return ((ay * u + by) * u + cy) * u;
482 }
483 let d = (3.0 * ax * u + 2.0 * bx) * u + cx;
484 if d.abs() < 1e-6 {
485 break;
486 }
487 u = u - x / d;
488 };
489
490 if t > 1. {
491 return (ay + by) + cy;
492 }
493 if t < 0. {
494 return 0.0;
495 }
496
497 let mut w = 0.0;
498 let mut v = 1.0;
499 u = t;
500 for _i in 0..8 {
501 let x = ((ax * u + bx) * u + cx) * u;
502 if (x - t).abs() < epsilon {
503 return ((ay * u + by) * u + cy) * u;
504 }
505
506 if t > x {
507 w = u;
508 }
509 else {
510 v = u;
511 }
512 u = (v - w) * 0.5 + w;
513 }
514
515 return ((ay * u + by) * u + cy) * u;
516 }
517 }
518 }
519}
520
521#[derive(Default)]
522pub struct Animator {
523 pub ignore_missing: bool,
524 pub live_ptr: LiveRef,
525 pub state: Option<Vec<LiveNode >>,
526 pub next_frame: NextFrame,
527}
528
529#[derive(Copy, Clone)]
530pub enum AnimatorAction {
531 Animating {redraw: bool},
532 None
533}
534
535impl LiveHook for Animator {}
536impl LiveNew for Animator {
537 fn new(_cx: &mut Cx) -> Self {Self::default()}
538
539 fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
540 LiveTypeInfo {
541 module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
542 live_type: LiveType::of::<Self>(),
543 live_ignore: true,
544 fields: Vec::new(),
545 type_name: id_lut!(States)
546 }
547 }
548}
549impl LiveApply for Animator {
550 fn apply(&mut self, cx: &mut Cx, from: ApplyFrom, start_index: usize, nodes: &[LiveNode]) -> usize {
551 if let Some(file_id) = from.file_id() {
552 self.live_ptr = Some(cx.live_registry.borrow().file_id_index_to_live_ptr(file_id, start_index));
553 }
554 if !nodes[start_index].value.is_structy_type() {
555 cx.apply_error_wrong_type_for_struct(live_error_origin!(), start_index, nodes, live_id!(States));
556 return nodes.skip_node(start_index);
557 }
558 let mut index = start_index + 1;
560 loop {
561 if nodes[index].value.is_close() {
562 index += 1;
563 break;
564 }
565 if nodes[index].id == live_id!(ignore_missing){
566 self.ignore_missing = nodes[index].value.as_bool().unwrap_or(false);
567 }
568 else if !nodes[index].origin.has_prop_type(LivePropType::Instance) {
569 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
570 }
571 index = nodes.skip_node(index);
572 }
573 return index;
574 }
575}
576
577impl AnimatorAction {
578 pub fn must_redraw(&self) -> bool {
579 match self {
580 Self::Animating {redraw} => *redraw,
581 _ => false
582 }
583 }
584 pub fn is_animating(&self) -> bool {
585 match self {
586 Self::Animating {..} => true,
587 _ => false
588 }
589 }
590}
591impl Animator {
592
593 pub fn swap_out_state(&mut self) -> Vec<LiveNode> {
594 if let Some(state) = self.state.take() {
595 state
596 }
597 else {
598 Vec::new()
599 }
600 }
601
602 pub fn swap_in_state(&mut self, state: Vec<LiveNode>) {
603 self.state = Some(state);
604 }
605
606 pub fn need_init(&self) -> bool {
607 self.state.is_none()
608 }
609
610 pub fn handle_event(&mut self, cx: &mut Cx, event: &Event) -> AnimatorAction {
611
612 if let Event::NextFrame(nf) = event {
613 if !nf.set.contains(&self.next_frame) {
614 return AnimatorAction::None
615 }
616 if self.state.is_none() {
617 return AnimatorAction::None
618 }
619 let state_nodes = self.state.as_mut().unwrap();
620
621 let mut state_index = state_nodes.child_by_name(0, live_id!(state).as_field()).unwrap();
622 let mut stack_depth = 0;
623 let mut ended = true;
624 let mut redraw = false;
625 while state_index < state_nodes.len() {
626 let state_node = &state_nodes[state_index];
627 if state_node.is_array() {
628 let (play_ended, play_redraw) = Self::update_timeline_value(cx, state_index, state_nodes, nf.time);
630 if !play_ended {
631 ended = false;
632 }
633 if play_redraw {
634 redraw = true;
635 }
636 state_index = state_nodes.skip_node(state_index);
637 }
638 else { if state_node.value.is_open() {
640 stack_depth += 1;
641 state_index += 1;
642 }
643 else if state_node.value.is_close() {
644 stack_depth -= 1;
645 state_index += 1;
646 if stack_depth == 0 {
647 break;
648 }
649 }
650 else {
651 state_index = state_nodes.skip_node(state_index);
652 }
653 }
654 }
655 if !ended {
657 self.next_frame = cx.new_next_frame();
658 }
659
660 return AnimatorAction::Animating {redraw}
661 }
662 AnimatorAction::None
663 }
664
665 pub fn update_timeline_value(cx: &mut Cx, index: usize, nodes: &mut [LiveNode], ext_time: f64) -> (bool, bool) {
667 if nodes[index].is_array() {
669 let mut node_iter = nodes.first_child(index);
670
671 let (ended, time, redraw, track_id) = if let Some(id_index) = node_iter {
673 if let LiveValue::Id(track_id) = nodes[id_index].value {
674 let track_index = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field()]).unwrap();
676
677 let time_index = if let Some(time_index) = nodes.child_by_name(track_index, live_id!(time).as_field()) {time_index}
678 else {
679 return (true, false);
680 };
681
682 let start_time = match &nodes[time_index].value {
683 LiveValue::Id(v) => {
684 assert!(*v == live_id!(void));
685 nodes[time_index].value = LiveValue::Float64(ext_time);
686 ext_time
687 }
688 LiveValue::Float64(time) => {
689 *time
690 }
691 _ => panic!()
692 };
693
694 let play = if let Some(play_index) = nodes.child_by_name(track_index, live_id!(play).as_field()) {
695 Play::new_apply(cx, ApplyFrom::New, play_index, nodes)
696 }
697 else {
698 Play::new(cx)
699 };
700 node_iter = nodes.next_child(id_index);
701
702 let (ended, time) = play.get_ended_time(ext_time - start_time);
703
704 if ended { if let Some(index) = nodes.child_by_name(track_index, live_id!(ended).as_field()) {
706 nodes[index].value = LiveValue::Int64(cx.event_id as i64);
707 }
708 }
709
710 let redraw = if let Some(index) = nodes.child_by_name(track_index, live_id!(redraw).as_field()) {
711 if let LiveValue::Bool(redraw) = &nodes[index].value {
712 *redraw
713 }else {false}
714 }else {false};
715
716 (ended, time, redraw, track_id)
717 }
718 else {panic!()}
719 }
720 else {panic!()};
721
722 let default_ease = if let Some(ease_index) = nodes.child_by_path(0, &[live_id!(tracks).as_field(), track_id.as_field(), live_id!(ease).as_field()]) {
723 Ease::new_apply(cx, ApplyFrom::New, ease_index, nodes)
724 }
725 else {
726 Ease::Linear
727 };
728
729 let mut prev_kf: Option<KeyFrame> = None;
730 let mut last_child_index = node_iter.unwrap();
731 while let Some(node_index) = node_iter {
732 if nodes[node_index + 1].is_close() { last_child_index = node_index;
734 break;
735 }
736 let next_kf = if nodes[node_index].is_value_type() { if prev_kf.is_some() {
738 KeyFrame {
739 ease: default_ease.clone(),
740 time: 1.0,
741 value: nodes[node_index].value.clone()
742 }
743 }
744 else {
745 KeyFrame {
746 ease: default_ease.clone(),
747 time: 0.0,
748 value: nodes[node_index].value.clone()
749 }
750 }
751 }
752 else { let mut kf = KeyFrame::new_apply(cx, ApplyFrom::New, node_index, nodes);
754 if nodes.child_by_name(node_index, live_id!(ease).as_field()).is_none() {
755 kf.ease = default_ease.clone();
756 }
757 kf
758 };
759
760 if let Some(prev_kf) = prev_kf {
761 if time >= prev_kf.time && time <= next_kf.time {
762 let normalised_time = (time - prev_kf.time) / (next_kf.time - prev_kf.time);
763 let mix = next_kf.ease.map(normalised_time);
764 while let Some(node_index) = node_iter {
766 last_child_index = node_index;
767 node_iter = nodes.next_child(node_index);
768 }
769
770 let a = &prev_kf.value;
771 let b = &next_kf.value;
772
773 let new_val = match a {
774 LiveValue::Int64(va) => match b {
775 LiveValue::Int64(vb) => {
776 LiveValue::Float64(((vb - va) as f64) * mix + *va as f64)
777 }
778 LiveValue::Float64(vb) => {
779 LiveValue::Float64(((vb - *va as f64) as f64) * mix + *va as f64)
780 }
781 _ => LiveValue::None
782 }
783 LiveValue::Float64(va) => match b {
784 LiveValue::Int64(vb) => {
785 LiveValue::Float64(((*vb as f64 - va) as f64) * mix + *va as f64)
786 }
787 LiveValue::Float64(vb) => {
788 LiveValue::Float64(((vb - va)) * mix + *va)
789 }
790 _ => LiveValue::None
791 }
792 LiveValue::Color(va) => match b {
793 LiveValue::Color(vb) => {
794 LiveValue::Color(Vec4::from_lerp(Vec4::from_u32(*va), Vec4::from_u32(*vb), mix as f32).to_u32())
795 }
796 _ => LiveValue::None
797 }
798 LiveValue::Vec2(va) => match b {
799 LiveValue::Vec2(vb) => {
800 LiveValue::Vec2(Vec2::from_lerp(*va, *vb, mix as f32))
801 }
802 _ => LiveValue::None
803 }
804 LiveValue::Vec3(va) => match b {
805 LiveValue::Vec3(vb) => {
806 LiveValue::Vec3(Vec3::from_lerp(*va, *vb, mix as f32))
807 }
808 _ => LiveValue::None
809 }
810 LiveValue::Id(_) => match b {
811 LiveValue::Id(vb) => {
812 LiveValue::Id(*vb)
813 }
814 _ => LiveValue::None
815 }
816 _ => LiveValue::None
817 };
818 if let LiveValue::None = &new_val {
819 cx.apply_key_frame_cannot_be_interpolated(live_error_origin!(), index, nodes, a, b);
820 return (ended, redraw)
821 }
822 nodes[last_child_index].value = new_val;
823
824 return (ended, redraw)
825 }
826 }
827 prev_kf = Some(next_kf);
828 last_child_index = node_index;
829 node_iter = nodes.next_child(node_index);
830 }
831 if let Some(prev_kf) = prev_kf {
832 nodes[last_child_index].value = prev_kf.value
833 }
834 return (ended, redraw)
835 }
836 (false, false)
837 }
838
839
840 pub fn last_keyframe_value_from_array(index: usize, nodes: &[LiveNode]) -> Option<usize> {
841 if let Some(index) = nodes.last_child(index) {
842 if nodes[index].value.is_object() {
843 return nodes.child_by_name(index, live_id!(value).as_field());
844 }
845 else {
846 return Some(index)
847 }
848 }
849 return None
850 }
851
852 pub fn first_keyframe_time_from_array(reader: &LiveNodeReader) -> f64 {
853 if let Some(reader) = reader.first_child() {
854 if reader.is_object() {
855 if let Some(reader) = reader.child_by_name(live_id!(time).as_field()) {
856 return match &reader.value {
857 LiveValue::Float64(v) => *v,
858 LiveValue::Int64(v) => *v as f64,
859 _ => 1.0
860 }
861 }
862 }
863 }
864 return 1.0
865 }
866
867 pub fn is_track_animating(&self, cx: &mut Cx, track_id: &[LiveId;1]) -> bool {
868 if let Some(state) = self.state.as_ref() {
869 if let Some(LiveValue::Int64(ended)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track_id[0].as_field(), live_id!(ended).as_field()]) {
870 if *ended == 0 || *ended == cx.event_id as i64 {
871 return true
872 }
873 }
874 }
875 false
876 }
877
878 pub fn animator_in_state(&self, cx: &Cx, check_state_pair: &[LiveId; 2]) -> bool {
879 if self.need_init() {
881 if let Some(live_ptr) = self.live_ptr {
882 let live_registry_rc = cx.live_registry.clone();
883 let live_registry = live_registry_rc.borrow();
884 if live_registry.generation_valid(live_ptr) {
885 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
886 if let Some(LiveValue::Id(default_id)) = nodes.child_value_by_path(index, &[check_state_pair[0].as_instance(), live_id!(default).as_field()]) {
887 return *default_id == check_state_pair[1];
888 }
889 }
890 }
891 }
892 else {
893 let state = self.state.as_ref().unwrap();
894 if let Some(LiveValue::Id(id)) = &state.child_value_by_path(0, &[live_id!(tracks).as_field(), check_state_pair[0].as_field(), live_id!(state_id).as_field()]) {
895 return *id == check_state_pair[1];
896 }
897 }
898 false
899 }
900
901 pub fn cut_to_live(&mut self, cx: &mut Cx, state_id: &[LiveId; 2]) {
902 if let Some(live_ptr) = self.live_ptr {
903 let live_registry_rc = cx.live_registry.clone();
904 let live_registry = live_registry_rc.borrow();
905 if live_registry.generation_valid(live_ptr) {
906 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
908
909 self.init_as_needed(cx, index, nodes);
910
911 if let Some(index) = nodes.child_by_path(index, &[state_id[0].as_instance(), state_id[1].as_instance()]) {
912 self.cut_to(cx, state_id, index, nodes);
913 }
914 else {
915 error!("cut_to_live {}.{} not found", state_id[0], state_id[1]);
916 }
917 }
918 else {
919 error!("cut_to_live generaiton invalid")
920 }
921 }
922 }
923
924 pub fn cut_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
926
927 if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
928 let cursor = MouseCursor::new_apply(cx, ApplyFrom::New, index, nodes);
929 cx.set_cursor(cursor);
930 }
931 let mut state = self.swap_out_state();
933 let track = state_pair[0];
935
936 if state.len() == 0 {
937 state.push_live(live!{
938 tracks: {},
939 state: {}
940 });
941 }
942
943 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
944 [track]: {state_id: (state_pair[1]), ended: 1}
945 });
946
947 let mut path = Vec::new();
948 path.push(live_id!(state).as_field());
949
950 let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
951 reader
952 }
953 else {
954 cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
955 self.swap_in_state(state);
956 return
957 };
958
959 reader.walk();
960 while !reader.is_eot() {
961 if reader.is_array() {
962 path.push(reader.prop());
963 if let Some(last_value) = Self::last_keyframe_value_from_array(reader.index(), reader.nodes()) {
964 state.replace_or_insert_first_node_by_path(0, &path, live_array!{
965 [(track), (reader.nodes()[last_value].value.clone())]
966 });
967 }
968 path.pop();
969 reader.skip();
970 }
971 else {
972 if reader.is_expr() {
973 path.push(reader.prop());
974 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
975 path.pop();
976 reader.skip();
977 continue;
978 }
979 else if reader.is_open() {
980 path.push(reader.prop());
981 if reader.is_enum() {
982 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
983 }
984 }
985 else if reader.is_close() {
986 path.pop();
987 }
988 else {
989 path.push(reader.prop());
990 state.replace_or_insert_first_node_by_path(0, &path, live_array!{
991 [(track), (reader.value.clone())]
992 });
993 path.pop();
994 }
995 reader.walk();
996 }
997 }
998 self.swap_in_state(state);
999 }
1002
1003 pub fn init_as_needed(&mut self, cx: &mut Cx, index: usize, nodes: &[LiveNode]) {
1004 if self.need_init() {
1005 let mut index = index + 1;
1006 while !nodes[index].is_close() {
1007 let track_id = nodes[index].id;
1008 if let Some(LiveValue::Id(state_id)) = nodes.child_value_by_path(index, &[live_id!(default).as_field()]) {
1009 if let Some(index) = nodes.child_by_name(index, state_id.as_instance()) {
1010 self.cut_to(cx, &[track_id, *state_id], index, nodes);
1011 }
1012 }
1013 index = nodes.skip_node(index);
1014 }
1015 }
1016 }
1017
1018 pub fn animate_to_live(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2]) {
1019 if let Some(live_ptr) = self.live_ptr {
1020 let live_registry_rc = cx.live_registry.clone();
1021 let live_registry = live_registry_rc.borrow();
1022 if live_registry.generation_valid(live_ptr) {
1023 let (nodes, index) = live_registry.ptr_to_nodes_index(live_ptr);
1024
1025 self.init_as_needed(cx, index, nodes);
1026
1027 if let Some(index) = nodes.child_by_path(index, &[state_pair[0].as_instance(), state_pair[1].as_instance()]) {
1028 self.animate_to(cx, state_pair, index, nodes)
1029 }
1030 else if !self.ignore_missing{
1031 error!("animate_to_live {}.{} not found", state_pair[0], state_pair[1])
1032 }
1033 }
1034 else {
1035 error!("animate_to_live generation invalid");
1036 }
1037 }
1038 }
1039
1040 pub fn animate_to(&mut self, cx: &mut Cx, state_pair: &[LiveId; 2], index: usize, nodes: &[LiveNode]) {
1041
1042 if let Some(index) = nodes.child_by_name(index, live_id!(cursor).as_field()) {
1043 let cursor = MouseCursor::new_apply(cx, ApplyFrom::New, index, nodes);
1044 cx.set_cursor(cursor);
1045 }
1046
1047 let mut state = self.swap_out_state();
1048 if state.len() == 0 { panic!();
1052 }
1053
1054 let track = state_pair[0];
1055
1056 let from_id = if let Some(LiveValue::Id(id)) = state.child_value_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(state_id).as_field()]) {
1058 *id
1059 }
1060 else {
1061 cx.apply_error_animate_to_unknown_track(live_error_origin!(), index, nodes, track, state_pair[1]);
1062 return
1063 };
1064
1065 let mut path = Vec::new();
1066
1067 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field()], live_object!{
1068 [track]: {state_id: (state_pair[1]), ended: 0, time: void},
1069 });
1070
1071 if let Some(index) = nodes.child_by_name(index, live_id!(from).as_field()) {
1073 if let Some(index) = nodes.child_by_name(index, from_id.as_field()) {
1074 state.replace_or_insert_last_node_by_path(
1075 0,
1076 &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1077 nodes.node_slice(index)
1078 );
1079 }
1080 else if let Some(index) = nodes.child_by_name(index, live_id!(all).as_field()) {
1081 state.replace_or_insert_last_node_by_path(
1082 0,
1083 &[live_id!(tracks).as_field(), track.as_field(), live_id!(play).as_field()],
1084 nodes.node_slice(index)
1085 );
1086 }
1087 }
1088
1089 if let Some(index) = nodes.child_by_name(index, live_id!(ease).as_field()) {
1091 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(ease).as_field()], nodes.node_slice(index));
1092 }
1093
1094 if let Some(index) = nodes.child_by_name(index, live_id!(redraw).as_field()) {
1095 state.replace_or_insert_last_node_by_path(0, &[live_id!(tracks).as_field(), track.as_field(), live_id!(redraw).as_field()], nodes.node_slice(index));
1096 }
1097
1098 path.push(live_id!(state).as_field());
1099
1100 let mut reader = if let Some(reader) = LiveNodeReader::new(index, nodes).child_by_name(live_id!(apply).as_field()) {
1101 reader
1102 }
1103 else {
1104 cx.apply_animate_missing_apply_block(live_error_origin!(), index, nodes);
1105 return
1106 };
1107 reader.walk();
1108 while !reader.is_eot() {
1109
1110 if reader.is_array() {
1111 path.push(reader.prop());
1112 let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1113 if let Some(last_index) = state.last_child(state_child) {
1114 (state_child + 1, last_index)
1115 }
1116 else {panic!()}
1117 }
1118 else {
1119 cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1120 path.pop();
1121 reader.skip();
1122 continue;
1123 };
1124 if let LiveValue::Id(check_id) = &state[first_index].value {
1126 if *check_id != track {
1127 cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1128 path.pop();
1129 reader.skip();
1130 continue;
1131 }
1132 }
1133 else {
1134 panic!()
1135 }
1136 let first_time = Self::first_keyframe_time_from_array(&reader);
1137
1138 let mut timeline = Vec::new();
1139 timeline.open_array(live_id!(0));
1140 timeline.push_id(live_id!(0), track);
1141 if first_time != 0.0 { timeline.push_live(state.node_slice(last_index));
1143 }
1144 timeline.push_live(reader.children_slice());
1145 timeline.push_live(state.node_slice(last_index));
1146 timeline.close();
1147 state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1148
1149 path.pop();
1150 reader.skip();
1151 }
1152 else {
1153 if reader.is_expr() {
1154 path.push(reader.prop());
1155 state.replace_or_insert_last_node_by_path(0, &path, reader.node_slice());
1156 path.pop();
1157 reader.skip();
1158 continue;
1159 }
1160 if reader.is_open() {
1161 path.push(reader.prop());
1162 }
1163 else if reader.is_close() {
1164 path.pop();
1165 }
1166 else {
1167 path.push(reader.prop());
1168
1169 let (first_index, last_index) = if let Some(state_child) = state.child_by_path(0, &path) {
1170 if let Some(last_index) = state.last_child(state_child) {
1171 (state_child + 1, last_index)
1172 }
1173 else {panic!()}
1174 }
1175 else {
1176 cx.apply_error_animation_missing_state(live_error_origin!(), index, nodes, track, state_pair[1], &path);
1179 path.pop();
1180 reader.skip();
1181 continue;
1182 };
1183 if let LiveValue::Id(check_id) = &state[first_index].value {
1185 if *check_id != track {
1186 cx.apply_error_wrong_animation_track_used(live_error_origin!(), index, nodes, path.last().unwrap().0, *check_id, track);
1187 path.pop();
1188 reader.skip();
1189 continue;
1190 }
1191 }
1192 else {
1193 panic!()
1194 }
1195 let mut timeline = Vec::new();
1196 timeline.open_array(LiveId(0));
1197 timeline.push_live(live_array!{(track)});
1198 timeline.push_live(state.node_slice(last_index));
1199 timeline.push_live(reader.node_slice());
1200 timeline.push_live(state.node_slice(last_index));
1202 timeline.close();
1203 state.replace_or_insert_last_node_by_path(0, &path, &timeline);
1204 path.pop();
1205 }
1206 reader.walk();
1207 }
1208 }
1209
1210 self.swap_in_state(state);
1211
1212 self.next_frame = cx.new_next_frame();
1213 }
1214
1215}