Skip to content

Commit

Permalink
Fix slider bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Razmoth committed Dec 7, 2023
1 parent b28d86b commit f0f322c
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 19 deletions.
99 changes: 99 additions & 0 deletions Audio/Controls/PlaybackSlider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Utilities;
using System;

namespace Audio.Controls;
internal class PlaybackSlider : Slider
{
public static readonly DirectProperty<PlaybackSlider, double> TimeProperty = AvaloniaProperty.RegisterDirect<PlaybackSlider, double>(nameof(Time), o => o.Time, (o, v) => o.Time = v, defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);
public static readonly DirectProperty<PlaybackSlider, bool> IsSeekingProperty = AvaloniaProperty.RegisterDirect<PlaybackSlider, bool>(nameof(IsSeeking), o => o.IsSeeking, (o, v) => o.IsSeeking = v, defaultBindingMode: Avalonia.Data.BindingMode.TwoWay);

private double _time;
private bool _isSeeking;
private RepeatButton _decreaseButton;
private RepeatButton _increaseButton;
private Track _track;
public bool IsSeeking
{
get => _isSeeking;
set => SetAndRaise(IsSeekingProperty, ref _isSeeking, value);
}
public double Time
{
get => _time;
set => SetAndRaise(TimeProperty, ref _time, value);
}
protected override Type StyleKeyOverride => typeof(Slider);
static PlaybackSlider()
{
Thumb.DragDeltaEvent.AddClassHandler<PlaybackSlider>((x, e) => x.OnThumbDragStarted(e), RoutingStrategies.Bubble);
Thumb.DragCompletedEvent.AddClassHandler<PlaybackSlider>((x, e) => x.OnThumbDragCompleted(e), RoutingStrategies.Bubble);
}
protected override void OnThumbDragStarted(VectorEventArgs e)
{
IsSeeking = true;
}
protected override void OnThumbDragCompleted(VectorEventArgs e)
{
IsSeeking = false;
Time = Value;
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_track = e.NameScope.Find<Track>("PART_Track");
_decreaseButton = e.NameScope.Find("PART_DecreaseButton") as RepeatButton;
_increaseButton = e.NameScope.Find("PART_IncreaseButton") as RepeatButton;

if (_decreaseButton != null)
{
_decreaseButton.AddHandler(PointerPressedEvent, TrackPressed, RoutingStrategies.Tunnel);
_decreaseButton.AddHandler(PointerReleasedEvent, TrackReleased, RoutingStrategies.Tunnel);
}

if (_increaseButton != null)
{
_increaseButton.AddHandler(PointerPressedEvent, TrackPressed, RoutingStrategies.Tunnel);
_increaseButton.AddHandler(PointerReleasedEvent, TrackReleased, RoutingStrategies.Tunnel);
}

AddHandler(PointerMovedEvent, TrackMoved, RoutingStrategies.Tunnel);
}
private void TrackPressed(object? sender, PointerPressedEventArgs e)
{
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
{
MoveToPoint(e.GetCurrentPoint(_track));
IsSeeking = true;
}
}
private void TrackReleased(object? sender, PointerReleasedEventArgs e)
{
IsSeeking = false;
Time = Value;
}
private void TrackMoved(object? sender, PointerEventArgs e)
{
if (IsSeeking)
{
MoveToPoint(e.GetCurrentPoint(_track));
}
}
private void MoveToPoint(PointerPoint posOnTrack)
{
if (_track is null)
return;

var thumbLength = _track.Thumb?.Bounds.Width ?? 0.0 + double.Epsilon;
var trackLength = _track.Bounds.Width - thumbLength;
var trackPos = posOnTrack.Position.X;
var pos = MathUtilities.Clamp((trackPos - thumbLength * 0.5) / trackLength, 0.0d, 1.0d);
var range = Maximum - Minimum;
var finalValue = pos * range + Minimum;

SetCurrentValue(ValueProperty, finalValue);
}
}
31 changes: 20 additions & 11 deletions Audio/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public partial class MainViewModel : ViewModelBase
private double _progressValue;
private double _duration;
private double _time;
private double _value;
private bool _isPlay;

