mirror of
https://github.com/LanZhan-Harmony/WindowsMusicPlayer-TheUntamedMusicPlayer.git
synced 2026-05-06 19:20:18 +08:00
更新背景Service
This commit is contained in:
@@ -30,7 +30,7 @@ public partial class App : Application
|
||||
if ((Current as App)!.Host.Services.GetService(typeof(T)) is not T service)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs."
|
||||
$"{typeof(T)} 需要在 App.xaml.cs 的 ConfigureServices 中注册"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public partial class App : Application
|
||||
UnhandledException += App_UnhandledException;
|
||||
}
|
||||
|
||||
protected override async void OnLaunched(LaunchActivatedEventArgs args)
|
||||
protected async override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
base.OnLaunched(args);
|
||||
MainWindow = new MainWindow();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
using Windows.UI;
|
||||
|
||||
@@ -42,7 +43,7 @@ public interface IColorExtractionService
|
||||
/// <summary>
|
||||
/// 动态背景服务接口
|
||||
/// </summary>
|
||||
public interface IDynamicBackgroundService
|
||||
public interface IDynamicBackgroundService : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
@@ -58,16 +59,11 @@ public interface IDynamicBackgroundService
|
||||
/// 初始化动态背景服务
|
||||
/// </summary>
|
||||
/// <param name="targetElement">目标元素</param>
|
||||
void Initialize(Microsoft.UI.Xaml.FrameworkElement targetElement);
|
||||
Task InitializeAsync(FrameworkElement? targetElement = null);
|
||||
|
||||
/// <summary>
|
||||
/// 手动更新背景
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task UpdateBackgroundAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
void Dispose();
|
||||
}
|
||||
|
||||
@@ -2,28 +2,67 @@ using Windows.UI;
|
||||
|
||||
namespace The_Untamed_Music_Player.Contracts.Services;
|
||||
|
||||
public interface IMaterialSelectorService
|
||||
public interface IMaterialSelectorService : IDisposable
|
||||
{
|
||||
MaterialType Material { get; }
|
||||
bool IsFallBack { get; }
|
||||
byte LuminosityOpacity { get; }
|
||||
Color TintColor { get; }
|
||||
Task InitializeAsync();
|
||||
Task<(byte, Color)> SetMaterial(MaterialType material);
|
||||
Task<(byte, Color)> SetMaterial(
|
||||
MaterialType material,
|
||||
bool firstStart = false,
|
||||
bool forced = false
|
||||
);
|
||||
void SetIsFallBack(bool isFallBack);
|
||||
void SetLuminosityOpacity(byte opacity);
|
||||
void SetTintColor(Color color);
|
||||
void SetLuminosityOpacity(byte opacity, bool firstStart = false);
|
||||
void SetTintColor(Color color, bool firstStart = false);
|
||||
}
|
||||
|
||||
public enum MaterialType
|
||||
{
|
||||
/// <summary>
|
||||
/// 无背景
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 云母
|
||||
/// </summary>
|
||||
Mica = 1,
|
||||
|
||||
/// <summary>
|
||||
/// 云母Alt
|
||||
/// </summary>
|
||||
MicaAlt = 2,
|
||||
|
||||
/// <summary>
|
||||
/// 桌面亚克力
|
||||
/// </summary>
|
||||
DesktopAcrylic = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 基础亚克力
|
||||
/// </summary>
|
||||
AcrylicBase = 4,
|
||||
|
||||
/// <summary>
|
||||
/// 薄亚克力
|
||||
/// </summary>
|
||||
AcrylicThin = 5,
|
||||
|
||||
/// <summary>
|
||||
/// 模糊
|
||||
/// </summary>
|
||||
Blur = 6,
|
||||
|
||||
/// <summary>
|
||||
/// 透明
|
||||
/// </summary>
|
||||
Transparent = 7,
|
||||
|
||||
/// <summary>
|
||||
/// 变色
|
||||
/// </summary>
|
||||
Animated = 8,
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace The_Untamed_Music_Player.Contracts.Services;
|
||||
|
||||
public interface IThemeSelectorService
|
||||
{
|
||||
ElementTheme Theme { get; }
|
||||
Task InitializeAsync();
|
||||
Task SetThemeAsync(ElementTheme theme);
|
||||
Task SetRequestedThemeAsync();
|
||||
ElementTheme Theme { get; set; }
|
||||
void Initialize();
|
||||
void SetThemeAsync(ElementTheme theme);
|
||||
void SetRequestedThemeAsync();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public sealed partial class EditAlbumInfoDialog : ContentDialog, INotifyProperty
|
||||
_year = $"{info.Year}";
|
||||
Cover = info.Cover;
|
||||
_isSaveCoverButtonEnabled = Cover is not null;
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ public sealed partial class EditPlaylistInfoDialog : ContentDialog, INotifyPrope
|
||||
_coverPaths = [.. info.CoverPaths]; // 注意要创建副本
|
||||
IsDeleteCoverButtonEnabled = Cover is not null;
|
||||
IsSaveCoverButtonEnabled = Cover is not null && _isCoverEdited;
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public sealed partial class EditSongInfoDialog : ContentDialog, INotifyPropertyC
|
||||
_lyric = detailedInfo.Lyric;
|
||||
Cover = detailedInfo.Cover;
|
||||
IsSaveCoverButtonEnabled = Cover is not null;
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
LyricEditor.Document.SetText(TextSetOptions.None, _lyric);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
|
||||
namespace The_Untamed_Music_Player.Controls;
|
||||
|
||||
@@ -8,7 +8,7 @@ public sealed partial class EqualizerDialog : ContentDialog
|
||||
{
|
||||
public EqualizerDialog()
|
||||
{
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public sealed partial class ImportPlaylistDialog : ContentDialog, INotifyPropert
|
||||
|
||||
public ImportPlaylistDialog()
|
||||
{
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
|
||||
namespace The_Untamed_Music_Player.Controls;
|
||||
|
||||
@@ -10,7 +11,7 @@ public sealed partial class NewPlaylistInfoDialog : ContentDialog
|
||||
|
||||
public NewPlaylistInfoDialog()
|
||||
{
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.Diagnostics;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using The_Untamed_Music_Player.Contracts.Models;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
|
||||
namespace The_Untamed_Music_Player.Controls;
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed partial class PropertiesDialog : ContentDialog
|
||||
public PropertiesDialog(IDetailedSongInfoBase info)
|
||||
{
|
||||
_song = info;
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme ? ElementTheme.Dark : ElementTheme.Light;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using The_Untamed_Music_Player.Contracts.Services;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Messages;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
@@ -22,13 +23,15 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
private readonly DispatcherQueue dispatcherQueue;
|
||||
private readonly UISettings settings;
|
||||
private readonly ILogger _logger = LoggingService.CreateLogger<MainWindow>();
|
||||
private InfoBarManager? _infoBarManager;
|
||||
private readonly InfoBarManager? _infoBarManager;
|
||||
|
||||
public MainViewModel ViewModel { get; }
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Data.MainWindow = this;
|
||||
ViewModel = App.GetService<MainViewModel>();
|
||||
|
||||
AppWindow.SetIcon(Path.Combine(AppContext.BaseDirectory, "Assets/AppIcon/Icon.ico"));
|
||||
Title = "AppDisplayName".GetLocalized();
|
||||
@@ -38,10 +41,7 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
settings = new UISettings();
|
||||
settings.ColorValuesChanged += Settings_ColorValuesChanged;
|
||||
|
||||
Data.MainWindow = this;
|
||||
|
||||
ShellFrame.Navigate(typeof(ShellPage));
|
||||
ViewModel = App.GetService<MainViewModel>();
|
||||
|
||||
// 初始化InfoBar管理器
|
||||
_infoBarManager = new InfoBarManager(
|
||||
@@ -135,13 +135,12 @@ public sealed partial class MainWindow : WindowEx, IRecipient<LogMessage>
|
||||
try
|
||||
{
|
||||
Data.MusicPlayer.Dispose();
|
||||
ViewModel.CleanupDynamicBackgroundService(); // 清理背景服务
|
||||
ViewModel.CleanupSystemBackdrop(); // 清理系统背景
|
||||
Data.DesktopLyricWindow?.Close(); // 关闭桌面歌词窗口
|
||||
Data.DesktopLyricWindow?.Dispose();
|
||||
StrongReferenceMessenger.Default.Unregister<LogMessage>(this); // 清理消息接收
|
||||
_infoBarManager?.Dispose(); // 清理InfoBar管理器
|
||||
_infoBarManager = null;
|
||||
App.GetService<IMaterialSelectorService>().Dispose();
|
||||
App.GetService<IDynamicBackgroundService>().Dispose();
|
||||
LoggingService.Shutdown(); // 关闭日志服务
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using The_Untamed_Music_Player.Contracts.Models;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.ViewModels;
|
||||
@@ -8,11 +7,6 @@ namespace The_Untamed_Music_Player.Models;
|
||||
|
||||
public static class Data
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否是第一次使用本软件
|
||||
/// </summary>
|
||||
public static bool? NotFirstUsed { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在下载或更改音乐
|
||||
/// </summary>
|
||||
@@ -23,20 +17,13 @@ public static class Data
|
||||
/// </summary>
|
||||
public static bool IsFileActivationLaunch { get; set; } = false;
|
||||
|
||||
public static LocalAlbumInfo? SelectedLocalAlbum { get; set; }
|
||||
public static LocalArtistInfo? SelectedLocalArtist { get; set; }
|
||||
public static PlaylistInfo? SelectedPlaylist { get; set; }
|
||||
public static IBriefOnlineAlbumInfo? SelectedOnlineAlbum { get; set; }
|
||||
public static IBriefOnlineArtistInfo? SelectedOnlineArtist { get; set; }
|
||||
public static IBriefOnlinePlaylistInfo? SelectedOnlinePlaylist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 软件显示名称
|
||||
/// </summary>
|
||||
public static readonly string AppDisplayName = "AppDisplayName".GetLocalized();
|
||||
|
||||
/// <summary>
|
||||
/// 播放器支持的音频文件类型
|
||||
/// 支持的音频文件类型
|
||||
/// </summary>
|
||||
public static readonly string[] SupportedAudioTypes =
|
||||
[
|
||||
@@ -55,6 +42,9 @@ public static class Data
|
||||
".bwf",
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// 支持的封面图片类型
|
||||
/// </summary>
|
||||
public static readonly string[] SupportedCoverTypes =
|
||||
[
|
||||
".png",
|
||||
@@ -69,47 +59,34 @@ public static class Data
|
||||
".tiff",
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// 是否为独占模式
|
||||
/// </summary>
|
||||
public static bool IsExclusiveMode { get; set; }
|
||||
#region 用于导航的信息
|
||||
public static LocalAlbumInfo? SelectedLocalAlbum { get; set; }
|
||||
public static LocalArtistInfo? SelectedLocalArtist { get; set; }
|
||||
public static PlaylistInfo? SelectedPlaylist { get; set; }
|
||||
public static IBriefOnlineAlbumInfo? SelectedOnlineAlbum { get; set; }
|
||||
public static IBriefOnlineArtistInfo? SelectedOnlineArtist { get; set; }
|
||||
public static IBriefOnlinePlaylistInfo? SelectedOnlinePlaylist { get; set; }
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 是否为如果当前位于音乐库歌曲页面且使用文件夹排序方式,点击歌曲仅会将其所在文件夹内的歌曲加入播放队列
|
||||
/// </summary>
|
||||
public static bool IsOnlyAddSpecificFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 歌词字体
|
||||
/// </summary>
|
||||
public static FontFamily SelectedFontFamily { get; set; } = new("Microsoft YaHei");
|
||||
|
||||
/// <summary>
|
||||
/// 歌词字号
|
||||
/// </summary>
|
||||
public static double SelectedCurrentFontSize { get; set; } = 50.0;
|
||||
public static double SelectedNotCurrentFontSize { get; set; } = 20.0;
|
||||
|
||||
/// <summary>
|
||||
/// 是否显示歌词背景
|
||||
/// </summary>
|
||||
public static bool IsWindowBackgroundFollowsCover { get; set; } = false;
|
||||
|
||||
public static OnlineMusicLibrary OnlineMusicLibrary { get; set; } = new();
|
||||
public static MusicLibrary MusicLibrary { get; set; } = new();
|
||||
public static OnlineMusicLibrary OnlineMusicLibrary { get; set; } = new();
|
||||
public static PlaylistLibrary PlaylistLibrary { get; set; } = new();
|
||||
public static MusicPlayer MusicPlayer { get; set; } = new();
|
||||
|
||||
#region Views
|
||||
public static MainWindow? MainWindow { get; set; }
|
||||
public static ShellPage? ShellPage { get; set; }
|
||||
public static HomePage HomePage { get; set; } = null!;
|
||||
public static HomePage? HomePage { get; set; }
|
||||
public static LyricPage? LyricPage { get; set; }
|
||||
public static RootPlayBarView? RootPlayBarView { get; set; }
|
||||
public static DesktopLyricWindow? DesktopLyricWindow { get; set; }
|
||||
public static MainViewModel? MainViewModel { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ViewModels
|
||||
public static SettingsViewModel? SettingsViewModel { get; set; }
|
||||
public static ShellViewModel? ShellViewModel { get; set; }
|
||||
public static RootPlayBarViewModel? RootPlayBarViewModel { get; set; }
|
||||
public static LocalSongsViewModel? LocalSongsViewModel { get; set; }
|
||||
public static LocalAlbumsViewModel? LocalAlbumsViewModel { get; set; }
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public partial class LyricSlice(double time, string content) : ObservableObject
|
||||
} = false;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial double FontSize { get; set; } = Data.SelectedNotCurrentFontSize;
|
||||
public partial double FontSize { get; set; } = Settings.LyricPageNotCurrentFontSize;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial Thickness Margin { get; set; } = new(0, 20, 0, 20);
|
||||
@@ -32,7 +32,9 @@ public partial class LyricSlice(double time, string content) : ObservableObject
|
||||
|
||||
public void UpdateStyle()
|
||||
{
|
||||
FontSize = IsCurrent ? Data.SelectedCurrentFontSize : Data.SelectedNotCurrentFontSize;
|
||||
FontSize = IsCurrent
|
||||
? Settings.LyricPageCurrentFontSize
|
||||
: Settings.LyricPageNotCurrentFontSize;
|
||||
Margin = IsCurrent ? new Thickness(0, 40, 0, 40) : new Thickness(0, 20, 0, 20);
|
||||
Opacity = IsCurrent ? 1.0 : 0.5;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Messages;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
@@ -109,7 +110,8 @@ public partial class MusicLibrary : ObservableRecipient
|
||||
_logger.ZLogInformation(ex, $"加载音乐文件夹失败:{path}");
|
||||
}
|
||||
}
|
||||
Data.SettingsViewModel?.NotifyEmptyFolderMessageVisibilityChanged();
|
||||
Data.SettingsViewModel?.EmptyFolderMessageVisibility =
|
||||
Folders.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
_librarySemaphore.Release();
|
||||
}
|
||||
|
||||
@@ -1443,11 +1443,8 @@ public partial class MusicPlayer
|
||||
ShuffleMode = await _localSettingsService.ReadSettingAsync<bool>("ShuffleMode");
|
||||
RepeatMode = await _localSettingsService.ReadSettingAsync<byte>("RepeatMode");
|
||||
IsMute = await _localSettingsService.ReadSettingAsync<bool>("IsMute");
|
||||
while (!Data.NotFirstUsed.HasValue)
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
if (Data.NotFirstUsed.Value)
|
||||
|
||||
if (Settings.NotFirstUsed)
|
||||
{
|
||||
CurrentVolume = await _localSettingsService.ReadSettingAsync<double>(
|
||||
"CurrentVolume"
|
||||
|
||||
@@ -220,25 +220,15 @@ public static class Settings
|
||||
?? "Microsoft YaHei"
|
||||
);
|
||||
var themeName = await _localSettingsService.ReadSettingAsync<string>(nameof(Theme));
|
||||
if (Enum.TryParse(themeName, out ElementTheme cacheTheme))
|
||||
{
|
||||
Theme = cacheTheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
Theme = ElementTheme.Default;
|
||||
}
|
||||
Theme = Enum.TryParse<ElementTheme>(themeName, out var cacheTheme)
|
||||
? cacheTheme
|
||||
: ElementTheme.Default;
|
||||
var materialName = await _localSettingsService.ReadSettingAsync<string>(
|
||||
nameof(Material)
|
||||
);
|
||||
if (Enum.TryParse(materialName, out MaterialType cacheMaterial))
|
||||
{
|
||||
Material = cacheMaterial;
|
||||
}
|
||||
else
|
||||
{
|
||||
Material = MaterialType.DesktopAcrylic;
|
||||
}
|
||||
Material = Enum.TryParse<MaterialType>(materialName, out var cacheMaterial)
|
||||
? cacheMaterial
|
||||
: MaterialType.DesktopAcrylic;
|
||||
|
||||
if (NotFirstUsed)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using The_Untamed_Music_Player.Activation;
|
||||
using The_Untamed_Music_Player.Contracts.Services;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using ZLinq;
|
||||
|
||||
namespace The_Untamed_Music_Player.Services;
|
||||
@@ -12,18 +13,21 @@ public class ActivationService(IEnumerable<IActivationHandler> activationHandler
|
||||
App.GetService<IThemeSelectorService>();
|
||||
private readonly IMaterialSelectorService _materialSelectorService =
|
||||
App.GetService<IMaterialSelectorService>();
|
||||
private readonly IDynamicBackgroundService _dynamicBackgroundService =
|
||||
App.GetService<IDynamicBackgroundService>();
|
||||
|
||||
public async Task ActivateAsync(object activationArgs)
|
||||
{
|
||||
await InitializeAsync(); // 在激活之前执行任务
|
||||
await InitializeAsync(); // 在激活之前执行的任务
|
||||
await HandleActivationAsync(activationArgs); // 通过 ActivationHandlers 处理激活
|
||||
App.MainWindow?.Activate(); // 打开 MainWindow
|
||||
await StartupAsync(); // 在激活之后执行任务
|
||||
await StartupAsync(); // 在激活之后执行的任务
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
await _themeSelectorService.InitializeAsync().ConfigureAwait(false);
|
||||
await Settings.InitializeAsync().ConfigureAwait(false);
|
||||
_themeSelectorService.Initialize();
|
||||
}
|
||||
|
||||
private async Task HandleActivationAsync(object activationArgs)
|
||||
@@ -40,7 +44,8 @@ public class ActivationService(IEnumerable<IActivationHandler> activationHandler
|
||||
|
||||
private async Task StartupAsync()
|
||||
{
|
||||
await _themeSelectorService.SetRequestedThemeAsync();
|
||||
_themeSelectorService.SetRequestedThemeAsync();
|
||||
await _materialSelectorService.InitializeAsync();
|
||||
await _dynamicBackgroundService.InitializeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace The_Untamed_Music_Player.Services;
|
||||
/// <summary>
|
||||
/// 动态背景服务,根据当前播放歌曲的封面颜色动态改变窗口背景
|
||||
/// </summary>
|
||||
public class DynamicBackgroundService(IColorExtractionService colorExtractionService)
|
||||
public partial class DynamicBackgroundService(IColorExtractionService colorExtractionService)
|
||||
: IDynamicBackgroundService
|
||||
{
|
||||
private readonly ILogger _logger = LoggingService.CreateLogger<DynamicBackgroundService>();
|
||||
@@ -37,7 +37,7 @@ public class DynamicBackgroundService(IColorExtractionService colorExtractionSer
|
||||
ClearBackground();
|
||||
}
|
||||
}
|
||||
} = Data.IsWindowBackgroundFollowsCover;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 背景更新事件
|
||||
@@ -48,27 +48,15 @@ public class DynamicBackgroundService(IColorExtractionService colorExtractionSer
|
||||
/// 初始化动态背景服务
|
||||
/// </summary>
|
||||
/// <param name="targetElement">目标元素(通常是MainWindow的根容器)</param>
|
||||
public void Initialize(FrameworkElement targetElement)
|
||||
public async Task InitializeAsync(FrameworkElement? targetElement = null)
|
||||
{
|
||||
_targetElement = targetElement;
|
||||
_compositor = ElementCompositionPreview.GetElementVisual(targetElement).Compositor;
|
||||
IsEnabled = Settings.IsWindowBackgroundFollowsCover;
|
||||
_targetElement = targetElement ?? Data.MainWindow!.GetBackgroundGrid();
|
||||
_compositor = ElementCompositionPreview.GetElementVisual(_targetElement).Compositor;
|
||||
|
||||
// 监听当前歌曲变化
|
||||
Data.MusicPlayer.PropertyChanged += OnMusicPlayerPropertyChanged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Data.MusicPlayer.PropertyChanged -= OnMusicPlayerPropertyChanged;
|
||||
|
||||
// ClearBackground();
|
||||
_backgroundVisual?.Dispose();
|
||||
_currentGradientBrush?.Dispose();
|
||||
|
||||
_targetElement?.SizeChanged -= OnTargetElementSizeChanged;
|
||||
await UpdateBackgroundAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -358,4 +346,16 @@ public class DynamicBackgroundService(IColorExtractionService colorExtractionSer
|
||||
(byte)((b + m) * 255)
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Data.MusicPlayer.PropertyChanged -= OnMusicPlayerPropertyChanged;
|
||||
_backgroundVisual?.Dispose();
|
||||
_currentGradientBrush?.Dispose();
|
||||
_targetElement?.SizeChanged -= OnTargetElementSizeChanged;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
IsInputActive = true,
|
||||
};
|
||||
private ISystemBackdropControllerWithTargets? _currentBackdropController;
|
||||
public bool _firstStart = true;
|
||||
public MaterialType Material
|
||||
{
|
||||
get;
|
||||
@@ -67,11 +66,19 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
IsFallBack = Settings.IsFallBack;
|
||||
LuminosityOpacity = Settings.LuminosityOpacity;
|
||||
TintColor = Settings.TintColor;
|
||||
await SetMaterial(Material);
|
||||
await SetMaterial(Material, true, true);
|
||||
}
|
||||
|
||||
public async Task<(byte, Color)> SetMaterial(MaterialType material)
|
||||
public async Task<(byte, Color)> SetMaterial(
|
||||
MaterialType material,
|
||||
bool firstStart = false,
|
||||
bool forced = false
|
||||
)
|
||||
{
|
||||
if (Material == material && !forced)
|
||||
{
|
||||
return (LuminosityOpacity, TintColor);
|
||||
}
|
||||
_mainWindow.SystemBackdrop = null;
|
||||
_currentBackdropController?.RemoveAllSystemBackdropTargets();
|
||||
_currentBackdropController?.Dispose();
|
||||
@@ -111,11 +118,10 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
};
|
||||
}
|
||||
|
||||
if (_firstStart && ThemeSelectorService.IsDarkTheme == Settings.PreviousIsDarkTheme)
|
||||
if (firstStart && ThemeSelectorService.IsDarkTheme == Settings.PreviousIsDarkTheme)
|
||||
{
|
||||
SetLuminosityOpacity(LuminosityOpacity);
|
||||
SetTintColor(TintColor);
|
||||
_firstStart = false;
|
||||
SetLuminosityOpacity(LuminosityOpacity, true);
|
||||
SetTintColor(TintColor, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,8 +134,12 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
|
||||
public void SetIsFallBack(bool isFallBack) => IsFallBack = isFallBack;
|
||||
|
||||
public void SetLuminosityOpacity(byte opacity)
|
||||
public void SetLuminosityOpacity(byte opacity, bool forced = false)
|
||||
{
|
||||
if (LuminosityOpacity == opacity && !forced)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_currentBackdropController is MicaController micaController)
|
||||
{
|
||||
micaController.LuminosityOpacity = opacity / 100f;
|
||||
@@ -141,8 +151,12 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
LuminosityOpacity = opacity;
|
||||
}
|
||||
|
||||
public void SetTintColor(Color color)
|
||||
public void SetTintColor(Color color, bool forced = false)
|
||||
{
|
||||
if (TintColor == color && !forced)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_currentBackdropController is MicaController micaController)
|
||||
{
|
||||
micaController.TintColor = color;
|
||||
@@ -203,11 +217,11 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
{
|
||||
color = Material switch
|
||||
{
|
||||
MaterialType.Mica => Color.FromArgb(255, 32, 32, 32),
|
||||
MaterialType.MicaAlt => Color.FromArgb(255, 10, 10, 10),
|
||||
MaterialType.DesktopAcrylic => Color.FromArgb(255, 44, 44, 44),
|
||||
MaterialType.AcrylicBase => Color.FromArgb(255, 32, 32, 32),
|
||||
MaterialType.AcrylicThin => Color.FromArgb(255, 84, 84, 84),
|
||||
MaterialType.Mica => ColorFromHex(0xFF202020),
|
||||
MaterialType.MicaAlt => ColorFromHex(0xFF0A0A0A),
|
||||
MaterialType.DesktopAcrylic => ColorFromHex(0xFF2C2C2C),
|
||||
MaterialType.AcrylicBase => ColorFromHex(0xFF202020),
|
||||
MaterialType.AcrylicThin => ColorFromHex(0xFF545454),
|
||||
_ => TintColor,
|
||||
};
|
||||
}
|
||||
@@ -215,11 +229,11 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
{
|
||||
color = Material switch
|
||||
{
|
||||
MaterialType.Mica => Color.FromArgb(255, 243, 243, 243),
|
||||
MaterialType.MicaAlt => Color.FromArgb(255, 218, 218, 218),
|
||||
MaterialType.DesktopAcrylic => Color.FromArgb(255, 252, 252, 252),
|
||||
MaterialType.AcrylicBase => Color.FromArgb(255, 243, 243, 243),
|
||||
MaterialType.AcrylicThin => Color.FromArgb(255, 211, 211, 211),
|
||||
MaterialType.Mica => ColorFromHex(0xFFF3F3F3),
|
||||
MaterialType.MicaAlt => ColorFromHex(0xFFDADADA),
|
||||
MaterialType.DesktopAcrylic => ColorFromHex(0xFFFCFCFC),
|
||||
MaterialType.AcrylicBase => ColorFromHex(0xFFF3F3F3),
|
||||
MaterialType.AcrylicThin => ColorFromHex(0xFFD3D3D3),
|
||||
_ => TintColor,
|
||||
};
|
||||
}
|
||||
@@ -234,6 +248,15 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
TintColor = color;
|
||||
}
|
||||
|
||||
private static Color ColorFromHex(uint hex)
|
||||
{
|
||||
var a = (byte)((hex >> 24) & 0xFF);
|
||||
var r = (byte)((hex >> 16) & 0xFF);
|
||||
var g = (byte)((hex >> 8) & 0xFF);
|
||||
var b = (byte)(hex & 0xFF);
|
||||
return Color.FromArgb(a, r, g, b);
|
||||
}
|
||||
|
||||
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
if (IsFallBack)
|
||||
@@ -252,4 +275,14 @@ public class MaterialSelectorService : IMaterialSelectorService
|
||||
SetConfigurationSourceTheme();
|
||||
ChangeTheme();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_currentBackdropController?.RemoveAllSystemBackdropTargets();
|
||||
_currentBackdropController?.Dispose();
|
||||
_currentBackdropController = null;
|
||||
_mainWindow.Activated -= MainWindow_Activated;
|
||||
((FrameworkElement)_mainWindow.Content).ActualThemeChanged -= Window_ThemeChanged;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,46 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using The_Untamed_Music_Player.Contracts.Services;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
|
||||
namespace The_Untamed_Music_Player.Services;
|
||||
|
||||
public class ThemeSelectorService : IThemeSelectorService
|
||||
{
|
||||
private const string SettingsKey = "AppBackgroundRequestedTheme";
|
||||
private readonly ILocalSettingsService _localSettingsService =
|
||||
App.GetService<ILocalSettingsService>();
|
||||
public ElementTheme Theme
|
||||
{
|
||||
get;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
Settings.Theme = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDarkTheme =>
|
||||
((FrameworkElement)App.MainWindow!.Content).ActualTheme == ElementTheme.Dark
|
||||
|| (
|
||||
((FrameworkElement)App.MainWindow!.Content).ActualTheme == ElementTheme.Default
|
||||
&& App.Current.RequestedTheme == ApplicationTheme.Dark
|
||||
);
|
||||
public ElementTheme Theme { get; set; } = ElementTheme.Default;
|
||||
|
||||
public async Task InitializeAsync()
|
||||
public void Initialize()
|
||||
{
|
||||
Theme = await LoadThemeFromSettingsAsync();
|
||||
Theme = Settings.Theme;
|
||||
}
|
||||
|
||||
public async Task SetThemeAsync(ElementTheme theme)
|
||||
public void SetThemeAsync(ElementTheme theme)
|
||||
{
|
||||
Theme = theme;
|
||||
await SetRequestedThemeAsync();
|
||||
await SaveThemeInSettingsAsync(Theme);
|
||||
SetRequestedThemeAsync();
|
||||
}
|
||||
|
||||
public async Task SetRequestedThemeAsync()
|
||||
public void SetRequestedThemeAsync()
|
||||
{
|
||||
if (App.MainWindow!.Content is FrameworkElement rootElement)
|
||||
{
|
||||
rootElement.RequestedTheme = Theme;
|
||||
TitleBarHelper.UpdateTitleBar(Theme);
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task<ElementTheme> LoadThemeFromSettingsAsync()
|
||||
{
|
||||
var themeName = await _localSettingsService.ReadSettingAsync<string>(SettingsKey);
|
||||
if (Enum.TryParse(themeName, out ElementTheme cacheTheme))
|
||||
{
|
||||
return cacheTheme;
|
||||
}
|
||||
return ElementTheme.Default;
|
||||
}
|
||||
|
||||
private async Task SaveThemeInSettingsAsync(ElementTheme theme)
|
||||
{
|
||||
await _localSettingsService.SaveSettingAsync(SettingsKey, $"{theme}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public partial class HomeViewModel : ObservableObject
|
||||
_selectorBar?.SelectedItem = _selectorBar.Items[currentSelectedIndex];
|
||||
|
||||
_ = Data.OnlineMusicLibrary.Search();
|
||||
Data.HomePage.GetFrame()
|
||||
Data.HomePage?.GetFrame()
|
||||
.Navigate(
|
||||
page,
|
||||
null,
|
||||
|
||||
@@ -235,7 +235,7 @@ public partial class LocalSongsViewModel
|
||||
{
|
||||
if (_isGrouped)
|
||||
{
|
||||
if ((SortMode is 10 or 11) && Data.IsOnlyAddSpecificFolder)
|
||||
if ((SortMode is 10 or 11) && Settings.IsOnlyAddSpecificFolder)
|
||||
{
|
||||
return
|
||||
[
|
||||
|
||||
@@ -1,66 +1,6 @@
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Composition;
|
||||
using Microsoft.UI.Composition.SystemBackdrops;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using The_Untamed_Music_Player.Contracts.Services;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using Windows.UI;
|
||||
using WinRT;
|
||||
using WinUIEx;
|
||||
|
||||
namespace The_Untamed_Music_Player.ViewModels;
|
||||
|
||||
public class MainViewModel
|
||||
{
|
||||
private readonly ILocalSettingsService _localSettingsService =
|
||||
App.GetService<ILocalSettingsService>();
|
||||
private IDynamicBackgroundService _dynamicBackgroundService = null!;
|
||||
|
||||
private readonly MainWindow _mainWindow;
|
||||
|
||||
public bool IsDarkTheme { get; set; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
_mainWindow = Data.MainWindow ?? new();
|
||||
IsDarkTheme =
|
||||
((FrameworkElement)_mainWindow.Content).ActualTheme == ElementTheme.Dark
|
||||
|| (
|
||||
((FrameworkElement)_mainWindow.Content).ActualTheme == ElementTheme.Default
|
||||
&& App.Current.RequestedTheme == ApplicationTheme.Dark
|
||||
);
|
||||
InitializeDynamicBackground();
|
||||
((FrameworkElement)_mainWindow.Content).ActualThemeChanged += Window_ThemeChanged;
|
||||
Data.MainViewModel = this;
|
||||
}
|
||||
|
||||
public void InitializeDynamicBackground()
|
||||
{
|
||||
_dynamicBackgroundService = App.GetService<IDynamicBackgroundService>();
|
||||
// 初始化动态背景服务,使用根网格作为目标元素
|
||||
_dynamicBackgroundService.Initialize(_mainWindow.GetBackgroundGrid());
|
||||
|
||||
// 如果当前已有正在播放的歌曲,立即更新背景
|
||||
_ = _dynamicBackgroundService.UpdateBackgroundAsync();
|
||||
}
|
||||
|
||||
private void Window_ThemeChanged(FrameworkElement sender, object args)
|
||||
{
|
||||
IsDarkTheme =
|
||||
((FrameworkElement)_mainWindow.Content).ActualTheme == ElementTheme.Dark
|
||||
|| (
|
||||
((FrameworkElement)_mainWindow.Content).ActualTheme == ElementTheme.Default
|
||||
&& App.Current.RequestedTheme == ApplicationTheme.Dark
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理动态背景服务
|
||||
/// </summary>
|
||||
public void CleanupDynamicBackgroundService()
|
||||
{
|
||||
_dynamicBackgroundService?.Dispose();
|
||||
}
|
||||
public MainViewModel() { }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
@@ -41,8 +40,8 @@ public partial class SettingsViewModel
|
||||
/// <summary>
|
||||
/// 是否显示文件夹为空信息
|
||||
/// </summary>
|
||||
public Visibility EmptyFolderMessageVisibility =>
|
||||
Data.MusicLibrary.Folders?.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
public partial Visibility EmptyFolderMessageVisibility { get; set; } = Visibility.Collapsed;
|
||||
|
||||
/// <summary>
|
||||
/// 歌曲下载位置
|
||||
@@ -129,12 +128,12 @@ public partial class SettingsViewModel
|
||||
public partial ElementTheme ElementTheme { get; set; }
|
||||
|
||||
[RelayCommand]
|
||||
public async Task SwitchThemeAsync(ElementTheme theme)
|
||||
public void SwitchTheme(ElementTheme theme)
|
||||
{
|
||||
if (ElementTheme != theme)
|
||||
{
|
||||
ElementTheme = theme;
|
||||
await _themeSelectorService.SetThemeAsync(theme);
|
||||
_themeSelectorService.SetThemeAsync(theme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +201,8 @@ public partial class SettingsViewModel
|
||||
TintColor = _materialSelectorService.TintColor;
|
||||
VersionDescription = GetVersionDescription();
|
||||
|
||||
EmptyFolderMessageVisibility =
|
||||
Data.MusicLibrary.Folders.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
LoadSongDownloadLocationAsync();
|
||||
LoadFonts();
|
||||
IsExportPlaylistsButtonEnabled = Data.PlaylistLibrary.Playlists.Count > 0;
|
||||
@@ -213,14 +214,6 @@ public partial class SettingsViewModel
|
||||
IsExportPlaylistsButtonEnabled = message.HasPlaylist;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知 EmptyFolderMessageVisibility 属性发生了变化(供外部调用)
|
||||
/// </summary>
|
||||
public void NotifyEmptyFolderMessageVisibilityChanged()
|
||||
{
|
||||
OnPropertyChanged(nameof(EmptyFolderMessageVisibility));
|
||||
}
|
||||
|
||||
public async void PickMusicFolderButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
(sender as Button)!.IsEnabled = false;
|
||||
@@ -236,7 +229,8 @@ public partial class SettingsViewModel
|
||||
)
|
||||
{
|
||||
Data.MusicLibrary.Folders.Add(folder.Path);
|
||||
OnPropertyChanged(nameof(EmptyFolderMessageVisibility));
|
||||
EmptyFolderMessageVisibility =
|
||||
Data.MusicLibrary.Folders.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
await SaveFoldersAsync();
|
||||
await Data.MusicLibrary.LoadLibraryAgainAsync(); // 重新加载音乐库
|
||||
}
|
||||
@@ -246,7 +240,8 @@ public partial class SettingsViewModel
|
||||
public async void RemoveMusicFolder(string folder)
|
||||
{
|
||||
Data.MusicLibrary.Folders.Remove(folder);
|
||||
OnPropertyChanged(nameof(EmptyFolderMessageVisibility));
|
||||
EmptyFolderMessageVisibility =
|
||||
Data.MusicLibrary.Folders.Count > 0 ? Visibility.Collapsed : Visibility.Visible;
|
||||
await SaveFoldersAsync();
|
||||
await Data.MusicLibrary.LoadLibraryAgainAsync();
|
||||
}
|
||||
@@ -463,18 +458,22 @@ public partial class SettingsViewModel
|
||||
public async void MaterialComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
var (opacity, color) = await _materialSelectorService.SetMaterial(
|
||||
(MaterialType)SelectedMaterial
|
||||
(MaterialType)SelectedMaterial,
|
||||
false,
|
||||
false
|
||||
);
|
||||
LuminosityOpacity = opacity;
|
||||
TintColor = color;
|
||||
}
|
||||
|
||||
public async void ResetButton_Click(object sender, RoutedEventArgs e)
|
||||
public async void ResetMaterialButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IsFallBack = true;
|
||||
SelectedMaterial = 3;
|
||||
SelectedMaterial = (byte)MaterialType.DesktopAcrylic;
|
||||
var (opacity, color) = await _materialSelectorService.SetMaterial(
|
||||
(MaterialType)SelectedMaterial
|
||||
(MaterialType)SelectedMaterial,
|
||||
false,
|
||||
true
|
||||
);
|
||||
LuminosityOpacity = opacity;
|
||||
TintColor = color;
|
||||
@@ -486,12 +485,12 @@ public partial class SettingsViewModel
|
||||
RangeBaseValueChangedEventArgs e
|
||||
)
|
||||
{
|
||||
_materialSelectorService.SetLuminosityOpacity(LuminosityOpacity);
|
||||
_materialSelectorService.SetLuminosityOpacity(LuminosityOpacity, false);
|
||||
}
|
||||
|
||||
public void TintColorPicker_ColorChanged(ColorPicker sender, ColorChangedEventArgs args)
|
||||
{
|
||||
_materialSelectorService.SetTintColor(args.NewColor);
|
||||
_materialSelectorService.SetTintColor(args.NewColor, false);
|
||||
}
|
||||
|
||||
public void FontFamilyComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Behavior="Bouncing" Direction="Left"
|
||||
FontFamily="{x:Bind model:Data.SelectedFontFamily}"
|
||||
FontFamily="{x:Bind model:Settings.FontFamily}"
|
||||
FontSize="32" Foreground="#FDFDFD"
|
||||
Loaded="LyricContent_Loaded"
|
||||
SizeChanged="LyricContentTextBlock_SizeChanged"
|
||||
|
||||
@@ -33,7 +33,7 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
private readonly TextBlock _measureTextBlock = new()
|
||||
{
|
||||
FontSize = 32,
|
||||
FontFamily = Data.SelectedFontFamily,
|
||||
FontFamily = Settings.FontFamily,
|
||||
};
|
||||
|
||||
public DesktopLyricViewModel ViewModel { get; }
|
||||
@@ -58,7 +58,7 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
var exStyle = GetWindowLong(_hWnd, GWL_EXSTYLE);
|
||||
exStyle |= WS_EX_TOOLWINDOW; // 添加工具窗口样式
|
||||
exStyle &= ~WS_EX_APPWINDOW; // 移除应用窗口样式
|
||||
_ = SetWindowLong(_hWnd, GWL_EXSTYLE, exStyle);
|
||||
SetWindowLong(_hWnd, GWL_EXSTYLE, exStyle);
|
||||
|
||||
SetTopmost(true);
|
||||
|
||||
@@ -147,16 +147,12 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
if (isClickThrough)
|
||||
{
|
||||
// 添加 WS_EX_TRANSPARENT 使窗口点击穿透
|
||||
_ = SetWindowLong(_hWnd, GWL_EXSTYLE, currentStyle | WS_EX_LAYERED | WS_EX_TRANSPARENT);
|
||||
SetWindowLong(_hWnd, GWL_EXSTYLE, currentStyle | WS_EX_LAYERED | WS_EX_TRANSPARENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 移除 WS_EX_TRANSPARENT 使窗口可接收点击
|
||||
_ = SetWindowLong(
|
||||
_hWnd,
|
||||
GWL_EXSTYLE,
|
||||
(currentStyle | WS_EX_LAYERED) & ~WS_EX_TRANSPARENT
|
||||
);
|
||||
SetWindowLong(_hWnd, GWL_EXSTYLE, (currentStyle | WS_EX_LAYERED) & ~WS_EX_TRANSPARENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,24 +163,10 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
const uint SWP_NOSIZE = 0x0001;
|
||||
const uint SWP_NOACTIVATE = 0x0010;
|
||||
const uint flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE;
|
||||
|
||||
var position = value ? new nint(-1) : new nint(-2);
|
||||
|
||||
SetWindowPos(_hWnd, position, 0, 0, 0, 0, flags);
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
Data.RootPlayBarViewModel?.IsDesktopLyricWindowStarted = false;
|
||||
if (_updateTimer250ms is not null)
|
||||
{
|
||||
_updateTimer250ms.Stop();
|
||||
_updateTimer250ms = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
private void AnimatedBorder_PointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
_isDragging = true;
|
||||
@@ -227,7 +209,7 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
{
|
||||
Text = "TEST测试",
|
||||
FontSize = 32,
|
||||
FontFamily = Data.SelectedFontFamily,
|
||||
FontFamily = Settings.FontFamily,
|
||||
};
|
||||
textBlock.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
|
||||
(sender as MarqueeText)!.Height = textBlock.DesiredSize.Height;
|
||||
@@ -282,4 +264,13 @@ public sealed partial class DesktopLyricWindow : WindowEx, IDisposable
|
||||
_logger.ZLogInformation(ex, $"调整灵动词岛宽度时发生错误");
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
Data.RootPlayBarViewModel?.IsDesktopLyricWindowStarted = false;
|
||||
_updateTimer250ms?.Stop();
|
||||
_updateTimer250ms = null;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
<TextBlock x:Name="LyricTextBlock"
|
||||
Margin="{x:Bind Margin, Mode=OneWay}"
|
||||
FontFamily="{x:Bind model:Data.SelectedFontFamily}"
|
||||
FontFamily="{x:Bind model:Settings.FontFamily}"
|
||||
FontSize="{x:Bind FontSize, Mode=OneWay}"
|
||||
Opacity="{x:Bind Opacity, Mode=OneWay}"
|
||||
SizeChanged="TextBlock_SizeChanged"
|
||||
@@ -128,6 +128,19 @@
|
||||
<ColumnDefinition Width="1.2*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="ShadowTarget"/>
|
||||
<ScrollViewer x:Name="LyricViewer" VerticalScrollBarVisibility="Hidden">
|
||||
<StackPanel>
|
||||
<StackPanel Height="600"/>
|
||||
<ListView x:Name="LyricView"
|
||||
helper:ListViewExtensions.ItemCornerRadius="15"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.ListView_ItemClick}"
|
||||
ItemTemplate="{StaticResource LyricViewTemplate}"
|
||||
ItemsSource="{x:Bind model:Data.MusicPlayer.CurrentLyric, Mode=OneWay}"
|
||||
SelectionMode="None"/>
|
||||
<StackPanel Height="600"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Grid x:Name="ReferenceGrid"
|
||||
Grid.Row="0" Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
@@ -203,19 +216,6 @@
|
||||
Offset="20,20"/>
|
||||
</ui:Effects.Shadow>
|
||||
</Border>
|
||||
<ScrollViewer x:Name="LyricViewer" VerticalScrollBarVisibility="Hidden">
|
||||
<StackPanel>
|
||||
<StackPanel Height="600"/>
|
||||
<ListView x:Name="LyricView"
|
||||
helper:ListViewExtensions.ItemCornerRadius="15"
|
||||
IsItemClickEnabled="True"
|
||||
ItemClick="{x:Bind ViewModel.ListView_ItemClick}"
|
||||
ItemTemplate="{StaticResource LyricViewTemplate}"
|
||||
ItemsSource="{x:Bind model:Data.MusicPlayer.CurrentLyric, Mode=OneWay}"
|
||||
SelectionMode="None"/>
|
||||
<StackPanel Height="600"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@@ -128,8 +128,8 @@ public sealed partial class LyricPage : Page, IDisposable
|
||||
|
||||
private void TextBlock_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
var textblock = sender as TextBlock;
|
||||
if (textblock!.FontSize == Data.SelectedCurrentFontSize)
|
||||
var textblock = (sender as TextBlock)!;
|
||||
if (Math.Abs(textblock.FontSize - Settings.LyricPageCurrentFontSize) < 1e-3)
|
||||
{
|
||||
var currentScrollPosition = LyricViewer.VerticalOffset;
|
||||
var point = new Point(0, currentScrollPosition);
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.UI.Xaml.Media.Animation;
|
||||
using The_Untamed_Music_Player.Controls;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
using The_Untamed_Music_Player.ViewModels;
|
||||
|
||||
namespace The_Untamed_Music_Player.Views;
|
||||
@@ -217,7 +218,7 @@ public sealed partial class PlayListsPage : Page
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme
|
||||
? ElementTheme.Dark
|
||||
: ElementTheme.Light,
|
||||
Title = titleTextBlock,
|
||||
|
||||
@@ -6,6 +6,7 @@ using The_Untamed_Music_Player.Contracts.Models;
|
||||
using The_Untamed_Music_Player.Controls;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
using The_Untamed_Music_Player.ViewModels;
|
||||
using ZLinq;
|
||||
|
||||
@@ -280,7 +281,7 @@ public sealed partial class PlayQueuePage : Page
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme
|
||||
? ElementTheme.Dark
|
||||
: ElementTheme.Light,
|
||||
Title = titleTextBlock,
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
|
||||
<toolkit:SettingsExpander x:Uid="Settings_WindowMaterial" HeaderIcon="{ui:FontIcon FontFamily={StaticResource UntamedFontFamily}, Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<Button x:Uid="Settings_Reset" Click="{x:Bind ViewModel.ResetButton_Click}"/>
|
||||
<Button x:Uid="Settings_Reset" Click="{x:Bind ViewModel.ResetMaterialButton_Click}"/>
|
||||
<ComboBox x:Name="MaterialComboBox" x:Uid="Settings_ChooseAMaterial"
|
||||
ItemsSource="{x:Bind ViewModel.Materials}"
|
||||
SelectedIndex="{x:Bind ViewModel.SelectedMaterial, Mode=TwoWay}"
|
||||
|
||||
@@ -3,7 +3,7 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using The_Untamed_Music_Player.Controls;
|
||||
using The_Untamed_Music_Player.Helpers;
|
||||
using The_Untamed_Music_Player.Models;
|
||||
using The_Untamed_Music_Player.Services;
|
||||
using The_Untamed_Music_Player.ViewModels;
|
||||
using Windows.Storage;
|
||||
using Windows.System;
|
||||
@@ -34,7 +34,7 @@ public sealed partial class SettingsPage : Page
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme
|
||||
? ElementTheme.Dark
|
||||
: ElementTheme.Light,
|
||||
Title = titleTextBlock,
|
||||
@@ -66,7 +66,7 @@ public sealed partial class SettingsPage : Page
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme
|
||||
? ElementTheme.Dark
|
||||
: ElementTheme.Light,
|
||||
Title = titleTextBlock,
|
||||
@@ -104,7 +104,7 @@ public sealed partial class SettingsPage : Page
|
||||
{
|
||||
XamlRoot = XamlRoot,
|
||||
Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
|
||||
RequestedTheme = Data.MainViewModel!.IsDarkTheme
|
||||
RequestedTheme = ThemeSelectorService.IsDarkTheme
|
||||
? ElementTheme.Dark
|
||||
: ElementTheme.Light,
|
||||
Title = titleTextBlock,
|
||||
|
||||
Reference in New Issue
Block a user