1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Timeline - Added snapping/rounding when resizing segments

This commit is contained in:
Robert 2022-07-26 19:17:02 +02:00
parent 2872712d66
commit 92ad3eea92
4 changed files with 28 additions and 16 deletions

View File

@ -36,7 +36,7 @@ public class EndSegmentView : ReactiveUserControl<EndSegmentViewModel>
{ {
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; 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) private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
@ -44,6 +44,6 @@ public class EndSegmentView : ReactiveUserControl<EndSegmentViewModel>
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; return;
e.Pointer.Capture(null); 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));
} }
} }

View File

@ -36,7 +36,7 @@ public class MainSegmentView : ReactiveUserControl<MainSegmentViewModel>
{ {
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; 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) private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
@ -44,7 +44,7 @@ public class MainSegmentView : ReactiveUserControl<MainSegmentViewModel>
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; return;
e.Pointer.Capture(null); 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) private void KeyframeDragStartAnchor_OnPointerPressed(object? sender, PointerPressedEventArgs e)

View File

@ -36,7 +36,7 @@ public class StartSegmentView : ReactiveUserControl<StartSegmentViewModel>
{ {
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; 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) private void KeyframeDragAnchor_OnPointerReleased(object? sender, PointerReleasedEventArgs e)
@ -44,6 +44,6 @@ public class StartSegmentView : ReactiveUserControl<StartSegmentViewModel>
if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor)) if (ViewModel == null || !ReferenceEquals(e.Pointer.Captured, _keyframeDragAnchor))
return; return;
e.Pointer.Capture(null); 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));
} }
} }

View File

@ -105,25 +105,25 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase
_initialLength = Length; _initialLength = Length;
} }
public void UpdateResize(double x) public void UpdateResize(double x, bool snap, bool round)
{ {
if (_profileElement == null) if (_profileElement == null)
return; return;
TimeSpan difference = GetTimeFromX(x) - Length; TimeSpan difference = GetTimeFromX(x, snap, round) - Length;
List<ILayerPropertyKeyframe> keyframes = _profileElement.GetAllLayerProperties().SelectMany(p => p.UntypedKeyframes).ToList(); List<ILayerPropertyKeyframe> keyframes = _profileElement.GetAllLayerProperties().SelectMany(p => p.UntypedKeyframes).ToList();
ShiftKeyframes(keyframes.Where(k => k.Position > End.Add(difference)), difference); 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) if (_profileElement == null)
return; return;
using ProfileEditorCommandScope scope = _profileEditorService.CreateCommandScope("Resize segment"); using ProfileEditorCommandScope scope = _profileEditorService.CreateCommandScope("Resize segment");
ApplyPendingKeyframeMovement(); ApplyPendingKeyframeMovement();
_profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, GetTimeFromX(x), _initialLength)); _profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, GetTimeFromX(x, snap, round), _initialLength));
} }
public void RemoveSegment() public void RemoveSegment()
@ -148,12 +148,18 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase
_profileEditorService.ExecuteCommand(new ResizeTimelineSegment(Type, _profileElement, TimeSpan.Zero)); _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); TimeSpan time = TimeSpan.FromSeconds(x / _pixelsPerSecond);
if (length < TimeSpan.Zero) if (time < TimeSpan.Zero)
length = TimeSpan.Zero; time = TimeSpan.Zero;
return length;
if (round)
time = _profileEditorService.RoundTime(time);
if (snap)
time = SnapToTimeline(time);
return time;
} }
protected void ShiftKeyframes(IEnumerable<ILayerPropertyKeyframe> keyframes, TimeSpan amount) protected void ShiftKeyframes(IEnumerable<ILayerPropertyKeyframe> keyframes, TimeSpan amount)
@ -173,4 +179,10 @@ public abstract class TimelineSegmentViewModel : ActivatableViewModelBase
_originalKeyframePositions.Clear(); _originalKeyframePositions.Clear();
} }
private TimeSpan SnapToTimeline(TimeSpan time)
{
TimeSpan tolerance = TimeSpan.FromMilliseconds(1000f / _pixelsPerSecond * 5);
return _profileEditorService.SnapToTimeline(time, tolerance, false, true);
}
} }