public FileInfo PreviewInput { get; set; }
Expand All @@ -46,6 +47,7 @@ public partial class MainViewModel : ViewModelBase
public FlatTreeDataGridSource<Entry> EntrySource { get; set; }
public List<Entry> SelectedEntries { get; set; }
public string ClipboardText { get; set; }
public bool IsSeeking { get; set; }
public bool IsExportAudio { get; set; }
public bool AllowBanks { get; set; }
public bool EnableTXTH { get; set; }
Expand Down Expand Up @@ -117,7 +119,16 @@ public double Duration
public double Time
{
get => _time;
set => this.RaiseAndSetIfChanged(ref _time, value);
set
{
MediaPlayer.Time = (long)value;
this.RaiseAndSetIfChanged(ref _time, value);
}
}
public double Value
{
get => _value;
set => this.RaiseAndSetIfChanged(ref _value, value);
}
public string VOPath
{
Expand Down Expand Up @@ -164,7 +175,7 @@ public MainViewModel()
StatusText = "";
IsExportAudio = true;
Duration = 1;
Time = 0;
Value = 0;

PreviewInput = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "preview.wem"));
PreviewOutput = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "preview.wav"));
Expand Down Expand Up @@ -247,11 +258,6 @@ public async void Search()
await Task.Run(Refresh);
StatusText = "Updated !!";
}
public void Seek(double value)
{
MediaPlayer.Time = (long)(value * 1000.0d);
MediaPlayer.Play();
}
public void LoadAudio()
{
IsPlay = false;
Expand Down Expand Up @@ -292,7 +298,7 @@ public void LoadAudio()
{
MediaPlayer.Media = new Media(_vlcLib, PreviewOutput.FullName);
Duration = 1;
Time = 0;
Value = 0;
}

StatusText = $"Loaded {SelectedEntry.Name}";
Expand All @@ -313,15 +319,18 @@ private void MediaPlayer_EndReached(object? sender, EventArgs e)
IsPlay = false;
ThreadPool.QueueUserWorkItem(state => MediaPlayer.Stop());
Duration = 1;
Time = 0;
Value = 0;
}
private void MediaPlayer_LengthChanged(object? sender, MediaPlayerLengthChangedEventArgs e)
{
Duration = MediaPlayer.Length / 1000.0d;
Duration = MediaPlayer.Length;
}
private void MediaPlayer_TimeChanged(object? sender, MediaPlayerTimeChangedEventArgs e)
{
Time = MediaPlayer.Time / 1000.0d;
if (!IsSeeking)
{
Value = MediaPlayer.Time;
}
}
private async void LoadPaths(string[] paths)
{
Expand Down
3 changes: 2 additions & 1 deletion Audio/Views/MainView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Audio.ViewModels"
xmlns:models="clr-namespace:Audio.Models.Entries"
xmlns:controls="clr-namespace:Audio.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Audio.Views.MainView"
x:DataType="vm:MainViewModel">
Expand Down Expand Up @@ -84,7 +85,7 @@
<PathIcon Classes="Pause" Data="{StaticResource PauseIcon}"/>
</Panel>
</ToggleButton>
<Slider Grid.Column="1" HorizontalAlignment="Stretch" Minimum="0" Maximum="{Binding Duration}" Value="{Binding Time}" PointerPressed="Slider_PointerPressed"/>
<controls:PlaybackSlider Grid.Column="1" HorizontalAlignment="Stretch" Minimum="0" Maximum="{Binding Duration}" Value="{Binding Value}" Time="{Binding Time}" IsSeeking="{Binding IsSeeking}"/>
</Grid>
<Border Grid.Row="1" BorderThickness="1" BorderBrush="White">
<SelectableTextBlock Text="{Binding StatusText}"/>
Expand Down
7 changes: 0 additions & 7 deletions Audio/Views/MainView.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,6 @@ private async void DumpInfo_Click(object? sender, RoutedEventArgs e)
ViewModel.DumpInfo(output);
}
}
private void Slider_PointerPressed(object? sender, PointerPressedEventArgs e)
{
if (sender is Slider slider)
{
ViewModel.Seek(slider.Value);
}
}
private void TreeDataGrid_DoubleTapped(object? sender, TappedEventArgs e)
{
if (e.Pointer.Captured is TextBlock _)
Expand Down

0 comments on commit f0f322c

Please sign in to comment.