private IEnumerator <object> Drag(Boundaries boundaries, DragSide side) { IntVector2?last = null; Save(boundaries); bool isStretchingMarkers = input.IsKeyPressed(Key.Control); using (Document.Current.History.BeginTransaction()) { while (input.IsMousePressed()) { Utils.ChangeCursorIfDefault(MouseCursor.SizeWE); var current = grid.CellUnderMouse(); if (current == last) { yield return(null); continue; } Document.Current.History.RollbackTransaction(); current.X = Math.Max(current.X, 0); if (side == DragSide.Left) { current.X = Math.Min(current.X, boundaries.Right - 1); } else { current.X = Math.Max(current.X, boundaries.Left + 1); } Stretch(boundaries, side, current.X, stretchMarkers: isStretchingMarkers); if (side == DragSide.Left) { boundaries.Left = current.X; } else { boundaries.Right = current.X; } ClearGridSelection.Perform(); for (int i = boundaries.Top; i <= boundaries.Bottom; ++i) { SelectGridSpan.Perform(i, boundaries.Left, boundaries.Right); } SetCurrentColumn.Perform(boundaries.Right); last = current; yield return(null); } Document.Current.History.CommitTransaction(); } yield return(null); }
private void Save(Boundaries boundaries) { savedPositions.Clear(); savedKeyframes.Clear(); savedMarkerPositions.Clear(); savedMarkers.Clear(); var length = 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) { 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.Container.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); } }
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); } } }