Minor updatees.
This commit is contained in:
@@ -12,6 +12,34 @@
|
|||||||
<!--<FluentTheme />-->
|
<!--<FluentTheme />-->
|
||||||
<semi:SemiTheme Locale="en-US"/>
|
<semi:SemiTheme Locale="en-US"/>
|
||||||
|
|
||||||
|
<!-- Flat Button -->
|
||||||
|
<Style Selector="Button.Flat">
|
||||||
|
<Setter Property="Padding" Value="10"/>
|
||||||
|
<Setter Property="Margin" Value="8 0 8 0"/>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderThickness" Value="0"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Flat Button Path Icon -->
|
||||||
|
<Style Selector="PathIcon.FlatButtonIcon">
|
||||||
|
<Setter Property="Padding" Value="10"/>
|
||||||
|
<Setter Property="Width" Value="18"/>
|
||||||
|
<Setter Property="Height" Value="18"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Flat Button Path Icon (Large) -->
|
||||||
|
<Style Selector="PathIcon.FlatButtonIcon.Medium">
|
||||||
|
<Setter Property="Width" Value="24"/>
|
||||||
|
<Setter Property="Height" Value="24"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<!-- Flat Button Path Icon (Large) -->
|
||||||
|
<Style Selector="PathIcon.FlatButtonIcon.Large">
|
||||||
|
<Setter Property="Width" Value="36"/>
|
||||||
|
<Setter Property="Height" Value="36"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<!-- Context Menu Global Style -->
|
<!-- Context Menu Global Style -->
|
||||||
<Style Selector="ContextMenu">
|
<Style Selector="ContextMenu">
|
||||||
<Setter Property="FontSize" Value="13"/>
|
<Setter Property="FontSize" Value="13"/>
|
||||||
@@ -57,6 +85,10 @@
|
|||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<vm:ViewModelLocator x:Key="Locator" />
|
<vm:ViewModelLocator x:Key="Locator" />
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
|
|
||||||
|
<!-- Brushes -->
|
||||||
|
<SolidColorBrush x:Key="HighlightTextColor">#ffe073</SolidColorBrush>
|
||||||
|
|
||||||
<!-- Converters -->
|
<!-- Converters -->
|
||||||
<converters:SecondsToStringConverter x:Key="SecondsToString" />
|
<converters:SecondsToStringConverter x:Key="SecondsToString" />
|
||||||
<converters:ArtistsToStringConverter x:Key="ArtistsToString" />
|
<converters:ArtistsToStringConverter x:Key="ArtistsToString" />
|
||||||
|
|||||||
@@ -39,7 +39,19 @@ public class PlaylistViewModel : ViewModelBase
|
|||||||
private Timer? _filterTimer;
|
private Timer? _filterTimer;
|
||||||
|
|
||||||
public Playlist? Playlist { get; private set; }
|
public Playlist? Playlist { get; private set; }
|
||||||
public PlaylistSong? PlayingSong => _audioPlayer.PlayingSong;
|
|
||||||
|
private PlaylistSong? _playingSong;
|
||||||
|
public PlaylistSong? PlayingSong
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _playingSong;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetProperty(ref _playingSong, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ObservableCollection<PlaylistSong> _playlistSongs = [];
|
private ObservableCollection<PlaylistSong> _playlistSongs = [];
|
||||||
public ObservableCollection<PlaylistSong> PlaylistSongs
|
public ObservableCollection<PlaylistSong> PlaylistSongs
|
||||||
@@ -79,8 +91,7 @@ public class PlaylistViewModel : ViewModelBase
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_filteredPlaylistSongs = value;
|
SetProperty(ref _filteredPlaylistSongs, value);
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +117,6 @@ public class PlaylistViewModel : ViewModelBase
|
|||||||
public ICommand CopySongsCommand => new AsyncRelayCommand(CopySongsAsync, AreSongsSelected);
|
public ICommand CopySongsCommand => new AsyncRelayCommand(CopySongsAsync, AreSongsSelected);
|
||||||
public ICommand PasteSongsCommand => new AsyncRelayCommand(PasteSongsAsync, CanPasteSongs);
|
public ICommand PasteSongsCommand => new AsyncRelayCommand(PasteSongsAsync, CanPasteSongs);
|
||||||
public ICommand OpenFileLocationCommand => new RelayCommand(OpenFileLocation, AreSongsSelected);
|
public ICommand OpenFileLocationCommand => new RelayCommand(OpenFileLocation, AreSongsSelected);
|
||||||
|
|
||||||
public ICommand RefreshTagsCommand => new RelayCommand(RefreshTags);
|
public ICommand RefreshTagsCommand => new RelayCommand(RefreshTags);
|
||||||
public ICommand RemoveMissingSongsCommand => new RelayCommand(RemoveMissingSongs);
|
public ICommand RemoveMissingSongsCommand => new RelayCommand(RemoveMissingSongs);
|
||||||
public ICommand RemoveDuplicateSongsCommand => new RelayCommand(RemoveDuplicateSongs);
|
public ICommand RemoveDuplicateSongsCommand => new RelayCommand(RemoveDuplicateSongs);
|
||||||
@@ -186,7 +196,8 @@ public class PlaylistViewModel : ViewModelBase
|
|||||||
|
|
||||||
private void OnAudioPlayerPlayingSongChanged(object? sender, EventArgs e)
|
private void OnAudioPlayerPlayingSongChanged(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(PlayingSong));
|
//OnPropertyChanged(nameof(PlayingSong));
|
||||||
|
PlayingSong = _audioPlayer.PlayingSong;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PlaySongAsync(PlaylistSong playlistSong)
|
public async Task PlaySongAsync(PlaylistSong playlistSong)
|
||||||
@@ -414,60 +425,44 @@ public class PlaylistViewModel : ViewModelBase
|
|||||||
|
|
||||||
private bool CanPasteSongs()
|
private bool CanPasteSongs()
|
||||||
{
|
{
|
||||||
if (Playlist == null)
|
return GetSongsFromClipboardAsync().Result.Length > 0;
|
||||||
return false;
|
|
||||||
|
|
||||||
IClipboard? clipboard = _clipboardLocator.Get();
|
|
||||||
|
|
||||||
if (clipboard == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string? clipboardText = clipboard.GetTextAsync().Result;
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(clipboardText))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Song[] songs = [];
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
songs = JsonSerializer.Deserialize<Song[]>(clipboardText) ?? [];
|
|
||||||
}
|
|
||||||
catch (JsonException)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return songs.Length > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PasteSongsAsync()
|
private async Task PasteSongsAsync()
|
||||||
{
|
{
|
||||||
if (Playlist == null)
|
if (Playlist == null || SelectedPlaylistSongs.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int selectedPlaylistSongIndex = Playlist.Songs.IndexOf(SelectedPlaylistSongs[0]);
|
||||||
|
|
||||||
|
if (selectedPlaylistSongIndex == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Song[] songs = await GetSongsFromClipboardAsync();
|
||||||
|
|
||||||
|
Playlist.AddSongs(songs, selectedPlaylistSongIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Song[]> GetSongsFromClipboardAsync()
|
||||||
|
{
|
||||||
IClipboard? clipboard = _clipboardLocator.Get();
|
IClipboard? clipboard = _clipboardLocator.Get();
|
||||||
|
|
||||||
if (clipboard == null)
|
if (clipboard == null)
|
||||||
return;
|
return [];
|
||||||
|
|
||||||
string? clipboardText = await clipboard.GetTextAsync();
|
string? clipboardText = await clipboard.GetTextAsync();
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(clipboardText))
|
if (string.IsNullOrWhiteSpace(clipboardText))
|
||||||
return;
|
return [];
|
||||||
|
|
||||||
Song[] songs = [];
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
songs = JsonSerializer.Deserialize<Song[]>(clipboardText) ?? [];
|
return JsonSerializer.Deserialize<Song[]>(clipboardText) ?? [];
|
||||||
}
|
}
|
||||||
catch (JsonException)
|
catch (JsonException)
|
||||||
{
|
{
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Playlist.AddSongs(songs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenFileLocation()
|
private void OpenFileLocation()
|
||||||
|
|||||||
@@ -8,47 +8,6 @@
|
|||||||
DataContext="{x:Static vm:ViewModelLocator.PlaybackBarViewModel}"
|
DataContext="{x:Static vm:ViewModelLocator.PlaybackBarViewModel}"
|
||||||
x:Class="Harmonia.UI.Views.PlaybackBar"
|
x:Class="Harmonia.UI.Views.PlaybackBar"
|
||||||
x:DataType="vm:PlaybackBarViewModel">
|
x:DataType="vm:PlaybackBarViewModel">
|
||||||
<UserControl.Resources>
|
|
||||||
<converter:SecondsToStringConverter x:Key="SecondsToString" />
|
|
||||||
<converter:ArtistsToStringConverter x:Key="ArtistsToString" />
|
|
||||||
<converter:NullVisibilityConverter x:Key="NullVisibility" />
|
|
||||||
<converter:SongTitleConverter x:Key="SongTitle" />
|
|
||||||
</UserControl.Resources>
|
|
||||||
<UserControl.Styles>
|
|
||||||
<!-- Flat Button -->
|
|
||||||
<Style Selector="Button.Flat">
|
|
||||||
<Setter Property="Padding" Value="10"/>
|
|
||||||
<Setter Property="Margin" Value="8 0 8 0"/>
|
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
|
||||||
<Setter Property="BorderThickness" Value="0"/>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<!-- Flat Button ViewBox -->
|
|
||||||
<!--<Style Selector="Viewbox.FlatButtonViewbox">
|
|
||||||
<Setter Property="Width" Value="18"/>
|
|
||||||
<Setter Property="Height" Value="18"/>
|
|
||||||
</Style>-->
|
|
||||||
|
|
||||||
<!-- Flat Button Path Icon -->
|
|
||||||
<Style Selector="PathIcon.FlatButtonIcon">
|
|
||||||
<Setter Property="Padding" Value="10"/>
|
|
||||||
<Setter Property="Width" Value="18"/>
|
|
||||||
<Setter Property="Height" Value="18"/>
|
|
||||||
<Setter Property="Foreground" Value="White"/>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<!-- Flat Button Path Icon (Large) -->
|
|
||||||
<Style Selector="PathIcon.FlatButtonIcon.Medium">
|
|
||||||
<Setter Property="Width" Value="24"/>
|
|
||||||
<Setter Property="Height" Value="24"/>
|
|
||||||
</Style>
|
|
||||||
|
|
||||||
<!-- Flat Button Path Icon (Large) -->
|
|
||||||
<Style Selector="PathIcon.FlatButtonIcon.Large">
|
|
||||||
<Setter Property="Width" Value="36"/>
|
|
||||||
<Setter Property="Height" Value="36"/>
|
|
||||||
</Style>
|
|
||||||
</UserControl.Styles>
|
|
||||||
<Border Background="#1a1a1a" Padding="10">
|
<Border Background="#1a1a1a" Padding="10">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
xmlns:controls="clr-namespace:Harmonia.UI.Controls"
|
xmlns:controls="clr-namespace:Harmonia.UI.Controls"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||||
DataContext="{x:Static vm:ViewModelLocator.PlaylistViewModel}"
|
DataContext="{x:Static vm:ViewModelLocator.PlaylistViewModel}"
|
||||||
Loaded="OnLoaded"
|
|
||||||
x:Class="Harmonia.UI.Views.PlaylistView"
|
x:Class="Harmonia.UI.Views.PlaylistView"
|
||||||
x:DataType="vm:PlaylistViewModel">
|
x:DataType="vm:PlaylistViewModel">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
@@ -42,7 +41,7 @@
|
|||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Grid.Playing TextBlock">
|
<Style Selector="Grid.Playing TextBlock">
|
||||||
<Setter Property="Foreground" Value="#76b9ed"/>
|
<Setter Property="Foreground" Value="{StaticResource HighlightTextColor}"/>
|
||||||
<!-- Light Blue for Highlight -->
|
<!-- Light Blue for Highlight -->
|
||||||
</Style>
|
</Style>
|
||||||
</UserControl.Styles>
|
</UserControl.Styles>
|
||||||
@@ -59,9 +58,9 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Watermark="Filter" Text="{Binding Filter, Mode=TwoWay}"></TextBox>
|
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Watermark="Filter" Text="{Binding Filter, Mode=TwoWay}"></TextBox>
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||||
<Button Foreground="#7FD184" Margin="10 0 0 0">
|
<Button Classes="Flat" Foreground="#7FD184" Margin="10 0 0 0" CornerRadius="32">
|
||||||
<Button.Content>
|
<Button.Content>
|
||||||
<PathIcon Data="{StaticResource SemiIconPlus}"></PathIcon>
|
<PathIcon Classes="FlatButtonIcon" Foreground="#7FD184" Data="{StaticResource SemiIconPlus}"></PathIcon>
|
||||||
</Button.Content>
|
</Button.Content>
|
||||||
<Button.Flyout>
|
<Button.Flyout>
|
||||||
<controls:AnimatedMenuFlyout Placement="Bottom">
|
<controls:AnimatedMenuFlyout Placement="Bottom">
|
||||||
@@ -84,9 +83,9 @@
|
|||||||
</controls:AnimatedMenuFlyout>
|
</controls:AnimatedMenuFlyout>
|
||||||
</Button.Flyout>
|
</Button.Flyout>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Foreground="#F9F9F9" Margin="10 0 0 0">
|
<Button Classes="Flat" Foreground="#F9F9F9" Margin="10 0 0 0" CornerRadius="32">
|
||||||
<Button.Content>
|
<Button.Content>
|
||||||
<PathIcon Data="{StaticResource SemiIconMore}"></PathIcon>
|
<PathIcon Classes="FlatButtonIcon" Data="{StaticResource SemiIconMore}"></PathIcon>
|
||||||
</Button.Content>
|
</Button.Content>
|
||||||
<Button.Flyout>
|
<Button.Flyout>
|
||||||
<controls:AnimatedMenuFlyout Placement="Bottom">
|
<controls:AnimatedMenuFlyout Placement="Bottom">
|
||||||
@@ -150,6 +149,7 @@
|
|||||||
ItemsSource="{Binding FilteredPlaylistSongs, Mode=OneWay}"
|
ItemsSource="{Binding FilteredPlaylistSongs, Mode=OneWay}"
|
||||||
SelectedItems="{Binding SelectedPlaylistSongs, Mode=OneWay}"
|
SelectedItems="{Binding SelectedPlaylistSongs, Mode=OneWay}"
|
||||||
DragDrop.AllowDrop="True"
|
DragDrop.AllowDrop="True"
|
||||||
|
DragDrop.Drop="OnPlaylistListBoxDrop"
|
||||||
DoubleTapped="ListBox_DoubleTapped"
|
DoubleTapped="ListBox_DoubleTapped"
|
||||||
SelectionMode="Multiple">
|
SelectionMode="Multiple">
|
||||||
<!--<ListBox.Styles>
|
<!--<ListBox.Styles>
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
</ListBox.Styles>-->
|
</ListBox.Styles>-->
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid Classes.Playing="{Binding $parent[ListBox].((vm:PlaylistViewModel)DataContext).PlayingSong, Converter={StaticResource PlaylistSongEquality}, ConverterParameter={Binding .}}">
|
<Grid Loaded="Grid_Loaded">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="70"></ColumnDefinition>
|
<ColumnDefinition Width="70"></ColumnDefinition>
|
||||||
<ColumnDefinition Width="*"></ColumnDefinition>
|
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
using Avalonia.Controls;
|
using Avalonia;
|
||||||
|
using Avalonia.Animation;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Presenters;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.Media.Imaging;
|
using Avalonia.Media.Imaging;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
using Avalonia.VisualTree;
|
||||||
using Harmonia.Core.Playlists;
|
using Harmonia.Core.Playlists;
|
||||||
using Harmonia.UI.ViewModels;
|
using Harmonia.UI.ViewModels;
|
||||||
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -22,25 +28,105 @@ public partial class PlaylistView : UserControl
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_viewModel = (PlaylistViewModel)DataContext!;
|
_viewModel = (PlaylistViewModel)DataContext!;
|
||||||
|
_viewModel.PropertyChanging += OnViewModelPropertyChanging;
|
||||||
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void OnBeforeFilteredSongsUpdate(object? sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(SlideOutSongs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void OnAfterFilteredSongsUpdate(object? sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(SlideInSongs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnViewModelPropertyChanging(object? sender, PropertyChangingEventArgs e)
|
||||||
|
{
|
||||||
|
switch (e.PropertyName)
|
||||||
|
{
|
||||||
|
case nameof(_viewModel.PlayingSong):
|
||||||
|
RemovePlayingSongClass();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
private async void OnViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.PropertyName == nameof(_viewModel.FilteredPlaylistSongs))
|
switch (e.PropertyName)
|
||||||
{
|
{
|
||||||
|
case nameof(_viewModel.FilteredPlaylistSongs):
|
||||||
await Dispatcher.UIThread.InvokeAsync(SlideInSongs);
|
await Dispatcher.UIThread.InvokeAsync(SlideInSongs);
|
||||||
|
break;
|
||||||
|
case nameof(_viewModel.PlayingSong):
|
||||||
|
AddPlayingSongClass();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task SlideOutSongs()
|
||||||
|
{
|
||||||
|
await Animations.Animations.SlideToRight(100, duration: 300).RunAsync(PlaylistListBox);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SlideInSongs()
|
private async Task SlideInSongs()
|
||||||
{
|
{
|
||||||
await Animations.Animations.SlideFromRight(100, duration: 300).RunAsync(PlaylistListBox);
|
await Animations.Animations.SlideFromRight(100, duration: 300).RunAsync(PlaylistListBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLoaded(object? sender, RoutedEventArgs e)
|
private void RemovePlayingSongClass()
|
||||||
{
|
{
|
||||||
//_storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
|
PlaylistSong? playingSong = _viewModel.PlayingSong;
|
||||||
|
|
||||||
|
if (playingSong == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Control? control = PlaylistListBox.ContainerFromItem(playingSong);
|
||||||
|
|
||||||
|
if (control is not ListBoxItem listBoxItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (listBoxItem.GetVisualChildren().FirstOrDefault() is not ContentPresenter contentPresentor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (contentPresentor.GetVisualChildren().FirstOrDefault() is not Grid grid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grid.Classes.Remove("Playing");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPlayingSongClass()
|
||||||
|
{
|
||||||
|
PlaylistSong? playingSong = _viewModel.PlayingSong;
|
||||||
|
|
||||||
|
if (playingSong == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlaylistListBox.UpdateLayout();
|
||||||
|
PlaylistListBox.ScrollIntoView(playingSong);
|
||||||
|
|
||||||
|
Control? control = PlaylistListBox.ContainerFromItem(playingSong);
|
||||||
|
|
||||||
|
if (control is ListBoxItem listBoxItem)
|
||||||
|
{
|
||||||
|
listBoxItem.BringIntoView();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlaylistListBox.ScrollIntoView(playingSong);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control is not ListBoxItem listBoxItem2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (listBoxItem2.GetVisualChildren().FirstOrDefault() is not ContentPresenter contentPresentor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (contentPresentor.GetVisualChildren().FirstOrDefault() is not Grid grid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
grid.Classes.Add("Playing");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ListBox_DoubleTapped(object? sender, TappedEventArgs e)
|
private async void ListBox_DoubleTapped(object? sender, TappedEventArgs e)
|
||||||
@@ -104,4 +190,144 @@ public partial class PlaylistView : UserControl
|
|||||||
_imageCancellationTokens.TryGetValue(hashCode, out CancellationTokenSource? cancellationTokenSource);
|
_imageCancellationTokens.TryGetValue(hashCode, out CancellationTokenSource? cancellationTokenSource);
|
||||||
cancellationTokenSource?.Cancel();
|
cancellationTokenSource?.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Grid_Loaded(object? sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is not Grid grid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (grid.Parent is not ListBoxItem listBoxItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//SetupDragAndDrop(grid, d => d.Set(DataFormats.Text,
|
||||||
|
// $"Text was dragged x times."),
|
||||||
|
// DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link);
|
||||||
|
|
||||||
|
if (PlaylistListBox.ItemFromContainer(listBoxItem) is not PlaylistSong playlistSong)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (playlistSong == _viewModel.PlayingSong)
|
||||||
|
grid.Classes.Add("Playing");
|
||||||
|
|
||||||
|
//await Dispatcher.UIThread.InvokeAsync(() => SlideInPlaylistSong(sender));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SlideOutPlaylistSong(object sender)
|
||||||
|
{
|
||||||
|
if (sender is not Animatable animatable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Animations.Animations.SlideToRight(100, duration: 300).RunAsync(animatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SlideInPlaylistSong(object sender)
|
||||||
|
{
|
||||||
|
if (sender is not Animatable animatable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Animations.Animations.SlideFromRight(100, duration: 300).RunAsync(animatable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPlaylistListBoxDrop(object? sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void SetupDragAndDrop(IInputElement draggable, Action<DataObject> factory, DragDropEffects effects)
|
||||||
|
//{
|
||||||
|
// draggable.PointerPressed += (sender, e) => StartDrag(sender, factory, e, effects);
|
||||||
|
|
||||||
|
// AddHandler(DragDrop.DropEvent, Drop);
|
||||||
|
// AddHandler(DragDrop.DragOverEvent, DragOver);
|
||||||
|
// AddHandler(DragDrop.DragEnterEvent, DragEnter);
|
||||||
|
// AddHandler(DragDrop.DragLeaveEvent, DragLeave);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private async void StartDrag(object? sender, Action<DataObject> factory, PointerPressedEventArgs e, DragDropEffects effects)
|
||||||
|
{
|
||||||
|
if (e.GetCurrentPoint((Visual)sender!).Properties.IsLeftButtonPressed == false)
|
||||||
|
{
|
||||||
|
// It was a left click
|
||||||
|
Console.WriteLine("Left mouse button pressed!");
|
||||||
|
e.Handled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var dragData = new DataObject();
|
||||||
|
factory(dragData);
|
||||||
|
|
||||||
|
var result = await DragDrop.DoDragDrop(e, dragData, effects);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DragOver(object? sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Source == PlaylistListBox)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if (e.Source is Animatable animatable)
|
||||||
|
//{
|
||||||
|
// //await Animations.Animations.SlideToRight(200).RunAsync(animatable);
|
||||||
|
// animatable.P
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (e.Source is Grid grid)
|
||||||
|
//{
|
||||||
|
// grid.Opacity = 0.5;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (Equals(e.Source, MoveTarget))
|
||||||
|
//{
|
||||||
|
// e.DragEffects &= DragDropEffects.Move;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// e.DragEffects &= DragDropEffects.Copy;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// Only allow if the dragged data contains text or filenames.
|
||||||
|
//if (!e.Data.Contains(DataFormats.Text)
|
||||||
|
// && !e.Data.Contains(DataFormats.Files)
|
||||||
|
// && !e.Data.Contains(CustomFormat))
|
||||||
|
// e.DragEffects = DragDropEffects.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DragEnter(object? sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Source is ListBoxItem grid)
|
||||||
|
{
|
||||||
|
grid.Opacity = 0.5;
|
||||||
|
//Animations.Animations.SlideToRight(200).RunAsync(grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DragLeave(object? sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Source is ListBoxItem grid)
|
||||||
|
{
|
||||||
|
grid.Opacity = 1;
|
||||||
|
//Animations.Animations.SlideToRight(200).RunAsync(grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Drop(object? sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
//if (Equals(e.Source, MoveTarget))
|
||||||
|
//{
|
||||||
|
// e.DragEffects &= DragDropEffects.Move;
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// e.DragEffects &= DragDropEffects.Copy;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (e.Data.Contains(DataFormats.Text))
|
||||||
|
//{
|
||||||
|
// DropState.Text = e.Data.GetText();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//else if (e.Data.Contains(CustomFormat))
|
||||||
|
//{
|
||||||
|
// DropState.Text = e.Data.Get(CustomFormat)?.ToString();
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user