From 66d8705066d0cf23d5532a9ef4d475e442506b87 Mon Sep 17 00:00:00 2001 From: Zhe Fang Date: Tue, 17 Jun 2025 14:01:52 -0400 Subject: [PATCH] change: remove system tray, combine desktop and in-app lyrics mode into one single window --- .../BetterLyrics.WinUI3/App.xaml.cs | 13 +- .../BetterLyrics.WinUI3.csproj | 24 +- .../BetterLyrics.WinUI3/ClassDiagram1.cd | 26 -- .../Controls/LyricsSettingsControl.xaml.cs | 6 +- .../{Models => Enums}/AutoStartWindowType.cs | 2 +- .../{Models => Enums}/BackdropType.cs | 2 +- .../{Models => Enums}/Language.cs | 2 +- .../{Models => Enums}/LyricsAlignmentType.cs | 2 +- .../LyricsDisplayType.cs} | 4 +- .../{Models => Enums}/LyricsFontColorType.cs | 2 +- .../{Models => Enums}/LyricsPlayingState.cs | 2 +- .../{Models => Enums}/LyricsType.cs | 2 +- .../{Models => Enums}/LyricsWindowType.cs | 2 +- .../{Models => Enums}/TitleBarType.cs | 2 +- .../IsPlayingChangedEventArgs.cs | 2 +- .../PositionChangedEventArgs.cs | 2 +- .../SongInfoChangedEventArgs.cs | 3 +- .../Helper/{AppBarHelper.cs => DockHelper.cs} | 100 ++--- .../Helper/SystemBackdropHelper.cs | 2 +- .../Helper/WindowHelper.cs | 85 +++-- .../BetterLyrics.WinUI3/Models/LyricsLine.cs | 1 + .../BetterLyrics.WinUI3/Models/SongInfo.cs | 3 +- .../Renderer/DesktopLyricsRenderer.xaml | 46 --- .../Renderer/DesktopLyricsRenderer.xaml.cs | 54 --- ...yricsRenderer.xaml => LyricsRenderer.xaml} | 2 +- ...enderer.xaml.cs => LyricsRenderer.xaml.cs} | 8 +- .../Services/Database/DatabaseService.cs | 12 +- .../Services/Playback/IPlaybackService.cs | 1 + .../Services/Playback/PlaybackService.cs | 1 + .../Services/Settings/ISettingsService.cs | 2 +- .../Services/Settings/SettingsService.cs | 4 +- .../Strings/en-US/Resources.resw | 16 +- .../Strings/zh-CN/Resources.resw | 16 +- .../Strings/zh-TW/Resources.resw | 16 +- .../BaseLyricsSettingsControlViewModel.cs | 76 ---- .../ViewModels/BaseWindowViewModel.cs | 62 ---- .../ViewModels/DesktopLyricsPageViewModel.cs | 21 -- .../DesktopLyricsRendererViewModel.cs | 220 ----------- .../DesktopLyricsSettingsControlViewModel.cs | 99 ----- .../ViewModels/HostWindowViewModel.cs | 51 +-- .../InAppLyricsRendererViewModel.cs | 350 ------------------ ...ageViewModel.cs => LyricsPageViewModel.cs} | 46 ++- ...iewModel.cs => LyricsRendererViewModel.cs} | 324 +++++++++++++++- ...l.cs => LyricsSettingsControlViewModel.cs} | 33 +- .../ViewModels/OverlayWindowViewModel.cs | 27 -- .../ViewModels/SettingsViewModel.cs | 13 +- .../ViewModels/SystemTrayPageViewModel.cs | 42 --- .../Views/DesktopLyricsPage.xaml | 59 --- .../Views/DesktopLyricsPage.xaml.cs | 51 --- .../BetterLyrics.WinUI3/Views/HostWindow.xaml | 22 +- .../Views/HostWindow.xaml.cs | 167 ++++++--- .../{InAppLyricsPage.xaml => LyricsPage.xaml} | 63 +--- ...pLyricsPage.xaml.cs => LyricsPage.xaml.cs} | 22 +- .../Views/OverlayWindow.xaml | 15 - .../Views/OverlayWindow.xaml.cs | 88 ----- .../Views/SettingsPage.xaml | 16 +- .../Views/SettingsPage.xaml.cs | 7 +- .../Views/SystemTrayPage.xaml | 28 -- .../Views/SystemTrayPage.xaml.cs | 36 -- 59 files changed, 740 insertions(+), 1665 deletions(-) delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ClassDiagram1.cd rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/AutoStartWindowType.cs (86%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/BackdropType.cs (88%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/Language.cs (87%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/LyricsAlignmentType.cs (85%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models/InAppLyricsDisplayType.cs => Enums/LyricsDisplayType.cs} (56%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/LyricsFontColorType.cs (84%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/LyricsPlayingState.cs (92%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/LyricsType.cs (84%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/LyricsWindowType.cs (85%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Enums}/TitleBarType.cs (94%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Events}/IsPlayingChangedEventArgs.cs (87%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Events}/PositionChangedEventArgs.cs (87%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/{Models => Events}/SongInfoChangedEventArgs.cs (79%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/{AppBarHelper.cs => DockHelper.cs} (67%) delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml.cs rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/{InAppLyricsRenderer.xaml => LyricsRenderer.xaml} (92%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/{InAppLyricsRenderer.xaml.cs => LyricsRenderer.xaml.cs} (81%) delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsSettingsControlViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseWindowViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsPageViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsRendererViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsSettingsControlViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsRendererViewModel.cs rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/{InAppLyricsPageViewModel.cs => LyricsPageViewModel.cs} (79%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/{BaseLyricsRendererViewModel.cs => LyricsRendererViewModel.cs} (70%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/{InAppLyricsSettingsControlViewModel.cs => LyricsSettingsControlViewModel.cs} (74%) delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/OverlayWindowViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SystemTrayPageViewModel.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml.cs rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/{InAppLyricsPage.xaml => LyricsPage.xaml} (92%) rename BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/{InAppLyricsPage.xaml.cs => LyricsPage.xaml.cs} (75%) delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/OverlayWindow.xaml delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/OverlayWindow.xaml.cs delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SystemTrayPage.xaml delete mode 100644 BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SystemTrayPage.xaml.cs diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs index 555b680..4eaa220 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs @@ -76,16 +76,11 @@ namespace BetterLyrics.WinUI3 .AddSingleton() .AddSingleton() // ViewModels (Singleton) - .AddSingleton() .AddSingleton() - .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() - .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() .BuildServiceProvider() ); } @@ -105,7 +100,7 @@ namespace BetterLyrics.WinUI3 /// Details about the launch request and process. protected override void OnLaunched(LaunchActivatedEventArgs args) { - WindowHelper.OpenSystemTrayWindow(); + WindowHelper.OpenLyricsWindow(); } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj index 00b395d..1e7ca95 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj @@ -12,11 +12,6 @@ - - - - - @@ -74,24 +69,9 @@ MSBuild:Compile - - - MSBuild:Compile - - - - - MSBuild:Compile - - - - - MSBuild:Compile - - False @@ -115,7 +95,7 @@ AssemblyVersion AssemblyVersion.None.None 2025.6.0 - 2025.6.17.0154 - 2025.6.17.0154 + 2025.6.17.1756 + 2025.6.17.1756 diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ClassDiagram1.cd b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ClassDiagram1.cd deleted file mode 100644 index ee88bb5..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ClassDiagram1.cd +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - ABCAAAgAABAAAAAAABAABAAAggAAQAAQAIAAAAAAAAg= - ViewModels\HostWindowViewModel.cs - - - - - - - IAQABAAACZABAgIQEAAABAAAAFCBAAACIAAAYIAAAiA= - ViewModels\SettingsViewModel.cs - - - - - - AAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAQAAAAACAAA= - Views\DesktopLyricsPage.xaml.cs - - - - \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSettingsControl.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSettingsControl.xaml.cs index 3b6e276..ac0b221 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSettingsControl.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Controls/LyricsSettingsControl.xaml.cs @@ -40,15 +40,15 @@ namespace BetterLyrics.WinUI3.Controls // new PropertyMetadata(null) //); - public BaseLyricsSettingsControlViewModel ViewModel + public LyricsSettingsControlViewModel ViewModel { - get => (BaseLyricsSettingsControlViewModel)GetValue(ViewModelProperty); + get => (LyricsSettingsControlViewModel)GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); } public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register( nameof(ViewModel), - typeof(BaseLyricsSettingsControlViewModel), + typeof(LyricsSettingsControlViewModel), typeof(LyricsSettingsControl), new PropertyMetadata(null) ); diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/AutoStartWindowType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/AutoStartWindowType.cs similarity index 86% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/AutoStartWindowType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/AutoStartWindowType.cs index 85b6f38..ec05dda 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/AutoStartWindowType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/AutoStartWindowType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum AutoStartWindowType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/BackdropType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/BackdropType.cs similarity index 88% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/BackdropType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/BackdropType.cs index c0a82ad..78a8ec1 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/BackdropType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/BackdropType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum BackdropType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/Language.cs similarity index 87% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/Language.cs index 3f33568..7b03a91 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/Language.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum Language { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsAlignmentType.cs similarity index 85% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsAlignmentType.cs index 06d1e1f..2be15c7 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsAlignmentType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum LyricsAlignmentType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/InAppLyricsDisplayType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsDisplayType.cs similarity index 56% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/InAppLyricsDisplayType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsDisplayType.cs index c0921fd..999ba97 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/InAppLyricsDisplayType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsDisplayType.cs @@ -1,6 +1,6 @@ -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { - public enum InAppLyricsDisplayType + public enum LyricsDisplayType { AlbumArtOnly, LyricsOnly, diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsFontColorType.cs similarity index 84% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsFontColorType.cs index a560f4e..422fa19 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsFontColorType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum LyricsFontColorType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsPlayingState.cs similarity index 92% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsPlayingState.cs index de7e486..bc8acc4 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsPlayingState.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum LyricsPlayingState { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsType.cs similarity index 84% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsType.cs index 89488d4..13dfd66 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum LyricsType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsWindowType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsWindowType.cs similarity index 85% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsWindowType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsWindowType.cs index f0c32fd..6c5d8a4 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsWindowType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/LyricsWindowType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum LyricsWindowType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/TitleBarType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/TitleBarType.cs similarity index 94% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/TitleBarType.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/TitleBarType.cs index 8e9a8c7..c4da218 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/TitleBarType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/TitleBarType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Enums { public enum TitleBarType { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/IsPlayingChangedEventArgs.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/IsPlayingChangedEventArgs.cs similarity index 87% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/IsPlayingChangedEventArgs.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/IsPlayingChangedEventArgs.cs index 5ab6c01..347fda4 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/IsPlayingChangedEventArgs.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/IsPlayingChangedEventArgs.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Events { public class IsPlayingChangedEventArgs(bool isPlaying) : EventArgs { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PositionChangedEventArgs.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/PositionChangedEventArgs.cs similarity index 87% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PositionChangedEventArgs.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/PositionChangedEventArgs.cs index f4aa6dc..e42add5 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/PositionChangedEventArgs.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/PositionChangedEventArgs.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Events { public class PositionChangedEventArgs(TimeSpan position) : EventArgs() { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfoChangedEventArgs.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/SongInfoChangedEventArgs.cs similarity index 79% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfoChangedEventArgs.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/SongInfoChangedEventArgs.cs index 896fff4..325648d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfoChangedEventArgs.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Events/SongInfoChangedEventArgs.cs @@ -3,8 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using BetterLyrics.WinUI3.Models; -namespace BetterLyrics.WinUI3.Models +namespace BetterLyrics.WinUI3.Events { public class SongInfoChangedEventArgs(SongInfo? songInfo) : EventArgs { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppBarHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DockHelper.cs similarity index 67% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppBarHelper.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DockHelper.cs index 137c13c..1a81096 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppBarHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DockHelper.cs @@ -11,51 +11,85 @@ using WinUIEx; namespace BetterLyrics.WinUI3.Helper { - public static class AppBarHelper + public static class DockHelper { - // 记录哪些 HWND 已经注册 AppBar private static readonly HashSet _registered = []; - /// - /// Enable AppBar function - /// - /// Target window - /// App bar height - /// Is click-through enabled + private static readonly Dictionary _originalPositions = []; + + private static readonly Dictionary _originalWindowStyle = []; + + public static void Disable(Window window) + { + window.SetIsShownInSwitchers(true); + window.ExtendsContentIntoTitleBar = true; + + IntPtr hwnd = WindowNative.GetWindowHandle(window); + + window.SetWindowStyle(_originalWindowStyle[hwnd]); + _originalWindowStyle.Remove(hwnd); + + if (_originalPositions.TryGetValue(hwnd, out var rect)) + { + SetWindowPos( + hwnd, + IntPtr.Zero, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW + ); + _originalPositions.Remove(hwnd); + } + + window.SetIsAlwaysOnTop(false); + + UnregisterAppBar(hwnd); + } + public static void Enable(Window window, int appBarHeight) { + window.SetIsShownInSwitchers(false); + window.ExtendsContentIntoTitleBar = false; + IntPtr hwnd = WindowNative.GetWindowHandle(window); + if (!_originalWindowStyle.ContainsKey(hwnd)) + { + _originalWindowStyle[hwnd] = window.GetWindowStyle(); + } + window.SetWindowStyle(WindowStyle.Popup | WindowStyle.Visible); + + if (!_originalPositions.ContainsKey(hwnd)) + { + if (GetWindowRect(hwnd, out var rect)) + { + _originalPositions[hwnd] = rect; + } + } + RegisterAppBar(hwnd, appBarHeight); int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); SetWindowPos( hwnd, - HWND_TOPMOST, + IntPtr.Zero, 0, 0, screenWidth, appBarHeight, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW ); + + window.SetIsAlwaysOnTop(true); } - /// - /// 关闭并注销 AppBar,占位恢复。 - /// - public static void Disable(Window window) - { - IntPtr hwnd = WindowNative.GetWindowHandle(window); - UnregisterAppBar(hwnd); + [DllImport("user32.dll", SetLastError = true)] + private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); - // 移除 WS_EX_TRANSPARENT(可根据需求恢复其他样式) - int exStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - exStyle &= ~WS_EX_TRANSPARENT; - SetWindowLong(hwnd, GWL_EXSTYLE, exStyle); - } - - #region AppBar 注册逻辑 + #region AppBar registration private const uint ABM_NEW = 0x00000000; private const uint ABM_REMOVE = 0x00000001; private const uint ABM_SETPOS = 0x00000003; @@ -121,15 +155,11 @@ namespace BetterLyrics.WinUI3.Helper } #endregion - #region Win32 Helper & 常量 - - private const int GWL_EXSTYLE = -20; - private const int WS_EX_TRANSPARENT = 0x20; + #region Win32 Helper and Constants private const int SWP_NOACTIVATE = 0x0010; private const int SWP_NOOWNERZORDER = 0x0200; private const int SWP_SHOWWINDOW = 0x0040; - private static readonly IntPtr HWND_TOPMOST = new(-1); private const int SM_CXSCREEN = 0; private const int SM_CYSCREEN = 0; @@ -137,12 +167,6 @@ namespace BetterLyrics.WinUI3.Helper [DllImport("user32.dll")] private static extern int GetSystemMetrics(int nIndex); - [DllImport("user32.dll", SetLastError = true)] - private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); - - [DllImport("user32.dll", SetLastError = true)] - private static extern int GetWindowLong(IntPtr hWnd, int nIndex); - [DllImport("user32.dll", SetLastError = true)] private static extern bool SetWindowPos( IntPtr hWnd, @@ -153,14 +177,6 @@ namespace BetterLyrics.WinUI3.Helper int cy, uint uFlags ); - - [DllImport("user32.dll", SetLastError = true)] - private static extern bool SetLayeredWindowAttributes( - IntPtr hwnd, - uint crKey, - byte bAlpha, - uint dwFlags - ); #endregion } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs index f50c010..a9ba13e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs @@ -1,4 +1,4 @@ -using BetterLyrics.WinUI3.Models; +using BetterLyrics.WinUI3.Enums; using Microsoft.UI.Composition.SystemBackdrops; using Microsoft.UI.Xaml.Media; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WindowHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WindowHelper.cs index 4f8ac3d..731cdcb 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WindowHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/WindowHelper.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using BetterLyrics.WinUI3.Views; +using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using WinUIEx; @@ -7,46 +9,61 @@ namespace BetterLyrics.WinUI3.Helper { public static class WindowHelper { - public static void OpenSystemTrayWindow() + private static readonly Dictionary _windowCache = new(); + + public static void HideSystemTitleBar(this Window window) { - var window = new OverlayWindow(clickThrough: true); - TrackWindow(window); - window.Navigate(typeof(SystemTrayPage)); - window.Activate(); + window.ExtendsContentIntoTitleBar = true; + window.AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed; } - public static void OpenDesktopLyricsWindow() + public static void HideSystemTitleBarAndSetCustomTitleBar( + this Window window, + UIElement titleBar + ) { - var window = new OverlayWindow(listenOnActivatedWindowChange: true); - TrackWindow(window); - window.Navigate(typeof(DesktopLyricsPage)); - AppBarHelper.Enable(window, 48); - window.Activate(); + window.HideSystemTitleBar(); + window.SetTitleBar(titleBar); } public static void OpenSettingsWindow() { - var window = new HostWindow(); - TrackWindow(window); - window.Navigate(typeof(SettingsPage)); - window.Activate(); + OpenOrShowWindow(typeof(SettingsPage)); } - public static void OpenInAppLyricsWindow() + public static void OpenLyricsWindow() { - var window = new HostWindow(); - TrackWindow(window); - window.Navigate(typeof(InAppLyricsPage)); - window.Activate(); + OpenOrShowWindow(typeof(LyricsPage)); } - public static void TrackWindow(Window window) + private static void OpenOrShowWindow(Type pageType) { - window.Closed += (sender, args) => + if (_windowCache.TryGetValue(pageType, out var window)) { - _activeWindows.Remove(window); - }; - _activeWindows.Add(window); + if (window is HostWindow hostWindow) + { + hostWindow.Navigate(pageType); + } + window.TryShow(); + } + else + { + var newWindow = new HostWindow(); + TrackWindow(newWindow, pageType); + newWindow.Navigate(pageType); + newWindow.Activate(); + } + } + + public static void TrackWindow(Window window, Type pageType = null) + { + if (pageType != null) + { + _windowCache[pageType] = window; + } + + if (!_activeWindows.Contains(window)) + _activeWindows.Add(window); } public static Window GetWindowForElement(UIElement element) @@ -86,5 +103,21 @@ namespace BetterLyrics.WinUI3.Helper } private static List _activeWindows = new List(); + + public static void TryShow(this Window window) + { + if (window is not null) + { + window.Activate(); + } + } + + public static void TryHide(this Window window) + { + if (window is not null) + { + window.Hide(); + } + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs index ece1aae..b8f2702 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Numerics; +using BetterLyrics.WinUI3.Enums; namespace BetterLyrics.WinUI3.Models { diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfo.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfo.cs index 51f9b0b..549fa7d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfo.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/SongInfo.cs @@ -32,8 +32,7 @@ namespace BetterLyrics.WinUI3.Models public byte[]? AlbumArt { get; set; } = null; [ObservableProperty] - public partial ObservableCollection CoverImageDominantColors { get; set; } = - [.. Enumerable.Repeat(Colors.Transparent, ImageHelper.AccentColorCount)]; + public partial List? CoverImageDominantColors { get; set; } = null; public SongInfo() { } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml deleted file mode 100644 index 7ec7dcf..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml.cs deleted file mode 100644 index b289537..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/DesktopLyricsRenderer.xaml.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using BetterLyrics.WinUI3.ViewModels; -using CommunityToolkit.Mvvm.DependencyInjection; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; -using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Input; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Navigation; -using Windows.Foundation; -using Windows.Foundation.Collections; - -// To learn more about WinUI, the WinUI project structure, -// and more about our project templates, see: http://aka.ms/winui-project-info. - -namespace BetterLyrics.WinUI3.Renderer -{ - public sealed partial class DesktopLyricsRenderer : UserControl - { - public DesktopLyricsRendererViewModel ViewModel = - Ioc.Default.GetRequiredService(); - - public DesktopLyricsRenderer() - { - InitializeComponent(); - } - - private void LyricsCanvas_Draw( - Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, - Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedDrawEventArgs args - ) - { - ViewModel.Draw(sender, args.DrawingSession); - } - - private void LyricsCanvas_Update( - Microsoft.Graphics.Canvas.UI.Xaml.ICanvasAnimatedControl sender, - Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedUpdateEventArgs args - ) - { - ViewModel.Calculate(sender, args); - } - - private void LyricsCanvas_Loaded(object sender, RoutedEventArgs e) - { - ViewModel.RequestRelayout(); - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/InAppLyricsRenderer.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.xaml similarity index 92% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/InAppLyricsRenderer.xaml rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.xaml index ce17fd1..4921722 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/InAppLyricsRenderer.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Renderer/LyricsRenderer.xaml @@ -1,6 +1,6 @@ (); + ViewModel = Ioc.Default.GetRequiredService(); } private void LyricsCanvas_Draw( diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs index d3ae4fb..46b672c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs @@ -161,17 +161,13 @@ namespace BetterLyrics.WinUI3.Services.Database if (initSongInfo.AlbumArt == null) { - initSongInfo.CoverImageDominantColors = - [ - .. Enumerable.Repeat(Colors.Transparent, ImageHelper.AccentColorCount), - ]; + initSongInfo.CoverImageDominantColors = null; } else { - initSongInfo.CoverImageDominantColors = - [ - .. await ImageHelper.GetAccentColorsFromByte(initSongInfo.AlbumArt), - ]; + initSongInfo.CoverImageDominantColors = await ImageHelper.GetAccentColorsFromByte( + initSongInfo.AlbumArt + ); } if (initSongInfo.LyricsLines == null) { } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/IPlaybackService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/IPlaybackService.cs index daa0520..489fafc 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/IPlaybackService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/IPlaybackService.cs @@ -1,4 +1,5 @@ using System; +using BetterLyrics.WinUI3.Events; using BetterLyrics.WinUI3.Models; namespace BetterLyrics.WinUI3.Services.Playback diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/PlaybackService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/PlaybackService.cs index 36abd0d..172346a 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/PlaybackService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Playback/PlaybackService.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Threading.Tasks; +using BetterLyrics.WinUI3.Events; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Database; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/ISettingsService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/ISettingsService.cs index 38af36b..fc5cb97 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/ISettingsService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/ISettingsService.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using BetterLyrics.WinUI3.Models; +using BetterLyrics.WinUI3.Enums; using Microsoft.UI.Xaml; namespace BetterLyrics.WinUI3.Services.Settings diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs index 2a07e42..86cb61c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs @@ -2,7 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using BetterLyrics.WinUI3.Models; +using BetterLyrics.WinUI3.Enums; using CommunityToolkit.Mvvm.ComponentModel; using Microsoft.UI.Xaml; using Newtonsoft.Json; @@ -243,7 +243,7 @@ namespace BetterLyrics.WinUI3.Services.Settings SetDefault(ThemeTypeKey, (int)ElementTheme.Default); SetDefault(LanguageKey, (int)Language.FollowSystem); SetDefault(MusicLibrariesKey, "[]"); - SetDefault(BackdropTypeKey, (int)Models.BackdropType.DesktopAcrylic); + SetDefault(BackdropTypeKey, (int)BackdropType.DesktopAcrylic); // App behavior SetDefault(AutoStartWindowTypeKey, (int)AutoStartWindowType.InAppLyrics); // Album art diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw index 9482679..a3f85a1 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw @@ -223,9 +223,9 @@ Album art background opacity - Settings + Settings - BetterLyrics - + BetterLyrics @@ -382,7 +382,7 @@ Switch to desktop lyrics mode - Enter picture-in-picture mode + Picture-in-picture mode Exit picture-in-picture mode @@ -390,8 +390,8 @@ Lyrics not found - - In-app lyrics style & effect + + Lyrics style & effect Desktop lyrics style & effect @@ -420,4 +420,10 @@ Lyrics not found + + System tray - BetterLyrics + + + Dock mode + \ 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 5893b73..8dd52b3 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw @@ -223,9 +223,9 @@ 专辑图片背景不透明度 - 设置 + 设置 - BetterLyrics - + BetterLyrics @@ -382,7 +382,7 @@ 切换到桌面歌词模式 - 进入画中画模式 + 画中画模式 退出画中画模式 @@ -390,8 +390,8 @@ 未找到歌词 - - 应用内歌词样式与动效 + + 歌词样式与动效 桌面歌词样式与动效 @@ -420,4 +420,10 @@ 未找到歌词 + + 系统托盘 - BetterLyrics + + + 停靠模式 + \ 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 5fbd525..54160dd 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw @@ -223,9 +223,9 @@ 專輯圖片背景不透明度 - 設定 + 設定 - BetterLyrics - + BetterLyrics @@ -382,7 +382,7 @@ 切換到桌面歌詞模式 - 進入畫中畫模式 + 畫中畫模式 退出畫中畫模式 @@ -390,8 +390,8 @@ 找不到歌詞 - - 應用程式內歌詞樣式與動效 + + 歌詞樣式與動效 桌面歌詞樣式與動效 @@ -420,4 +420,10 @@ 找不到歌詞 + + 系統托盤 - BetterLyrics + + + 停靠模式 + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsSettingsControlViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsSettingsControlViewModel.cs deleted file mode 100644 index ce06352..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsSettingsControlViewModel.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Services.Playback; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; -using Microsoft.UI; -using Windows.UI; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public abstract partial class BaseLyricsSettingsControlViewModel : BaseViewModel - { - [ObservableProperty] - public partial ObservableCollection CoverImageDominantColors { get; set; } - - public abstract LyricsAlignmentType LyricsAlignmentType { get; set; } - - public abstract int LyricsBlurAmount { get; set; } - - public abstract int LyricsVerticalEdgeOpacity { get; set; } - - public abstract float LyricsLineSpacingFactor { get; set; } - - public abstract int LyricsFontSize { get; set; } - - public abstract bool IsLyricsGlowEffectEnabled { get; set; } - - public abstract bool IsLyricsDynamicGlowEffectEnabled { get; set; } - - public abstract LyricsFontColorType LyricsFontColorType { get; set; } - - private readonly IPlaybackService _playbackService; - - public BaseLyricsSettingsControlViewModel( - ISettingsService settingsService, - IPlaybackService playbackService - ) - : base(settingsService) - { - _playbackService = playbackService; - - _playbackService.SongInfoChanged += (s, e) => - { - UpdateCoverImageDominantColors(e.SongInfo?.CoverImageDominantColors); - }; - - UpdateCoverImageDominantColors(_playbackService.SongInfo?.CoverImageDominantColors); - } - - private void UpdateCoverImageDominantColors(ObservableCollection? value) - { - CoverImageDominantColors ??= - [ - .. Enumerable.Repeat(Colors.Transparent, ImageHelper.AccentColorCount), - ]; - for (int i = 0; i < CoverImageDominantColors.Count; i++) - { - CoverImageDominantColors[i] = Colors.Transparent; - } - if (value != null) - { - for (int i = 0; i < Math.Min(value.Count, CoverImageDominantColors.Count); i++) - { - CoverImageDominantColors[i] = value[i]; - } - } - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseWindowViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseWindowViewModel.cs deleted file mode 100644 index 1d27ccc..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseWindowViewModel.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Services.Settings; -using BetterLyrics.WinUI3.Views; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Messaging; -using CommunityToolkit.Mvvm.Messaging.Messages; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Media; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public abstract partial class BaseWindowViewModel - : BaseViewModel, - IRecipient>, - IRecipient>, - IRecipient> - { - public abstract Models.BackdropType BackdropType { get; set; } - - public abstract Models.TitleBarType TitleBarType { get; set; } - - [ObservableProperty] - public partial ElementTheme ThemeType { get; set; } - - public BaseWindowViewModel(ISettingsService settingsService) - : base(settingsService) - { - BackdropType = _settingsService.BackdropType; - TitleBarType = _settingsService.TitleBarType; - ThemeType = _settingsService.ThemeType; - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is SettingsViewModel) - { - if (message.PropertyName == nameof(SettingsViewModel.TitleBarType)) - { - TitleBarType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is SettingsViewModel) - { - if (message.PropertyName == nameof(SettingsViewModel.BackdropType)) - { - BackdropType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - ThemeType = message.NewValue; - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsPageViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsPageViewModel.cs deleted file mode 100644 index 733631e..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsPageViewModel.cs +++ /dev/null @@ -1,21 +0,0 @@ -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class DesktopLyricsPageViewModel(ISettingsService settingsService) - : BaseViewModel(settingsService) - { - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public partial double LimitedLineWidth { get; set; } = 0.0; - - [RelayCommand] - private void OpenSettingsWindow() - { - WindowHelper.OpenSettingsWindow(); - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsRendererViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsRendererViewModel.cs deleted file mode 100644 index 6b6d892..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsRendererViewModel.cs +++ /dev/null @@ -1,220 +0,0 @@ -using System.Numerics; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Services.Playback; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.Messaging; -using CommunityToolkit.Mvvm.Messaging.Messages; -using CommunityToolkit.WinUI; -using Microsoft.Graphics.Canvas; -using Microsoft.Graphics.Canvas.Text; -using Microsoft.Graphics.Canvas.UI.Xaml; -using Windows.UI; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class DesktopLyricsRendererViewModel - : BaseLyricsRendererViewModel, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient> - { - private Color _startColor; - private Color _targetColor; - private float _progress; // From 0 to 1 - private const float TransitionSeconds = 0.3f; - private bool _isTransitioning; - - public Color ActivatedWindowAccentColor { get; set; } - - public DesktopLyricsRendererViewModel( - ISettingsService settingsService, - IPlaybackService playbackService - ) - : base(settingsService, playbackService) - { - LyricsFontColorType = _settingsService.DesktopLyricsFontColorType; - LyricsAlignmentType = _settingsService.DesktopLyricsAlignmentType; - LyricsVerticalEdgeOpacity = _settingsService.DesktopLyricsVerticalEdgeOpacity; - LyricsLineSpacingFactor = _settingsService.DesktopLyricsLineSpacingFactor; - LyricsFontSize = _settingsService.DesktopLyricsFontSize; - LyricsBlurAmount = _settingsService.DesktopLyricsBlurAmount; - IsLyricsGlowEffectEnabled = _settingsService.IsDesktopLyricsGlowEffectEnabled; - IsLyricsDynamicGlowEffectEnabled = - _settingsService.IsDesktopLyricsDynamicGlowEffectEnabled; - - _startColor = _targetColor = ActivatedWindowAccentColor; - _progress = 0f; - - UpdateFontColor(); - } - - public override void Calculate( - ICanvasAnimatedControl control, - CanvasAnimatedUpdateEventArgs args - ) - { - base.Calculate(control, args); - - // Detect if the accent color has changed - if (ActivatedWindowAccentColor != _targetColor) - { - _startColor = _isTransitioning - ? ColorHelper.GetInterpolatedColor(_progress, _startColor, _targetColor) - : _targetColor; - _targetColor = ActivatedWindowAccentColor; - _progress = 0f; - _isTransitioning = true; - } - - // Update the transition progress - if (_isTransitioning) - { - _progress += (float)(ElapsedTime.TotalSeconds / TransitionSeconds); - if (_progress >= 1f) - { - _progress = 1f; - _isTransitioning = false; - } - } - } - - public override void Draw(ICanvasAnimatedControl control, CanvasDrawingSession ds) - { - var color = _isTransitioning - ? ColorHelper.GetInterpolatedColor(_progress, _startColor, _targetColor) - : _targetColor; - - float padding = 0f; - var rect = control.Size.ToRect(); - rect.X += padding; - rect.Y += padding; - rect.Width -= 2 * padding; - rect.Height -= 2 * padding; - - ds.FillRectangle(rect, color); - - base.Draw(control, ds); - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.IsLyricsGlowEffectEnabled) - ) - { - IsLyricsGlowEffectEnabled = message.NewValue; - } - else if ( - message.PropertyName - == nameof( - DesktopLyricsSettingsControlViewModel.IsLyricsDynamicGlowEffectEnabled - ) - ) - { - IsLyricsDynamicGlowEffectEnabled = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsVerticalEdgeOpacity) - ) - { - LyricsVerticalEdgeOpacity = message.NewValue; - } - else if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsBlurAmount) - ) - { - LyricsBlurAmount = message.NewValue; - } - else if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsFontSize) - ) - { - LyricsFontSize = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is OverlayWindowViewModel) - { - if ( - message.PropertyName - == nameof(OverlayWindowViewModel.ActivatedWindowAccentColor) - ) - ActivatedWindowAccentColor = message.NewValue; - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsFontColorType) - ) - { - LyricsFontColorType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsAlignmentType) - ) - { - LyricsAlignmentType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(DesktopLyricsSettingsControlViewModel.LyricsLineSpacingFactor) - ) - { - LyricsLineSpacingFactor = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is DesktopLyricsPageViewModel) - { - if (message.PropertyName == nameof(DesktopLyricsPageViewModel.LimitedLineWidth)) - { - LimitedLineWidth = message.NewValue; - } - } - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsSettingsControlViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsSettingsControlViewModel.cs deleted file mode 100644 index e0f88fb..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/DesktopLyricsSettingsControlViewModel.cs +++ /dev/null @@ -1,99 +0,0 @@ -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Services.Playback; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class DesktopLyricsSettingsControlViewModel : BaseLyricsSettingsControlViewModel - { - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial LyricsAlignmentType LyricsAlignmentType { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial int LyricsBlurAmount { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial int LyricsVerticalEdgeOpacity { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial float LyricsLineSpacingFactor { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial int LyricsFontSize { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial bool IsLyricsGlowEffectEnabled { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial bool IsLyricsDynamicGlowEffectEnabled { get; set; } - - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public override partial LyricsFontColorType LyricsFontColorType { get; set; } - - public DesktopLyricsSettingsControlViewModel( - ISettingsService settingsService, - IPlaybackService playbackService - ) - : base(settingsService, playbackService) - { - LyricsAlignmentType = _settingsService.DesktopLyricsAlignmentType; - LyricsBlurAmount = _settingsService.DesktopLyricsBlurAmount; - LyricsVerticalEdgeOpacity = _settingsService.DesktopLyricsVerticalEdgeOpacity; - LyricsLineSpacingFactor = _settingsService.DesktopLyricsLineSpacingFactor; - LyricsFontSize = _settingsService.DesktopLyricsFontSize; - IsLyricsGlowEffectEnabled = _settingsService.IsDesktopLyricsGlowEffectEnabled; - IsLyricsDynamicGlowEffectEnabled = - _settingsService.IsDesktopLyricsDynamicGlowEffectEnabled; - LyricsFontColorType = _settingsService.DesktopLyricsFontColorType; - } - - partial void OnLyricsAlignmentTypeChanged(LyricsAlignmentType value) - { - _settingsService.DesktopLyricsAlignmentType = value; - } - - partial void OnLyricsBlurAmountChanged(int value) - { - _settingsService.DesktopLyricsBlurAmount = value; - } - - partial void OnLyricsVerticalEdgeOpacityChanged(int value) - { - _settingsService.DesktopLyricsVerticalEdgeOpacity = value; - } - - partial void OnLyricsLineSpacingFactorChanged(float value) - { - _settingsService.DesktopLyricsLineSpacingFactor = value; - } - - partial void OnLyricsFontSizeChanged(int value) - { - _settingsService.DesktopLyricsFontSize = value; - } - - partial void OnIsLyricsGlowEffectEnabledChanged(bool value) - { - _settingsService.IsDesktopLyricsGlowEffectEnabled = value; - } - - partial void OnIsLyricsDynamicGlowEffectEnabledChanged(bool value) - { - _settingsService.IsDesktopLyricsDynamicGlowEffectEnabled = value; - } - - partial void OnLyricsFontColorTypeChanged(LyricsFontColorType value) - { - _settingsService.DesktopLyricsFontColorType = value; - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/HostWindowViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/HostWindowViewModel.cs index 07ed06e..9d10934 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/HostWindowViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/HostWindowViewModel.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Messages; using BetterLyrics.WinUI3.Models; @@ -9,13 +10,18 @@ using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; using Microsoft.UI.Xaml; +using Windows.UI; namespace BetterLyrics.WinUI3 { public partial class HostWindowViewModel - : BaseWindowViewModel, - IRecipient> + : BaseViewModel, + IRecipient>, + IRecipient> { + [ObservableProperty] + public partial ElementTheme ThemeType { get; set; } + [ObservableProperty] public partial double AppLogoImageIconHeight { get; set; } @@ -32,23 +38,22 @@ namespace BetterLyrics.WinUI3 public partial bool ShowInfoBar { get; set; } = false; [ObservableProperty] - public override partial BackdropType BackdropType { get; set; } + public partial TitleBarType TitleBarType { get; set; } [ObservableProperty] - public override partial TitleBarType TitleBarType { get; set; } + [NotifyPropertyChangedRecipients] + public partial bool IsDockMode { get; set; } = false; [ObservableProperty] - public partial bool IsImmersiveMode { get; set; } - - [ObservableProperty] - public partial int TopCommandGridOpacity { get; set; } = 1; + [NotifyPropertyChangedRecipients] + public partial Color ActivatedWindowAccentColor { get; set; } public HostWindowViewModel(ISettingsService settingsService) : base(settingsService) { TitleBarType = _settingsService.TitleBarType; + ThemeType = _settingsService.ThemeType; OnTitleBarTypeChanged(TitleBarType); - BackdropType = _settingsService.BackdropType; WeakReferenceMessenger.Default.Register( this, @@ -71,20 +76,13 @@ namespace BetterLyrics.WinUI3 ); } - partial void OnIsImmersiveModeChanged(bool value) + public void UpdateAccentColor(nint hwnd) { - if (value) - { - TopCommandGridOpacity = 0; - } - else - { - TopCommandGridOpacity = 1; - } + ActivatedWindowAccentColor = WindowColorHelper + .GetDominantColorBelow(hwnd) + .ToWindowsUIColor(); } - partial void OnBackdropTypeChanged(BackdropType value) { } - partial void OnTitleBarTypeChanged(TitleBarType value) { switch (value) @@ -118,15 +116,20 @@ namespace BetterLyrics.WinUI3 return null; } - public void Receive(PropertyChangedMessage message) + public void Receive(PropertyChangedMessage message) { - if (message.Sender is InAppLyricsPageViewModel) + if (message.Sender is SettingsViewModel) { - if (message.PropertyName == nameof(InAppLyricsPageViewModel.IsImmersiveMode)) + if (message.PropertyName == nameof(SettingsViewModel.TitleBarType)) { - IsImmersiveMode = message.NewValue; + TitleBarType = message.NewValue; } } } + + public void Receive(PropertyChangedMessage message) + { + ThemeType = message.NewValue; + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsRendererViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsRendererViewModel.cs deleted file mode 100644 index 9a9dd8f..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsRendererViewModel.cs +++ /dev/null @@ -1,350 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Numerics; -using System.Text; -using System.Threading.Tasks; -using BetterInAppLyrics.WinUI3.ViewModels; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Messages; -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Rendering; -using BetterLyrics.WinUI3.Services.Playback; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Messaging; -using CommunityToolkit.Mvvm.Messaging.Messages; -using Microsoft.Graphics.Canvas; -using Microsoft.Graphics.Canvas.Effects; -using Microsoft.Graphics.Canvas.UI.Xaml; -using Microsoft.UI.Dispatching; -using Windows.Graphics.Imaging; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class InAppLyricsRendererViewModel - : BaseLyricsRendererViewModel, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient>, - IRecipient> - { - public InAppLyricsDisplayType DisplayType { get; set; } - - private float _rotateAngle = 0f; - - [ObservableProperty] - public override partial SongInfo? SongInfo { get; set; } - - private SoftwareBitmap? _lastSoftwareBitmap = null; - private SoftwareBitmap? _softwareBitmap = null; - private SoftwareBitmap? SoftwareBitmap - { - get => _softwareBitmap; - set - { - if (_softwareBitmap != null) - { - _lastSoftwareBitmap = _softwareBitmap; - _transitionStartTime = DateTimeOffset.Now; - _isTransitioning = true; - _transitionAlpha = 0f; - } - - _softwareBitmap = value; - } - } - - public int CoverImageRadius { get; set; } - public bool IsCoverOverlayEnabled { get; set; } - public bool IsDynamicCoverOverlayEnabled { get; set; } - public int CoverOverlayOpacity { get; set; } - public int CoverOverlayBlurAmount { get; set; } - - private float _transitionAlpha = 1f; - private TimeSpan _transitionDuration = TimeSpan.FromMilliseconds(1000); - private DateTimeOffset _transitionStartTime; - private bool _isTransitioning = false; - - private readonly float _coverRotateSpeed = 0.003f; - - public InAppLyricsRendererViewModel( - ISettingsService settingsService, - IPlaybackService playbackService - ) - : base(settingsService, playbackService) - { - CoverImageRadius = _settingsService.CoverImageRadius; - IsCoverOverlayEnabled = _settingsService.IsCoverOverlayEnabled; - IsDynamicCoverOverlayEnabled = _settingsService.IsDynamicCoverOverlayEnabled; - CoverOverlayOpacity = _settingsService.CoverOverlayOpacity; - CoverOverlayBlurAmount = _settingsService.CoverOverlayBlurAmount; - - LyricsFontColorType = _settingsService.InAppLyricsFontColorType; - LyricsAlignmentType = _settingsService.InAppLyricsAlignmentType; - LyricsVerticalEdgeOpacity = _settingsService.InAppLyricsVerticalEdgeOpacity; - LyricsLineSpacingFactor = _settingsService.InAppLyricsLineSpacingFactor; - LyricsFontSize = _settingsService.InAppLyricsFontSize; - LyricsBlurAmount = _settingsService.InAppLyricsBlurAmount; - IsLyricsGlowEffectEnabled = _settingsService.IsInAppLyricsGlowEffectEnabled; - IsLyricsDynamicGlowEffectEnabled = - _settingsService.IsInAppLyricsDynamicGlowEffectEnabled; - - UpdateFontColor(); - } - - async partial void OnSongInfoChanged(SongInfo? value) - { - if (value?.AlbumArt is byte[] bytes) - SoftwareBitmap = await ( - await ImageHelper.GetDecoderFromByte(bytes) - ).GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); - } - - public override void Draw(ICanvasAnimatedControl control, CanvasDrawingSession ds) - { - if (!IsCoverOverlayEnabled || SoftwareBitmap == null) - return; - - ds.Transform = Matrix3x2.CreateRotation(_rotateAngle, control.Size.ToVector2() * 0.5f); - - var overlappedCovers = new CanvasCommandList(control.Device); - using var overlappedCoversDs = overlappedCovers.CreateDrawingSession(); - - if (_isTransitioning && _lastSoftwareBitmap != null) - { - DrawImgae(control, overlappedCoversDs, _lastSoftwareBitmap, 1 - _transitionAlpha); - DrawImgae(control, overlappedCoversDs, SoftwareBitmap, _transitionAlpha); - } - else - { - DrawImgae(control, overlappedCoversDs, SoftwareBitmap, 1); - } - - using var coverOverlayEffect = new OpacityEffect - { - Opacity = CoverOverlayOpacity / 100f, - Source = new GaussianBlurEffect - { - BlurAmount = CoverOverlayBlurAmount, - Source = overlappedCovers, - }, - }; - ds.DrawImage(coverOverlayEffect); - - ds.Transform = Matrix3x2.Identity; - - switch (DisplayType) - { - case InAppLyricsDisplayType.AlbumArtOnly: - case InAppLyricsDisplayType.PlaceholderOnly: - break; - case InAppLyricsDisplayType.LyricsOnly: - case InAppLyricsDisplayType.SplitView: - base.Draw(control, ds); - break; - default: - break; - } - } - - private static void DrawImgae( - ICanvasAnimatedControl control, - CanvasDrawingSession ds, - SoftwareBitmap softwareBitmap, - float opacity - ) - { - using var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(control, softwareBitmap); - float imageWidth = (float)canvasBitmap.Size.Width; - float imageHeight = (float)canvasBitmap.Size.Height; - - var scaleFactor = - (float)Math.Sqrt(Math.Pow(control.Size.Width, 2) + Math.Pow(control.Size.Height, 2)) - / Math.Min(imageWidth, imageHeight); - - ds.DrawImage( - new OpacityEffect - { - Source = new ScaleEffect - { - InterpolationMode = CanvasImageInterpolation.HighQualityCubic, - BorderMode = EffectBorderMode.Hard, - Scale = new Vector2(scaleFactor), - Source = canvasBitmap, - }, - Opacity = opacity, - }, - (float)control.Size.Width / 2 - imageWidth * scaleFactor / 2, - (float)control.Size.Height / 2 - imageHeight * scaleFactor / 2 - ); - } - - public override void Calculate( - ICanvasAnimatedControl control, - CanvasAnimatedUpdateEventArgs args - ) - { - if (_isTransitioning) - { - var elapsed = DateTimeOffset.Now - _transitionStartTime; - float progress = (float)( - elapsed.TotalMilliseconds / _transitionDuration.TotalMilliseconds - ); - _transitionAlpha = Math.Clamp(progress, 0f, 1f); - - if (_transitionAlpha >= 1f) - { - _isTransitioning = false; - _lastSoftwareBitmap?.Dispose(); - _lastSoftwareBitmap = null; - } - } - - if (IsDynamicCoverOverlayEnabled) - { - _rotateAngle += _coverRotateSpeed; - _rotateAngle %= MathF.PI * 2; - } - - base.Calculate(control, args); - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is SettingsViewModel) - { - if (message.PropertyName == nameof(SettingsViewModel.IsDynamicCoverOverlayEnabled)) - { - IsDynamicCoverOverlayEnabled = message.NewValue; - } - else if (message.PropertyName == nameof(SettingsViewModel.IsCoverOverlayEnabled)) - { - IsCoverOverlayEnabled = message.NewValue; - } - } - else if (message.Sender is InAppLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.IsLyricsGlowEffectEnabled) - ) - { - IsLyricsGlowEffectEnabled = message.NewValue; - } - else if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.IsLyricsDynamicGlowEffectEnabled) - ) - { - IsLyricsDynamicGlowEffectEnabled = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is SettingsViewModel) - { - if (message.PropertyName == nameof(SettingsViewModel.CoverImageRadius)) - { - CoverImageRadius = message.NewValue; - } - else if (message.PropertyName == nameof(SettingsViewModel.CoverOverlayOpacity)) - { - CoverOverlayOpacity = message.NewValue; - } - else if (message.PropertyName == nameof(SettingsViewModel.CoverOverlayBlurAmount)) - { - CoverOverlayBlurAmount = message.NewValue; - } - } - else if (message.Sender is InAppLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsVerticalEdgeOpacity) - ) - { - LyricsVerticalEdgeOpacity = message.NewValue; - } - else if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsBlurAmount) - ) - { - LyricsBlurAmount = message.NewValue; - } - else if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsFontSize) - ) - { - LyricsFontSize = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is InAppLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsFontColorType) - ) - { - LyricsFontColorType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is InAppLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsAlignmentType) - ) - { - LyricsAlignmentType = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is InAppLyricsSettingsControlViewModel) - { - if ( - message.PropertyName - == nameof(InAppLyricsSettingsControlViewModel.LyricsLineSpacingFactor) - ) - { - LyricsLineSpacingFactor = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - if (message.Sender is InAppLyricsPageViewModel) - { - if (message.PropertyName == nameof(InAppLyricsPageViewModel.LimitedLineWidth)) - { - LimitedLineWidth = message.NewValue; - } - } - } - - public void Receive(PropertyChangedMessage message) - { - DisplayType = message.NewValue; - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsPageViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsPageViewModel.cs similarity index 79% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsPageViewModel.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsPageViewModel.cs index de87d23..1023ce5 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsPageViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsPageViewModel.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Threading.Tasks; using BetterInAppLyrics.WinUI3.ViewModels; +using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Messages; using BetterLyrics.WinUI3.Models; @@ -17,9 +18,10 @@ using WinUIEx.Messaging; namespace BetterLyrics.WinUI3.ViewModels { - public partial class InAppLyricsPageViewModel + public partial class LyricsPageViewModel : BaseViewModel, - IRecipient> + IRecipient>, + IRecipient> { [ObservableProperty] public partial bool IsDesktopLyricsOpened { get; set; } = false; @@ -30,8 +32,8 @@ namespace BetterLyrics.WinUI3.ViewModels [ObservableProperty] [NotifyPropertyChangedRecipients] - public partial InAppLyricsDisplayType DisplayType { get; set; } = - InAppLyricsDisplayType.PlaceholderOnly; + public partial LyricsDisplayType DisplayType { get; set; } = + LyricsDisplayType.PlaceholderOnly; [ObservableProperty] public partial BitmapImage? CoverImage { get; set; } @@ -40,16 +42,12 @@ namespace BetterLyrics.WinUI3.ViewModels public partial SongInfo? SongInfo { get; set; } = null; [ObservableProperty] - public partial InAppLyricsDisplayType? PreferredDisplayType { get; set; } = - InAppLyricsDisplayType.SplitView; + public partial LyricsDisplayType? PreferredDisplayType { get; set; } = + LyricsDisplayType.SplitView; [ObservableProperty] public partial bool AboutToUpdateUI { get; set; } - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public partial bool IsImmersiveMode { get; set; } - [ObservableProperty] public partial double CoverImageGridActualHeight { get; set; } @@ -65,9 +63,12 @@ namespace BetterLyrics.WinUI3.ViewModels [ObservableProperty] public partial bool IsFirstRun { get; set; } + [ObservableProperty] + public partial bool IsNotMockMode { get; set; } = true; + private readonly IPlaybackService _playbackService; - public InAppLyricsPageViewModel( + public LyricsPageViewModel( ISettingsService settingsService, IPlaybackService playbackService ) @@ -112,8 +113,8 @@ namespace BetterLyrics.WinUI3.ViewModels private void OnDisplayTypeChanged(object value) { int index = Convert.ToInt32(value); - PreferredDisplayType = (InAppLyricsDisplayType)index; - DisplayType = (InAppLyricsDisplayType)index; + PreferredDisplayType = (LyricsDisplayType)index; + DisplayType = (LyricsDisplayType)index; } [RelayCommand] @@ -134,19 +135,19 @@ namespace BetterLyrics.WinUI3.ViewModels ? null : await ImageHelper.GetBitmapImageFromBytesAsync(songInfo.AlbumArt); - InAppLyricsDisplayType displayType; + LyricsDisplayType displayType; if (songInfo == null) { - displayType = InAppLyricsDisplayType.PlaceholderOnly; + displayType = LyricsDisplayType.PlaceholderOnly; } - else if (PreferredDisplayType is InAppLyricsDisplayType preferredDisplayType) + else if (PreferredDisplayType is LyricsDisplayType preferredDisplayType) { displayType = preferredDisplayType; } else { - displayType = InAppLyricsDisplayType.SplitView; + displayType = LyricsDisplayType.SplitView; } DisplayType = displayType; @@ -176,5 +177,16 @@ namespace BetterLyrics.WinUI3.ViewModels } } } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is HostWindowViewModel) + { + if (message.PropertyName == nameof(HostWindowViewModel.IsDockMode)) + { + IsNotMockMode = !message.NewValue; + } + } + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsRendererViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsRendererViewModel.cs similarity index 70% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsRendererViewModel.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsRendererViewModel.cs index b8c4b69..68e990e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/BaseLyricsRendererViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsRendererViewModel.cs @@ -3,6 +3,11 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using BetterInAppLyrics.WinUI3.ViewModels; +using BetterLyrics.WinUI3.Enums; +using BetterLyrics.WinUI3.Events; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Messages; using BetterLyrics.WinUI3.Models; @@ -21,15 +26,21 @@ using Microsoft.UI; using Microsoft.UI.Dispatching; using Microsoft.UI.Text; using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Shapes; using Windows.Foundation; +using Windows.Graphics.Imaging; using Windows.UI; namespace BetterLyrics.WinUI3.ViewModels { - public partial class BaseLyricsRendererViewModel + public partial class LyricsRendererViewModel : BaseRendererViewModel, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, + IRecipient>, IRecipient> { private protected CanvasTextFormat _textFormat = new() @@ -40,8 +51,37 @@ namespace BetterLyrics.WinUI3.ViewModels //FontFamily = "Segoe UI Mono", }; + public LyricsDisplayType DisplayType { get; set; } + + private float _rotateAngle = 0f; + [ObservableProperty] - public virtual partial SongInfo? SongInfo { get; set; } + public partial SongInfo? SongInfo { get; set; } + + private SoftwareBitmap? _lastSoftwareBitmap = null; + private SoftwareBitmap? _softwareBitmap = null; + private SoftwareBitmap? SoftwareBitmap + { + get => _softwareBitmap; + set + { + if (_softwareBitmap != null) + { + _lastSoftwareBitmap = _softwareBitmap; + _transitionStartTime = DateTimeOffset.Now; + _isTransitioning = true; + _transitionAlpha = 0f; + } + + _softwareBitmap = value; + } + } + + public int CoverImageRadius { get; set; } + public bool IsCoverOverlayEnabled { get; set; } + public bool IsDynamicCoverOverlayEnabled { get; set; } + public int CoverOverlayOpacity { get; set; } + public int CoverOverlayBlurAmount { get; set; } [ObservableProperty] public partial bool IsPlaying { get; set; } @@ -85,7 +125,6 @@ namespace BetterLyrics.WinUI3.ViewModels [ObservableProperty] public partial ElementTheme Theme { get; set; } - public List CoverImageDominantColors { get; set; } [ObservableProperty] public partial LyricsFontColorType LyricsFontColorType { get; set; } @@ -104,22 +143,43 @@ namespace BetterLyrics.WinUI3.ViewModels private protected readonly IPlaybackService _playbackService; - public BaseLyricsRendererViewModel( + private float _transitionAlpha = 1f; + private TimeSpan _transitionDuration = TimeSpan.FromMilliseconds(1000); + private DateTimeOffset _transitionStartTime; + private bool _isTransitioning = false; + + private readonly float _coverRotateSpeed = 0.003f; + + public LyricsRendererViewModel( ISettingsService settingsService, IPlaybackService playbackService ) : base(settingsService) { - CoverImageDominantColors = - [ - .. Enumerable.Repeat(Colors.Transparent, ImageHelper.AccentColorCount), - ]; + CoverImageRadius = _settingsService.CoverImageRadius; + IsCoverOverlayEnabled = _settingsService.IsCoverOverlayEnabled; + IsDynamicCoverOverlayEnabled = _settingsService.IsDynamicCoverOverlayEnabled; + CoverOverlayOpacity = _settingsService.CoverOverlayOpacity; + CoverOverlayBlurAmount = _settingsService.CoverOverlayBlurAmount; + + LyricsFontColorType = _settingsService.InAppLyricsFontColorType; + LyricsAlignmentType = _settingsService.InAppLyricsAlignmentType; + LyricsVerticalEdgeOpacity = _settingsService.InAppLyricsVerticalEdgeOpacity; + LyricsLineSpacingFactor = _settingsService.InAppLyricsLineSpacingFactor; + LyricsFontSize = _settingsService.InAppLyricsFontSize; + LyricsBlurAmount = _settingsService.InAppLyricsBlurAmount; + IsLyricsGlowEffectEnabled = _settingsService.IsInAppLyricsGlowEffectEnabled; + IsLyricsDynamicGlowEffectEnabled = + _settingsService.IsInAppLyricsDynamicGlowEffectEnabled; + _playbackService = playbackService; _playbackService.IsPlayingChanged += PlaybackService_IsPlayingChanged; _playbackService.SongInfoChanged += PlaybackService_SongInfoChanged; _playbackService.PositionChanged += PlaybackService_PositionChanged; RefreshPlaybackInfo(); + + UpdateFontColor(); } public void RequestRelayout() @@ -154,12 +214,13 @@ namespace BetterLyrics.WinUI3.ViewModels _isRelayoutNeeded = true; } - partial void OnSongInfoChanged(SongInfo? value) + async partial void OnSongInfoChanged(SongInfo? value) { - if (value != null) - { - CoverImageDominantColors = [.. value.CoverImageDominantColors]; - } + if (value?.AlbumArt is byte[] bytes) + SoftwareBitmap = await ( + await ImageHelper.GetDecoderFromByte(bytes) + ).GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied); + UpdateFontColor(); _isRelayoutNeeded = true; } @@ -214,7 +275,7 @@ namespace BetterLyrics.WinUI3.ViewModels } break; case LyricsFontColorType.Dominant: - _fontColor = CoverImageDominantColors[0]; + _fontColor = SongInfo?.CoverImageDominantColors?[0] ?? _lightFontColor; break; default: break; @@ -375,13 +436,55 @@ namespace BetterLyrics.WinUI3.ViewModels } } - public virtual void Draw(ICanvasAnimatedControl control, CanvasDrawingSession ds) + public void Draw(ICanvasAnimatedControl control, CanvasDrawingSession ds) { + if (!IsCoverOverlayEnabled || SoftwareBitmap == null) + return; + + ds.Transform = Matrix3x2.CreateRotation(_rotateAngle, control.Size.ToVector2() * 0.5f); + + var overlappedCovers = new CanvasCommandList(control.Device); + using var overlappedCoversDs = overlappedCovers.CreateDrawingSession(); + + if (_isTransitioning && _lastSoftwareBitmap != null) + { + DrawImgae(control, overlappedCoversDs, _lastSoftwareBitmap, 1 - _transitionAlpha); + DrawImgae(control, overlappedCoversDs, SoftwareBitmap, _transitionAlpha); + } + else + { + DrawImgae(control, overlappedCoversDs, SoftwareBitmap, 1); + } + + using var coverOverlayEffect = new OpacityEffect + { + Opacity = CoverOverlayOpacity / 100f, + Source = new GaussianBlurEffect + { + BlurAmount = CoverOverlayBlurAmount, + Source = overlappedCovers, + }, + }; + ds.DrawImage(coverOverlayEffect); + + ds.Transform = Matrix3x2.Identity; + // Lyrics only layer using var lyrics = new CanvasCommandList(control); using (var lyricsDs = lyrics.CreateDrawingSession()) { - DrawLyrics(control, lyricsDs); + switch (DisplayType) + { + case LyricsDisplayType.AlbumArtOnly: + case LyricsDisplayType.PlaceholderOnly: + break; + case LyricsDisplayType.LyricsOnly: + case LyricsDisplayType.SplitView: + DrawLyrics(control, lyricsDs); + break; + default: + break; + } } using var glowedLyrics = new CanvasCommandList(control); @@ -542,6 +645,28 @@ namespace BetterLyrics.WinUI3.ViewModels { base.Calculate(control, args); + if (_isTransitioning) + { + var elapsed = DateTimeOffset.Now - _transitionStartTime; + float progress = (float)( + elapsed.TotalMilliseconds / _transitionDuration.TotalMilliseconds + ); + _transitionAlpha = Math.Clamp(progress, 0f, 1f); + + if (_transitionAlpha >= 1f) + { + _isTransitioning = false; + _lastSoftwareBitmap?.Dispose(); + _lastSoftwareBitmap = null; + } + } + + if (IsDynamicCoverOverlayEnabled) + { + _rotateAngle += _coverRotateSpeed; + _rotateAngle %= MathF.PI * 2; + } + if (_isRelayoutNeeded) { ReLayout(control); @@ -779,5 +904,168 @@ namespace BetterLyrics.WinUI3.ViewModels } } } + + private static void DrawImgae( + ICanvasAnimatedControl control, + CanvasDrawingSession ds, + SoftwareBitmap softwareBitmap, + float opacity + ) + { + using var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(control, softwareBitmap); + float imageWidth = (float)canvasBitmap.Size.Width; + float imageHeight = (float)canvasBitmap.Size.Height; + + var scaleFactor = + (float)Math.Sqrt(Math.Pow(control.Size.Width, 2) + Math.Pow(control.Size.Height, 2)) + / Math.Min(imageWidth, imageHeight); + + ds.DrawImage( + new OpacityEffect + { + Source = new ScaleEffect + { + InterpolationMode = CanvasImageInterpolation.HighQualityCubic, + BorderMode = EffectBorderMode.Hard, + Scale = new Vector2(scaleFactor), + Source = canvasBitmap, + }, + Opacity = opacity, + }, + (float)control.Size.Width / 2 - imageWidth * scaleFactor / 2, + (float)control.Size.Height / 2 - imageHeight * scaleFactor / 2 + ); + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is SettingsViewModel) + { + if (message.PropertyName == nameof(SettingsViewModel.IsDynamicCoverOverlayEnabled)) + { + IsDynamicCoverOverlayEnabled = message.NewValue; + } + else if (message.PropertyName == nameof(SettingsViewModel.IsCoverOverlayEnabled)) + { + IsCoverOverlayEnabled = message.NewValue; + } + } + else if (message.Sender is LyricsSettingsControlViewModel) + { + if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.IsLyricsGlowEffectEnabled) + ) + { + IsLyricsGlowEffectEnabled = message.NewValue; + } + else if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.IsLyricsDynamicGlowEffectEnabled) + ) + { + IsLyricsDynamicGlowEffectEnabled = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is SettingsViewModel) + { + if (message.PropertyName == nameof(SettingsViewModel.CoverImageRadius)) + { + CoverImageRadius = message.NewValue; + } + else if (message.PropertyName == nameof(SettingsViewModel.CoverOverlayOpacity)) + { + CoverOverlayOpacity = message.NewValue; + } + else if (message.PropertyName == nameof(SettingsViewModel.CoverOverlayBlurAmount)) + { + CoverOverlayBlurAmount = message.NewValue; + } + } + else if (message.Sender is LyricsSettingsControlViewModel) + { + if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.LyricsVerticalEdgeOpacity) + ) + { + LyricsVerticalEdgeOpacity = message.NewValue; + } + else if ( + message.PropertyName == nameof(LyricsSettingsControlViewModel.LyricsBlurAmount) + ) + { + LyricsBlurAmount = message.NewValue; + } + else if ( + message.PropertyName == nameof(LyricsSettingsControlViewModel.LyricsFontSize) + ) + { + LyricsFontSize = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is LyricsSettingsControlViewModel) + { + if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.LyricsFontColorType) + ) + { + LyricsFontColorType = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is LyricsSettingsControlViewModel) + { + if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.LyricsAlignmentType) + ) + { + LyricsAlignmentType = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is LyricsSettingsControlViewModel) + { + if ( + message.PropertyName + == nameof(LyricsSettingsControlViewModel.LyricsLineSpacingFactor) + ) + { + LyricsLineSpacingFactor = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + if (message.Sender is LyricsPageViewModel) + { + if (message.PropertyName == nameof(LyricsPageViewModel.LimitedLineWidth)) + { + LimitedLineWidth = message.NewValue; + } + } + } + + public void Receive(PropertyChangedMessage message) + { + DisplayType = message.NewValue; + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsSettingsControlViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsSettingsControlViewModel.cs similarity index 74% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsSettingsControlViewModel.cs rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsSettingsControlViewModel.cs index 7269f57..82dddd9 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/InAppLyricsSettingsControlViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/LyricsSettingsControlViewModel.cs @@ -1,50 +1,53 @@ -using BetterLyrics.WinUI3.Models; +using System; +using System.Collections.ObjectModel; +using System.Linq; +using BetterLyrics.WinUI3.Enums; +using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Services.Playback; using BetterLyrics.WinUI3.Services.Settings; using BetterLyrics.WinUI3.ViewModels; using CommunityToolkit.Mvvm.ComponentModel; +using Microsoft.UI; +using Windows.UI; namespace BetterInAppLyrics.WinUI3.ViewModels { - public partial class InAppLyricsSettingsControlViewModel : BaseLyricsSettingsControlViewModel + public partial class LyricsSettingsControlViewModel : BaseViewModel { [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial LyricsAlignmentType LyricsAlignmentType { get; set; } + public partial LyricsAlignmentType LyricsAlignmentType { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial int LyricsBlurAmount { get; set; } + public partial int LyricsBlurAmount { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial int LyricsVerticalEdgeOpacity { get; set; } + public partial int LyricsVerticalEdgeOpacity { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial float LyricsLineSpacingFactor { get; set; } + public partial float LyricsLineSpacingFactor { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial int LyricsFontSize { get; set; } + public partial int LyricsFontSize { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial bool IsLyricsGlowEffectEnabled { get; set; } + public partial bool IsLyricsGlowEffectEnabled { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial bool IsLyricsDynamicGlowEffectEnabled { get; set; } + public partial bool IsLyricsDynamicGlowEffectEnabled { get; set; } [ObservableProperty] [NotifyPropertyChangedRecipients] - public override partial LyricsFontColorType LyricsFontColorType { get; set; } + public partial LyricsFontColorType LyricsFontColorType { get; set; } - public InAppLyricsSettingsControlViewModel( - ISettingsService settingsService, - IPlaybackService playbackService - ) - : base(settingsService, playbackService) + public LyricsSettingsControlViewModel(ISettingsService settingsService) + : base(settingsService) { IsActive = true; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/OverlayWindowViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/OverlayWindowViewModel.cs deleted file mode 100644 index d23ea93..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/OverlayWindowViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; -using Windows.UI; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class OverlayWindowViewModel(ISettingsService settingsService) - : BaseViewModel(settingsService) - { - [ObservableProperty] - [NotifyPropertyChangedRecipients] - public partial Color ActivatedWindowAccentColor { get; set; } - - public void UpdateAccentColor(nint hwnd) - { - ActivatedWindowAccentColor = WindowColorHelper - .GetDominantColorBelow(hwnd) - .ToWindowsUIColor(); - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs index 21bbcb9..678dbf3 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Messages; using BetterLyrics.WinUI3.Models; @@ -89,22 +90,22 @@ namespace BetterLyrics.WinUI3.ViewModels } [ObservableProperty] - public partial Models.Language Language { get; set; } + public partial Enums.Language Language { get; set; } - partial void OnLanguageChanged(Models.Language value) + partial void OnLanguageChanged(Enums.Language value) { switch (value) { - case Models.Language.FollowSystem: + case Enums.Language.FollowSystem: ApplicationLanguages.PrimaryLanguageOverride = ""; break; - case Models.Language.English: + case Enums.Language.English: ApplicationLanguages.PrimaryLanguageOverride = "en-US"; break; - case Models.Language.SimplifiedChinese: + case Enums.Language.SimplifiedChinese: ApplicationLanguages.PrimaryLanguageOverride = "zh-CN"; break; - case Models.Language.TraditionalChinese: + case Enums.Language.TraditionalChinese: ApplicationLanguages.PrimaryLanguageOverride = "zh-TW"; break; default: diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SystemTrayPageViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SystemTrayPageViewModel.cs deleted file mode 100644 index c243a47..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SystemTrayPageViewModel.cs +++ /dev/null @@ -1,42 +0,0 @@ -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Models; -using BetterLyrics.WinUI3.Services.Settings; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Microsoft.UI.Xaml; - -namespace BetterLyrics.WinUI3.ViewModels -{ - public partial class SystemTrayPageViewModel : BaseViewModel - { - public SystemTrayPageViewModel(ISettingsService settingsService) - : base(settingsService) - { - switch (_settingsService.AutoStartWindowType) - { - case AutoStartWindowType.None: - break; - case AutoStartWindowType.InAppLyrics: - WindowHelper.OpenInAppLyricsWindow(); - break; - case AutoStartWindowType.DesktopLyrics: - WindowHelper.OpenDesktopLyricsWindow(); - break; - default: - break; - } - } - - [RelayCommand] - private void OpenSettingsWindow() - { - WindowHelper.OpenSettingsWindow(); - } - - [RelayCommand] - private void ExitApp() - { - Application.Current.Exit(); - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml deleted file mode 100644 index d248f7f..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml.cs deleted file mode 100644 index e49f009..0000000 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/DesktopLyricsPage.xaml.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using BetterLyrics.WinUI3.Helper; -using BetterLyrics.WinUI3.Messages; -using BetterLyrics.WinUI3.ViewModels; -using CommunityToolkit.Mvvm.DependencyInjection; -using CommunityToolkit.Mvvm.Messaging; -using Microsoft.Graphics.Canvas.UI.Xaml; -using Microsoft.UI.Dispatching; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; - -// To learn more about WinUI, the WinUI project structure, -// and more about our project templates, see: http://aka.ms/winui-project-info. - -namespace BetterLyrics.WinUI3.Views -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class DesktopLyricsPage : Page - { - public DesktopLyricsPageViewModel ViewModel => (DesktopLyricsPageViewModel)DataContext; - - public DesktopLyricsSettingsControlViewModel DesktopLyricsSettingsControlViewModel => - Ioc.Default.GetService()!; - - public DesktopLyricsPage() - { - this.InitializeComponent(); - DataContext = Ioc.Default.GetService(); - } - - private void LyricsPlaceholderGrid_SizeChanged(object sender, SizeChangedEventArgs e) - { - ViewModel.LimitedLineWidth = e.NewSize.Width; - } - - private void InAppLyricsSwitchButton_Click(object sender, RoutedEventArgs e) - { - var window = WindowHelper.GetWindowForElement(this); - AppBarHelper.Disable(window); - window.Close(); - WindowHelper.OpenInAppLyricsWindow(); - } - - private void RightCommandArea_Loaded(object sender, RoutedEventArgs e) - { - RightCommandArea.Opacity = 0; - } - } -} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml index 53ee2e1..bb52c7c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml @@ -14,7 +14,7 @@ + Opacity="0" + PointerEntered="TopCommandGrid_PointerEntered" + PointerExited="TopCommandGrid_PointerExited"> @@ -44,15 +46,11 @@ x:Name="AppTitleTextBlock" FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}" FontWeight="SemiBold" - Opacity=".5" Text="{x:Bind Title, Mode=OneWay}" /> - + diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml.cs index 1e35d98..84762d4 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/HostWindow.xaml.cs @@ -1,7 +1,7 @@ using System; +using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Messages; -using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Settings; using BetterLyrics.WinUI3.ViewModels; using CommunityToolkit.Mvvm.DependencyInjection; @@ -14,6 +14,8 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Input; using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Navigation; +using WinRT.Interop; +using WinUIEx; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -27,25 +29,53 @@ namespace BetterLyrics.WinUI3.Views : Window, IRecipient> { - public HostWindowViewModel ViewModel { get; set; } = - Ioc.Default.GetService()!; + public HostWindowViewModel ViewModel { get; set; } - private readonly ILogger _logger = Ioc.Default.GetService< - ILogger - >()!; + private readonly ISettingsService _settingsService = + Ioc.Default.GetRequiredService(); - public HostWindow() + private readonly bool _listenOnActivatedWindowChange; + + public HostWindow( + bool alwaysOnTop = false, + bool clickThrough = false, + bool listenOnActivatedWindowChange = false + ) { this.InitializeComponent(); + ViewModel = Ioc.Default.GetRequiredService(); + + _listenOnActivatedWindowChange = listenOnActivatedWindowChange; + AppWindow.Changed += AppWindow_Changed; - ExtendsContentIntoTitleBar = true; - SetTitleBar(TopCommandGrid); + this.HideSystemTitleBarAndSetCustomTitleBar(TopCommandGrid); - AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Collapsed; + if (clickThrough) + this.SetExtendedWindowStyle( + ExtendedWindowStyle.Transparent | ExtendedWindowStyle.Layered + ); - SystemBackdrop = new MicaBackdrop(); + SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop( + _settingsService.BackdropType + ); + + if (alwaysOnTop) + ((OverlappedPresenter)AppWindow.Presenter).IsAlwaysOnTop = true; + + if (listenOnActivatedWindowChange) + { + var hwnd = WindowNative.GetWindowHandle(this); + var windowWatcher = new ForegroundWindowWatcherHelper( + hwnd, + onWindowChanged => + { + ViewModel.UpdateAccentColor(hwnd); + } + ); + windowWatcher.Start(); + } } private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args) @@ -66,7 +96,14 @@ namespace BetterLyrics.WinUI3.Views private void CloseButton_Click(object sender, RoutedEventArgs e) { - Close(); + if (RootFrame.SourcePageType == typeof(LyricsPage)) + { + Application.Current.Exit(); + } + else + { + AppWindow.Hide(); + } } private void MaximiseButton_Click(object sender, RoutedEventArgs e) @@ -105,9 +142,8 @@ namespace BetterLyrics.WinUI3.Views RestoreButton.Visibility = AOTFlyoutItem.Visibility = FullScreenFlyoutItem.Visibility = - MiniFlyoutItem.Visibility = + DockFlyoutItem.Visibility = Visibility.Collapsed; - UnMiniFlyoutItem.Visibility = Visibility.Visible; break; case AppWindowPresenterKind.FullScreen: MinimiseButton.Visibility = @@ -115,30 +151,43 @@ namespace BetterLyrics.WinUI3.Views RestoreButton.Visibility = AOTFlyoutItem.Visibility = MiniFlyoutItem.Visibility = - UnMiniFlyoutItem.Visibility = + DockFlyoutItem.Visibility = Visibility.Collapsed; FullScreenFlyoutItem.IsChecked = true; break; case AppWindowPresenterKind.Overlapped: + DockFlyoutItem.Visibility = Visibility.Visible; var overlappedPresenter = (OverlappedPresenter)AppWindow.Presenter; - MinimiseButton.Visibility = - AOTFlyoutItem.Visibility = - MiniFlyoutItem.Visibility = - FullScreenFlyoutItem.Visibility = - Visibility.Visible; - FullScreenFlyoutItem.IsChecked = false; - AOTFlyoutItem.IsChecked = overlappedPresenter.IsAlwaysOnTop; - UnMiniFlyoutItem.Visibility = Visibility.Collapsed; - - if (overlappedPresenter.State == OverlappedPresenterState.Maximized) + if (DockFlyoutItem.IsChecked) { - MaximiseButton.Visibility = Visibility.Collapsed; - RestoreButton.Visibility = Visibility.Visible; + MinimiseButton.Visibility = + MaximiseButton.Visibility = + RestoreButton.Visibility = + AOTFlyoutItem.Visibility = + FullScreenFlyoutItem.Visibility = + MiniFlyoutItem.Visibility = + Visibility.Collapsed; } - else if (overlappedPresenter.State == OverlappedPresenterState.Restored) + else { - MaximiseButton.Visibility = Visibility.Visible; - RestoreButton.Visibility = Visibility.Collapsed; + MinimiseButton.Visibility = + AOTFlyoutItem.Visibility = + MiniFlyoutItem.Visibility = + FullScreenFlyoutItem.Visibility = + Visibility.Visible; + FullScreenFlyoutItem.IsChecked = false; + AOTFlyoutItem.IsChecked = overlappedPresenter.IsAlwaysOnTop; + + if (overlappedPresenter.State == OverlappedPresenterState.Maximized) + { + MaximiseButton.Visibility = Visibility.Collapsed; + RestoreButton.Visibility = Visibility.Visible; + } + else if (overlappedPresenter.State == OverlappedPresenterState.Restored) + { + MaximiseButton.Visibility = Visibility.Visible; + RestoreButton.Visibility = Visibility.Collapsed; + } } break; default: @@ -178,28 +227,56 @@ namespace BetterLyrics.WinUI3.Views } } - private void RootGrid_KeyDown(object sender, KeyRoutedEventArgs e) - { - if ( - AppWindow.Presenter.Kind == AppWindowPresenterKind.FullScreen - && e.Key == Windows.System.VirtualKey.Escape - ) - AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped); - } - private void MiniFlyoutItem_Click(object sender, RoutedEventArgs e) { - AppWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay); - } - - private void UnMiniFlyoutItem_Click(object sender, RoutedEventArgs e) - { - AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped); + if (MiniFlyoutItem.IsChecked) + { + AppWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay); + } + else + { + AppWindow.SetPresenter(AppWindowPresenterKind.Overlapped); + } } public void Receive(PropertyChangedMessage message) { SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(message.NewValue); } + + private void RootGrid_Loaded(object sender, RoutedEventArgs e) + { + if (_listenOnActivatedWindowChange) + { + var hwnd = WindowNative.GetWindowHandle(this); + ViewModel.UpdateAccentColor(hwnd); + } + } + + private void DockFlyoutItem_Click(object sender, RoutedEventArgs e) + { + if (DockFlyoutItem.IsChecked) + { + DockHelper.Enable(this, 48); + } + else + { + DockHelper.Disable(this); + } + ViewModel.IsDockMode = DockFlyoutItem.IsChecked; + UpdateTitleBarWindowButtonsVisibility(); + } + + private void TopCommandGrid_PointerEntered(object sender, PointerRoutedEventArgs e) + { + if (TopCommandGrid.Opacity == 0) + TopCommandGrid.Opacity = .5; + } + + private void TopCommandGrid_PointerExited(object sender, PointerRoutedEventArgs e) + { + if (TopCommandGrid.Opacity == .5) + TopCommandGrid.Opacity = 0; + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/InAppLyricsPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/LyricsPage.xaml similarity index 92% rename from BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/InAppLyricsPage.xaml rename to BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/LyricsPage.xaml index 3fb5b49..b5a0dc2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/InAppLyricsPage.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/LyricsPage.xaml @@ -1,6 +1,6 @@ - + @@ -63,13 +63,13 @@ - - - - + + + + - + @@ -124,7 +124,10 @@ - + @@ -241,43 +244,16 @@ HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="Transparent" - Opacity=".5" + Opacity="0" PointerEntered="BottomCommandGrid_PointerEntered" - PointerExited="BottomCommandGrid_PointerExited"> + PointerExited="BottomCommandGrid_PointerExited" + Visibility="{x:Bind ViewModel.IsNotMockMode, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}"> - - - - - - - - - - - - - - -