From d01be4b883870d70bf376d0cf576e2c3827162e7 Mon Sep 17 00:00:00 2001 From: Zhe Fang Date: Thu, 5 Jun 2025 17:44:04 -0400 Subject: [PATCH] add support for editing album art corner radius --- .../Services/Database/DatabaseService.cs | 81 +++++++ .../Settings/SettingsDefaultValues.cs | 4 + .../Services/Settings/SettingsKey.cs | 5 + .../Services/Settings/SettingsService.cs | 204 ++++++++++++------ .../Strings/en-US/Resources.resw | 8 +- .../Strings/zh-CN/Resources.resw | 8 +- .../Strings/zh-TW/Resources.resw | 8 +- .../ViewModels/MainViewModel.cs | 114 ++-------- .../Views/MainPage.xaml.cs | 84 +++++--- .../Views/SettingsPage.xaml | 25 ++- 10 files changed, 345 insertions(+), 196 deletions(-) diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs index 871a04a..aeb4b0c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs @@ -11,6 +11,7 @@ using CommunityToolkit.Mvvm.Messaging; using Microsoft.UI.Xaml; using SQLite; using Ude; +using Windows.Media.Control; namespace BetterLyrics.WinUI3.Services.Database { @@ -18,6 +19,8 @@ namespace BetterLyrics.WinUI3.Services.Database { private readonly SQLiteConnection _connection; + private readonly CharsetDetector _charsetDetector = new(); + public DatabaseService() { _connection = new SQLiteConnection(Helper.AppInfo.DatabasePath); @@ -53,5 +56,83 @@ namespace BetterLyrics.WinUI3.Services.Database } }); } + + public Track? GetMusicMetadata( + GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps + ) + { + if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null) + return null; + + var founds = _connection + .Table() + // Look up by Title and Artist (these two props were fetched by reading metadata in music file befoe) first + // then by Path (music file name usually contains song name and artist so this can be a second way to look up for) + // Please note for .lrc file, only the second way works for it + .Where(m => + ( + m.Title != null + && m.Artist != null + && m.Title.Contains(mediaProps.Title) + && m.Artist.Contains(mediaProps.Artist) + ) + || ( + m.Path != null + && m.Path.Contains(mediaProps.Title) + && m.Path.Contains(mediaProps.Artist) + ) + ) + .ToList(); + if (founds == null || founds.Count == 0) + { + return null; + } + else + { + var first = new Track(founds[0].Path); + if (founds.Count == 1) + { + return first; + } + else + { + if (first.Lyrics.Exists()) + { + return first; + } + else + { + foreach (var found in founds) + { + if (found.Path.EndsWith(".lrc")) + { + using (FileStream fs = File.OpenRead(found.Path)) + { + _charsetDetector.Feed(fs); + _charsetDetector.DataEnd(); + } + + string content; + if (_charsetDetector.Charset != null) + { + Encoding encoding = Encoding.GetEncoding( + _charsetDetector.Charset + ); + content = File.ReadAllText(found.Path, encoding); + } + else + { + content = File.ReadAllText(found.Path, Encoding.UTF8); + } + first.Lyrics.ParseLRC(content); + + return first; + } + } + return first; + } + } + } + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs index f9d8886..e4b3929 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs @@ -27,6 +27,9 @@ namespace BetterLyrics.WinUI3.Services.Settings public const int CoverOverlayOpacity = 100; // 1.0 public const int CoverOverlayBlurAmount = 200; + // Album art + public const int CoverImageRadius = 24; + // Lyrics public const int LyricsAlignmentType = 1; // Center public const int LyricsBlurAmount = 0; @@ -36,5 +39,6 @@ namespace BetterLyrics.WinUI3.Services.Settings public const bool IsLyricsGlowEffectEnabled = false; public const bool IsLyricsDynamicGlowEffectEnabled = false; public const int LyricsFontColorType = 0; // Default + public const int LyricsFontSelectedAccentColorIndex = 0; } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs index ff1f1a5..6117a88 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs @@ -26,6 +26,9 @@ namespace BetterLyrics.WinUI3.Services.Settings public const string CoverOverlayOpacity = "CoverOverlayOpacity"; public const string CoverOverlayBlurAmount = "CoverOverlayBlurAmount"; + // Album art + public const string CoverImageRadius = "CoverImageRadius"; + // Lyrics public const string LyricsAlignmentType = "LyricsAlignmentType"; public const string LyricsBlurAmount = "LyricsBlurAmount"; @@ -35,5 +38,7 @@ namespace BetterLyrics.WinUI3.Services.Settings public const string IsLyricsGlowEffectEnabled = "IsLyricsGlowEffectEnabled"; public const string IsLyricsDynamicGlowEffectEnabled = "IsLyricsDynamicGlowEffectEnabled"; public const string LyricsFontColorType = "LyricsFontColorType"; + public const string LyricsFontSelectedAccentColorIndex = + "LyricsFontSelectedAccentColorIndex"; } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs index 5215757..0e52d80 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs @@ -1,54 +1,62 @@ -using BetterLyrics.WinUI3.Messages; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Messaging; -using DevWinUI; -using Microsoft.UI.Xaml; -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using BetterLyrics.WinUI3.Messages; +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Messaging; +using DevWinUI; +using Microsoft.UI.Xaml; +using Newtonsoft.Json; using Windows.Globalization; using Windows.Storage; -namespace BetterLyrics.WinUI3.Services.Settings { - public partial class SettingsService : ObservableObject { - +namespace BetterLyrics.WinUI3.Services.Settings +{ + public partial class SettingsService : ObservableObject + { private readonly ApplicationDataContainer _localSettings; - public SettingsService() { - + public SettingsService() + { _localSettings = ApplicationData.Current.LocalSettings; - _musicLibraries = [.. JsonConvert.DeserializeObject>( - Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!)!]; + _musicLibraries = + [ + .. JsonConvert.DeserializeObject>( + Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)! + )!, + ]; _musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries(); } - private void WatchMultipleDirectories(IEnumerable directories) { - foreach (var dir in directories) { - if (!Directory.Exists(dir)) continue; + private void WatchMultipleDirectories(IEnumerable directories) + { + foreach (var dir in directories) + { + if (!Directory.Exists(dir)) + continue; - var watcher = new FileSystemWatcher { + var watcher = new FileSystemWatcher + { Path = dir, Filter = "*.*", NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite, - EnableRaisingEvents = true + EnableRaisingEvents = true, }; } } - private void OnFileCreated(object sender, FileSystemEventArgs e) { - App.DispatcherQueue.TryEnqueue(() => - { - Debug.WriteLine($"[Created] {e.FullPath}"); - }); + private void OnFileCreated(object sender, FileSystemEventArgs e) + { + App.DispatcherQueue.TryEnqueue(() => { }); } - public bool IsFirstRun { + public bool IsFirstRun + { get => Get(SettingsKeys.IsFirstRun, SettingsDefaultValues.IsFirstRun); set => Set(SettingsKeys.IsFirstRun, value); } @@ -57,9 +65,11 @@ namespace BetterLyrics.WinUI3.Services.Settings { private bool _isRebuildingLyricsIndexDatabase = false; // Theme - public int Theme { + public int Theme + { get => Get(SettingsKeys.ThemeType, SettingsDefaultValues.ThemeType); - set { + set + { Set(SettingsKeys.ThemeType, value); WeakReferenceMessenger.Default.Send(new ThemeChangedMessage((ElementTheme)value)); } @@ -68,12 +78,13 @@ namespace BetterLyrics.WinUI3.Services.Settings { // Music private ObservableCollection _musicLibraries; - public ObservableCollection MusicLibraries { - get { - return _musicLibraries; - } - set { - if (_musicLibraries != null) { + public ObservableCollection MusicLibraries + { + get { return _musicLibraries; } + set + { + if (_musicLibraries != null) + { _musicLibraries.CollectionChanged -= (_, _) => SaveMusicLibraries(); } @@ -84,17 +95,20 @@ namespace BetterLyrics.WinUI3.Services.Settings { } } - private void SaveMusicLibraries() { + private void SaveMusicLibraries() + { Set(SettingsKeys.MusicLibraries, JsonConvert.SerializeObject(MusicLibraries.ToList())); } - // Language - public int Language { + public int Language + { get => Get(SettingsKeys.Language, SettingsDefaultValues.Language); - set { + set + { Set(SettingsKeys.Language, value); - switch ((Models.Language)Language) { + switch ((Models.Language)Language) + { case Models.Language.FollowSystem: ApplicationLanguages.PrimaryLanguageOverride = ""; break; @@ -114,76 +128,138 @@ namespace BetterLyrics.WinUI3.Services.Settings { } // Backdrop - public int BackdropType { + public int BackdropType + { get => Get(SettingsKeys.BackdropType, SettingsDefaultValues.BackdropType); - set { + set + { Set(SettingsKeys.BackdropType, value); - WeakReferenceMessenger.Default.Send(new SystemBackdropChangedMessage((BackdropType)value)); + WeakReferenceMessenger.Default.Send( + new SystemBackdropChangedMessage((BackdropType)value) + ); } } - public bool IsCoverOverlayEnabled { - get => Get(SettingsKeys.IsCoverOverlayEnabled, SettingsDefaultValues.IsCoverOverlayEnabled); + public bool IsCoverOverlayEnabled + { + get => + Get( + SettingsKeys.IsCoverOverlayEnabled, + SettingsDefaultValues.IsCoverOverlayEnabled + ); set => Set(SettingsKeys.IsCoverOverlayEnabled, value); } - public bool IsDynamicCoverOverlay { - get => Get(SettingsKeys.IsDynamicCoverOverlay, SettingsDefaultValues.IsDynamicCoverOverlay); + public bool IsDynamicCoverOverlay + { + get => + Get( + SettingsKeys.IsDynamicCoverOverlay, + SettingsDefaultValues.IsDynamicCoverOverlay + ); set => Set(SettingsKeys.IsDynamicCoverOverlay, value); } - public int CoverOverlayOpacity { + public int CoverOverlayOpacity + { get => Get(SettingsKeys.CoverOverlayOpacity, SettingsDefaultValues.CoverOverlayOpacity); set => Set(SettingsKeys.CoverOverlayOpacity, value); } - public int CoverOverlayBlurAmount { - get => Get(SettingsKeys.CoverOverlayBlurAmount, SettingsDefaultValues.CoverOverlayBlurAmount); + public int CoverOverlayBlurAmount + { + get => + Get( + SettingsKeys.CoverOverlayBlurAmount, + SettingsDefaultValues.CoverOverlayBlurAmount + ); set => Set(SettingsKeys.CoverOverlayBlurAmount, value); } + // Album art + public int CoverImageRadius + { + get => Get(SettingsKeys.CoverImageRadius, SettingsDefaultValues.CoverImageRadius); + set => Set(SettingsKeys.CoverImageRadius, value); + } + // Lyrics - public int LyricsAlignmentType { + public int LyricsAlignmentType + { get => Get(SettingsKeys.LyricsAlignmentType, SettingsDefaultValues.LyricsAlignmentType); set => Set(SettingsKeys.LyricsAlignmentType, value); } - public int LyricsBlurAmount { + public int LyricsBlurAmount + { get => Get(SettingsKeys.LyricsBlurAmount, SettingsDefaultValues.LyricsBlurAmount); set => Set(SettingsKeys.LyricsBlurAmount, value); } - public int LyricsVerticalEdgeOpacity { - get => Get(SettingsKeys.LyricsVerticalEdgeOpacity, SettingsDefaultValues.LyricsVerticalEdgeOpacity); + public int LyricsVerticalEdgeOpacity + { + get => + Get( + SettingsKeys.LyricsVerticalEdgeOpacity, + SettingsDefaultValues.LyricsVerticalEdgeOpacity + ); set => Set(SettingsKeys.LyricsVerticalEdgeOpacity, value); } - public float LyricsLineSpacingFactor { - get => Get(SettingsKeys.LyricsLineSpacingFactor, SettingsDefaultValues.LyricsLineSpacingFactor); + public float LyricsLineSpacingFactor + { + get => + Get( + SettingsKeys.LyricsLineSpacingFactor, + SettingsDefaultValues.LyricsLineSpacingFactor + ); set => Set(SettingsKeys.LyricsLineSpacingFactor, value); } - public int LyricsFontSize { + public int LyricsFontSize + { get => Get(SettingsKeys.LyricsFontSize, SettingsDefaultValues.LyricsFontSize); set => Set(SettingsKeys.LyricsFontSize, value); } - public bool IsLyricsGlowEffectEnabled { - get => Get(SettingsKeys.IsLyricsGlowEffectEnabled, SettingsDefaultValues.IsLyricsGlowEffectEnabled); + public bool IsLyricsGlowEffectEnabled + { + get => + Get( + SettingsKeys.IsLyricsGlowEffectEnabled, + SettingsDefaultValues.IsLyricsGlowEffectEnabled + ); set => Set(SettingsKeys.IsLyricsGlowEffectEnabled, value); } - public bool IsLyricsDynamicGlowEffectEnabled { - get => Get(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled); + public bool IsLyricsDynamicGlowEffectEnabled + { + get => + Get( + SettingsKeys.IsLyricsDynamicGlowEffectEnabled, + SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled + ); set => Set(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, value); } - public int LyricsFontColorType { + public int LyricsFontColorType + { get => Get(SettingsKeys.LyricsFontColorType, SettingsDefaultValues.LyricsFontColorType); set => Set(SettingsKeys.LyricsFontColorType, value); } + public int LyricsFontSelectedAccentColorIndex + { + get => + Get( + SettingsKeys.LyricsFontSelectedAccentColorIndex, + SettingsDefaultValues.LyricsFontSelectedAccentColorIndex + ); + set => Set(SettingsKeys.LyricsFontSelectedAccentColorIndex, value); + } - private T? Get(string key, T? defaultValue = default) { - if (_localSettings.Values.TryGetValue(key, out object? value)) { + private T? Get(string key, T? defaultValue = default) + { + if (_localSettings.Values.TryGetValue(key, out object? value)) + { return (T)Convert.ChangeType(value, typeof(T)); } return defaultValue; } - private void Set(string key, T value, [CallerMemberName] string? propertyName = null) { + private void Set(string key, T value, [CallerMemberName] string? propertyName = null) + { _localSettings.Values[key] = value; OnPropertyChanged(propertyName); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw index 05636b2..02afdd6 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw @@ -279,7 +279,7 @@ Lyrics effect - + Album background @@ -363,4 +363,10 @@ Album art accent color + + Album art style + + + Corner radius + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw index f1fb93a..e303bb2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw @@ -279,7 +279,7 @@ 歌词效果 - + 专辑背景 @@ -363,4 +363,10 @@ 专辑强调色 + + 专辑封面样式 + + + 圆角半径 + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw index 2274e5e..f24bac3 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw @@ -279,7 +279,7 @@ 歌詞效果 - + 專輯背景 @@ -363,4 +363,10 @@ 專輯強調色 + + 專輯封面樣式 + + + 圓角半徑 + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs index 6141aad..895e061 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs @@ -28,10 +28,11 @@ using static CommunityToolkit.WinUI.Animations.Expressions.ExpressionValues; namespace BetterLyrics.WinUI3.ViewModels { - public partial class MainViewModel(SettingsService settingsService) : ObservableObject + public partial class MainViewModel( + SettingsService settingsService, + DatabaseService databaseService + ) : ObservableObject { - private readonly CharsetDetector _charsetDetector = new(); - [ObservableProperty] private bool _isAnyMusicSessionExisted = false; @@ -67,12 +68,13 @@ namespace BetterLyrics.WinUI3.ViewModels private readonly Helper.ColorThief _colorThief = new(); private readonly SettingsService _settingsService = settingsService; + private readonly DatabaseService _databaseService = databaseService; public List GetLyrics(Track? track) { List result = []; - var lyricsPhrases = track?.Lyrics.SynchronizedLyrics; + var lyricsPhrases = track?.Lyrics?.SynchronizedLyrics; if (lyricsPhrases?.Count > 0) { @@ -126,91 +128,6 @@ namespace BetterLyrics.WinUI3.ViewModels return result; } - public async Task FindTrackFromDirectories( - IEnumerable directories, - GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps - ) - { - Track? finalResult = null; - - if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null) - return finalResult; - - finalResult = new() { Title = mediaProps.Title, Artist = mediaProps.Artist }; - - bool coverFound = false; - bool lyricsFound = false; - - if (mediaProps.Thumbnail is IRandomAccessStreamReference streamReference) - { - coverFound = true; - PictureInfo pictureInfo = PictureInfo.fromBinaryData( - await ImageHelper.ToByteArrayAsync(streamReference) - ); - finalResult.EmbeddedPictures.Add(pictureInfo); - } - - foreach (var dir in directories) - { - if (!Directory.Exists(dir)) - continue; - - foreach ( - var file in Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories) - ) - { - string content = File.ReadAllText(file); - var result = new Track(content); - - if ( - result.Title.Contains(mediaProps.Title) - && result.Artist.Contains(mediaProps.Artist) - ) - { - if (!coverFound && result.EmbeddedPictures.Count > 0) - { - coverFound = true; - finalResult.EmbeddedPictures.AddRange(result.EmbeddedPictures); - } - - if (!lyricsFound && result.Lyrics != null) - { - lyricsFound = true; - finalResult.Lyrics = result.Lyrics; - } - } - - if (!lyricsFound && file.EndsWith(".lrc")) - { - using (FileStream fs = File.OpenRead(file)) - { - _charsetDetector.Feed(fs); - _charsetDetector.DataEnd(); - } - - if (_charsetDetector.Charset != null) - { - Encoding encoding = Encoding.GetEncoding(_charsetDetector.Charset); - content = File.ReadAllText(file, encoding); - } - else - { - content = File.ReadAllText(file, Encoding.UTF8); - } - - lyricsFound = true; - finalResult.Lyrics = new(); - finalResult.Lyrics.ParseLRC(content); - } - - if (coverFound && lyricsFound) - return finalResult; - } - } - - return finalResult; - } - public async Task<(List, SoftwareBitmap?, uint, uint)> SetSongInfoAsync( GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps ) @@ -224,10 +141,23 @@ namespace BetterLyrics.WinUI3.ViewModels IRandomAccessStream? stream = null; - var track = await FindTrackFromDirectories(_settingsService.MusicLibraries, mediaProps); + var track = _databaseService.GetMusicMetadata(mediaProps); - if (track?.EmbeddedPictures?[0].PictureData is byte[] bytes) - stream = await ImageHelper.GetStreamFromBytesAsync(bytes); + if (mediaProps?.Thumbnail is IRandomAccessStreamReference reference) + { + stream = await reference.OpenReadAsync(); + } + else + { + if (track?.EmbeddedPictures.Count > 0) + { + var bytes = track.EmbeddedPictures[0].PictureData; + if (bytes != null) + { + stream = await Helper.ImageHelper.GetStreamFromBytesAsync(bytes); + } + } + } // Set cover image and dominant colors if (stream == null) diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs index 00e8f02..b8c8762 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs @@ -40,7 +40,7 @@ namespace BetterLyrics.WinUI3.Views public sealed partial class MainPage : Page { public MainViewModel ViewModel => (MainViewModel)DataContext; - private readonly SettingsService _settingsService; + public SettingsService SettingsService { get; set; } private List _lyricsLines = []; @@ -101,24 +101,21 @@ namespace BetterLyrics.WinUI3.Views { this.InitializeComponent(); + _queueTimer = _dispatcherQueue.CreateTimer(); + _logger = Ioc.Default.GetService>()!; + SettingsService = Ioc.Default.GetService()!; + DataContext = Ioc.Default.GetService(); + + SettingsService.PropertyChanged += SettingsService_PropertyChanged; + ViewModel.PropertyChanged += ViewModel_PropertyChanged; SetLyricsColor(); - _settingsService = Ioc.Default.GetService()!; - - if (_settingsService.IsFirstRun) + if (SettingsService.IsFirstRun) { WelcomeTeachingTip.IsOpen = true; } - - _settingsService.PropertyChanged += SettingsService_PropertyChanged; - - DataContext = Ioc.Default.GetService(); - - ViewModel.PropertyChanged += ViewModel_PropertyChanged; - - _queueTimer = _dispatcherQueue.CreateTimer(); } private async Task ForceToScrollToCurrentPlayingLineAsync() @@ -135,21 +132,28 @@ namespace BetterLyrics.WinUI3.Views { switch (e.PropertyName) { - case nameof(_settingsService.LyricsFontSize): - case nameof(_settingsService.LyricsLineSpacingFactor): + case nameof(SettingsService.LyricsFontSize): + case nameof(SettingsService.LyricsLineSpacingFactor): LayoutLyrics(); await ForceToScrollToCurrentPlayingLineAsync(); break; - case nameof(_settingsService.IsRebuildingLyricsIndexDatabase): - if (!_settingsService.IsRebuildingLyricsIndexDatabase) + case nameof(SettingsService.IsRebuildingLyricsIndexDatabase): + if (!SettingsService.IsRebuildingLyricsIndexDatabase) { CurrentSession_MediaPropertiesChanged(_currentSession, null); } break; - case nameof(_settingsService.Theme): + case nameof(SettingsService.Theme): + case nameof(SettingsService.LyricsFontColorType): + case nameof(SettingsService.LyricsFontSelectedAccentColorIndex): await Task.Delay(1); SetLyricsColor(); break; + case nameof(SettingsService.CoverImageRadius): + CoverImageGrid.CornerRadius = new CornerRadius( + SettingsService.CoverImageRadius / 100f * (CoverImageGrid.ActualHeight / 2) + ); + break; default: break; } @@ -172,7 +176,19 @@ namespace BetterLyrics.WinUI3.Views private void SetLyricsColor() { - _lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color; + switch ((LyricsFontColorType)SettingsService.LyricsFontColorType) + { + case LyricsFontColorType.Default: + _lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color; + break; + case LyricsFontColorType.Dominant: + _lyricsColor = ViewModel.CoverImageDominantColors[ + SettingsService.LyricsFontSelectedAccentColorIndex + ]; + break; + default: + break; + } } private async void InitMediaManager() @@ -391,7 +407,7 @@ namespace BetterLyrics.WinUI3.Views var b = _lyricsColor.B; // Draw (dynamic) cover image as the very first layer - if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) + if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) { DrawCoverImage(sender, ds); } @@ -406,7 +422,7 @@ namespace BetterLyrics.WinUI3.Views using var glowedLyrics = new CanvasCommandList(sender); using (var glowedLyricsDs = glowedLyrics.CreateDrawingSession()) { - if (_settingsService.IsLyricsGlowEffectEnabled) + if (SettingsService.IsLyricsGlowEffectEnabled) { glowedLyricsDs.DrawImage( new GaussianBlurEffect @@ -432,7 +448,7 @@ namespace BetterLyrics.WinUI3.Views // Mock gradient blurred lyrics layer using var combinedBlurredLyrics = new CanvasCommandList(sender); using var combinedBlurredLyricsDs = combinedBlurredLyrics.CreateDrawingSession(); - if (_settingsService.LyricsBlurAmount == 0) + if (SettingsService.LyricsBlurAmount == 0) { combinedBlurredLyricsDs.DrawImage(glowedLyrics); } @@ -446,7 +462,7 @@ namespace BetterLyrics.WinUI3.Views { Source = glowedLyrics, BlurAmount = (float)( - _settingsService.LyricsBlurAmount * (1 - i / (0.5 - step)) + SettingsService.LyricsBlurAmount * (1 - i / (0.5 - step)) ), Optimization = EffectOptimization.Quality, BorderMode = EffectBorderMode.Soft, @@ -483,7 +499,7 @@ namespace BetterLyrics.WinUI3.Views maskedCombinedBlurredLyrics.CreateDrawingSession() ) { - if (_settingsService.LyricsVerticalEdgeOpacity == 100) + if (SettingsService.LyricsVerticalEdgeOpacity == 100) { maskedCombinedBlurredLyricsDs.DrawImage(combinedBlurredLyrics); } @@ -538,7 +554,7 @@ namespace BetterLyrics.WinUI3.Views float centerX = position.X; float centerY = position.Y + (float)line.TextLayout.LayoutBounds.Height / 2; - switch ((LyricsAlignmentType)_settingsService.LyricsAlignmentType) + switch ((LyricsAlignmentType)SettingsService.LyricsAlignmentType) { case LyricsAlignmentType.Left: line.TextLayout.HorizontalAlignment = CanvasHorizontalAlignment.Left; @@ -632,10 +648,10 @@ namespace BetterLyrics.WinUI3.Views using var coverOverlayEffect = new OpacityEffect { - Opacity = _settingsService.CoverOverlayOpacity / 100f, + Opacity = SettingsService.CoverOverlayOpacity / 100f, Source = new GaussianBlurEffect { - BlurAmount = _settingsService.CoverOverlayBlurAmount, + BlurAmount = SettingsService.CoverOverlayBlurAmount, Source = new ScaleEffect { InterpolationMode = CanvasImageInterpolation.HighQualityCubic, @@ -664,9 +680,7 @@ namespace BetterLyrics.WinUI3.Views byte b ) { - byte verticalEdgeAlpha = (byte)( - 255 * _settingsService.LyricsVerticalEdgeOpacity / 100f - ); + byte verticalEdgeAlpha = (byte)(255 * SettingsService.LyricsVerticalEdgeOpacity / 100f); using var maskBrush = new CanvasLinearGradientBrush( control, [ @@ -690,18 +704,18 @@ namespace BetterLyrics.WinUI3.Views { _currentTime += args.Timing.ElapsedTime; - if (_settingsService.IsDynamicCoverOverlay) + if (SettingsService.IsDynamicCoverOverlay) { _coverBitmapRotateAngle += _coverRotateSpeed; _coverBitmapRotateAngle %= MathF.PI * 2; } - if (_settingsService.IsLyricsDynamicGlowEffectEnabled) + if (SettingsService.IsLyricsDynamicGlowEffectEnabled) { _lyricsGlowEffectAngle += _lyricsGlowEffectSpeed; _lyricsGlowEffectAngle %= MathF.PI * 2; } - if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) + if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) { var diagonal = Math.Sqrt( Math.Pow(_lyricsAreaWidth, 2) + Math.Pow(_lyricsAreaHeight, 2) @@ -850,7 +864,7 @@ namespace BetterLyrics.WinUI3.Views { using CanvasTextFormat textFormat = new() { - FontSize = _settingsService.LyricsFontSize, + FontSize = SettingsService.LyricsFontSize, HorizontalAlignment = CanvasHorizontalAlignment.Left, VerticalAlignment = CanvasVerticalAlignment.Top, FontWeight = FontWeights.Bold, @@ -876,7 +890,7 @@ namespace BetterLyrics.WinUI3.Views y += (float)line.TextLayout.LayoutBounds.Height / line.TextLayout.LineCount - * (line.TextLayout.LineCount + _settingsService.LyricsLineSpacingFactor); + * (line.TextLayout.LineCount + SettingsService.LyricsLineSpacingFactor); } } @@ -1028,7 +1042,7 @@ namespace BetterLyrics.WinUI3.Views TeachingTipClosedEventArgs args ) { - _settingsService.IsFirstRun = false; + SettingsService.IsFirstRun = false; } private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e) diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml index a2373ff..3550b0f 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml @@ -138,7 +138,7 @@ - + + + + + + + + + + + + @@ -241,7 +262,7 @@ - +