mirror of
https://github.com/unclshura/splitter.git
synced 2026-06-21 16:12:01 +00:00
Back/Forward buttons fixed
This commit is contained in:
parent
f412db219f
commit
2058ae0f7e
@ -1,5 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
@ -68,14 +69,15 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
private readonly object _cacheLock = new();
|
||||
|
||||
private IDisposable? _segmentsSubscription;
|
||||
private bool _isInternalSliderUpdate;
|
||||
private JobViewModel? _currentVm;
|
||||
|
||||
// Interaction state
|
||||
private bool _isPointerCaptured;
|
||||
private Point _lastPointerPoint;
|
||||
private double _lastPointerXForDrag; // used to compute delta for segment drag
|
||||
private DragMode _dragMode = DragMode.None;
|
||||
private int _activeSegmentIndex = -1;
|
||||
private bool _isSplitModifierActive;
|
||||
private bool _isPointerCaptured;
|
||||
private Point _lastPointerPoint;
|
||||
private DragMode _dragMode = DragMode.None;
|
||||
private int _activeSegmentIndex = -1;
|
||||
private bool _isSplitModifierActive;
|
||||
|
||||
// Throttle invalidation during drag
|
||||
private DateTime _lastInvalidate = DateTime.MinValue;
|
||||
@ -83,17 +85,17 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
|
||||
public TimelinePreviewSlider()
|
||||
{
|
||||
Focusable = true;
|
||||
Height = _timelineHeight;
|
||||
Focusable = true;
|
||||
Height = _timelineHeight;
|
||||
ClipToBounds = true;
|
||||
|
||||
// Use property change override instead of GetObservable.Subscribe to avoid IObserver compile issues.
|
||||
PointerPressed += OnPointerPressed;
|
||||
PointerMoved += OnPointerMoved;
|
||||
PointerReleased += OnPointerReleased;
|
||||
PointerPressed += OnPointerPressed;
|
||||
PointerMoved += OnPointerMoved;
|
||||
PointerReleased += OnPointerReleased;
|
||||
PointerCaptureLost += OnPointerCaptureLost;
|
||||
KeyDown += OnKeyDown;
|
||||
KeyUp += OnKeyUp;
|
||||
KeyDown += OnKeyDown;
|
||||
KeyUp += OnKeyUp;
|
||||
}
|
||||
|
||||
// Override to detect ViewModel property changes
|
||||
@ -116,11 +118,24 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
if (vm != null)
|
||||
{
|
||||
_segmentsSubscription = SubscribeToSegments(vm.Segments);
|
||||
vm.PropertyChanged += OnVmPropertyChanged;
|
||||
}
|
||||
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
|
||||
private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(JobViewModel.SliderLiveValue))
|
||||
{
|
||||
if (_isInternalSliderUpdate)
|
||||
return;
|
||||
|
||||
InvalidateVisual();
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable SubscribeToSegments(ObservableCollection<Segment> segments)
|
||||
{
|
||||
NotifyCollectionChangedEventHandler handler = (s, e) =>
|
||||
@ -135,6 +150,11 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
|
||||
private void UnsubscribeFromViewModel()
|
||||
{
|
||||
if (_currentVm != null)
|
||||
_currentVm.PropertyChanged -= OnVmPropertyChanged;
|
||||
|
||||
_currentVm = null;
|
||||
|
||||
_segmentsSubscription?.Dispose();
|
||||
_segmentsSubscription = null;
|
||||
}
|
||||
@ -519,7 +539,6 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
|
||||
var p = e.GetPosition(this);
|
||||
_lastPointerPoint = p;
|
||||
_lastPointerXForDrag = p.X;
|
||||
_isSplitModifierActive = e.KeyModifiers.HasFlag(KeyModifiers.Control);
|
||||
|
||||
var hit = HitTestAtPoint(p);
|
||||
@ -576,7 +595,9 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
break;
|
||||
}
|
||||
|
||||
_isInternalSliderUpdate = true;
|
||||
vm.SliderLiveValue = sec;
|
||||
_isInternalSliderUpdate = false;
|
||||
|
||||
ThrottledInvalidate();
|
||||
_lastPointerPoint = p;
|
||||
@ -665,7 +686,6 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
_dragMode = mode;
|
||||
_activeSegmentIndex = segmentIndex;
|
||||
_lastPointerPoint = e.GetPosition(this);
|
||||
_lastPointerXForDrag = _lastPointerPoint.X;
|
||||
}
|
||||
|
||||
private void ThrottledInvalidate()
|
||||
@ -681,10 +701,16 @@ public class TimelinePreviewSlider : Control, IDisposable
|
||||
private void SetPlayheadFromPoint(Point p)
|
||||
{
|
||||
var vm = ViewModel;
|
||||
if (vm == null) return;
|
||||
var sec = PixelToSeconds(p.X);
|
||||
if (vm == null)
|
||||
return;
|
||||
|
||||
double sec = PixelToSeconds(p.X);
|
||||
sec = Math.Max(0, Math.Min(vm.DurationSeconds, sec));
|
||||
|
||||
_isInternalSliderUpdate = true;
|
||||
vm.SliderLiveValue = sec;
|
||||
_isInternalSliderUpdate = false;
|
||||
|
||||
InvalidateVisual();
|
||||
}
|
||||
|
||||
|
||||
@ -462,26 +462,48 @@ public partial class JobViewModel : ObservableObject
|
||||
|
||||
private void StepForward()
|
||||
{
|
||||
if (DurationSeconds <= 0)
|
||||
if (Segments.Count <= 1)
|
||||
return;
|
||||
|
||||
var duration = SegmentDuration;
|
||||
var segment = Math.Round(SliderLiveValue / duration, MidpointRounding.ToZero)+1;
|
||||
var current = GetCurrentSegment();
|
||||
if ( current < 0 || current >= Segments.Count - 1 )
|
||||
return;
|
||||
|
||||
SliderLiveValue = Math.Min(DurationSeconds - duration, segment * duration);
|
||||
// trigger seek in your playback pipeline here
|
||||
SliderLiveValue = Segments[current + 1].Start;
|
||||
}
|
||||
|
||||
private void StepBackward()
|
||||
{
|
||||
if (DurationSeconds <= 0)
|
||||
if (Segments.Count <= 0)
|
||||
return;
|
||||
|
||||
var duration = SegmentDuration;
|
||||
var segment = Math.Max(0, Math.Round(SliderLiveValue / duration, MidpointRounding.ToZero)-1);
|
||||
var current = GetCurrentSegment();
|
||||
if (current <= 0)
|
||||
{
|
||||
SliderLiveValue = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
SliderLiveValue = segment * duration;
|
||||
// trigger seek in your playback pipeline here
|
||||
if (SliderLiveValue > Segments[current].Start)
|
||||
SliderLiveValue = Segments[current].Start;
|
||||
else
|
||||
SliderLiveValue = Segments[current - 1].Start;
|
||||
}
|
||||
|
||||
private int GetCurrentSegment()
|
||||
{
|
||||
double pos = SliderLiveValue;
|
||||
|
||||
for (int i = 0; i < Segments.Count; i++)
|
||||
{
|
||||
var s = Segments[i];
|
||||
if (pos < s.Start)
|
||||
return i - 1;
|
||||
if (pos == s.Start)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
partial void OnSliderLiveValueChanged(double value)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user