Example #1
0
 public static void Perform()
 {
     Document.Current.History.DoTransaction(() => {
         foreach (var row in Document.Current.SelectedRows())
         {
             var spans = row.Components.Get <GridSpanListComponent>()?.Spans;
             if (spans == null)
             {
                 continue;
             }
             var node = row.Components.Get <NodeRow>()?.Node;
             if (node.EditorState().Locked)
             {
                 continue;
             }
             var animable = (IAnimationHost)node;
             if (animable == null)
             {
                 continue;
             }
             foreach (var animator in animable.Animators.ToList())
             {
                 if (animator.AnimationId != Document.Current.AnimationId)
                 {
                     continue;
                 }
                 foreach (var keyframe in animator.Keys.Where(i => spans.Any(j => j.Contains(i.Frame))).ToList())
                 {
                     RemoveKeyframe.Perform(animator, keyframe.Frame);
                 }
             }
         }
     });
 }
Example #2
0
        private void ScaleKeyframes()
        {
            var boundaries = GridSelection.GetSelectionBoundaries();

            if (boundaries.HasValue || Scale < Mathf.ZeroTolerance)
            {
                var saved = new List <IKeyframe>();
                for (int i = boundaries.Value.Top; i <= boundaries.Value.Bottom; ++i)
                {
                    if (!(Document.Current.Rows[i].Components.Get <NodeRow>()?.Node is IAnimationHost animable))
                    {
                        continue;
                    }
                    foreach (var animator in animable.Animators.ToList())
                    {
                        saved.Clear();
                        IEnumerable <IKeyframe> keys = animator.ReadonlyKeys.Where(k =>
                                                                                   k.Frame >= boundaries.Value.Left && k.Frame < boundaries.Value.Right
                                                                                   ).ToList();
                        if (Scale < 1)
                        {
                            keys = keys.Reverse().ToList();
                        }
                        foreach (var key in keys)
                        {
                            saved.Add(key);
                            RemoveKeyframe.Perform(animator, key.Frame);
                        }
                        foreach (var key in saved)
                        {
                            // The formula should behave similiar to stretching animation with mouse
                            int newFrame = (int)(
                                boundaries.Value.Left +
                                (key.Frame - boundaries.Value.Left) *
                                (1 + (boundaries.Value.Left - boundaries.Value.Right) * Scale) /
                                (1 + boundaries.Value.Left - boundaries.Value.Right)
                                );
                            var newKey = key.Clone();
                            newKey.Frame = newFrame;
                            SetAnimableProperty.Perform(
                                animable, animator.TargetPropertyPath, newKey.Value,
                                createAnimatorIfNeeded: true,
                                createInitialKeyframeForNewAnimator: false,
                                newKey.Frame
                                );
                            SetKeyframe.Perform(animable, animator.TargetPropertyPath, Document.Current.AnimationId, newKey);
                        }
                    }
                }
                ClearGridSelection.Perform();
                for (int i = boundaries.Value.Top; i <= boundaries.Value.Bottom; ++i)
                {
                    SelectGridSpan.Perform(i, boundaries.Value.Left, (int)(boundaries.Value.Left + (boundaries.Value.Right - boundaries.Value.Left) * Scale));
                }
            }
            else
            {
                Document.Current.History.RollbackTransaction();
            }
        }
Example #3
0
        public static void Perform()
        {
            var Boundaries = GetSelectionBoundaries();

            if (Boundaries == null)
            {
                AlertDialog.Show("Can't invert animation in a non-rectangular selection. The selection must be a single rectangle.");
                return;
            }
            using (Document.Current.History.BeginTransaction()) {
                for (int i = Boundaries.Value.Top; i <= Boundaries.Value.Bottom; ++i)
                {
                    if (!(Document.Current.Rows[i].Components.Get <NodeRow>()?.Node is IAnimationHost animable))
                    {
                        continue;
                    }
                    foreach (var animator in animable.Animators.ToList())
                    {
                        var saved = animator.Keys.Where(k =>
                                                        Boundaries.Value.Left <= k.Frame &&
                                                        k.Frame < Boundaries.Value.Right).ToList();
                        foreach (var key in saved)
                        {
                            RemoveKeyframe.Perform(animator, key.Frame);
                        }
                        foreach (var key in saved)
                        {
                            SetProperty.Perform(key, nameof(IKeyframe.Frame), Boundaries.Value.Left + Boundaries.Value.Right - key.Frame - 1);
                            SetKeyframe.Perform(animable, animator.TargetPropertyPath, animator.AnimationId, key);
                        }
                    }
                }
                Document.Current.History.CommitTransaction();
            }
        }
