Compare commits

..

2 Commits

5 changed files with 66 additions and 43 deletions

View File

@ -0,0 +1,23 @@
using System.Globalization;
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace ABStemPlayer.Converters;
public class PlayPauseGeometryConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
bool isPlaying = value is bool b && b;
// Pause icon
if (isPlaying)
return Geometry.Parse("M 12 8 L 18 8 L 18 32 L 12 32 Z M 22 8 L 28 8 L 28 32 L 22 32 Z");
// Play icon
return Geometry.Parse("M 10 8 L 32 20 L 10 32 Z");
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}

View File

@ -36,7 +36,6 @@ public sealed partial class PlaybackViewModel : ObservableObject
public ICommand OpenFileCommand { get; } public ICommand OpenFileCommand { get; }
public ICommand PlayCommand { get; } public ICommand PlayCommand { get; }
public ICommand PauseCommand { get; }
public ICommand StopCommand { get; } public ICommand StopCommand { get; }
public ICommand RewindCommand { get; } public ICommand RewindCommand { get; }
public ICommand FastForwardCommand { get; } public ICommand FastForwardCommand { get; }
@ -48,6 +47,7 @@ public sealed partial class PlaybackViewModel : ObservableObject
// Playback properties // Playback properties
// ----------------------------- // -----------------------------
[ObservableProperty] private bool _isPlaying;
[ObservableProperty] private bool _loopEnabled; [ObservableProperty] private bool _loopEnabled;
[ObservableProperty] private float _playbackSpeed = 1f; [ObservableProperty] private float _playbackSpeed = 1f;
[ObservableProperty] private TimeSpan _currentTime; [ObservableProperty] private TimeSpan _currentTime;
@ -83,8 +83,7 @@ public sealed partial class PlaybackViewModel : ObservableObject
OpenFileCommand = new AsyncRelayCommand(OpenFileAsync); OpenFileCommand = new AsyncRelayCommand(OpenFileAsync);
PlayCommand = new AsyncRelayCommand(OnPlay); PlayCommand = new AsyncRelayCommand(OnPlay);
PauseCommand = new AsyncRelayCommand(() => _engine.PauseAsync()); StopCommand = new AsyncRelayCommand(OnStop);
StopCommand = new AsyncRelayCommand(async () => { await _engine.StopAsync(); await _engine.SeekAsync(TimeSpan.Zero); });
RewindCommand = new AsyncRelayCommand(() => _engine.SeekAsync(CurrentTime - TimeSpan.FromSeconds(5))); RewindCommand = new AsyncRelayCommand(() => _engine.SeekAsync(CurrentTime - TimeSpan.FromSeconds(5)));
FastForwardCommand = new AsyncRelayCommand(() => _engine.SeekAsync(CurrentTime + TimeSpan.FromSeconds(5))); FastForwardCommand = new AsyncRelayCommand(() => _engine.SeekAsync(CurrentTime + TimeSpan.FromSeconds(5)));
@ -123,6 +122,13 @@ public sealed partial class PlaybackViewModel : ObservableObject
private async Task OnPlay() private async Task OnPlay()
{ {
if (IsPlaying)
{
await _engine.PauseAsync();
IsPlaying = false;
return;
}
if (_engine.CurrentSession == null) if (_engine.CurrentSession == null)
return; return;
@ -135,6 +141,14 @@ public sealed partial class PlaybackViewModel : ObservableObject
await _engine.UpdatePlaybackSpeedAsync(new PlaybackSpeedSettings { Speed = PlaybackSpeed }); await _engine.UpdatePlaybackSpeedAsync(new PlaybackSpeedSettings { Speed = PlaybackSpeed });
await _engine.PlayAsync(); await _engine.PlayAsync();
IsPlaying = true;
}
private async Task OnStop()
{
await _engine.StopAsync();
IsPlaying = false;
CurrentTime = TimeSpan.Zero;
} }
partial void OnMixerChanged(MixerViewModel? oldValue, MixerViewModel newValue) partial void OnMixerChanged(MixerViewModel? oldValue, MixerViewModel newValue)

View File

@ -39,14 +39,12 @@
Grid.Column="0" Grid.Column="0"
Margin="8"> Margin="8">
<ScrollViewer Margin="8" <ScrollViewer Margin="8" VerticalScrollBarVisibility="Auto">
VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Bands}" <ItemsControl ItemsSource="{Binding Bands}"
Margin="0,2"> Margin="0,2">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/> <VirtualizingStackPanel Orientation="Vertical"/>
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
@ -56,7 +54,6 @@
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>

View File

