From 92ad3eea9216ce2ba5b37f60190b6e758404948a Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Jul 2022 19:17:02 +0200 Subject: [PATCH] Timeline - Added snapping/rounding when resizing segments --- .../Timeline/Segments/EndSegmentView.axaml.cs | 4 +-- .../Segments/MainSegmentView.axaml.cs | 4 +-- .../Segments/StartSegmentView.axaml.cs | 4 +-- .../Segments/TimelineSegmentViewModel.cs | 32 +++++++++++++------ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml.cs index 1560dc8fe..17ec9c101 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/EndSegmentView.axaml.cs @@ -36,7 +36,7 @@ public class EndSegmentView : ReactiveUserControl { if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; - ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) @@ -44,6 +44,6 @@ public class EndSegmentView : ReactiveUserControl if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; e.Pointer.Capture(null); - ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs index c138bc0f9..8c09b98dc 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/MainSegmentView.axaml.cs @@ -36,7 +36,7 @@ public class MainSegmentView : ReactiveUserControl { if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; - ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) @@ -44,7 +44,7 @@ public class MainSegmentView : ReactiveUserControl if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; e.Pointer.Capture(null); - ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragStartAnchor_OnPointerPressed(object? sender, PointerPressedEventArgs e) diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs index 308d30f8f..9876e5c6c 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/StartSegmentView.axaml.cs @@ -36,7 +36,7 @@ public class StartSegmentView : ReactiveUserControl { if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; - ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.UpdateResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e) @@ -44,6 +44,6 @@ public class StartSegmentView : ReactiveUserControl if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) return; e.Pointer.Capture(null); - ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset); + ViewModel.FinishResize(e.GetCurrentPoint(this).Position.X + _dragOffset, e.KeyModifiers.HasFlag(KeyModifiers.Shift), e.KeyModifiers.HasFlag(KeyModifiers.Control)); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs index 4f9a1a422..92e9154f4 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/Panels/Properties/Timeline/Segments/TimelineSegmentViewModel.cs @@ -105,25 +105,25 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase _initialLength = Length; } - public void UpdateResize(double x) + public void UpdateResize(double x, bool snap, bool round) { if (_profileElement == null) return; - TimeSpan difference = GetTimeFromX(x) - Length; + TimeSpan difference = GetTimeFromX(x, snap, round) - Length; List keyframes = _profileElement.GetAllLayerProperties().SelectMany(p => p.UntypedKeyframes).ToList(); ShiftKeyframes(keyframes.Where(k => k.Position > End.Add(difference)), difference); - Length = GetTimeFromX(x); + Length = GetTimeFromX(x, snap, round); } - public void FinishResize(double x) + public void FinishResize(double x, bool snap, bool round) { if (_profileElement == null) return; using ProfileEditorCommandScope scope = _profileEditorService.CreateCommandScope("Resize segment"); ApplyPendingKeyframeMovement(); - _profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, GetTimeFromX(x), _initialLength)); + _profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, GetTimeFromX(x, snap, round), _initialLength)); } public void RemoveSegment() @@ -148,12 +148,18 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase _profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, TimeSpan.Zero)); } - protected TimeSpan GetTimeFromX(double x) + protected TimeSpan GetTimeFromX(double x, bool snap, bool round) { - TimeSpan length = TimeSpan.FromSeconds(x / _pixelsPerSecond); - if (length < TimeSpan.Zero) - length = TimeSpan.Zero; - return length; + TimeSpan time = TimeSpan.FromSeconds(x / _pixelsPerSecond); + if (time < TimeSpan.Zero) + time = TimeSpan.Zero; + + if (round) + time = _profileEditorService.RoundTime(time); + if (snap) + time = SnapToTimeline(time); + + return time; } protected void ShiftKeyframes(IEnumerable keyframes, TimeSpan amount) @@ -173,4 +179,10 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase _originalKeyframePositions.Clear(); } + + private TimeSpan SnapToTimeline(TimeSpan time) + { + TimeSpan tolerance = TimeSpan.FromMilliseconds(1000f / _pixelsPerSecond * 5); + return _profileEditorService.SnapToTimeline(time, tolerance, false, true); + } } \ No newline at end of file