mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-13 03:34:55 +08:00
add search function for music gallery
This commit is contained in:
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Planet.png
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Planet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -40,15 +40,18 @@
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.MetadataControl" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
|
||||
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.0" />
|
||||
<PackageReference Include="ICU4N" Version="60.1.0-alpha.438" />
|
||||
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.7" />
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum SongOrderType
|
||||
{
|
||||
Title,
|
||||
Album,
|
||||
Artist
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -12,19 +13,15 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class CollectionHelper
|
||||
{
|
||||
public static ObservableCollection<GroupInfoList> GetGroupedByTitleAsync(this ICollection<Track> tracks)
|
||||
public static ObservableCollection<GroupInfoList> GetGroupedBy<T>(
|
||||
this IEnumerable<T> items,
|
||||
Func<T, object> groupKeySelector,
|
||||
Func<object, object>? orderSelector = null)
|
||||
{
|
||||
// Grab Contact objects from pre-existing list (list is returned from function GetContactsAsync())
|
||||
var query = from item in tracks
|
||||
|
||||
// Group the items returned from the query, sort and select the ones you want to keep
|
||||
group item by item.Title.Substring(0, 1).ToUpper() into g
|
||||
var query = from item in items
|
||||
group item by groupKeySelector(item) into g
|
||||
orderby g.Key
|
||||
|
||||
// GroupInfoList is a simple custom class that has an IEnumerable type attribute, and
|
||||
// a key attribute. The IGrouping-typed variable g now holds the Contact objects,
|
||||
// and these objects will be used to create a new GroupInfoList object.
|
||||
select new GroupInfoList(g) { Key = g.Key };
|
||||
select new GroupInfoList(g.Cast<object>(), orderSelector) { Key = g.Key };
|
||||
|
||||
return new ObservableCollection<GroupInfoList>(query);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using ICU4N.Text;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using NTextCat;
|
||||
using System;
|
||||
@@ -15,6 +16,7 @@ namespace BetterLyrics.WinUI3.Services
|
||||
private static readonly RankedLanguageIdentifierFactory _factory = new();
|
||||
private static readonly RankedLanguageIdentifier _identifier;
|
||||
private static readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
private static readonly Transliterator _transliterator = Transliterator.GetInstance("Any-Latin; Latin-ASCII;");
|
||||
|
||||
public static List<Models.LanguageInfo> SupportedTargetLanguages =>
|
||||
[
|
||||
@@ -124,5 +126,20 @@ namespace BetterLyrics.WinUI3.Services
|
||||
if (found == -1) found = 7; // 默认使用英语
|
||||
return found;
|
||||
}
|
||||
|
||||
public static string GetOrderChar(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text)) return "#";
|
||||
char c = text[0];
|
||||
if (char.IsLetter(c) && c < 128) // 英文
|
||||
return char.ToUpper(c).ToString();
|
||||
|
||||
// 使用 ICU4N 转写为拉丁字母
|
||||
string latin = _transliterator.Transliterate(text);
|
||||
if (!string.IsNullOrEmpty(latin) && char.IsLetter(latin[0]))
|
||||
return char.ToUpper(latin[0]).ToString();
|
||||
|
||||
return "#";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.System;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class LauncherHelper
|
||||
{
|
||||
public static async Task SelectAndShowFile(string filePath)
|
||||
{
|
||||
var file = await StorageFile.GetFileFromPathAsync(filePath);
|
||||
var folder = await file.GetParentAsync();
|
||||
|
||||
var folderOptions = new FolderLauncherOptions();
|
||||
folderOptions.ItemsToSelect.Add(file);
|
||||
|
||||
await Launcher.LaunchFolderAsync(folder, folderOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,20 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public partial class GroupInfoList(IEnumerable<object> items) : List<object>(items)
|
||||
public partial class GroupInfoList : List<object>
|
||||
{
|
||||
public required object Key { get; set; }
|
||||
|
||||
public GroupInfoList(IEnumerable<object> items, Func<object, object>? orderSelector = null)
|
||||
: base(orderSelector != null
|
||||
? items.OrderBy(orderSelector)
|
||||
: items)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "Group " + Key.ToString();
|
||||
return $"{Key}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace BetterLyrics.WinUI3.TemplateSelector;
|
||||
|
||||
public class SongOrderTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate ByTitleTemplate { get; set; }
|
||||
public DataTemplate ByAlbumTemplate { get; set; }
|
||||
public DataTemplate ByArtistTemplate { get; set; }
|
||||
|
||||
public SongOrderType SongOrderType { get; set; }
|
||||
|
||||
protected override DataTemplate SelectTemplateCore(object item)
|
||||
{
|
||||
return SongOrderType switch
|
||||
{
|
||||
SongOrderType.Title => ByTitleTemplate,
|
||||
SongOrderType.Album => ByAlbumTemplate,
|
||||
SongOrderType.Artist => ByArtistTemplate,
|
||||
_ => ByTitleTemplate
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,9 @@ namespace BetterLyrics.WinUI3
|
||||
[ObservableProperty]
|
||||
public partial string LockHotKey { get; set; } = "";
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsMusicGalleryPageExpanded { get; set; } = false;
|
||||
|
||||
private void AutoHideOrShowWindow()
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
@@ -29,36 +31,67 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private readonly MediaTimelineController _timelineController = new();
|
||||
private readonly SystemMediaTransportControls _smtc;
|
||||
private List<Track> _tracks = [];
|
||||
private List<Track> _filteredTracks = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<GroupInfoList> TracksByTitle { get; set; } = [];
|
||||
public partial bool IsLocalMediaNotFound { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<GroupInfoList> GroupedTracks { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial ObservableCollection<Track> TrackSearchSuggestions { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
public partial SongOrderType SongOrderType { get; set; } = SongOrderType.Title;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsDataLoading { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Track TrackRightTapped { get; set; } = new();
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int SelectedSongIndex { get; set; } = -1;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string SongSearchQuery { get; set; } = string.Empty;
|
||||
|
||||
public MusicGalleryViewModel(ISettingsService settingsService, ILibWatcherService libWatcherService) : base(settingsService)
|
||||
{
|
||||
_mediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
|
||||
_timelineController = _mediaPlayer.TimelineController = new();
|
||||
_timelineController.PositionChanged += TimelineController_PositionChanged;
|
||||
_smtc = _mediaPlayer.SystemMediaTransportControls;
|
||||
_mediaPlayer.CommandManager.IsEnabled = false;
|
||||
_smtc.IsEnabled = true;
|
||||
_smtc.IsPlayEnabled = true;
|
||||
_smtc.IsPauseEnabled = true;
|
||||
_smtc.IsNextEnabled = true;
|
||||
_smtc.IsPreviousEnabled = true;
|
||||
_smtc.ButtonPressed += Smtc_ButtonPressed;
|
||||
_smtc.PlaybackPositionChangeRequested += Smtc_PlaybackPositionChangeRequested;
|
||||
|
||||
_libWatcherService = libWatcherService;
|
||||
_libWatcherService.MusicLibraryFilesChanged += LibWatcherService_MusicLibraryFilesChanged;
|
||||
}
|
||||
|
||||
private void Smtc_PlaybackPositionChangeRequested(SystemMediaTransportControls sender, PlaybackPositionChangeRequestedEventArgs args)
|
||||
{
|
||||
_timelineController.Position = args.RequestedPlaybackPosition;
|
||||
}
|
||||
|
||||
private void MediaPlayer_MediaOpened(MediaPlayer sender, object args)
|
||||
{
|
||||
_timelineController.Start();
|
||||
_smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
|
||||
}
|
||||
|
||||
private void TimelineController_PositionChanged(MediaTimelineController sender, object args)
|
||||
{
|
||||
_smtc.UpdateTimelineProperties(new SystemMediaTransportControlsTimelineProperties()
|
||||
{
|
||||
Position = sender.Position,
|
||||
EndTime = sender.Duration ?? TimeSpan.Zero
|
||||
EndTime = _mediaPlayer.PlaybackSession.NaturalDuration
|
||||
});
|
||||
}
|
||||
|
||||
@@ -68,14 +101,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
case SystemMediaTransportControlsButton.Play:
|
||||
_smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
|
||||
_mediaPlayer.Play();
|
||||
_timelineController.Resume();
|
||||
break;
|
||||
case SystemMediaTransportControlsButton.Pause:
|
||||
_smtc.PlaybackStatus = MediaPlaybackStatus.Paused;
|
||||
_mediaPlayer.Pause();
|
||||
_timelineController.Pause();
|
||||
break;
|
||||
case SystemMediaTransportControlsButton.Next:
|
||||
//Next
|
||||
break;
|
||||
case SystemMediaTransportControlsButton.Previous:
|
||||
//Previous
|
||||
@@ -90,58 +122,108 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
public void RefreshSongs()
|
||||
{
|
||||
IsDataLoading = true;
|
||||
_tracks.Clear();
|
||||
|
||||
Task.Run(() =>
|
||||
_dispatcherQueueTimer.Debounce(() =>
|
||||
{
|
||||
foreach (var folder in _settingsService.LocalMediaFolders)
|
||||
IsDataLoading = true;
|
||||
_tracks.Clear();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
if (Directory.Exists(folder.Path) && folder.IsEnabled)
|
||||
foreach (var folder in _settingsService.LocalMediaFolders)
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(folder.Path, $"*.*", SearchOption.AllDirectories))
|
||||
if (Directory.Exists(folder.Path) && folder.IsEnabled)
|
||||
{
|
||||
Track track = new(file);
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
foreach (var file in Directory.GetFiles(folder.Path, $"*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
Track track = new(file);
|
||||
if (track.Duration <= 0) continue;
|
||||
_tracks.Add(track);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
TracksByTitle.AddRange(_tracks.GetGroupedByTitleAsync());
|
||||
IsDataLoading = false;
|
||||
ApplySongSearchQuery();
|
||||
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
|
||||
{
|
||||
IsLocalMediaNotFound = !_filteredTracks.Any();
|
||||
ApplySongOrderType();
|
||||
IsDataLoading = false;
|
||||
});
|
||||
});
|
||||
});
|
||||
}, TimeSpan.FromMilliseconds(100));
|
||||
}
|
||||
|
||||
public void PlaySongAt(int? index)
|
||||
public void ApplySongSearchQuery()
|
||||
{
|
||||
if (index.HasValue)
|
||||
if (string.IsNullOrWhiteSpace(SongSearchQuery))
|
||||
{
|
||||
var track = _tracks.ElementAtOrDefault(index.Value);
|
||||
if (track != null)
|
||||
{
|
||||
_mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(track.Path));
|
||||
var updater = _smtc.DisplayUpdater;
|
||||
updater.AppMediaId = Package.Current.Id.FullName;
|
||||
updater.Type = MediaPlaybackType.Music;
|
||||
updater.MusicProperties.Title = track.Title;
|
||||
updater.MusicProperties.Artist = track.Artist;
|
||||
updater.MusicProperties.AlbumTitle = track.Album;
|
||||
if (track.EmbeddedPictures.FirstOrDefault()?.PictureData is byte[] pictureData)
|
||||
{
|
||||
updater.Thumbnail = ImageHelper.ByteArrayToRandomAccessStreamReference(pictureData);
|
||||
}
|
||||
_timelineController.Duration = TimeSpan.FromSeconds(track.Duration);
|
||||
_timelineController.Start();
|
||||
updater.Update();
|
||||
_smtc.PlaybackStatus = MediaPlaybackStatus.Playing;
|
||||
}
|
||||
_filteredTracks = _tracks;
|
||||
return;
|
||||
}
|
||||
_filteredTracks = new List<Track>(
|
||||
_tracks.Where(t => t.Title.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
t.Artist.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
t.Album.Contains(SongSearchQuery, StringComparison.OrdinalIgnoreCase))
|
||||
);
|
||||
}
|
||||
|
||||
private void ApplySongOrderType()
|
||||
{
|
||||
switch (SongOrderType)
|
||||
{
|
||||
case SongOrderType.Title:
|
||||
GroupedTracks = _filteredTracks.GetGroupedBy(
|
||||
t => LanguageHelper.GetOrderChar(t.Title),
|
||||
o => ((Track)o).Title
|
||||
);
|
||||
break;
|
||||
case SongOrderType.Artist:
|
||||
GroupedTracks = _filteredTracks.GetGroupedBy(
|
||||
t => LanguageHelper.GetOrderChar(t.Artist),
|
||||
o => ((Track)o).Artist
|
||||
);
|
||||
break;
|
||||
case SongOrderType.Album:
|
||||
GroupedTracks = _filteredTracks.GetGroupedBy(
|
||||
t => LanguageHelper.GetOrderChar(t.Album),
|
||||
o => ((Track)o).Album
|
||||
);
|
||||
break;
|
||||
}
|
||||
SelectedSongIndex = -1;
|
||||
}
|
||||
|
||||
public void PlayTrack(Track? track)
|
||||
{
|
||||
if (track == null) return;
|
||||
|
||||
_smtc.IsEnabled = true;
|
||||
_mediaPlayer.Source = MediaSource.CreateFromUri(new Uri(track.Path));
|
||||
var updater = _smtc.DisplayUpdater;
|
||||
updater.AppMediaId = Package.Current.Id.FullName;
|
||||
updater.Type = MediaPlaybackType.Music;
|
||||
updater.MusicProperties.Title = track.Title;
|
||||
updater.MusicProperties.Artist = track.Artist;
|
||||
updater.MusicProperties.AlbumTitle = track.Album;
|
||||
if (track.EmbeddedPictures.FirstOrDefault()?.PictureData is byte[] pictureData)
|
||||
{
|
||||
updater.Thumbnail = ImageHelper.ByteArrayToRandomAccessStreamReference(pictureData);
|
||||
}
|
||||
updater.Update();
|
||||
}
|
||||
|
||||
partial void OnSongOrderTypeChanged(SongOrderType value)
|
||||
{
|
||||
ApplySongOrderType();
|
||||
IsLocalMediaNotFound = !_filteredTracks.Any();
|
||||
}
|
||||
|
||||
partial void OnSongSearchQueryChanged(string value)
|
||||
{
|
||||
ApplySongSearchQuery();
|
||||
IsLocalMediaNotFound = !_filteredTracks.Any();
|
||||
ApplySongOrderType();
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<ObservableCollection<LocalMediaFolder>> message)
|
||||
|
||||
@@ -345,13 +345,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
Broadcast(LocalMediaFolders, LocalMediaFolders, nameof(LocalMediaFolders));
|
||||
}
|
||||
|
||||
public void ToggleLocalLyricsFolder(LocalMediaFolder folder)
|
||||
public void ToggleLocalLyricsFolder()
|
||||
{
|
||||
_settingsService.LocalMediaFolders = [.. LocalMediaFolders];
|
||||
Broadcast(LocalMediaFolders, LocalMediaFolders, nameof(LocalMediaFolders));
|
||||
}
|
||||
|
||||
public void ToggleLyricsSearchProvider(LyricsSearchProviderInfo providerInfo)
|
||||
public void ToggleLyricsSearchProvider()
|
||||
{
|
||||
_settingsService.LyricsSearchProvidersInfo = [.. LyricsSearchProvidersInfo];
|
||||
Broadcast(
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Name="TimelineOffsetToolTip" x:Uid="LyricsPageTimelineOffsetButtonToolTip" />
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.DataContext>
|
||||
<Button.ContextFlyout>
|
||||
<Flyout x:Name="TimelineOffsetFlyout" ShouldConstrainToRootBounds="False">
|
||||
<StackPanel>
|
||||
<Slider
|
||||
@@ -122,7 +122,7 @@
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.DataContext>
|
||||
</Button.ContextFlyout>
|
||||
</Button>
|
||||
|
||||
</StackPanel>
|
||||
@@ -244,7 +244,7 @@
|
||||
</FontIcon.OpacityTransition>
|
||||
</FontIcon>
|
||||
</Grid>
|
||||
<Button.DataContext>
|
||||
<Button.ContextFlyout>
|
||||
<Flyout x:Name="VolumeFlyout" ShouldConstrainToRootBounds="False">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Uid="SettingsPageSliderPrefix" VerticalAlignment="Center" />
|
||||
@@ -273,7 +273,7 @@
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Name="TranslationToolTip" x:Uid="LyricsPageTranslationButtonToolTip" />
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.DataContext>
|
||||
<Button.ContextFlyout>
|
||||
<Flyout x:Name="TranslationFlyout" ShouldConstrainToRootBounds="False">
|
||||
<StackPanel>
|
||||
<ToggleSwitch x:Uid="LyricsPageTranslationEnabled" IsOn="{x:Bind ViewModel.IsTranslationEnabled, Mode=TwoWay}" />
|
||||
@@ -283,7 +283,7 @@
|
||||
IsOn="{x:Bind ViewModel.ShowTranslationOnly, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.DataContext>
|
||||
</Button.ContextFlyout>
|
||||
</Button>
|
||||
|
||||
<!-- Display type -->
|
||||
@@ -297,7 +297,7 @@
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Name="PresentationTypeToolTip" x:Uid="LyricsPageDisplayTypeButtonToolTip" />
|
||||
</ToolTipService.ToolTip>
|
||||
<Button.DataContext>
|
||||
<Button.ContextFlyout>
|
||||
<Flyout x:Name="DisplayTypeSwitchFlyout" ShouldConstrainToRootBounds="false">
|
||||
<Flyout.FlyoutPresenterStyle>
|
||||
<Style TargetType="FlyoutPresenter">
|
||||
@@ -311,7 +311,7 @@
|
||||
<RadioButton x:Uid="MainPageSplitView" Click="SplitViewRadioButton_Click" />
|
||||
</RadioButtons>
|
||||
</Flyout>
|
||||
</Button.DataContext>
|
||||
</Button.ContextFlyout>
|
||||
</Button>
|
||||
|
||||
<!-- Settings -->
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
|
||||
<local:LyricsPage />
|
||||
|
||||
<local:MusicGalleryPage x:Name="MusicGalleryPage" Padding="64">
|
||||
<local:MusicGalleryPage.TranslationTransition>
|
||||
<Vector3Transition />
|
||||
</local:MusicGalleryPage.TranslationTransition>
|
||||
</local:MusicGalleryPage>
|
||||
|
||||
<!-- Top command -->
|
||||
<Grid
|
||||
x:Name="TopCommandGrid"
|
||||
|
||||
@@ -77,12 +77,12 @@ namespace BetterLyrics.WinUI3.Views
|
||||
_settingsService.StandardWindowWidth = 1600;
|
||||
_settingsService.StandardWindowHeight = 800;
|
||||
}
|
||||
AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(
|
||||
_settingsService.StandardWindowLeft,
|
||||
_settingsService.StandardWindowTop,
|
||||
_settingsService.StandardWindowWidth,
|
||||
_settingsService.StandardWindowHeight
|
||||
));
|
||||
//AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(
|
||||
// _settingsService.StandardWindowLeft,
|
||||
// _settingsService.StandardWindowTop,
|
||||
// _settingsService.StandardWindowWidth,
|
||||
// _settingsService.StandardWindowHeight
|
||||
//));
|
||||
break;
|
||||
case AutoStartWindowType.DockMode:
|
||||
DockFlyoutItem.IsChecked = true;
|
||||
@@ -332,11 +332,25 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void RootGrid_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
UpdateMusicGalleryPageTranslation();
|
||||
}
|
||||
|
||||
private void MusicGalleryButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.OpenWindow<MusicGalleryWindow>();
|
||||
ViewModel.IsMusicGalleryPageExpanded = !ViewModel.IsMusicGalleryPageExpanded;
|
||||
UpdateMusicGalleryPageTranslation();
|
||||
}
|
||||
|
||||
private void UpdateMusicGalleryPageTranslation()
|
||||
{
|
||||
if (ViewModel.IsMusicGalleryPageExpanded)
|
||||
{
|
||||
MusicGalleryPage.Translation = new System.Numerics.Vector3(0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
MusicGalleryPage.Translation = new System.Numerics.Vector3(0, (float)RootGrid.ActualHeight, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,190 +12,370 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:media="using:CommunityToolkit.WinUI.Media"
|
||||
xmlns:models="using:BetterLyrics.WinUI3.Models"
|
||||
xmlns:templateselector="using:BetterLyrics.WinUI3.TemplateSelector"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
|
||||
Loaded="Page_Loaded"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<DataTemplate x:Key="ByTitleTemplate" x:DataType="atl:Track">
|
||||
<Grid
|
||||
Padding="12"
|
||||
RightTapped="SongListVireItemGrid_RightTapped"
|
||||
Tapped="SongListVireItemGrid_Tapped">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 歌曲名 -->
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Title}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌手名 -->
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Artist}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 专辑名 -->
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Album}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 年份 -->
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Year}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 流派 -->
|
||||
<TextBlock
|
||||
Grid.Column="4"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Genre}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲时长 -->
|
||||
<TextBlock
|
||||
Grid.Column="5"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="ByAlbumTemplate" x:DataType="atl:Track">
|
||||
<Grid
|
||||
Padding="12"
|
||||
RightTapped="SongListVireItemGrid_RightTapped"
|
||||
Tapped="SongListVireItemGrid_Tapped">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 专辑名 -->
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Text="{Binding Album}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲名 -->
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Title}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌手名 -->
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Artist}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
|
||||
<!-- 年份 -->
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Year}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 流派 -->
|
||||
<TextBlock
|
||||
Grid.Column="4"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Genre}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲时长 -->
|
||||
<TextBlock
|
||||
Grid.Column="5"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="ByArtistTemplate" x:DataType="atl:Track">
|
||||
<Grid
|
||||
Padding="12"
|
||||
RightTapped="SongListVireItemGrid_RightTapped"
|
||||
Tapped="SongListVireItemGrid_Tapped">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<ColumnDefinition Width="1*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 歌手名 -->
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Artist}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲名 -->
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Title}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 专辑名 -->
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Album}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 年份 -->
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Year}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 流派 -->
|
||||
<TextBlock
|
||||
Grid.Column="4"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Genre}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲时长 -->
|
||||
<TextBlock
|
||||
Grid.Column="5"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<templateselector:SongOrderTemplateSelector
|
||||
x:Key="SongOrderTemplateSelector"
|
||||
ByAlbumTemplate="{StaticResource ByAlbumTemplate}"
|
||||
ByArtistTemplate="{StaticResource ByArtistTemplate}"
|
||||
ByTitleTemplate="{StaticResource ByTitleTemplate}"
|
||||
SongOrderType="{x:Bind ViewModel.SongOrderType, Mode=OneWay}" />
|
||||
|
||||
<CollectionViewSource
|
||||
x:Name="TracksByTitleCVS"
|
||||
IsSourceGrouped="True"
|
||||
Source="{x:Bind ViewModel.TracksByTitle, Mode=OneWay}" />
|
||||
Source="{x:Bind ViewModel.GroupedTracks, Mode=OneWay}" />
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid Margin="0,12,0,0">
|
||||
<AutoSuggestBox
|
||||
x:Name="SongSearchBox"
|
||||
Margin="36,0"
|
||||
VerticalAlignment="Top"
|
||||
PlaceholderText="搜索歌曲"
|
||||
QueryIcon="Find"
|
||||
QuerySubmitted="SongSearchBox_QuerySubmitted"
|
||||
SuggestionChosen="SongSearchBox_SuggestionChosen"
|
||||
TextChanged="SongSearchBox_TextChanged" />
|
||||
|
||||
<controls:Segmented
|
||||
x:Name="Segmented"
|
||||
Margin="36,48,36,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
SelectedIndex="0"
|
||||
SelectionMode="Single">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{Binding ElementName=Segmented, Path=SelectedIndex, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="0">
|
||||
<interactivity:ChangePropertyAction PropertyName="Tag" Value="Song" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{Binding ElementName=Segmented, Path=SelectedIndex, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="1">
|
||||
<interactivity:ChangePropertyAction PropertyName="Tag" Value="Album" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{Binding ElementName=Segmented, Path=SelectedIndex, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Tag" Value="Artist" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<controls:SegmentedItem Content="歌曲" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
<controls:SegmentedItem Content="专辑" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
<controls:SegmentedItem Content="艺术家" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
</controls:Segmented>
|
||||
<Grid x:Name="SongViewer" Margin="0,36,0,0">
|
||||
|
||||
<controls:SwitchPresenter Margin="0,96,0,0" Value="{Binding ElementName=Segmented, Path=Tag, Mode=OneWay}">
|
||||
<controls:SwitchPresenter.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<PopupThemeTransition />
|
||||
</TransitionCollection>
|
||||
</controls:SwitchPresenter.ContentTransitions>
|
||||
<Grid Margin="12" VerticalAlignment="Top">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="16" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<AutoSuggestBox
|
||||
x:Name="SongSearchBox"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
PlaceholderText="搜索歌曲"
|
||||
QueryIcon="Find"
|
||||
Text="{x:Bind ViewModel.SongSearchQuery, Mode=TwoWay}" />
|
||||
<StackPanel
|
||||
Grid.Column="2"
|
||||
Orientation="Horizontal"
|
||||
Spacing="12">
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyStrongTextBlockStyle}"
|
||||
Text="排序方式" />
|
||||
<controls:Segmented
|
||||
x:Name="Segmented"
|
||||
SelectedIndex="{x:Bind ViewModel.SongOrderType, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}"
|
||||
SelectionMode="Single">
|
||||
<controls:SegmentedItem Content="歌曲" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
<controls:SegmentedItem Content="专辑" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
<controls:SegmentedItem Content="艺术家" Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||
</controls:Segmented>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<controls:Case Value="Song">
|
||||
<SemanticZoom>
|
||||
<SemanticZoom.ZoomedInView>
|
||||
<GridView
|
||||
ItemsSource="{x:Bind TracksByTitleCVS.View, Mode=OneWay}"
|
||||
ScrollViewer.IsHorizontalScrollChainingEnabled="False"
|
||||
SelectionMode="None">
|
||||
<GridView.GroupStyle>
|
||||
<GroupStyle />
|
||||
</GridView.GroupStyle>
|
||||
</GridView>
|
||||
</SemanticZoom.ZoomedInView>
|
||||
<SemanticZoom Margin="0,48,0,0">
|
||||
<SemanticZoom.ZoomedInView>
|
||||
<ListView
|
||||
x:Name="SongListView"
|
||||
ItemTemplateSelector="{StaticResource SongOrderTemplateSelector}"
|
||||
ItemsSource="{x:Bind TracksByTitleCVS.View, Mode=OneWay}">
|
||||
<ListView.ContextFlyout>
|
||||
<Flyout Placement="Right" ShouldConstrainToRootBounds="False">
|
||||
<StackPanel Spacing="12">
|
||||
|
||||
<SemanticZoom.ZoomedOutView>
|
||||
<ListView ItemsSource="{x:Bind TracksByTitleCVS.View.CollectionGroups, Mode=OneWay}" SelectionChanged="SongListView_SelectionChanged">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<ItemsStackPanel AreStickyGroupHeadersEnabled="True" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.HeaderTemplate>
|
||||
<DataTemplate x:DataType="models:GroupInfoList">
|
||||
<Border AutomationProperties.AccessibilityView="Raw">
|
||||
<TextBlock
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Text="{x:Bind Key}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</GroupStyle.HeaderTemplate>
|
||||
</GroupStyle>
|
||||
</ListView.GroupStyle>
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Padding" Value="36,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="atl:Track">
|
||||
<Grid Padding="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="2*" />
|
||||
<!-- 歌曲名 -->
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<!-- 歌手名 -->
|
||||
<ColumnDefinition Width="1.5*" />
|
||||
<!-- 专辑名 -->
|
||||
<ColumnDefinition Width="1*" />
|
||||
<!-- 年份 -->
|
||||
<ColumnDefinition Width="1.2*" />
|
||||
<!-- 流派 -->
|
||||
<ColumnDefinition Width="1*" />
|
||||
<!-- 歌曲时长 -->
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<!--<FontIcon FontFamily="{StaticResource IconFontFamily}" Glyph="" />-->
|
||||
<TextBlock Style="{StaticResource BodyStrongTextBlockStyle}" Text="文件信息" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 歌曲名 -->
|
||||
<ScrollViewer Width="300" Height="300">
|
||||
<StackPanel Spacing="12">
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="标题" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Title, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="艺术家" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Artist, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="专辑" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Album, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="年份" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Year, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="时长" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Duration, Converter={StaticResource SecondsToFormattedTimeConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="比特率" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Bitrate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="采样率" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.SampleRate, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="位深" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.BitDepth, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="格式" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.AudioFormat.Name, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="编码" />
|
||||
<TextBlock Text="{x:Bind ViewModel.TrackRightTapped.Encoder, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="路径" />
|
||||
<HyperlinkButton Click="SongPathHyperlinkButton_Click" Content="{x:Bind ViewModel.TrackRightTapped.Path, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</ListView.ContextFlyout>
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<ItemsStackPanel AreStickyGroupHeadersEnabled="True" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.HeaderTemplate>
|
||||
<DataTemplate x:DataType="models:GroupInfoList">
|
||||
<Border AutomationProperties.AccessibilityView="Raw">
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Title}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌手名 -->
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Artist}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 专辑名 -->
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Album}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 年份 -->
|
||||
<TextBlock
|
||||
Grid.Column="3"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Year}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 流派 -->
|
||||
<TextBlock
|
||||
Grid.Column="4"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Genre}"
|
||||
TextWrapping="Wrap" />
|
||||
|
||||
<!-- 歌曲时长 -->
|
||||
<TextBlock
|
||||
Grid.Column="5"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
|
||||
TextAlignment="Right"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
Style="{ThemeResource TitleTextBlockStyle}"
|
||||
Text="{Binding}" />
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</SemanticZoom.ZoomedOutView>
|
||||
</SemanticZoom>
|
||||
</controls:Case>
|
||||
</GroupStyle.HeaderTemplate>
|
||||
</GroupStyle>
|
||||
</ListView.GroupStyle>
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Padding" Value="36,0" />
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
</ListView>
|
||||
</SemanticZoom.ZoomedInView>
|
||||
|
||||
<controls:Case Value="Album">
|
||||
<ListView />
|
||||
</controls:Case>
|
||||
<SemanticZoom.ZoomedOutView>
|
||||
<GridView
|
||||
MaxWidth="500"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
ItemsSource="{x:Bind TracksByTitleCVS.View.CollectionGroups, Mode=OneWay}"
|
||||
ScrollViewer.IsHorizontalScrollChainingEnabled="False"
|
||||
SelectionMode="None">
|
||||
<GridView.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:GroupInfoList">
|
||||
<TextBlock Style="{ThemeResource TitleTextBlockStyle}" Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
</GridView.ItemTemplate>
|
||||
</GridView>
|
||||
</SemanticZoom.ZoomedOutView>
|
||||
</SemanticZoom>
|
||||
|
||||
<controls:Case Value="Artist">
|
||||
<ListView />
|
||||
</controls:Case>
|
||||
<Grid Margin="0,48,0,0" Visibility="{x:Bind ViewModel.IsLocalMediaNotFound, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image MaxWidth="200" Source="/Assets/Planet.png" />
|
||||
<TextBlock HorizontalAlignment="Center" Text="未在媒体库内找到任何歌曲" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</controls:SwitchPresenter>
|
||||
</Grid>
|
||||
|
||||
<Grid Background="{ThemeResource SolidBackgroundFillColorBaseBrush}" Visibility="{x:Bind ViewModel.IsDataLoading, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
@@ -209,10 +389,10 @@
|
||||
<RowDefinition Height="12" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<labs:Shimmer Grid.Row="0" CornerRadius="12" />
|
||||
<labs:Shimmer Grid.Row="2" CornerRadius="12" />
|
||||
<labs:Shimmer Grid.Row="4" CornerRadius="12" />
|
||||
<labs:Shimmer Grid.Row="6" CornerRadius="12" />
|
||||
<labs:Shimmer Grid.Row="0" CornerRadius="6" />
|
||||
<labs:Shimmer Grid.Row="2" CornerRadius="6" />
|
||||
<labs:Shimmer Grid.Row="4" CornerRadius="6" />
|
||||
<labs:Shimmer Grid.Row="6" CornerRadius="6" />
|
||||
</Grid>
|
||||
<ProgressRing IsActive="{x:Bind ViewModel.IsDataLoading, Mode=OneWay}" />
|
||||
</Grid>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -14,6 +17,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.System;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
@@ -26,35 +30,31 @@ namespace BetterLyrics.WinUI3.Views
|
||||
public sealed partial class MusicGalleryPage : Page
|
||||
{
|
||||
public MusicGalleryViewModel ViewModel => (MusicGalleryViewModel)DataContext;
|
||||
|
||||
public MusicGalleryPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<MusicGalleryViewModel>();
|
||||
}
|
||||
|
||||
private void SongListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
ViewModel.PlaySongAt((sender as ListView)?.SelectedIndex);
|
||||
}
|
||||
|
||||
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.RefreshSongs();
|
||||
}
|
||||
|
||||
private void SongSearchBox_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
private void SongListVireItemGrid_RightTapped(object sender, RightTappedRoutedEventArgs e)
|
||||
{
|
||||
|
||||
ViewModel.TrackRightTapped = (Track)((FrameworkElement)sender).DataContext;
|
||||
}
|
||||
|
||||
private void SongSearchBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
|
||||
private async void SongPathHyperlinkButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
await LauncherHelper.SelectAndShowFile($"{((HyperlinkButton)sender).Content}");
|
||||
}
|
||||
|
||||
private void SongSearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
private void SongListVireItemGrid_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
|
||||
ViewModel.PlayTrack((Track)((FrameworkElement)sender).DataContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
if (toggleSwitch.DataContext is LocalMediaFolder localLyricsFolder)
|
||||
{
|
||||
ViewModel.ToggleLocalLyricsFolder(localLyricsFolder);
|
||||
ViewModel.ToggleLocalLyricsFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
if (toggleSwitch.DataContext is LyricsSearchProviderInfo providerInfo)
|
||||
{
|
||||
ViewModel.ToggleLyricsSearchProvider(providerInfo);
|
||||
ViewModel.ToggleLyricsSearchProvider();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user