@ -3,10 +3,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:ABStemPlayer.ViewModels" xmlns:vm="using:ABStemPlayer.ViewModels"
xmlns:conv="using:ABStemPlayer.Converters" xmlns:conv="using:ABStemPlayer.Converters"
xmlns:av="clr-namespace:Avalonia;assembly=Avalonia.Base"
x:DataType="vm:PlaybackViewModel" x:DataType="vm:PlaybackViewModel"
x:Class="ABStemPlayer.Views.PlaybackControls"> x:Class="ABStemPlayer.Views.PlaybackControls">
<UserControl.Resources> <UserControl.Resources>
<conv:BoolInvertConverter x:Key="BoolInvert" /> <conv:BoolInvertConverter x:Key="BoolInvert" />
<conv:PlayPauseGeometryConverter x:Key="PlayPauseGeometry" />
</UserControl.Resources> </UserControl.Resources>
<Border Padding="8" <Border Padding="8"
@ -38,7 +40,8 @@
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="0" Grid.Column="0"
Margin="0,0,6,0"> Margin="0,0,6,0"
ToolTip.Tip="Open File">
<Path Fill="#e0e0e0" <Path Fill="#e0e0e0"
Stretch="None" Stretch="None"
RenderTransformOrigin="0,0"> RenderTransformOrigin="0,0">
@ -57,7 +60,8 @@
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="1" Grid.Column="1"
Margin="0,0,6,0"> Margin="0,0,6,0"
ToolTip.Tip="Rewind">
<Path Fill="#e0e0e0" <Path Fill="#e0e0e0"
Stretch="None" Stretch="None"
RenderTransformOrigin="0,0"> RenderTransformOrigin="0,0">
@ -72,41 +76,20 @@
</Button> </Button>
<!-- Play --> <!-- Play -->
<Button Command="{Binding PlayCommand}" <Button Width="40"
Width="40"
Height="40" Height="40"
Grid.Column="2" Grid.Column="2"
Margin="0,0,6,0"> Margin="0,0,6,0"
ToolTip.Tip="Play/Pause"
Command="{Binding PlayCommand}">
<Path Fill="#e0e0e0" <Path Fill="#e0e0e0"
Stretch="None" Stretch="None"
RenderTransformOrigin="0,0"> RenderTransformOrigin="0,0"
Data="{Binding IsPlaying, Converter={StaticResource PlayPauseGeometry}}">
<Path.RenderTransform> <Path.RenderTransform>
<TranslateTransform X="-8" Y="-8"/> <TranslateTransform X="-8" Y="-8"/>
</Path.RenderTransform> </Path.RenderTransform>
<Path.Data>
M 10 8 L 32 20 L 10 32 Z
</Path.Data>
</Path>
</Button>
<!-- Pause -->
<Button Command="{Binding PauseCommand}"
Width="40"
Height="40"
Grid.Column="3"
Margin="0,0,6,0">
<Path Fill="#e0e0e0"
Stretch="None"
RenderTransformOrigin="0,0">
<Path.RenderTransform>
<TranslateTransform X="-8" Y="-8"/>
</Path.RenderTransform>
<Path.Data>
M 8 8 H 16 V 32 H 8 Z
M 24 8 H 32 V 32 H 24 Z
</Path.Data>
</Path> </Path>
</Button> </Button>
@ -115,7 +98,8 @@
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="4" Grid.Column="4"
Margin="0,0,6,0"> Margin="0,0,6,0"
ToolTip.Tip="Stop">
<Path Fill="#e0e0e0" <Path Fill="#e0e0e0"
Stretch="None" Stretch="None"
RenderTransformOrigin="0,0"> RenderTransformOrigin="0,0">
@ -133,7 +117,8 @@
<Button Command="{Binding FastForwardCommand}" <Button Command="{Binding FastForwardCommand}"
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="5"> Grid.Column="5"
ToolTip.Tip="Fast Forward">
<Path Fill="#e0e0e0" <Path Fill="#e0e0e0"
Stretch="None" Stretch="None"
RenderTransformOrigin="0,0"> RenderTransformOrigin="0,0">
@ -189,6 +174,8 @@
<ToggleSwitch IsChecked="{Binding LoopEnabled}" <ToggleSwitch IsChecked="{Binding LoopEnabled}"
Content="Loop" Content="Loop"
OnContent=""
OffContent=""
VerticalAlignment="Center" VerticalAlignment="Center"
Grid.Column="0" Grid.Column="0"
Margin="0,0,6,0"/> Margin="0,0,6,0"/>
@ -197,7 +184,8 @@
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="1" Grid.Column="1"
Margin="0,0,6,0"> Margin="0,0,6,0"
ToolTip.Tip="Set Loop Point A">
<Grid> <Grid>
<Path Fill="#0080ff" <Path Fill="#0080ff"
Data="M 26 8 Data="M 26 8
@ -212,7 +200,8 @@ L 26 8" />
<Button Command="{Binding SetPointBCommand}" <Button Command="{Binding SetPointBCommand}"
Width="40" Width="40"
Height="40" Height="40"
Grid.Column="2"> Grid.Column="2"
ToolTip.Tip="Set Loop Point B">
<Grid> <Grid>
<Path Fill="#0080ff" <Path Fill="#0080ff"
Data="M 14 8 Data="M 14 8

View File

@ -454,7 +454,7 @@ public sealed class StemPlaybackEngine : IStemPlaybackEngine, IDisposable
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
catch (Exception ex) catch (Exception ex)
{ {
Debug.WriteLine($"StemPlaybackEngine: Error in StretchLoopAsync: {ex.Message}"); Msg($"StemPlaybackEngine: Error in StretchLoopAsync: {ex.Message}");
try { pipeline.Cts?.Cancel(); } catch { } try { pipeline.Cts?.Cancel(); } catch { }
} }
} }