Example #4
0
        public static void Perform(IntVector2 offset, bool removeOriginals)
        {
            var rows = Document.Current.Rows.ToList();

            if (offset.Y > 0)
            {
                rows.Reverse();
            }
            foreach (var row in rows)
            {
                var track = row.Components.Get <AnimationTrackRow>()?.Track;
                if (track?.EditorState().Locked != false)
                {
                    continue;
                }
                var clips = track.Clips.Where(i => i.IsSelected).ToList();
                var keys  = new List <IKeyframe>();
                if (track.Animators.TryFind(nameof(AnimationTrack.Weight), out var weightAnimator, Document.Current.AnimationId))
                {
                    keys = weightAnimator.ReadonlyKeys.Where(k => clips.Any(c => c.BeginFrame <= k.Frame && k.Frame <= c.EndFrame)).ToList();
                }
                if (removeOriginals)
                {
                    foreach (var key in keys)
                    {
                        RemoveKeyframe.Perform(weightAnimator, key.Frame);
                    }
                }
                foreach (var clip in clips)
                {
                    if (removeOriginals)
                    {
                        AnimationClipToolbox.RemoveClip(track, clip);
                    }
                    else
                    {
                        SetProperty.Perform(clip, nameof(AnimationClip.IsSelected), false);
                    }
                }
                int numRows   = Document.Current.Rows.Count;
                var destRow   = Document.Current.Rows[(row.Index + offset.Y).Clamp(0, numRows - 1)];
                var destTrack = destRow.Components.Get <AnimationTrackRow>()?.Track;
                foreach (var clip in clips)
                {
                    var newClip = clip.Clone();
                    newClip.BeginFrame += offset.X;
                    newClip.EndFrame   += offset.X;
                    newClip.IsSelected  = true;
                    AnimationClipToolbox.InsertClip(destTrack, newClip);
                }
                foreach (var k in keys)
                {
                    var key = k.Clone();
                    key.Frame += offset.X;
                    SetKeyframe.Perform(destTrack, nameof(AnimationTrack.Weight), Document.Current.AnimationId, key);
                }
            }
        }
 private void ScaleKeyframes()
 {
     if (GridSelection.GetSelectionBoundaries(out var boundaries) && Scale > Mathf.ZeroTolerance)
     {
         var processed = new HashSet <IAnimator>();
         var saved     = new List <IKeyframe>();
         foreach (var animable in GridSelection.EnumerateAnimators(boundaries))
         {
             foreach (var animator in animable.Animators)
             {
                 if (animator.AnimationId != Document.Current.AnimationId || processed.Contains(animator))
                 {
                     continue;
                 }
                 processed.Add(animator);
                 saved.Clear();
                 IEnumerable <IKeyframe> keys = animator.ReadonlyKeys.Where(k =>
                                                                            k.Frame >= boundaries.Left && k.Frame < boundaries.Right
                                                                            ).ToList();
                 if (Scale < 1)
                 {
                     keys = keys.Reverse().ToList();
                 }
                 foreach (var key in keys)
                 {
                     saved.Add(key);
                     RemoveKeyframe.Perform(animator, key.Frame);
                 }
                 foreach (var key in saved)
                 {
                     // The formula should behave similiar to stretching animation with mouse
                     int newFrame = (int)(
                         boundaries.Left +
                         (key.Frame - boundaries.Left) *
                         (1 + (boundaries.Left - boundaries.Right) * Scale) /
                         (1 + boundaries.Left - boundaries.Right)
                         );
                     var newKey = key.Clone();
                     newKey.Frame = newFrame;
                     SetAnimableProperty.Perform(
                         animable.Host, animator.TargetPropertyPath, newKey.Value,
                         createAnimatorIfNeeded: true,
                         createInitialKeyframeForNewAnimator: false,
                         newKey.Frame
                         );
                     SetKeyframe.Perform(animable.Host, animator.TargetPropertyPath, Document.Current.AnimationId, newKey);
                 }
             }
         }
         ClearGridSelection.Perform();
         for (int i = boundaries.Top; i <= boundaries.Bottom; ++i)
         {
             SelectGridSpan.Perform(i, boundaries.Left, (int)(boundaries.Left + (boundaries.Right - boundaries.Left) * Scale));
         }
     }
Example #6
0
 public static void Perform()
 {
     Document.Current.History.DoTransaction(() => {
         foreach (var track in Document.Current.Animation.Tracks)
         {
             var clips = track.Clips.Where(i => i.IsSelected).ToList();
             var keys  = new List <IKeyframe>();
             if (track.Animators.TryFind(nameof(AnimationTrack.Weight), out var weightAnimator, Document.Current.AnimationId))
             {
                 keys = weightAnimator.ReadonlyKeys.Where(k => clips.Any(c => c.BeginFrame <= k.Frame && k.Frame <= c.EndFrame)).ToList();
             }
             foreach (var key in keys)
             {
                 RemoveKeyframe.Perform(weightAnimator, key.Frame);
             }
             foreach (var clip in clips)
             {
                 AnimationClipToolbox.RemoveClip(track, clip);
             }
         }
     });
 }
        private void Stretch(IntRectangle boundaries, DragSide side, int newPos, bool stretchMarkers)
        {
            int length;

            if (side == DragSide.Left)
            {
                length = boundaries.Right - newPos - 1;
            }
            else
            {
                length = newPos - boundaries.Left - 1;
            }
            int oldLength = boundaries.Right - boundaries.Left - 1;
            var processed = new HashSet <IAnimator>();

            foreach (var animable in GridSelection.EnumerateAnimators(boundaries))
            {
                foreach (var animator in animable.Animators)
                {
                    if (animator.AnimationId != Document.Current.AnimationId || processed.Contains(animator) || !savedKeyframes.ContainsKey(animator))
                    {
                        continue;
                    }
                    processed.Add(animator);
                    IEnumerable <IKeyframe> saved = savedKeyframes[animator];
                    if (
                        side == DragSide.Left && length < oldLength ||
                        side == DragSide.Right && length > oldLength
                        )
                    {
                        saved = saved.Reverse();
                    }
                    foreach (var key in saved)
                    {
                        RemoveKeyframe.Perform(animator, key.Frame);
                    }
                    foreach (var key in saved)
                    {
                        double relpos = savedPositions[key];
                        int    newFrame;
                        if (side == DragSide.Left)
                        {
                            newFrame = (int)Math.Round(newPos + relpos * length);
                        }
                        else
                        {
                            newFrame = (int)Math.Round(boundaries.Left + relpos * length);
                        }
                        var newKey = key.Clone();
                        newKey.Frame = newFrame;
                        SetAnimableProperty.Perform(
                            animable.Host, animator.TargetPropertyPath, newKey.Value,
                            createAnimatorIfNeeded: true,
                            createInitialKeyframeForNewAnimator: false,
                            newKey.Frame
                            );
                        SetKeyframe.Perform(animable.Host, animator.TargetPropertyPath, Document.Current.AnimationId, newKey);
                    }
                }
            }
            if (stretchMarkers)
            {
                foreach (var marker in savedMarkers)
                {
                    DeleteMarker.Perform(marker, removeDependencies: false);
                }
                foreach (var marker in savedMarkers)
                {
                    double relpos = savedMarkerPositions[marker];
                    int    newFrame;
                    if (side == DragSide.Left)
                    {
                        newFrame = (int)Math.Round(newPos + relpos * length);
                    }
                    else
                    {
                        newFrame = (int)Math.Round(boundaries.Left + relpos * length);
                    }
                    var newMarker = marker.Clone();
                    newMarker.Frame = newFrame;
                    SetMarker.Perform(newMarker, removeDependencies: false);
                }
            }
        }
Example #8
0
        public static void Perform(IntVector2 offset, bool removeOriginals)
        {
            var processedKeys = new HashSet <IKeyframe>();
            var operations    = new List <Action>();

            foreach (var row in Document.Current.Rows)
            {
                var spans = row.Components.GetOrAdd <GridSpanListComponent>().Spans.GetNonOverlappedSpans(offset.X > 0);
                foreach (var span in spans)
                {
                    var node = row.Components.Get <NodeRow>()?.Node ?? row.Components.Get <PropertyRow>()?.Node;
                    if (node == null)
                    {
                        continue;
                    }
                    var property = row.Components.Get <PropertyRow>()?.Animator.TargetPropertyPath;
                    foreach (var a in node.Animators.ToList())
                    {
                        if (property != null && a.TargetPropertyPath != property)
                        {
                            continue;
                        }
                        IEnumerable <IKeyframe> keysEnumerable = a.Keys.Where(k => k.Frame >= span.A && k.Frame < span.B);
                        if (offset.X > 0)
                        {
                            keysEnumerable = keysEnumerable.Reverse();
                        }
                        foreach (var k in keysEnumerable)
                        {
                            if (processedKeys.Contains(k))
                            {
                                continue;
                            }
                            processedKeys.Add(k);
                            var destRow = row.Index + offset.Y;
                            if (!CheckRowRange(destRow))
                            {
                                continue;
                            }
                            var destRowComponents = Document.Current.Rows[destRow].Components;
                            var destNode          = destRowComponents.Get <NodeRow>()?.Node ?? destRowComponents.Get <PropertyRow>()?.Node;
                            if (destNode == null || !ArePropertiesCompatible(node, destNode, a.TargetPropertyPath))
                            {
                                continue;
                            }
                            if (k.Frame + offset.X >= 0)
                            {
                                var k1 = k.Clone();
                                k1.Frame += offset.X;
                                // The same logic is used to create keyframes as everywhere, but extended by setting
                                // all parameters from a particular keyframe. Yes, this creates some overhead.
                                operations.Add(() => SetAnimableProperty.Perform(destNode, a.TargetPropertyPath, k1.Value, true, false, k1.Frame));
                                operations.Add(() => SetKeyframe.Perform(destNode, a.TargetPropertyPath, Document.Current.AnimationId, k1));
                            }
                            // Order is importent. RemoveKeyframe must be after SetKeyframe,
                            // to prevent animator clean up if all keys were removed.
                            if (removeOriginals)
                            {
                                operations.Add(() => RemoveKeyframe.Perform(a, k.Frame));
                            }
                        }
                    }
                }
            }
            foreach (var o in operations)
            {
                o();
            }
        }
        private void Stretch(Boundaries boundaries, DragSide side, int newPos, bool stretchMarkers)
        {
            int length;

            if (side == DragSide.Left)
            {
                length = boundaries.Right - newPos - 1;
            }
            else
            {
                length = newPos - boundaries.Left - 1;
            }
            int oldLength = boundaries.Right - boundaries.Left - 1;

            for (int i = boundaries.Top; i <= boundaries.Bottom; ++i)
            {
                if (!(Document.Current.Rows[i].Components.Get <NodeRow>()?.Node is IAnimationHost animable))
                {
                    continue;
                }
                foreach (var animator in animable.Animators.ToList())
                {
                    IEnumerable <IKeyframe> saved = savedKeyframes[animator];
                    if (
                        side == DragSide.Left && length < oldLength ||
                        side == DragSide.Right && length > oldLength
                        )
                    {
                        saved = saved.Reverse();
                    }
                    foreach (var key in saved)
                    {
                        RemoveKeyframe.Perform(animator, key.Frame);
                    }
                    foreach (var key in saved)
                    {
                        double relpos = savedPositions[key];
                        int    newFrame;
                        if (side == DragSide.Left)
                        {
                            newFrame = (int)Math.Round(newPos + relpos * length);
                        }
                        else
                        {
                            newFrame = (int)Math.Round(boundaries.Left + relpos * length);
                        }
                        var newKey = key.Clone();
                        newKey.Frame = newFrame;
                        SetAnimableProperty.Perform(
                            animable, animator.TargetPropertyPath, newKey.Value,
                            createAnimatorIfNeeded: true,
                            createInitialKeyframeForNewAnimator: false,
                            newKey.Frame
                            );
                        SetKeyframe.Perform(animable, animator.TargetPropertyPath, Document.Current.AnimationId, newKey);
                    }
                }
            }
            if (stretchMarkers)
            {
                foreach (var marker in savedMarkers)
                {
                    DeleteMarker.Perform(Document.Current.Container, marker, removeDependencies: false);
                }
                foreach (var marker in savedMarkers)
                {
                    double relpos = savedMarkerPositions[marker];
                    int    newFrame;
                    if (side == DragSide.Left)
                    {
                        newFrame = (int)Math.Round(newPos + relpos * length);
                    }
                    else
                    {
                        newFrame = (int)Math.Round(boundaries.Left + relpos * length);
                    }
                    var newMarker = marker.Clone();
                    newMarker.Frame = newFrame;
                    SetMarker.Perform(Document.Current.Container, newMarker, removeDependencies: false);
                }
            }
        }