Ejemplo n.º 1
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();
            }
        }
Ejemplo n.º 2
0
 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));
         }
     }
Ejemplo n.º 3
0
        public IEnumerator <object> Task()
        {
            while (true)
            {
                if (!TimelineUserPreferences.Instance.AnimationStretchMode)
                {
                    yield return(null);

                    continue;
                }
                var boundaries = GridSelection.GetSelectionBoundaries();
                if (boundaries == null || boundaries.Value.Right - boundaries.Value.Left < 2)
                {
                    yield return(null);

                    continue;
                }
                var topLeft       = grid.CellToGridCoordinates(boundaries.Value.Top, boundaries.Value.Left);
                var bottomRight   = grid.CellToGridCoordinates(boundaries.Value.Bottom + 1, boundaries.Value.Right);
                var mousePosition = grid.ContentWidget.LocalMousePosition();
                if (mousePosition.Y < topLeft.Y || mousePosition.Y > bottomRight.Y)
                {
                    yield return(null);

                    continue;
                }
                if (mousePosition.X - topLeft.X < 0 && mousePosition.X - topLeft.X > -10)
                {
                    Utils.ChangeCursorIfDefault(MouseCursor.SizeWE);
                    if (input.ConsumeKeyPress(Key.Mouse0))
                    {
                        yield return(Drag(boundaries.Value, DragSide.Left));
                    }
                }
                else if (mousePosition.X - bottomRight.X > 0 && mousePosition.X - bottomRight.X < 10)
                {
                    Utils.ChangeCursorIfDefault(MouseCursor.SizeWE);
                    if (input.ConsumeKeyPress(Key.Mouse0))
                    {
                        yield return(Drag(boundaries.Value, DragSide.Right));
                    }
                }
                yield return(null);
            }
        }
        private void Save(IntRectangle boundaries)
        {
            savedPositions.Clear();
            savedKeyframes.Clear();
            savedMarkerPositions.Clear();
            savedMarkers.Clear();
            var length = boundaries.Right - boundaries.Left - 1;

            foreach (var animable in GridSelection.EnumerateAnimators(boundaries))
            {
                foreach (var animator in animable.Animators)
                {
                    if (animator.AnimationId != Document.Current.AnimationId)
                    {
                        continue;
                    }
                    savedKeyframes.Add(animator, new List <IKeyframe>());
                    var keys = animator.Keys.Where(k =>
                                                   boundaries.Left <= k.Frame &&
                                                   k.Frame < boundaries.Right
                                                   );
                    foreach (var key in keys)
                    {
                        savedPositions.Add(key, ((double)key.Frame - boundaries.Left) / length);
                        savedKeyframes[animator].Add(key);
                    }
                }
            }
            var markers = Document.Current.Animation.Markers.Where(k =>
                                                                   boundaries.Left <= k.Frame &&
                                                                   k.Frame < boundaries.Right);

            foreach (var marker in markers)
            {
                savedMarkerPositions.Add(marker, ((double)marker.Frame - boundaries.Left) / length);
                savedMarkers.Add(marker);
            }
        }
Ejemplo n.º 5
0
            public void Show()
            {
                var menu            = new Menu();
                var frameUnderMouse = Timeline.Instance.Grid.CellUnderMouse().X;
                var marker          = Document.Current.Animation.Markers.GetByFrame(frameUnderMouse);

                menu.Add(new Command(marker == null ? "Add Marker" : "Edit Marker", () => ShowMarkerDialog(frameUnderMouse)));
                menu.Add(new Command("Copy Marker", () => CopyMarker(marker))
                {
                    Enabled = marker != null
                });
                menu.Add(new Command("Paste Marker", () => PasteMarker(frameUnderMouse))
                {
                    Enabled = CanParseMarkerFromClipboard()
                });
                menu.Add(new Command("Delete Marker", () => DeleteMarker(marker))
                {
                    Enabled = marker != null
                });
                menu.Add(Command.MenuSeparator);
                menu.Add(new Command(TimelineCommands.CopyMarkers.Text, CopyMarkers)
                {
                    Enabled = Document.Current.Animation.Markers.Count > 0
                });
                menu.Add(new Command(TimelineCommands.PasteMarkers.Text, PasteMarkers)
                {
                    Enabled = CanParseMarkersFromClipboard()
                });
                menu.Add(new Command(TimelineCommands.DeleteMarkers.Text, DeleteMarkers)
                {
                    Enabled = Document.Current.Animation.Markers.Count > 0
                });
                menu.Add(new Command(TimelineCommands.DeleteMarkersInRange.Text, DeleteMarkersInRange)
                {
                    Enabled = GridSelection.GetSelectionBoundaries(out _) && Document.Current.Animation.Markers.Count > 0
                });
                menu.Popup();
            }
        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);
                }
            }
        }