mirror of
https://github.com/unclshura/ABStemPlayer.git
synced 2026-08-07 00:43:38 +00:00
Compare commits
2 Commits
72b4a16378
...
7410073224
| Author | SHA1 | Date | |
|---|---|---|---|
| 7410073224 | |||
| 8606801242 |
23
ABStemPlayer/Converters/PlayPauseGeometryConverter .cs
Normal file
23
ABStemPlayer/Converters/PlayPauseGeometryConverter .cs
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
@ -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)
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user