mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 10:54:55 +08:00
feat: multi lyrics window
This commit is contained in:
@@ -6,7 +6,6 @@ using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
|
||||
using BetterLyrics.WinUI3.Services.DiscordService;
|
||||
using BetterLyrics.WinUI3.Services.LastFMService;
|
||||
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.ResourceService;
|
||||
@@ -21,6 +20,7 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.ApplicationModel.Resources;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -69,12 +69,15 @@ namespace BetterLyrics.WinUI3
|
||||
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
// 设置托盘
|
||||
WindowHook.OpenOrShowWindow<SystemTrayWindow>();
|
||||
WindowHook.HideWindow<SystemTrayWindow>();
|
||||
// 先获取一个实例,确保初始化 LyricsWindowStatus
|
||||
var settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
|
||||
WindowHook.OpenOrShowWindow<NowPlayingWindow>();
|
||||
if (Ioc.Default.GetRequiredService<ISettingsService>().AppSettings.MusicGallerySettings.AutoOpen)
|
||||
// 设置托盘
|
||||
var systemTrayWindow = WindowHook.OpenOrShowWindow<SystemTrayWindow>();
|
||||
systemTrayWindow.HideWindow();
|
||||
|
||||
WindowHook.OpenOrShowWindow<NowPlayingWindow>(settingsService.AppSettings.WindowBoundsRecords.FirstOrDefault(x => x.IsDefault));
|
||||
if (settingsService.AppSettings.MusicGallerySettings.AutoOpen)
|
||||
{
|
||||
WindowHook.OpenOrShowWindow<MusicGalleryWindow>();
|
||||
}
|
||||
@@ -96,7 +99,6 @@ namespace BetterLyrics.WinUI3
|
||||
loggingBuilder.AddSerilog();
|
||||
})
|
||||
// Services
|
||||
.AddSingleton<ILiveStatesService, LiveStatesService>()
|
||||
.AddSingleton<ISettingsService, SettingsService>()
|
||||
.AddSingleton<IMediaSessionsService, MediaSessionsService>()
|
||||
.AddSingleton<IAlbumArtSearchService, AlbumArtSearchService>()
|
||||
@@ -114,9 +116,9 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<LyricsWindowSettingsControlViewModel>()
|
||||
.AddSingleton<LyricsWindowSwitchControlViewModel>()
|
||||
.AddSingleton<LyricsWindowSwitchWindowViewModel>()
|
||||
|
||||
.AddSingleton<NowPlayingWindowViewModel>()
|
||||
.AddSingleton<NowPlayingPageViewModel>()
|
||||
|
||||
.AddTransient<NowPlayingWindowViewModel>()
|
||||
.AddTransient<NowPlayingPageViewModel>()
|
||||
|
||||
.AddSingleton<SettingsWindowViewModel>()
|
||||
.AddSingleton<SystemTrayViewModel>()
|
||||
|
||||
@@ -79,14 +79,6 @@
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
<dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
|
||||
</dev:SettingsCard>
|
||||
|
||||
@@ -8,9 +8,9 @@ using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Renderer;
|
||||
using BetterLyrics.WinUI3.Services.LastFMService;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
@@ -20,6 +20,7 @@ using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Windows.Foundation;
|
||||
@@ -28,20 +29,11 @@ using Windows.UI;
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class LyricsCanvas : UserControl,
|
||||
IRecipient<PropertyChangedMessage<int>>,
|
||||
IRecipient<PropertyChangedMessage<AlbumArtThemeColors>>,
|
||||
IRecipient<PropertyChangedMessage<TimeSpan>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsData?>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>,
|
||||
IRecipient<PropertyChangedMessage<double>>,
|
||||
IRecipient<PropertyChangedMessage<bool>>,
|
||||
IRecipient<PropertyChangedMessage<TextAlignmentType>>,
|
||||
IRecipient<PropertyChangedMessage<SongInfo?>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsFontWeight>>,
|
||||
IRecipient<PropertyChangedMessage<string>>
|
||||
IRecipient<PropertyChangedMessage<SongInfo?>>
|
||||
{
|
||||
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
private readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
private readonly ILastFMService _lastFMService = Ioc.Default.GetRequiredService<ILastFMService>();
|
||||
|
||||
@@ -108,6 +100,9 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
private double _renderLyricsHeight = 0;
|
||||
private double _renderLyricsOpacity = 0;
|
||||
|
||||
private LyricsWindowStatus? _lyricsWindowStatus = null;
|
||||
private AlbumArtThemeColors _albumArtThemeColors = new();
|
||||
|
||||
private Point _mousePosition = new(0, 0);
|
||||
private int _mouseHoverLineIndex = -1;
|
||||
private bool _isMouseInLyricsArea = false;
|
||||
@@ -128,6 +123,24 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
public double ActualLyricsHeight => LyricsLayoutManager.CalculateActualHeight(_renderLyricsLines);
|
||||
public int CurrentHoveringLineIndex => _mouseHoverLineIndex;
|
||||
|
||||
public LyricsWindowStatus LyricsWindowStatus
|
||||
{
|
||||
get { return (LyricsWindowStatus)GetValue(LyricsWindowStatusProperty); }
|
||||
set { SetValue(LyricsWindowStatusProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsWindowStatusProperty =
|
||||
DependencyProperty.Register(nameof(LyricsWindowStatus), typeof(LyricsWindowStatus), typeof(LyricsCanvas), new PropertyMetadata(default, OnDependencyPropertyChanged));
|
||||
|
||||
public AlbumArtThemeColors AlbumArtThemeColors
|
||||
{
|
||||
get { return (AlbumArtThemeColors)GetValue(AlbumArtThemeColorsProperty); }
|
||||
set { SetValue(AlbumArtThemeColorsProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty AlbumArtThemeColorsProperty =
|
||||
DependencyProperty.Register(nameof(AlbumArtThemeColors), typeof(AlbumArtThemeColors), typeof(LyricsCanvas), new PropertyMetadata(new AlbumArtThemeColors(), OnDependencyPropertyChanged));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC> X <20><><EFBFBD><EFBFBD>
|
||||
public double LyricsStartX
|
||||
{
|
||||
@@ -136,7 +149,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsStartXProperty =
|
||||
DependencyProperty.Register(nameof(LyricsStartX), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(LyricsStartX), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ Y <20><><EFBFBD><EFBFBD>
|
||||
public double LyricsStartY
|
||||
@@ -146,7 +159,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsStartYProperty =
|
||||
DependencyProperty.Register(nameof(LyricsStartY), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(LyricsStartY), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
public double LyricsWidth
|
||||
@@ -156,7 +169,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsWidthProperty =
|
||||
DependencyProperty.Register(nameof(LyricsWidth), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(LyricsWidth), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>
|
||||
public double LyricsHeight
|
||||
@@ -166,7 +179,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsHeightProperty =
|
||||
DependencyProperty.Register(nameof(LyricsHeight), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(LyricsHeight), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><CDB8><EFBFBD><EFBFBD>
|
||||
public double LyricsOpacity
|
||||
@@ -176,7 +189,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsOpacityProperty =
|
||||
DependencyProperty.Register(nameof(LyricsOpacity), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(LyricsOpacity), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
/// <summary>
|
||||
/// <20>û<EFBFBD><C3BB>ٿ<EFBFBD><D9BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE>루<EFBFBD><EBA3A8> 0 <20><>ʼ<EFBFBD>㣩
|
||||
@@ -188,7 +201,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MouseScrollOffsetProperty =
|
||||
DependencyProperty.Register(nameof(MouseScrollOffset), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(MouseScrollOffset), typeof(double), typeof(LyricsCanvas), new PropertyMetadata(0.0, OnDependencyPropertyChanged));
|
||||
|
||||
/// <summary>
|
||||
/// <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD>굱ǰ<EAB5B1><C7B0>λ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻǣ<CFBD>
|
||||
@@ -200,7 +213,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty MousePositionProperty =
|
||||
DependencyProperty.Register(nameof(MousePosition), typeof(Point), typeof(LyricsCanvas), new PropertyMetadata(new Point(0, 0), OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(MousePosition), typeof(Point), typeof(LyricsCanvas), new PropertyMetadata(new Point(0, 0), OnDependencyPropertyChanged));
|
||||
|
||||
public bool IsMouseInLyricsArea
|
||||
{
|
||||
@@ -209,7 +222,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsMouseInLyricsAreaProperty =
|
||||
DependencyProperty.Register(nameof(IsMouseInLyricsArea), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(IsMouseInLyricsArea), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnDependencyPropertyChanged));
|
||||
|
||||
public bool IsMousePressing
|
||||
{
|
||||
@@ -218,7 +231,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsMousePressingProperty =
|
||||
DependencyProperty.Register(nameof(IsMousePressing), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(IsMousePressing), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnDependencyPropertyChanged));
|
||||
|
||||
public bool IsMouseScrolling
|
||||
{
|
||||
@@ -227,30 +240,33 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IsMouseScrollingProperty =
|
||||
DependencyProperty.Register(nameof(IsMouseScrolling), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnLayoutPropChanged));
|
||||
DependencyProperty.Register(nameof(IsMouseScrolling), typeof(bool), typeof(LyricsCanvas), new PropertyMetadata(false, OnDependencyPropertyChanged));
|
||||
|
||||
public LyricsCanvas()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<int>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<AlbumArtThemeColors>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<TimeSpan>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsData?>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsWindowStatus>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<double>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<bool>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<TextAlignmentType>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<SongInfo?>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsFontWeight>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<string>>(this);
|
||||
|
||||
UpdateRenderLyricsLines();
|
||||
}
|
||||
|
||||
private static void OnLayoutPropChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is LyricsCanvas canvas)
|
||||
{
|
||||
if (e.Property == LyricsStartXProperty)
|
||||
if (e.Property == LyricsWindowStatusProperty)
|
||||
{
|
||||
var oldValue = (LyricsWindowStatus?)e.OldValue;
|
||||
oldValue?.PropertyChanged -= canvas.LyricsWindowStatus_PropertyChanged;
|
||||
var newValue = (LyricsWindowStatus?)e.NewValue;
|
||||
newValue?.PropertyChanged += canvas.LyricsWindowStatus_PropertyChanged;
|
||||
canvas._lyricsWindowStatus = (LyricsWindowStatus)e.NewValue;
|
||||
canvas._isLayoutChanged = true;
|
||||
}
|
||||
else if (e.Property == LyricsStartXProperty)
|
||||
{
|
||||
canvas._renderLyricsStartX = Convert.ToDouble(e.NewValue);
|
||||
canvas._isLayoutChanged = true;
|
||||
@@ -300,30 +316,46 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
canvas._isMouseScrolling = value;
|
||||
}
|
||||
else if (e.Property == AlbumArtThemeColorsProperty)
|
||||
{
|
||||
var albumArtThemeColors = (AlbumArtThemeColors)e.NewValue;
|
||||
canvas._immersiveBgColorTransition.StartTransition(albumArtThemeColors.EnvColor);
|
||||
canvas._accentColor1Transition.StartTransition(albumArtThemeColors.AccentColor1);
|
||||
canvas._accentColor2Transition.StartTransition(albumArtThemeColors.AccentColor2);
|
||||
canvas._accentColor3Transition.StartTransition(albumArtThemeColors.AccentColor3);
|
||||
canvas._accentColor4Transition.StartTransition(albumArtThemeColors.AccentColor4);
|
||||
|
||||
canvas._albumArtThemeColors = albumArtThemeColors;
|
||||
canvas._isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
|
||||
// ====
|
||||
|
||||
private void Canvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
|
||||
{
|
||||
if (_lyricsWindowStatus == null) return;
|
||||
|
||||
var bounds = new Rect(0, 0, sender.Size.Width, sender.Size.Height);
|
||||
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var albumArtLayout = status.AlbumArtLayoutSettings;
|
||||
var lyricsBg = status.LyricsBackgroundSettings;
|
||||
var lyricsStyle = status.LyricsStyleSettings;
|
||||
var lyricsEffect = status.LyricsEffectSettings;
|
||||
var albumArtLayout = _lyricsWindowStatus.AlbumArtLayoutSettings;
|
||||
var lyricsBg = _lyricsWindowStatus.LyricsBackgroundSettings;
|
||||
var lyricsStyle = _lyricsWindowStatus.LyricsStyleSettings;
|
||||
var lyricsEffect = _lyricsWindowStatus.LyricsEffectSettings;
|
||||
|
||||
double songDuration = _mediaSessionsService.CurrentSongInfo?.DurationMs ?? 0;
|
||||
bool isForceWordByWord = _settingsService.AppSettings.GeneralSettings.IsForceWordByWordEffect;
|
||||
|
||||
var lyricsThemeColors = _mediaSessionsService.AlbumArtThemeColors;
|
||||
|
||||
Color overlayColor;
|
||||
double finalOpacity;
|
||||
|
||||
if (status.IsAdaptToEnvironment)
|
||||
if (_lyricsWindowStatus.IsAdaptToEnvironment)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>Ӧɫ
|
||||
overlayColor = _immersiveBgColorTransition.Value;
|
||||
@@ -368,10 +400,10 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
userScrollOffset: _mouseYScrollTransition.Value,
|
||||
lyricsOpacity: _renderLyricsOpacity,
|
||||
playingLineTopOffsetFactor: lyricsStyle.PlayingLineTopOffset / 100.0,
|
||||
windowStatus: status,
|
||||
strokeColor: lyricsThemeColors.StrokeFontColor,
|
||||
bgColor: lyricsThemeColors.BgFontColor,
|
||||
fgColor: lyricsThemeColors.FgFontColor,
|
||||
windowStatus: _lyricsWindowStatus,
|
||||
strokeColor: _albumArtThemeColors.StrokeFontColor,
|
||||
bgColor: _albumArtThemeColors.BgFontColor,
|
||||
fgColor: _albumArtThemeColors.FgFontColor,
|
||||
getPlaybackState: (lineIndex) =>
|
||||
{
|
||||
if (_renderLyricsLines == null) return new LinePlaybackState();
|
||||
@@ -403,33 +435,34 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
style: lyricsBg.SpectrumStyle,
|
||||
canvasWidth: sender.Size.Width,
|
||||
canvasHeight: sender.Size.Height,
|
||||
fillColor: lyricsThemeColors.BgFontColor
|
||||
fillColor: _albumArtThemeColors.BgFontColor
|
||||
);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
args.DrawingSession.DrawText(
|
||||
$"Lyrics render start pos: ({(int)_renderLyricsStartX}, {(int)_renderLyricsStartY})\n" +
|
||||
$"Lyrics render size: [{(int)_renderLyricsWidth} x {(int)_renderLyricsHeight}]\n" +
|
||||
$"Lyrics actual height: {LyricsLayoutManager.CalculateActualHeight(_renderLyricsLines)}\n" +
|
||||
$"Playing line (idx): {_playingLineIndex}\n" +
|
||||
$"Mouse hovering line (idx): {_mouseHoverLineIndex}\n" +
|
||||
$"Visible lines range (idx): [{_visibleRange.Start}, {_visibleRange.End}]\n" +
|
||||
$"Total line count: {LyricsLayoutManager.CalculateMaxRange(_renderLyricsLines).End + 1}\n" +
|
||||
$"Played: {_songPosition} / {TimeSpan.FromMilliseconds(_mediaSessionsService.CurrentSongInfo?.DurationMs ?? 0)}\n" +
|
||||
$"Y offset: {_canvasYScrollTransition.Value}\n" +
|
||||
$"User scroll offset: {_mouseYScrollTransition.Value}",
|
||||
new Vector2(0, 0), Colors.Red);
|
||||
//args.DrawingSession.DrawText(
|
||||
// $"Lyrics render start pos: ({(int)_renderLyricsStartX}, {(int)_renderLyricsStartY})\n" +
|
||||
// $"Lyrics render size: [{(int)_renderLyricsWidth} x {(int)_renderLyricsHeight}]\n" +
|
||||
// $"Lyrics actual height: {LyricsLayoutManager.CalculateActualHeight(_renderLyricsLines)}\n" +
|
||||
// $"Playing line (idx): {_playingLineIndex}\n" +
|
||||
// $"Mouse hovering line (idx): {_mouseHoverLineIndex}\n" +
|
||||
// $"Visible lines range (idx): [{_visibleRange.Start}, {_visibleRange.End}]\n" +
|
||||
// $"Total line count: {LyricsLayoutManager.CalculateMaxRange(_renderLyricsLines).End + 1}\n" +
|
||||
// $"Played: {_songPosition} / {TimeSpan.FromMilliseconds(_mediaSessionsService.CurrentSongInfo?.DurationMs ?? 0)}\n" +
|
||||
// $"Y offset: {_canvasYScrollTransition.Value}\n" +
|
||||
// $"User scroll offset: {_mouseYScrollTransition.Value}",
|
||||
// new Vector2(0, 0), Colors.Red);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs args)
|
||||
{
|
||||
var lyricsBg = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings;
|
||||
var lyricsStyle = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings;
|
||||
var lyricsEffect = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings;
|
||||
var albumArtThemeColors = _mediaSessionsService.AlbumArtThemeColors;
|
||||
if (_lyricsWindowStatus == null) return;
|
||||
|
||||
var lyricsBg = _lyricsWindowStatus.LyricsBackgroundSettings;
|
||||
var lyricsStyle = _lyricsWindowStatus.LyricsStyleSettings;
|
||||
var lyricsEffect = _lyricsWindowStatus.LyricsEffectSettings;
|
||||
var lyricsData = _mediaSessionsService.CurrentLyricsData;
|
||||
|
||||
TimeSpan elapsedTime = args.Timing.ElapsedTime;
|
||||
@@ -500,10 +533,10 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
sender.Size.Height,
|
||||
_canvasTargetScrollOffset,
|
||||
lyricsStyle.PlayingLineTopOffset / 100.0,
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings,
|
||||
_lyricsWindowStatus.LyricsEffectSettings,
|
||||
_canvasYScrollTransition,
|
||||
albumArtThemeColors.BgFontColor,
|
||||
albumArtThemeColors.FgFontColor,
|
||||
_albumArtThemeColors.BgFontColor,
|
||||
_albumArtThemeColors.FgFontColor,
|
||||
elapsedTime,
|
||||
_isMouseScrolling,
|
||||
_isLayoutChanged,
|
||||
@@ -592,12 +625,12 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
|
||||
private void TriggerRelayout()
|
||||
{
|
||||
if (_renderLyricsLines == null || !_isLayoutChanged) return;
|
||||
if (_renderLyricsLines == null || !_isLayoutChanged || _lyricsWindowStatus == null) return;
|
||||
|
||||
LyricsLayoutManager.MeasureAndArrange(
|
||||
resourceCreator: Canvas,
|
||||
lines: _renderLyricsLines,
|
||||
status: _liveStatesService.LiveStates.LyricsWindowStatus,
|
||||
status: _lyricsWindowStatus,
|
||||
appSettings: _settingsService.AppSettings,
|
||||
canvasWidth: Canvas.Size.Width,
|
||||
canvasHeight: Canvas.Size.Height,
|
||||
@@ -639,21 +672,20 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
_isLastFMTracked = false;
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<AlbumArtThemeColors> message)
|
||||
private void UpdateRenderLyricsLines()
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
_renderLyricsLines = null;
|
||||
if (_mediaSessionsService.CurrentLyricsData is LyricsData lyricsData)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtThemeColors))
|
||||
_renderLyricsLines = lyricsData.LyricsLines.Select(x => new RenderLyricsLine()
|
||||
{
|
||||
var lyricsThemeColors = message.NewValue;
|
||||
_immersiveBgColorTransition.StartTransition(lyricsThemeColors.EnvColor);
|
||||
_accentColor1Transition.StartTransition(lyricsThemeColors.AccentColor1);
|
||||
_accentColor2Transition.StartTransition(lyricsThemeColors.AccentColor2);
|
||||
_accentColor3Transition.StartTransition(lyricsThemeColors.AccentColor3);
|
||||
_accentColor4Transition.StartTransition(lyricsThemeColors.AccentColor4);
|
||||
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
LyricsSyllables = x.LyricsSyllables,
|
||||
StartMs = x.StartMs,
|
||||
EndMs = x.EndMs,
|
||||
PhoneticText = x.PhoneticText,
|
||||
OriginalText = x.OriginalText,
|
||||
TranslatedText = x.TranslatedText
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,128 +728,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.CurrentLyricsData))
|
||||
{
|
||||
_renderLyricsLines = null;
|
||||
if (_mediaSessionsService.CurrentLyricsData is LyricsData lyricsData)
|
||||
{
|
||||
_renderLyricsLines = lyricsData.LyricsLines.Select(x => new RenderLyricsLine()
|
||||
{
|
||||
LyricsSyllables = x.LyricsSyllables,
|
||||
StartMs = x.StartMs,
|
||||
EndMs = x.EndMs,
|
||||
PhoneticText = x.PhoneticText,
|
||||
OriginalText = x.OriginalText,
|
||||
TranslatedText = x.TranslatedText
|
||||
}).ToList();
|
||||
}
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
{
|
||||
if (message.Sender is LiveStates)
|
||||
{
|
||||
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<int> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.PhoneticLyricsFontSize))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.OriginalLyricsFontSize))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.TranslatedLyricsFontSize))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsFontStrokeWidth))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.PlayingLineTopOffset))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
else if (message.Sender is LyricsEffectSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsEffectSettings.LyricsScrollDuration))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.LyricsScrollTopDuration))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.LyricsScrollBottomDuration))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.LyricsScrollTopDelay))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.LyricsScrollBottomDelay))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.FanLyricsAngle))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<double> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsLineSpacingFactor))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is LyricsEffectSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsEffectSettings.IsFanLyricsEnabled))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsEffectSettings.IsLyricsBlurEffectEnabled))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
else if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.IsDynamicLyricsFontSize))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<TextAlignmentType> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsAlignmentType))
|
||||
{
|
||||
UpdateRenderLyricsLines();
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -834,30 +745,5 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsFontWeight> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsFontWeight))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<string> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCJKFontFamily))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsWesternFontFamily))
|
||||
{
|
||||
_isLayoutChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
Padding="0,12"
|
||||
CornerRadius="4"
|
||||
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
|
||||
SelectionMode="None">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
<!-- Window -->
|
||||
<controls:Case Value="Window">
|
||||
<uc:WindowSettingsControl LyricsWindowStatus="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=OneWay}" />
|
||||
<uc:WindowSettingsControl LyricsWindowStatus="{x:Bind LyricsWindowStatus, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Layout -->
|
||||
@@ -251,14 +251,14 @@
|
||||
<TextBlock x:Uid="SettingsPageLayout" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<dev:SettingsExpander x:Uid="SettingsPageDisplayTypeSwitcher" IsExpanded="True">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsWindowStatus.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<dev:SettingsExpander.Items>
|
||||
<dev:SettingsCard x:Uid="SettingsPageLayoutOrientation">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
|
||||
</ComboBox>
|
||||
@@ -273,27 +273,27 @@
|
||||
|
||||
<!-- Album art area style -->
|
||||
<controls:Case Value="AlbumArtStyle">
|
||||
<uc:AlbumArtAreaStyleSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
|
||||
<uc:AlbumArtAreaStyleSettingsControl AlbumArtLayoutSettings="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Album art area effect -->
|
||||
<controls:Case Value="AlbumArtEffect">
|
||||
<uc:AlbumArtAreaEffectSettingsControl AlbumArtAreaEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtAreaEffectSettings, Mode=OneWay}" />
|
||||
<uc:AlbumArtAreaEffectSettingsControl AlbumArtAreaEffectSettings="{x:Bind LyricsWindowStatus.AlbumArtAreaEffectSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics style -->
|
||||
<controls:Case Value="LyricsStyle">
|
||||
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
|
||||
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics effect -->
|
||||
<controls:Case Value="LyricsEffect">
|
||||
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
|
||||
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics background -->
|
||||
<controls:Case Value="LyricsBackground">
|
||||
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
|
||||
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
</controls:SwitchPresenter>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Serialization;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
@@ -25,7 +24,15 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
public LyricsWindowSettingsControlViewModel ViewModel => (LyricsWindowSettingsControlViewModel)DataContext;
|
||||
|
||||
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
|
||||
public LyricsWindowStatus LyricsWindowStatus
|
||||
{
|
||||
get { return (LyricsWindowStatus?)GetValue(LyricsWindowStatusProperty); }
|
||||
set { SetValue(LyricsWindowStatusProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsWindowStatusProperty =
|
||||
DependencyProperty.Register(nameof(LyricsWindowStatus), typeof(LyricsWindowStatus), typeof(LyricsWindowSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsWindowSettingsControl()
|
||||
{
|
||||
@@ -39,10 +46,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus == data)
|
||||
{
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus = ViewModel.AppSettings.WindowBoundsRecords.First();
|
||||
}
|
||||
// TODO <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>û<EFBFBD><C3BB><EFBFBD>ֱ<EFBFBD>ӹرն<D8B1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>
|
||||
ViewModel.AppSettings.WindowBoundsRecords.Remove(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
|
||||
<ListView
|
||||
Margin="48,56"
|
||||
ItemContainerStyle="{StaticResource ListViewStretchedItemContainerStyle}"
|
||||
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
|
||||
SelectionMode="None">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
|
||||
@@ -56,10 +57,20 @@
|
||||
<Grid
|
||||
Margin="0,10"
|
||||
Padding="5"
|
||||
AllowFocusOnInteraction="True"
|
||||
CornerRadius="4"
|
||||
Tapped="Grid_Tapped">
|
||||
<Grid.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem Text="Switch to this status in current window" />
|
||||
<MenuFlyoutItem Text="Open this status in new window" />
|
||||
</MenuFlyout>
|
||||
</Grid.ContextFlyout>
|
||||
<uc:DemoWindowGrid LyricsWindowStatus="{Binding}" />
|
||||
<Border
|
||||
BorderBrush="{ThemeResource AccentAAFillColorDefaultBrush}"
|
||||
BorderThickness="4"
|
||||
CornerRadius="4"
|
||||
Visibility="{Binding IsOpened, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
@@ -24,6 +25,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
|
||||
private async void Grid_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
WindowHook.OpenOrShowWindow<NowPlayingWindow>((LyricsWindowStatus)(((FrameworkElement)sender).DataContext));
|
||||
await HideAsync();
|
||||
}
|
||||
|
||||
@@ -37,7 +39,7 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
var lyricsWindowSwitchWindow = WindowHook.GetWindow<LyricsWindowSwitchWindow>();
|
||||
lyricsWindowSwitchWindow?.ViewModel.RootGridOpacity = 0;
|
||||
await Task.Delay(300);
|
||||
WindowHook.HideWindow<LyricsWindowSwitchWindow>();
|
||||
lyricsWindowSwitchWindow?.HideWindow();
|
||||
}
|
||||
|
||||
private void ShadowRect_Loaded(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
public enum ShortcutID
|
||||
{
|
||||
LyricsWindowShowOrHide,
|
||||
Borderless,
|
||||
ClickThrough,
|
||||
LyricsWindowSwitch,
|
||||
PlayOrPauseSong,
|
||||
NextSong,
|
||||
|
||||
@@ -53,42 +53,13 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static async Task<BitmapDecoder> MakeSquareWithThemeColor(IBuffer buffer, PaletteGeneratorType generatorType)
|
||||
public static async Task<BitmapDecoder> GetBitmapDecoder(IBuffer buffer)
|
||||
{
|
||||
using var stream = new InMemoryRandomAccessStream();
|
||||
await stream.WriteAsync(buffer);
|
||||
var decoder = await BitmapDecoder.CreateAsync(stream);
|
||||
|
||||
if (decoder.PixelWidth == decoder.PixelHeight)
|
||||
{
|
||||
// 已经是正方形,直接返回
|
||||
return decoder;
|
||||
}
|
||||
|
||||
using var device = CanvasDevice.GetSharedDevice();
|
||||
using var canvasBitmap = await CanvasBitmap.LoadAsync(device, stream);
|
||||
var size = Math.Max(decoder.PixelWidth, decoder.PixelHeight);
|
||||
|
||||
var result = await GetAccentColorAsync(decoder, generatorType);
|
||||
var color = Windows.UI.Color.FromArgb(255, (byte)result.Color.X, (byte)result.Color.Y, (byte)result.Color.Z);
|
||||
using var renderTarget = new CanvasRenderTarget(device, size, size, 96);
|
||||
|
||||
int offsetX = (int)(size - decoder.PixelWidth) / 2;
|
||||
int offsetY = (int)(size - decoder.PixelHeight) / 2;
|
||||
using (var ds = renderTarget.CreateDrawingSession())
|
||||
{
|
||||
ds.FillRectangle(0, 0, size, size, color);
|
||||
ds.DrawImage(canvasBitmap, offsetX, offsetY);
|
||||
}
|
||||
|
||||
// 保存为 PNG 并转为 byte[]
|
||||
stream.Seek(0);
|
||||
stream.Size = 0;
|
||||
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
|
||||
stream.Seek(0);
|
||||
var newDecoder = await BitmapDecoder.CreateAsync(stream);
|
||||
return newDecoder;
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
public static byte[] GenerateNoiseBGRA(int width, int height)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
@@ -29,25 +30,15 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
private static readonly Dictionary<HWND, WindowStyle> _defaultWindowStyle = [];
|
||||
private static readonly Dictionary<HWND, ExtendedWindowStyle> _defaultExtendedWindowStyle = [];
|
||||
|
||||
private static readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
private static readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
|
||||
private static DispatcherQueueTimer? _setLyricsWindowVisibilityByPlayingStatusTimer;
|
||||
|
||||
public static void HideWindow<T>()
|
||||
public static void HideWindow(this Window window)
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
var castedWindow = window as Window;
|
||||
castedWindow?.Hide();
|
||||
window.Hide();
|
||||
}
|
||||
|
||||
public static void CloseWindow<T>()
|
||||
public static void CloseWindow(this Window window)
|
||||
{
|
||||
if (typeof(T) == typeof(NowPlayingWindow))
|
||||
{
|
||||
EnsureDockModeReleased();
|
||||
}
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
if (window is Window w)
|
||||
{
|
||||
w.Close();
|
||||
@@ -55,6 +46,16 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
}
|
||||
}
|
||||
|
||||
public static void CloseWindow(this NowPlayingWindow window)
|
||||
{
|
||||
if (GetWindowHandle(window) is IntPtr hwnd)
|
||||
{
|
||||
UnregisterWorkArea(hwnd);
|
||||
}
|
||||
window.Status.IsOpened = false;
|
||||
window.CloseWindow();
|
||||
}
|
||||
|
||||
public static void MinimizeWindow<T>()
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
@@ -97,16 +98,22 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
return GetWindowHandle(GetWindow<T>());
|
||||
}
|
||||
|
||||
public static void OpenOrShowWindow<T>()
|
||||
public static T OpenOrShowWindow<T>(LyricsWindowStatus? status = null)
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
//window = null;
|
||||
var window = _activeWindows.Find(w =>
|
||||
(typeof(T) != typeof(NowPlayingWindow) && w is T) ||
|
||||
(typeof(T) == typeof(NowPlayingWindow) && w is T && ((NowPlayingWindow)w).Status == status)
|
||||
);
|
||||
|
||||
if (window == null)
|
||||
{
|
||||
if (typeof(T) == typeof(NowPlayingWindow))
|
||||
{
|
||||
window = new NowPlayingWindow();
|
||||
((NowPlayingWindow)window).SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(BackdropType.Transparent);
|
||||
if (status == null)
|
||||
{
|
||||
throw new NullReferenceException(nameof(status));
|
||||
}
|
||||
window = new NowPlayingWindow(status);
|
||||
}
|
||||
else if (typeof(T) == typeof(SettingsWindow))
|
||||
{
|
||||
@@ -140,15 +147,13 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
|
||||
if (typeof(T) == typeof(NowPlayingWindow))
|
||||
{
|
||||
_liveStatesService.InitLyricsWindowStatus();
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(castedWindow);
|
||||
_defaultWindowStyle.Add(hwnd, castedWindow.GetWindowStyle());
|
||||
_defaultExtendedWindowStyle.Add(hwnd, castedWindow.GetExtendedWindowStyle());
|
||||
|
||||
var lyricsWindow = (NowPlayingWindow)window;
|
||||
lyricsWindow.ViewModel.InitShortcuts();
|
||||
lyricsWindow.ViewModel.InitFgWindowWatcher();
|
||||
lyricsWindow.InitFgWindowWatcher();
|
||||
|
||||
_mediaSessionsService.InitPlaybackShortcuts();
|
||||
|
||||
@@ -170,6 +175,13 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
castedWindow.Activate();
|
||||
castedWindow.AppWindow.MoveInZOrderAtTop();
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(NowPlayingWindow))
|
||||
{
|
||||
((NowPlayingWindow)window).Status.IsOpened = true;
|
||||
}
|
||||
|
||||
return (T)window;
|
||||
}
|
||||
|
||||
public static void RestartApp(string args = "")
|
||||
@@ -194,13 +206,18 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
|
||||
public static void ExitApp()
|
||||
{
|
||||
EnsureDockModeReleased();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static void EnsureDockModeReleased()
|
||||
{
|
||||
SetIsWorkArea<NowPlayingWindow>(false);
|
||||
foreach (var item in _workAreas)
|
||||
{
|
||||
if (GetWindowHandle(item) is IntPtr hwnd)
|
||||
{
|
||||
UnregisterWorkArea(hwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void TrackWindow(object window)
|
||||
@@ -225,11 +242,8 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsClickThrough<T>(bool enable)
|
||||
public static void SetIsClickThrough(this Window window, bool enable)
|
||||
{
|
||||
Window? window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (enable)
|
||||
@@ -242,16 +256,15 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsWorkArea<T>(bool enable)
|
||||
public static void SetIsWorkArea(this NowPlayingWindow window, bool enable)
|
||||
{
|
||||
Window? window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
RegisterWorkArea(hwnd);
|
||||
RegisterWorkArea(hwnd, window.Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -259,11 +272,8 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsBorderless<T>(bool enable)
|
||||
public static void SetIsBorderless(this Window window, bool enable)
|
||||
{
|
||||
var window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (enable)
|
||||
@@ -276,55 +286,38 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsShowInSwitchers<T>(bool enable)
|
||||
public static void SetIsShowInSwitchers(this Window window, bool enable)
|
||||
{
|
||||
var window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
window.AppWindow.IsShownInSwitchers = enable;
|
||||
}
|
||||
|
||||
public static void SetIsAlwaysOnTop<T>(bool enable)
|
||||
public static void SetIsAlwaysOnTop(this Window window, bool enable)
|
||||
{
|
||||
var window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
if (window.AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.IsAlwaysOnTop = enable;
|
||||
}
|
||||
}
|
||||
|
||||
public static void MoveAndResize<T>(Rect rect)
|
||||
public static void MoveAndResize(this Window window, Rect rect)
|
||||
{
|
||||
var window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
window.AppWindow.Move(new Windows.Graphics.PointInt32((int)rect.X, (int)rect.Y));
|
||||
window.AppWindow.Resize(new Windows.Graphics.SizeInt32((int)rect.Width, (int)rect.Height));
|
||||
}
|
||||
|
||||
public static void SetTitleBarArea<T>(TitleBarArea titleBarArea)
|
||||
public static void SetTitleBarArea(this NowPlayingWindow window, TitleBarArea titleBarArea)
|
||||
{
|
||||
if (typeof(T) == typeof(NowPlayingWindow))
|
||||
{
|
||||
NowPlayingWindow? lyricsWindow = GetWindow<NowPlayingWindow>();
|
||||
lyricsWindow?.SetTitleBarArea(titleBarArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Unsupported window type: {typeof(T).FullName}");
|
||||
}
|
||||
window.SetTitleBarArea(titleBarArea);
|
||||
}
|
||||
|
||||
private static void RegisterWorkArea(IntPtr hwnd)
|
||||
private static void RegisterWorkArea(IntPtr hwnd, LyricsWindowStatus status)
|
||||
{
|
||||
if (_workAreas.Contains(hwnd)) return;
|
||||
|
||||
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
var uEdge = status.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top : _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
double top = status.DockPlacement == DockPlacement.Top ? status.MonitorBounds.Top : status.MonitorBounds.Bottom - status.DockHeight;
|
||||
double bottom = top + status.DockHeight;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
@@ -333,9 +326,9 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
Left = (int)status.MonitorBounds.Left,
|
||||
Top = (int)top,
|
||||
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
|
||||
Right = (int)status.MonitorBounds.Right,
|
||||
Bottom = (int)bottom,
|
||||
},
|
||||
};
|
||||
@@ -363,23 +356,22 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
_workAreas.Remove(hwnd);
|
||||
}
|
||||
|
||||
public static void UpdateWorkArea<T>()
|
||||
public static void UpdateWorkArea(this NowPlayingWindow window)
|
||||
{
|
||||
var window = GetWindow<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (!_workAreas.Contains(hwnd))
|
||||
return;
|
||||
|
||||
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
var status = window.Status;
|
||||
|
||||
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
var uEdge = status.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
double top = status.DockPlacement == DockPlacement.Top ?
|
||||
status.MonitorBounds.Top :
|
||||
status.MonitorBounds.Bottom - status.DockHeight;
|
||||
|
||||
double bottom = top + status.DockHeight;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
@@ -388,9 +380,9 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
Left = (int)status.MonitorBounds.Left,
|
||||
Top = (int)top,
|
||||
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
|
||||
Right = (int)status.MonitorBounds.Right,
|
||||
Bottom = (int)bottom,
|
||||
},
|
||||
};
|
||||
@@ -403,37 +395,39 @@ namespace BetterLyrics.WinUI3.Hooks
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dispatcherQueue">请确保此参数指向同一个对象,建议传值 BaseViewModel._dispatcherQueue</param>
|
||||
public static void SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue dispatcherQueue)
|
||||
public static void SetLyricsWindowVisibilityByPlayingStatus(this NowPlayingWindow window, DispatcherQueue dispatcherQueue)
|
||||
{
|
||||
_setLyricsWindowVisibilityByPlayingStatusTimer ??= dispatcherQueue.CreateTimer();
|
||||
var status = window.Status;
|
||||
|
||||
_setLyricsWindowVisibilityByPlayingStatusTimer.Debounce(() =>
|
||||
status.VisibilityTimer ??= dispatcherQueue.CreateTimer();
|
||||
|
||||
status.VisibilityTimer.Debounce(() =>
|
||||
{
|
||||
var window = GetWindow<NowPlayingWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.CurrentIsPlaying)
|
||||
if (status.AutoShowOrHideWindow && !_mediaSessionsService.CurrentIsPlaying)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
if (status.IsWorkArea)
|
||||
{
|
||||
_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
SetIsWorkArea<NowPlayingWindow>(false);
|
||||
_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
status.IsLyricsWindowStatusRefreshing = true;
|
||||
window.SetIsWorkArea(false);
|
||||
status.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
HideWindow<NowPlayingWindow>();
|
||||
window.HideWindow();
|
||||
}
|
||||
else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.CurrentIsPlaying)
|
||||
else if (window.Status.AutoShowOrHideWindow && _mediaSessionsService.CurrentIsPlaying)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
if (window.Status.IsWorkArea)
|
||||
{
|
||||
_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
SetIsWorkArea<NowPlayingWindow>(true);
|
||||
_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
status.IsLyricsWindowStatusRefreshing = true;
|
||||
window.SetIsWorkArea(true);
|
||||
status.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
OpenOrShowWindow<NowPlayingWindow>();
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
if (window.Status.IsWorkArea)
|
||||
{
|
||||
MoveAndResize<NowPlayingWindow>(_liveStatesService.LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
|
||||
window.MoveAndResize(window.Status.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
}
|
||||
}, Constants.Time.DebounceTimeout);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public partial class LiveStates : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowStatus LyricsWindowStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在需要暂时禁用监听歌词窗口位置大小变化时使用
|
||||
/// </summary>
|
||||
public bool IsLyricsWindowStatusRefreshing { get; set; } = false;
|
||||
|
||||
public LiveStates()
|
||||
{
|
||||
LyricsWindowStatus = new LyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
@@ -42,6 +44,15 @@ namespace BetterLyrics.WinUI3.Models
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowWidth { get; set; } = 800;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowHeight { get; set; } = 500;
|
||||
|
||||
[JsonIgnore][ObservableProperty] public partial bool IsOpened { get; set; } = false;
|
||||
|
||||
[JsonIgnore] public DispatcherQueueTimer? VisibilityTimer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在需要暂时禁用监听歌词窗口位置大小变化时使用
|
||||
/// </summary>
|
||||
[JsonIgnore] public bool IsLyricsWindowStatusRefreshing { get; set; } = false;
|
||||
|
||||
public LyricsWindowStatus()
|
||||
{
|
||||
UpdateMonitorNameAndBounds();
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ListenOnNewPlaybackSource { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IgnoreCacheWhenSearching { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> BorderlessShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "B" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ClickThroughShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "C" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> LyricsWindowSwitchShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "S" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> PlayOrPauseShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "P" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> NextSongShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "Right" };
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
{
|
||||
public interface ILiveStatesService
|
||||
{
|
||||
LiveStates LiveStates { get; set; }
|
||||
void InitLyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Extensions;
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.LiveStatesService
|
||||
{
|
||||
public partial class LiveStatesService : BaseViewModel, ILiveStatesService,
|
||||
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public LiveStates LiveStates { get; set; } = new LiveStates();
|
||||
|
||||
public LiveStatesService(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
public void InitLyricsWindowStatus()
|
||||
{
|
||||
var defaultLyricsWindowStatus = _settingsService.AppSettings.WindowBoundsRecords.FirstOrDefault(x => x.IsDefault);
|
||||
if (defaultLyricsWindowStatus == null)
|
||||
{
|
||||
defaultLyricsWindowStatus = LyricsWindowStatusExtensions.StandardMode();
|
||||
defaultLyricsWindowStatus.IsDefault = true;
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(defaultLyricsWindowStatus);
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DesktopMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DockedMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.NarrowMode());
|
||||
_settingsService.AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.FullscreenMode());
|
||||
}
|
||||
LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus;
|
||||
}
|
||||
|
||||
private async void RefreshLyricsWindowStatus()
|
||||
{
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
|
||||
|
||||
WindowHook.SetIsWorkArea<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
WindowHook.UpdateWorkArea<NowPlayingWindow>();
|
||||
}
|
||||
await Task.Delay(300);
|
||||
|
||||
WindowHook.SetIsShowInSwitchers<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
|
||||
WindowHook.SetIsAlwaysOnTop<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
|
||||
|
||||
WindowHook.SetIsClickThrough<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
|
||||
WindowHook.SetIsBorderless<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
|
||||
|
||||
WindowHook.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
WindowHook.SetTitleBarArea<NowPlayingWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
|
||||
|
||||
// 下述代码可以删除,但是为了避免给用户造成操作上的疑虑,暂时保留
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.WindowBounds = LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea();
|
||||
}
|
||||
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
|
||||
LiveStates.LyricsWindowStatus.WindowX = LiveStates.LyricsWindowStatus.WindowBounds.X;
|
||||
LiveStates.LyricsWindowStatus.WindowY = LiveStates.LyricsWindowStatus.WindowBounds.Y;
|
||||
LiveStates.LyricsWindowStatus.WindowWidth = LiveStates.LyricsWindowStatus.WindowBounds.Width;
|
||||
LiveStates.LyricsWindowStatus.WindowHeight = LiveStates.LyricsWindowStatus.WindowBounds.Height;
|
||||
|
||||
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
|
||||
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
|
||||
private void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(LyricsWindowStatus.IsWorkArea):
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
WindowHook.SetIsWorkArea<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.DockHeight):
|
||||
case nameof(LyricsWindowStatus.DockPlacement):
|
||||
case nameof(LyricsWindowStatus.MonitorDeviceName):
|
||||
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
|
||||
if (LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = true;
|
||||
WindowHook.UpdateWorkArea<NowPlayingWindow>();
|
||||
LiveStates.IsLyricsWindowStatusRefreshing = false;
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsShownInSwitchers):
|
||||
WindowHook.SetIsShowInSwitchers<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsAlwaysOnTop):
|
||||
WindowHook.SetIsAlwaysOnTop<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsClickThrough):
|
||||
WindowHook.SetIsClickThrough<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsBorderless):
|
||||
WindowHook.SetIsBorderless<NowPlayingWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowX):
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithX(LiveStates.LyricsWindowStatus.WindowX));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowY):
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithY(LiveStates.LyricsWindowStatus.WindowY));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowWidth):
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithWidth(LiveStates.LyricsWindowStatus.WindowWidth));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowHeight):
|
||||
WindowHook.MoveAndResize<NowPlayingWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithHeight(LiveStates.LyricsWindowStatus.WindowHeight));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.TitleBarArea):
|
||||
WindowHook.SetTitleBarArea<NowPlayingWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.AutoShowOrHideWindow):
|
||||
WindowHook.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
{
|
||||
if (message.Sender is LiveStates)
|
||||
{
|
||||
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
message.OldValue.PropertyChanged -= LyricsWindowStatus_PropertyChanged;
|
||||
message.NewValue.PropertyChanged += LyricsWindowStatus_PropertyChanged;
|
||||
RefreshLyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics.Imaging;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
@@ -33,8 +34,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
TimeSpan CurrentPosition { get; }
|
||||
LyricsData? CurrentLyricsData { get; }
|
||||
|
||||
BitmapDecoder? AlbumArtBitmapDecoder { get; }
|
||||
BitmapImage? AlbumArtBitmapImage { get; }
|
||||
AlbumArtThemeColors AlbumArtThemeColors { get; }
|
||||
|
||||
TranslationSearchProvider? TranslationSearchProvider { get; }
|
||||
LyricsSearchResult? CurrentLyricsSearchResult { get; }
|
||||
|
||||
@@ -22,12 +22,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
private readonly LatestOnlyTaskRunner _albumArtRefreshRunner = new();
|
||||
|
||||
private Color _envColor = Colors.Transparent;
|
||||
private List<Color> _lightAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
private List<Color> _darkAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial BitmapDecoder? AlbumArtBitmapDecoder { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial BitmapImage? AlbumArtBitmapImage { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial AlbumArtThemeColors AlbumArtThemeColors { get; set; } = new();
|
||||
|
||||
private void UpdateAlbumArt()
|
||||
{
|
||||
@@ -47,8 +43,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
IBuffer? buffer = await Task.Run(async () => await _albumArtSearchService.SearchAsync(CurrentSongInfo, _SMTCAlbumArtBuffer, token), token);
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
BitmapDecoder? decoder = null;
|
||||
|
||||
if (buffer == null)
|
||||
{
|
||||
using var placeHolderStream = await ImageHelper.GetAlbumArtPlaceholderAsync();
|
||||
@@ -59,146 +53,15 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
buffer = tempBuffer;
|
||||
}
|
||||
|
||||
decoder = await ImageHelper.MakeSquareWithThemeColor(buffer, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType);
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
var lightPalette = await ImageHelper.GetAccentColorsAsync(decoder, 4, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType, false);
|
||||
var darkPalette = await ImageHelper.GetAccentColorsAsync(decoder, 4, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType, true);
|
||||
AlbumArtBitmapDecoder = await ImageHelper.GetBitmapDecoder(buffer);
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
var bitmapImage = new BitmapImage();
|
||||
await bitmapImage.SetSourceAsync(ImageHelper.ToIRandomAccessStream(buffer));
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
_lightAccentColors = lightPalette.Palette.Select(Helper.ColorHelper.FromVector3).ToList();
|
||||
_darkAccentColors = darkPalette.Palette.Select(Helper.ColorHelper.FromVector3).ToList();
|
||||
|
||||
UpdateAlbumArtThemeColors();
|
||||
|
||||
AlbumArtBitmapImage = bitmapImage;
|
||||
}
|
||||
|
||||
private void UpdateAlbumArtThemeColors()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var result = new AlbumArtThemeColors();
|
||||
result.EnvColor = _envColor;
|
||||
|
||||
ElementTheme themeTypeSent;
|
||||
if (status.IsAdaptToEnvironment)
|
||||
{
|
||||
themeTypeSent = Helper.ColorHelper.GetElementThemeFromBackgroundColor(result.EnvColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
themeTypeSent = status.LyricsBackgroundSettings.LyricsBackgroundTheme;
|
||||
}
|
||||
|
||||
bool isLight = themeTypeSent switch
|
||||
{
|
||||
ElementTheme.Default => Application.Current.RequestedTheme == ApplicationTheme.Light,
|
||||
ElementTheme.Light => true,
|
||||
ElementTheme.Dark => false,
|
||||
_ => false
|
||||
};
|
||||
|
||||
Color adaptiveGrayedFontColor;
|
||||
Color grayedEnvironmentalColor;
|
||||
Color? adaptiveColoredFontColor;
|
||||
|
||||
Color darkColor = Colors.Black;
|
||||
Color lightColor = Colors.White;
|
||||
|
||||
if (isLight)
|
||||
{
|
||||
adaptiveGrayedFontColor = darkColor;
|
||||
// brightness = 0.7f;
|
||||
grayedEnvironmentalColor = lightColor;
|
||||
|
||||
result.AccentColor1 = _lightAccentColors.ElementAtOrDefault(0);
|
||||
result.AccentColor2 = _lightAccentColors.ElementAtOrDefault(1);
|
||||
result.AccentColor3 = _lightAccentColors.ElementAtOrDefault(2);
|
||||
result.AccentColor4 = _lightAccentColors.ElementAtOrDefault(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
adaptiveGrayedFontColor = lightColor;
|
||||
// brightness = 0.3f;
|
||||
grayedEnvironmentalColor = darkColor;
|
||||
|
||||
result.AccentColor1 = _darkAccentColors.ElementAtOrDefault(0);
|
||||
result.AccentColor2 = _darkAccentColors.ElementAtOrDefault(1);
|
||||
result.AccentColor3 = _darkAccentColors.ElementAtOrDefault(2);
|
||||
result.AccentColor4 = _darkAccentColors.ElementAtOrDefault(3);
|
||||
}
|
||||
|
||||
if (status.IsAdaptToEnvironment)
|
||||
{
|
||||
adaptiveColoredFontColor = Helper.ColorHelper.GetForegroundColor(result.EnvColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isLight)
|
||||
adaptiveColoredFontColor = _darkAccentColors.ElementAtOrDefault(0);
|
||||
else
|
||||
adaptiveColoredFontColor = _lightAccentColors.ElementAtOrDefault(0);
|
||||
}
|
||||
|
||||
result.ThemeType = themeTypeSent;
|
||||
|
||||
// 背景字色
|
||||
switch (status.LyricsStyleSettings.LyricsBgFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.BgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.BgFontColor = adaptiveColoredFontColor ?? adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.BgFontColor = status.LyricsStyleSettings.LyricsCustomBgFontColor;
|
||||
break;
|
||||
default:
|
||||
result.BgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
}
|
||||
|
||||
// 前景字色
|
||||
switch (status.LyricsStyleSettings.LyricsFgFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.FgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.FgFontColor = adaptiveColoredFontColor ?? adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.FgFontColor = status.LyricsStyleSettings.LyricsCustomFgFontColor;
|
||||
break;
|
||||
default:
|
||||
result.FgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
}
|
||||
|
||||
// 描边颜色
|
||||
switch (status.LyricsStyleSettings.LyricsStrokeFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.StrokeFontColor = grayedEnvironmentalColor.WithBrightness(0.7);
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.StrokeFontColor = result.EnvColor.WithBrightness(0.7);
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.StrokeFontColor = status.LyricsStyleSettings.LyricsCustomStrokeFontColor;
|
||||
break;
|
||||
default:
|
||||
result.StrokeFontColor = Colors.Transparent;
|
||||
break;
|
||||
}
|
||||
|
||||
AlbumArtThemeColors = result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
|
||||
using BetterLyrics.WinUI3.Services.DiscordService;
|
||||
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
|
||||
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.Services.TranslateService;
|
||||
@@ -44,13 +44,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
public partial class MediaSessionsService : BaseViewModel, IMediaSessionsService,
|
||||
IRecipient<PropertyChangedMessage<bool>>,
|
||||
IRecipient<PropertyChangedMessage<string>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>,
|
||||
IRecipient<PropertyChangedMessage<PaletteGeneratorType>>,
|
||||
IRecipient<PropertyChangedMessage<ChineseRomanization>>,
|
||||
IRecipient<PropertyChangedMessage<List<string>>>,
|
||||
IRecipient<PropertyChangedMessage<Color>>,
|
||||
IRecipient<PropertyChangedMessage<ElementTheme>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsFontColorType>>
|
||||
IRecipient<PropertyChangedMessage<List<string>>>
|
||||
{
|
||||
private EventSourceReader? _sse = null;
|
||||
private readonly MediaManager _mediaManager = new();
|
||||
@@ -61,7 +56,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
private readonly ITranslateService _translateService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILibWatcherService _libWatcherService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
private readonly IDiscordService _discordService;
|
||||
private readonly ILogger<MediaSessionsService> _logger;
|
||||
|
||||
@@ -81,7 +75,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
IAlbumArtSearchService albumArtSearchService,
|
||||
ILyricsSearchService musicSearchService,
|
||||
ILibWatcherService libWatcherService,
|
||||
ILiveStatesService liveStatesService,
|
||||
IDiscordService discordService,
|
||||
ITranslateService libreTranslateService,
|
||||
ILogger<MediaSessionsService> logger)
|
||||
@@ -91,7 +84,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
_lyrcsSearchService = musicSearchService;
|
||||
_libWatcherService = libWatcherService;
|
||||
_translateService = libreTranslateService;
|
||||
_liveStatesService = liveStatesService;
|
||||
_discordService = discordService;
|
||||
_logger = logger;
|
||||
|
||||
@@ -743,17 +735,18 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
{
|
||||
if (message.Sender is LiveStates)
|
||||
{
|
||||
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
UpdateTranslations();
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO 需要在此处更新翻译?
|
||||
//public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
//{
|
||||
// if (message.Sender is LiveStates)
|
||||
// {
|
||||
// if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
// {
|
||||
// UpdateAlbumArtThemeColors();
|
||||
// UpdateTranslations();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
public void Receive(PropertyChangedMessage<ChineseRomanization> message)
|
||||
{
|
||||
@@ -766,72 +759,5 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<PaletteGeneratorType> message)
|
||||
{
|
||||
if (message.Sender is LyricsBackgroundSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsBackgroundSettings.PaletteGeneratorType))
|
||||
{
|
||||
UpdateAlbumArt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<Color> message)
|
||||
{
|
||||
if (message.Sender is NowPlayingWindowViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(NowPlayingWindowViewModel.BackdropAccentColor))
|
||||
{
|
||||
_envColor = message.NewValue;
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
}
|
||||
else if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCustomBgFontColor))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCustomFgFontColor))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCustomStrokeFontColor))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<ElementTheme> message)
|
||||
{
|
||||
if (message.Sender is LyricsBackgroundSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsBackgroundSettings.LyricsBackgroundTheme))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsFontColorType> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsBgFontColorType))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsFgFontColorType))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsStrokeFontColorType))
|
||||
{
|
||||
UpdateAlbumArtThemeColors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using BetterLyrics.WinUI3.Collections;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Extensions;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
@@ -56,6 +57,22 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
|
||||
AppSettings.Version = MetadataHelper.AppVersion;
|
||||
|
||||
EnsureMediaSourceProvidersInfo();
|
||||
EnsureLyricsWindowStatus();
|
||||
}
|
||||
|
||||
public void EnsureLyricsWindowStatus()
|
||||
{
|
||||
var defaultLyricsWindowStatus = AppSettings.WindowBoundsRecords.FirstOrDefault(x => x.IsDefault);
|
||||
if (defaultLyricsWindowStatus == null)
|
||||
{
|
||||
defaultLyricsWindowStatus = LyricsWindowStatusExtensions.StandardMode();
|
||||
defaultLyricsWindowStatus.IsDefault = true;
|
||||
AppSettings.WindowBoundsRecords.Add(defaultLyricsWindowStatus);
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DesktopMode());
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.DockedMode());
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.NarrowMode());
|
||||
AppSettings.WindowBoundsRecords.Add(LyricsWindowStatusExtensions.FullscreenMode());
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureMediaSourceProvidersInfo()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
@@ -15,10 +14,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial class LyricsWindowSettingsControlViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial LiveStates LiveStates { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
@@ -35,13 +30,11 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial double DisplayPanelHeight { get; set; } = 0;
|
||||
|
||||
public LyricsWindowSettingsControlViewModel(ISettingsService settingsService, ILiveStatesService liveStatesService)
|
||||
public LyricsWindowSettingsControlViewModel(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_liveStatesService = liveStatesService;
|
||||
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
LiveStates = _liveStatesService.LiveStates;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
@@ -9,21 +8,14 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial class LyricsWindowSwitchControlViewModel : BaseViewModel
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial LiveStates LiveStates { get; set; }
|
||||
|
||||
|
||||
[ObservableProperty]
|
||||
public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
public LyricsWindowSwitchControlViewModel(ISettingsService settingsService, ILiveStatesService liveStatesService)
|
||||
public LyricsWindowSwitchControlViewModel(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_liveStatesService = liveStatesService;
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
LiveStates = _liveStatesService.LiveStates;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@@ -14,10 +14,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial class NowPlayingPageViewModel : BaseViewModel
|
||||
{
|
||||
public IMediaSessionsService MediaSessionsService { get; private set; }
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial LiveStates LiveStates { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int Volume { get; set; }
|
||||
@@ -37,13 +33,10 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial double TimelineSliderThumbSeconds { get; set; } = 0;
|
||||
|
||||
public NowPlayingPageViewModel(IMediaSessionsService mediaSessionsService, ILiveStatesService liveStatesService)
|
||||
public NowPlayingPageViewModel(IMediaSessionsService mediaSessionsService)
|
||||
{
|
||||
_liveStatesService = liveStatesService;
|
||||
MediaSessionsService = mediaSessionsService;
|
||||
|
||||
LiveStates = _liveStatesService.LiveStates;
|
||||
|
||||
Volume = SystemVolumeHook.MasterVolume;
|
||||
SystemVolumeHook.VolumeNotification += SystemVolumeHelper_VolumeNotification;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
@@ -14,6 +13,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -26,44 +26,26 @@ namespace BetterLyrics.WinUI3
|
||||
{
|
||||
public partial class NowPlayingWindowViewModel
|
||||
: BaseWindowViewModel,
|
||||
IRecipient<PropertyChangedMessage<bool>>,
|
||||
IRecipient<PropertyChangedMessage<List<string>>>,
|
||||
IRecipient<PropertyChangedMessage<AlbumArtThemeColors>>
|
||||
IRecipient<PropertyChangedMessage<List<string>>>
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILiveStatesService _liveStatesService;
|
||||
|
||||
private ForegroundWindowHook? _fgWindowWatcher = null;
|
||||
private DispatcherQueueTimer? _fgWindowWatcherTimer = null;
|
||||
|
||||
public NowPlayingWindowViewModel(ISettingsService settingsService, ILiveStatesService liveStatesService)
|
||||
public NowPlayingWindowViewModel(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_liveStatesService = liveStatesService;
|
||||
|
||||
AppSettings = _settingsService.AppSettings;
|
||||
LiveStates = _liveStatesService.LiveStates;
|
||||
}
|
||||
|
||||
[ObservableProperty] public partial AppSettings AppSettings { get; set; }
|
||||
|
||||
[ObservableProperty] public partial LiveStates LiveStates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 歌词窗口所在的背景主题色
|
||||
/// </summary>
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Color BackdropAccentColor { get; set; }
|
||||
|
||||
[ObservableProperty] public partial double TopCommandGridOpacity { get; set; } = 0;
|
||||
|
||||
[ObservableProperty] public partial ElementTheme ThemeType { get; set; } = ElementTheme.Default;
|
||||
|
||||
[ObservableProperty] public partial double TitleBarFontSize { get; set; } = 14;
|
||||
|
||||
public void InitShortcuts()
|
||||
{
|
||||
UpdateLyricsWindowBorderlessShortcut();
|
||||
UpdateLyricsWindowClickThroughShortcut();
|
||||
// TODO 这里最好移到另一个单例的地方做初始化
|
||||
UpdateLyricsWindowShowHideShortcut();
|
||||
UpdateLyricsWindowSwitchShortcut();
|
||||
}
|
||||
@@ -89,28 +71,6 @@ namespace BetterLyrics.WinUI3
|
||||
);
|
||||
}
|
||||
|
||||
private void UpdateLyricsWindowBorderlessShortcut()
|
||||
{
|
||||
GlobalHotKeyHook.UpdateHotKey<NowPlayingWindow>(ShortcutID.Borderless,
|
||||
_settingsService.AppSettings.GeneralSettings.BorderlessShortcut,
|
||||
() =>
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.IsBorderless = !LiveStates.LyricsWindowStatus.IsBorderless;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void UpdateLyricsWindowClickThroughShortcut()
|
||||
{
|
||||
GlobalHotKeyHook.UpdateHotKey<NowPlayingWindow>(ShortcutID.ClickThrough,
|
||||
_settingsService.AppSettings.GeneralSettings.ClickThroughShortcut,
|
||||
() =>
|
||||
{
|
||||
LiveStates.LyricsWindowStatus.IsClickThrough = !LiveStates.LyricsWindowStatus.IsClickThrough;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void UpdateLyricsWindowSwitchShortcut()
|
||||
{
|
||||
GlobalHotKeyHook.UpdateHotKey<NowPlayingWindow>(ShortcutID.LyricsWindowSwitch,
|
||||
@@ -122,75 +82,9 @@ namespace BetterLyrics.WinUI3
|
||||
);
|
||||
}
|
||||
|
||||
public void InitFgWindowWatcher()
|
||||
{
|
||||
var window = WindowHook.GetWindow<NowPlayingWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
_fgWindowWatcherTimer = _dispatcherQueue.CreateTimer();
|
||||
_fgWindowWatcher = new ForegroundWindowHook(
|
||||
hwnd,
|
||||
fgHwnd =>
|
||||
{
|
||||
_fgWindowWatcherTimer.Debounce(() =>
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsAlwaysOnTop &&
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling &&
|
||||
window.AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.IsAlwaysOnTop = true;
|
||||
}
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment)
|
||||
{
|
||||
UpdateBackdropAccentColor(hwnd);
|
||||
}
|
||||
}, Constants.Time.DebounceTimeout);
|
||||
}
|
||||
);
|
||||
_fgWindowWatcher.Start();
|
||||
UpdateBackdropAccentColor(hwnd);
|
||||
}
|
||||
|
||||
public void UpdateBackdropAccentColor(nint hwnd)
|
||||
{
|
||||
BackdropAccentColor = ColorHelper.GetAccentColor(
|
||||
hwnd,
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorDeviceName,
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.EnvironmentSampleMode);
|
||||
}
|
||||
|
||||
public void ExitOrClose()
|
||||
{
|
||||
if (_settingsService.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed)
|
||||
{
|
||||
WindowHook.ExitApp();
|
||||
}
|
||||
else
|
||||
{
|
||||
var window = WindowHook.GetWindow<NowPlayingWindow>();
|
||||
window?.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<List<string>> message)
|
||||
{
|
||||
if (message.Sender is GeneralSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(GeneralSettings.ClickThroughShortcut))
|
||||
{
|
||||
UpdateLyricsWindowClickThroughShortcut();
|
||||
}
|
||||
}
|
||||
else if (message.Sender is GeneralSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(GeneralSettings.BorderlessShortcut))
|
||||
{
|
||||
UpdateLyricsWindowBorderlessShortcut();
|
||||
}
|
||||
}
|
||||
else if (message.Sender is GeneralSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(GeneralSettings.ShowOrHideLyricsWindowShortcut))
|
||||
{
|
||||
@@ -206,26 +100,5 @@ namespace BetterLyrics.WinUI3
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<AlbumArtThemeColors> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtThemeColors))
|
||||
{
|
||||
ThemeType = message.NewValue.ThemeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.CurrentIsPlaying))
|
||||
{
|
||||
WindowHook.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
|
||||
{
|
||||
WindowHook.CloseWindow<LyricsSearchWindow>();
|
||||
this.CloseWindow();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
|
||||
{
|
||||
WindowHook.CloseWindow<MusicGalleryWindow>();
|
||||
this.CloseWindow();
|
||||
}
|
||||
|
||||
private void LyricsWindowButton_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -28,7 +28,10 @@
|
||||
SizeChanged="RootGrid_SizeChanged">
|
||||
|
||||
<!-- Win2D drawing area -->
|
||||
<uc:LyricsCanvas x:Name="LyricsCanvas" />
|
||||
<uc:LyricsCanvas
|
||||
x:Name="LyricsCanvas"
|
||||
AlbumArtThemeColors="{x:Bind AlbumArtThemeColors, Mode=OneWay}"
|
||||
LyricsWindowStatus="{x:Bind LyricsWindowStatus, Mode=OneWay}" />
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
@@ -72,19 +75,19 @@
|
||||
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
|
||||
</Grid.OpacityTransition>
|
||||
<uc:ImageSwitcher
|
||||
CornerRadiusAmount="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageRadius, Mode=OneWay}"
|
||||
ShadowAmount="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=OneWay}"
|
||||
CornerRadiusAmount="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageRadius, Mode=OneWay}"
|
||||
ShadowAmount="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=OneWay}"
|
||||
Source="{x:Bind ViewModel.MediaSessionsService.AlbumArtBitmapImage, Mode=OneWay}"
|
||||
SwitchType="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtAreaEffectSettings.ImageSwitchType, Mode=OneWay}" />
|
||||
SwitchType="{x:Bind LyricsWindowStatus.AlbumArtAreaEffectSettings.ImageSwitchType, Mode=OneWay}" />
|
||||
</Grid>
|
||||
|
||||
<!-- Song info -->
|
||||
<StackPanel x:Name="SongInfoStackPanel" HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<StackPanel x:Name="SongInfoStackPanel" HorizontalAlignment="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
|
||||
</StackPanel.OpacityTransition>
|
||||
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView.OpacityMask>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientStop Offset="0" Color="Transparent" />
|
||||
@@ -102,13 +105,13 @@
|
||||
ScrollingPixelsPreSecond="20">
|
||||
<TextBlock
|
||||
x:Name="TitleTextBlock"
|
||||
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
FontWeight="{x:Bind LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
TextTrimming="None"
|
||||
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowTitle, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
Visibility="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.ShowTitle, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</dev:AutoScrollView>
|
||||
</dev:OpacityMaskView>
|
||||
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView.OpacityMask>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientStop Offset="0" Color="Transparent" />
|
||||
@@ -126,14 +129,14 @@
|
||||
ScrollingPixelsPreSecond="20">
|
||||
<TextBlock
|
||||
x:Name="ArtistsTextBlock"
|
||||
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
FontWeight="{x:Bind LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
Opacity="0.6"
|
||||
TextTrimming="None"
|
||||
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowArtists, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
Visibility="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.ShowArtists, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</dev:AutoScrollView>
|
||||
</dev:OpacityMaskView>
|
||||
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView HorizontalAlignment="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=OneWay, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}}">
|
||||
<dev:OpacityMaskView.OpacityMask>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientStop Offset="0" Color="Transparent" />
|
||||
@@ -151,10 +154,10 @@
|
||||
ScrollingPixelsPreSecond="20">
|
||||
<TextBlock
|
||||
x:Name="AlbumTextBlock"
|
||||
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
FontWeight="{x:Bind LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
|
||||
Opacity="0.3"
|
||||
TextTrimming="None"
|
||||
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowAlbum, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
Visibility="{x:Bind LyricsWindowStatus.AlbumArtLayoutSettings.ShowAlbum, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</dev:AutoScrollView>
|
||||
</dev:OpacityMaskView>
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
@@ -26,37 +25,66 @@ using System.Threading.Tasks;
|
||||
namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
public sealed partial class NowPlayingPage : Page,
|
||||
IRecipient<PropertyChangedMessage<int>>,
|
||||
IRecipient<PropertyChangedMessage<bool>>,
|
||||
IRecipient<PropertyChangedMessage<string>>,
|
||||
IRecipient<PropertyChangedMessage<SongInfo?>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsLayoutOrientation>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsDisplayType>>,
|
||||
IRecipient<PropertyChangedMessage<AlbumArtThemeColors>>,
|
||||
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>
|
||||
IRecipient<PropertyChangedMessage<SongInfo?>>
|
||||
{
|
||||
private readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
|
||||
private readonly DispatcherQueueTimer _layoutChangedTimer = App.Current.Resources.DispatcherQueue.CreateTimer();
|
||||
private readonly DispatcherQueueTimer _scrollChangedTimer = App.Current.Resources.DispatcherQueue.CreateTimer();
|
||||
|
||||
public NowPlayingPageViewModel ViewModel => (NowPlayingPageViewModel)DataContext;
|
||||
|
||||
public LyricsWindowStatus LyricsWindowStatus
|
||||
{
|
||||
get { return (LyricsWindowStatus)GetValue(LyricsWindowStatusProperty); }
|
||||
set { SetValue(LyricsWindowStatusProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsWindowStatusProperty =
|
||||
DependencyProperty.Register(nameof(LyricsWindowStatus), typeof(LyricsWindowStatus), typeof(NowPlayingPage), new PropertyMetadata(default, OnDependencyPropertyChanged));
|
||||
|
||||
public AlbumArtThemeColors AlbumArtThemeColors
|
||||
{
|
||||
get { return (AlbumArtThemeColors)GetValue(AlbumArtThemeColorsProperty); }
|
||||
set { SetValue(AlbumArtThemeColorsProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty AlbumArtThemeColorsProperty =
|
||||
DependencyProperty.Register(nameof(AlbumArtThemeColors), typeof(AlbumArtThemeColors), typeof(NowPlayingPage), new PropertyMetadata(new AlbumArtThemeColors(), OnDependencyPropertyChanged));
|
||||
|
||||
public NowPlayingPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
DataContext = Ioc.Default.GetRequiredService<NowPlayingPageViewModel>();
|
||||
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<int>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<bool>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<string>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<SongInfo?>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsLayoutOrientation>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsDisplayType>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<AlbumArtThemeColors>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsWindowStatus>>(this);
|
||||
}
|
||||
|
||||
private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is NowPlayingPage page)
|
||||
{
|
||||
if (e.Property == LyricsWindowStatusProperty)
|
||||
{
|
||||
var oldValue = (LyricsWindowStatus?)e.OldValue;
|
||||
oldValue?.PropertyChanged -= page.LyricsWindowStatus_PropertyChanged;
|
||||
var newValue = (LyricsWindowStatus?)e.NewValue;
|
||||
newValue?.PropertyChanged += page.LyricsWindowStatus_PropertyChanged;
|
||||
page.OnLayoutChanged();
|
||||
page.RenderSongInfo();
|
||||
}
|
||||
else if (e.Property == AlbumArtThemeColorsProperty)
|
||||
{
|
||||
page.RenderSongInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
OnLayoutChanged();
|
||||
RenderSongInfo();
|
||||
}
|
||||
|
||||
private void CompositionTarget_Rendering(object? sender, object e)
|
||||
@@ -71,7 +99,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
if (sender == null || text == null || fontSize == 0) return;
|
||||
|
||||
var lyricsStyleSettings = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings;
|
||||
var lyricsStyleSettings = LyricsWindowStatus.LyricsStyleSettings;
|
||||
|
||||
sender.Inlines.Clear();
|
||||
foreach (var ch in text)
|
||||
@@ -80,14 +108,14 @@ namespace BetterLyrics.WinUI3.Views
|
||||
sender.Inlines.Add(new Run { Text = $"{ch}", FontFamily = new FontFamily(fontFamilyName) });
|
||||
}
|
||||
sender.FontSize = (int)fontSize;
|
||||
sender.Foreground = new SolidColorBrush(_mediaSessionsService.AlbumArtThemeColors.BgFontColor);
|
||||
sender.Foreground = new SolidColorBrush(AlbumArtThemeColors.BgFontColor);
|
||||
}
|
||||
|
||||
private void RenderSongInfo()
|
||||
{
|
||||
var lyricsLayoutMetrics = LyricsLayoutHelper.CalculateLayout(RootGrid.ActualWidth, RootGrid.ActualHeight);
|
||||
|
||||
var albumArtLayoutSettings = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings;
|
||||
var albumArtLayoutSettings = LyricsWindowStatus.AlbumArtLayoutSettings;
|
||||
|
||||
var titleFontSize = albumArtLayoutSettings.IsAutoSongInfoFontSize ? lyricsLayoutMetrics.SongTitleSize : albumArtLayoutSettings.SongInfoFontSize;
|
||||
var artistsFontSize = albumArtLayoutSettings.IsAutoSongInfoFontSize ? lyricsLayoutMetrics.ArtistNameSize : albumArtLayoutSettings.SongInfoFontSize * 0.8;
|
||||
@@ -100,7 +128,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateSongInfoOpacity()
|
||||
{
|
||||
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
|
||||
switch (LyricsWindowStatus.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
SongInfoStackPanel.Opacity = 1;
|
||||
@@ -119,7 +147,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
// ==== AlbumArt
|
||||
private void UpdateAlbumArtOpacity()
|
||||
{
|
||||
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
|
||||
switch (LyricsWindowStatus.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
AlbumArtGrid.Opacity = 1;
|
||||
@@ -139,7 +167,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateTrackSummaryGridSpan()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
switch (status.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
@@ -172,7 +200,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateSongInfoStackPanelSpan()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
switch (status.LyricsLayoutOrientation)
|
||||
{
|
||||
case LyricsLayoutOrientation.Horizontal:
|
||||
@@ -194,7 +222,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateLyricsPlaceholderSpan()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
switch (status.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
@@ -233,7 +261,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateAlbumArtGridSpan()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
switch (status.LyricsLayoutOrientation)
|
||||
{
|
||||
case LyricsLayoutOrientation.Horizontal:
|
||||
@@ -257,7 +285,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateLyricsOpacity()
|
||||
{
|
||||
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
|
||||
switch (LyricsWindowStatus.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
LyricsCanvas.LyricsOpacity = 0;
|
||||
@@ -273,7 +301,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void UpdateLyricsLayout()
|
||||
{
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
switch (status.LyricsDisplayType)
|
||||
{
|
||||
case LyricsDisplayType.AlbumArtOnly:
|
||||
@@ -314,7 +342,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
var lyricsLayoutMetrics = LyricsLayoutHelper.CalculateLayout(RootGrid.ActualWidth, RootGrid.ActualHeight);
|
||||
|
||||
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
|
||||
var status = LyricsWindowStatus;
|
||||
|
||||
double height = RootGrid.ActualHeight;
|
||||
double width = RootGrid.ActualWidth;
|
||||
@@ -684,51 +712,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
// ====
|
||||
|
||||
public void Receive(PropertyChangedMessage<int> message)
|
||||
{
|
||||
if (message.Sender is AlbumArtAreaStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(AlbumArtAreaStyleSettings.SongInfoFontSize))
|
||||
{
|
||||
RenderSongInfo();
|
||||
}
|
||||
else if (message.PropertyName == nameof(AlbumArtAreaStyleSettings.CoverImageHeight))
|
||||
{
|
||||
OnLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is AlbumArtAreaStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(AlbumArtAreaStyleSettings.IsAutoSongInfoFontSize))
|
||||
{
|
||||
RenderSongInfo();
|
||||
}
|
||||
else if (message.PropertyName == nameof(AlbumArtAreaStyleSettings.IsAutoCoverImageHeight))
|
||||
{
|
||||
OnLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<string> message)
|
||||
{
|
||||
if (message.Sender is LyricsStyleSettings)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCJKFontFamily))
|
||||
{
|
||||
RenderSongInfo();
|
||||
}
|
||||
else if (message.PropertyName == nameof(LyricsStyleSettings.LyricsWesternFontFamily))
|
||||
{
|
||||
RenderSongInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async void Receive(PropertyChangedMessage<SongInfo?> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
@@ -744,50 +727,5 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsLayoutOrientation> message)
|
||||
{
|
||||
if (message.Sender is LyricsWindowStatus)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsWindowStatus.LyricsLayoutOrientation))
|
||||
{
|
||||
OnLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsDisplayType> message)
|
||||
{
|
||||
if (message.Sender is LyricsWindowStatus)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsWindowStatus.LyricsDisplayType))
|
||||
{
|
||||
OnLayoutChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<AlbumArtThemeColors> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtThemeColors))
|
||||
{
|
||||
RenderSongInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LyricsWindowStatus> message)
|
||||
{
|
||||
if (message.Sender is LiveStates)
|
||||
{
|
||||
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
|
||||
{
|
||||
OnLayoutChanged();
|
||||
RenderSongInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid x:Name="RootGrid" RequestedTheme="{x:Bind ViewModel.ThemeType, Mode=OneWay}">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid
|
||||
x:Name="PlaceholderGrid"
|
||||
Width="1"
|
||||
@@ -20,7 +20,7 @@
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom" />
|
||||
|
||||
<local:NowPlayingPage />
|
||||
<local:NowPlayingPage x:Name="NowPlayingPage" />
|
||||
|
||||
<!-- Top command -->
|
||||
<Grid
|
||||
|
||||
@@ -2,29 +2,63 @@
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Extensions;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Hooks;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Vanara.PInvoke;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.UI;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx.Messaging;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
public sealed partial class NowPlayingWindow : Window
|
||||
public sealed partial class NowPlayingWindow : Window,
|
||||
IRecipient<PropertyChangedMessage<bool>>,
|
||||
IRecipient<PropertyChangedMessage<BitmapDecoder?>>
|
||||
{
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
|
||||
private ForegroundWindowHook? _fgWindowWatcher = null;
|
||||
private DispatcherQueueTimer? _fgWindowWatcherTimer = null;
|
||||
private readonly WindowMessageMonitor _wmm;
|
||||
|
||||
public NowPlayingWindowViewModel ViewModel { get; private set; } = Ioc.Default.GetRequiredService<NowPlayingWindowViewModel>();
|
||||
private Color _backdropAccentColor = Colors.Transparent;
|
||||
|
||||
public NowPlayingWindow()
|
||||
private List<Color> _lightAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
private List<Color> _darkAccentColors = Enumerable.Repeat(Colors.Black, 4).ToList();
|
||||
|
||||
public LyricsWindowStatus Status { get; private set; }
|
||||
|
||||
public NowPlayingWindowViewModel ViewModel { get; private set; } = Ioc.Default.GetRequiredService<NowPlayingWindowViewModel>();
|
||||
private readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
|
||||
public NowPlayingWindow(LyricsWindowStatus status)
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_fgWindowWatcherTimer = DispatcherQueue.CreateTimer();
|
||||
|
||||
Status = status;
|
||||
NowPlayingPage.LyricsWindowStatus = Status;
|
||||
|
||||
Status.PropertyChanged += LyricsWindowStatus_PropertyChanged;
|
||||
|
||||
_wmm = new WindowMessageMonitor(this);
|
||||
_wmm.WindowMessageReceived += Wmm_WindowMessageReceived;
|
||||
|
||||
@@ -32,11 +66,295 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
AppWindow.Changed += AppWindow_Changed;
|
||||
AppWindow.Closing += AppWindow_Closing;
|
||||
|
||||
_ = InitStatus();
|
||||
|
||||
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(BackdropType.Transparent);
|
||||
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<bool>>(this);
|
||||
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<BitmapDecoder?>>(this);
|
||||
|
||||
_ = UpdateAlbumArtThemeColorsAsync();
|
||||
}
|
||||
|
||||
private async Task InitStatus()
|
||||
{
|
||||
Status.IsLyricsWindowStatusRefreshing = true;
|
||||
|
||||
Status.UpdateMonitorBounds();
|
||||
|
||||
this.SetIsWorkArea(Status.IsWorkArea);
|
||||
if (Status.IsWorkArea)
|
||||
{
|
||||
this.UpdateWorkArea();
|
||||
}
|
||||
await Task.Delay(300);
|
||||
|
||||
this.SetIsShowInSwitchers(Status.IsShownInSwitchers);
|
||||
this.SetIsAlwaysOnTop(Status.IsAlwaysOnTop);
|
||||
|
||||
this.SetIsClickThrough(Status.IsClickThrough);
|
||||
this.SetIsBorderless(Status.IsBorderless);
|
||||
|
||||
this.SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue);
|
||||
this.SetTitleBarArea(Status.TitleBarArea);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˱<EFBFBD><CBB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
if (Status.IsWorkArea)
|
||||
{
|
||||
Status.WindowBounds = Status.GetWindowBoundsWhenWorkArea();
|
||||
}
|
||||
|
||||
this.MoveAndResize(Status.WindowBounds);
|
||||
Status.WindowX = Status.WindowBounds.X;
|
||||
Status.WindowY = Status.WindowBounds.Y;
|
||||
Status.WindowWidth = Status.WindowBounds.Width;
|
||||
Status.WindowHeight = Status.WindowBounds.Height;
|
||||
|
||||
Status.UpdateDemoWindowAndMonitorBounds();
|
||||
|
||||
Status.IsLyricsWindowStatusRefreshing = false;
|
||||
}
|
||||
|
||||
private async void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(LyricsWindowStatus.IsWorkArea):
|
||||
Status.IsLyricsWindowStatusRefreshing = true;
|
||||
this.SetIsWorkArea(Status.IsWorkArea);
|
||||
Status.IsLyricsWindowStatusRefreshing = false;
|
||||
if (Status.IsWorkArea)
|
||||
{
|
||||
this.MoveAndResize(Status.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.DockHeight):
|
||||
case nameof(LyricsWindowStatus.DockPlacement):
|
||||
case nameof(LyricsWindowStatus.MonitorDeviceName):
|
||||
Status.UpdateMonitorBounds();
|
||||
if (Status.IsWorkArea)
|
||||
{
|
||||
Status.IsLyricsWindowStatusRefreshing = true;
|
||||
this.UpdateWorkArea();
|
||||
Status.IsLyricsWindowStatusRefreshing = false;
|
||||
this.MoveAndResize(Status.GetWindowBoundsWhenWorkArea());
|
||||
}
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsShownInSwitchers):
|
||||
this.SetIsShowInSwitchers(Status.IsShownInSwitchers);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsAlwaysOnTop):
|
||||
this.SetIsAlwaysOnTop(Status.IsAlwaysOnTop);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsClickThrough):
|
||||
this.SetIsClickThrough(Status.IsClickThrough);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.IsBorderless):
|
||||
this.SetIsBorderless(Status.IsBorderless);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowX):
|
||||
this.MoveAndResize(Status.WindowBounds.WithX(Status.WindowX));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowY):
|
||||
this.MoveAndResize(Status.WindowBounds.WithY(Status.WindowY));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowWidth):
|
||||
this.MoveAndResize(Status.WindowBounds.WithWidth(Status.WindowWidth));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.WindowHeight):
|
||||
this.MoveAndResize(Status.WindowBounds.WithHeight(Status.WindowHeight));
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.TitleBarArea):
|
||||
this.SetTitleBarArea(Status.TitleBarArea);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.AutoShowOrHideWindow):
|
||||
this.SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue);
|
||||
break;
|
||||
case nameof(LyricsWindowStatus.LyricsBackgroundSettings):
|
||||
await UpdateAlbumArtThemeColorsAsync();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateBackdropAccentColor(nint hwnd)
|
||||
{
|
||||
_backdropAccentColor = Helper.ColorHelper.GetAccentColor(
|
||||
hwnd,
|
||||
Status.MonitorDeviceName,
|
||||
Status.EnvironmentSampleMode);
|
||||
UpdateAlbumArtThemeColorsAsync();
|
||||
}
|
||||
|
||||
public void InitFgWindowWatcher()
|
||||
{
|
||||
var hwnd = WindowNative.GetWindowHandle(this);
|
||||
|
||||
_fgWindowWatcher = new ForegroundWindowHook(
|
||||
hwnd,
|
||||
fgHwnd =>
|
||||
{
|
||||
_fgWindowWatcherTimer?.Debounce(() =>
|
||||
{
|
||||
if (Status.IsAlwaysOnTop &&
|
||||
Status.IsAlwaysOnTopPolling &&
|
||||
this.AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.IsAlwaysOnTop = true;
|
||||
}
|
||||
if (Status.IsAdaptToEnvironment)
|
||||
{
|
||||
UpdateBackdropAccentColor(hwnd);
|
||||
}
|
||||
}, Constants.Time.DebounceTimeout);
|
||||
}
|
||||
);
|
||||
_fgWindowWatcher.Start();
|
||||
UpdateBackdropAccentColor(hwnd);
|
||||
}
|
||||
|
||||
private async Task UpdateAlbumArtThemeColorsAsync()
|
||||
{
|
||||
if (_mediaSessionsService.AlbumArtBitmapDecoder is BitmapDecoder decoder)
|
||||
{
|
||||
var lightPalette = await ImageHelper.GetAccentColorsAsync(_mediaSessionsService.AlbumArtBitmapDecoder, 4, Status.LyricsBackgroundSettings.PaletteGeneratorType, false);
|
||||
var darkPalette = await ImageHelper.GetAccentColorsAsync(_mediaSessionsService.AlbumArtBitmapDecoder, 4, Status.LyricsBackgroundSettings.PaletteGeneratorType, true);
|
||||
_lightAccentColors = lightPalette.Palette.Select(Helper.ColorHelper.FromVector3).ToList();
|
||||
_darkAccentColors = darkPalette.Palette.Select(Helper.ColorHelper.FromVector3).ToList();
|
||||
}
|
||||
|
||||
var result = new AlbumArtThemeColors();
|
||||
result.EnvColor = _backdropAccentColor;
|
||||
|
||||
ElementTheme themeTypeSent;
|
||||
if (Status.IsAdaptToEnvironment)
|
||||
{
|
||||
themeTypeSent = Helper.ColorHelper.GetElementThemeFromBackgroundColor(result.EnvColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
themeTypeSent = Status.LyricsBackgroundSettings.LyricsBackgroundTheme;
|
||||
}
|
||||
|
||||
bool isLight = themeTypeSent switch
|
||||
{
|
||||
ElementTheme.Default => Application.Current.RequestedTheme == ApplicationTheme.Light,
|
||||
ElementTheme.Light => true,
|
||||
ElementTheme.Dark => false,
|
||||
_ => false
|
||||
};
|
||||
|
||||
Color adaptiveGrayedFontColor;
|
||||
Color grayedEnvironmentalColor;
|
||||
Color? adaptiveColoredFontColor;
|
||||
|
||||
Color darkColor = Colors.Black;
|
||||
Color lightColor = Colors.White;
|
||||
|
||||
if (isLight)
|
||||
{
|
||||
adaptiveGrayedFontColor = darkColor;
|
||||
// brightness = 0.7f;
|
||||
grayedEnvironmentalColor = lightColor;
|
||||
|
||||
result.AccentColor1 = _lightAccentColors.ElementAtOrDefault(0);
|
||||
result.AccentColor2 = _lightAccentColors.ElementAtOrDefault(1);
|
||||
result.AccentColor3 = _lightAccentColors.ElementAtOrDefault(2);
|
||||
result.AccentColor4 = _lightAccentColors.ElementAtOrDefault(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
adaptiveGrayedFontColor = lightColor;
|
||||
// brightness = 0.3f;
|
||||
grayedEnvironmentalColor = darkColor;
|
||||
|
||||
result.AccentColor1 = _darkAccentColors.ElementAtOrDefault(0);
|
||||
result.AccentColor2 = _darkAccentColors.ElementAtOrDefault(1);
|
||||
result.AccentColor3 = _darkAccentColors.ElementAtOrDefault(2);
|
||||
result.AccentColor4 = _darkAccentColors.ElementAtOrDefault(3);
|
||||
}
|
||||
|
||||
if (Status.IsAdaptToEnvironment)
|
||||
{
|
||||
adaptiveColoredFontColor = Helper.ColorHelper.GetForegroundColor(result.EnvColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isLight)
|
||||
adaptiveColoredFontColor = _darkAccentColors.ElementAtOrDefault(0);
|
||||
else
|
||||
adaptiveColoredFontColor = _lightAccentColors.ElementAtOrDefault(0);
|
||||
}
|
||||
|
||||
result.ThemeType = themeTypeSent;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
switch (Status.LyricsStyleSettings.LyricsBgFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.BgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.BgFontColor = adaptiveColoredFontColor ?? adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.BgFontColor = Status.LyricsStyleSettings.LyricsCustomBgFontColor;
|
||||
break;
|
||||
default:
|
||||
result.BgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
}
|
||||
|
||||
// ǰ<><C7B0><EFBFBD><EFBFBD>ɫ
|
||||
switch (Status.LyricsStyleSettings.LyricsFgFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.FgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.FgFontColor = adaptiveColoredFontColor ?? adaptiveGrayedFontColor;
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.FgFontColor = Status.LyricsStyleSettings.LyricsCustomFgFontColor;
|
||||
break;
|
||||
default:
|
||||
result.FgFontColor = adaptiveGrayedFontColor;
|
||||
break;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
|
||||
switch (Status.LyricsStyleSettings.LyricsStrokeFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.AdaptiveGrayed:
|
||||
result.StrokeFontColor = grayedEnvironmentalColor.WithBrightness(0.7);
|
||||
break;
|
||||
case LyricsFontColorType.AdaptiveColored:
|
||||
result.StrokeFontColor = result.EnvColor.WithBrightness(0.7);
|
||||
break;
|
||||
case LyricsFontColorType.Custom:
|
||||
result.StrokeFontColor = Status.LyricsStyleSettings.LyricsCustomStrokeFontColor;
|
||||
break;
|
||||
default:
|
||||
result.StrokeFontColor = Colors.Transparent;
|
||||
break;
|
||||
}
|
||||
|
||||
NowPlayingPage.AlbumArtThemeColors = result;
|
||||
RootGrid.RequestedTheme = result.ThemeType;
|
||||
}
|
||||
|
||||
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
|
||||
{
|
||||
ViewModel.ExitOrClose();
|
||||
if (_settingsService.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed)
|
||||
{
|
||||
WindowHook.ExitApp();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
args.Cancel = true;
|
||||
}
|
||||
|
||||
@@ -69,7 +387,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing)
|
||||
if (Status.IsLyricsWindowStatusRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +403,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
else
|
||||
{
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.WindowBounds = new Windows.Foundation.Rect(rect.X, rect.Y, size.Width, size.Height);
|
||||
Status.WindowBounds = new Windows.Foundation.Rect(rect.X, rect.Y, size.Width, size.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +425,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.ExitOrClose();
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void LyricsWindowSwitchButton_Click(object sender, RoutedEventArgs e)
|
||||
@@ -124,5 +442,31 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
WindowHook.MinimizeWindow<NowPlayingWindow>();
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.CurrentIsPlaying))
|
||||
{
|
||||
this.SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async void Receive(PropertyChangedMessage<BitmapDecoder?> message)
|
||||
{
|
||||
if (message.Sender is IMediaSessionsService)
|
||||
{
|
||||
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtBitmapDecoder))
|
||||
{
|
||||
if (message.NewValue is BitmapDecoder decoder)
|
||||
{
|
||||
await UpdateAlbumArtThemeColorsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
|
||||
{
|
||||
WindowHook.CloseWindow<SettingsWindow>();
|
||||
this.CloseWindow();
|
||||
}
|
||||
|
||||
private void LyricsWindowButton_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user