Compare commits

...

7 Commits

Author SHA1 Message Date
Zhe Fang
78c81347c8 feat: add window bounds settings in ui, change ExtendedSlider layout 2025-10-21 17:15:15 -04:00
Zhe Fang
65941323eb chore: update version code 2025-10-21 15:34:13 -04:00
Zhe Fang
aee79b9971 Update README.md
chrore: update Google Drive link
2025-10-21 15:33:09 -04:00
Zhe Fang
97df1c1891 fix: MediaSourceProviderInfo ctor with 2 args didn't listen on ItemPropertyChanged and CollectionChanged events of LyricsSearchProvidersInfo and AlbumArtSearchProvidersInfo 2025-10-21 15:22:31 -04:00
Zhe Fang
8a831b17cc add ani for fluid bg 2025-10-21 09:33:07 -04:00
Zhe Fang
78076efe40 Update README.md 2025-10-21 09:09:09 -04:00
Zhe Fang
d0346bf422 fix white edge issue in docked mode 2025-10-21 07:09:36 -04:00
25 changed files with 299 additions and 168 deletions

View File

@@ -12,7 +12,7 @@
<Identity
Name="37412.BetterLyrics"
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
Version="1.0.79.0" />
Version="1.0.82.0" />
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>

View File

@@ -4,20 +4,14 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="6,0,2,0"
VerticalAlignment="Center"
Text="{x:Bind Value, Mode=OneWay}" />
<TextBlock
Margin="0,0,14,0"
VerticalAlignment="Center"
Text="{x:Bind Unit, Mode=OneWay}" />
<StackPanel>
<Slider
Maximum="{x:Bind Maximum, Mode=OneWay}"
Minimum="{x:Bind Minimum, Mode=OneWay}"
@@ -26,32 +20,42 @@
TickFrequency="{x:Bind Frequency, Mode=OneWay}"
TickPlacement="None"
Value="{x:Bind Value, Mode=TwoWay}" />
<Button
Margin="3,0,0,0"
VerticalAlignment="Center"
Click="ResetButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}"
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
<Button
x:Name="SubtractButton"
Margin="3,0,0,0"
VerticalAlignment="Center"
Click="SubtractButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE738;}"
Style="{StaticResource GhostButtonStyle}" />
<Button
x:Name="AddButton"
Margin="3,0,0,0"
VerticalAlignment="Center"
Click="AddButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE710;}"
Style="{StaticResource GhostButtonStyle}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
VerticalAlignment="Center"
Click="ResetButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}"
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
<Button
x:Name="SubtractButton"
VerticalAlignment="Center"
Click="SubtractButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE738;}"
Style="{StaticResource GhostButtonStyle}" />
<StackPanel
Margin="3,-2,3,0"
Orientation="Horizontal"
Spacing="2">
<TextBlock VerticalAlignment="Center" Text="{x:Bind Value, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind Unit, Mode=OneWay}" />
</StackPanel>
<Button
x:Name="AddButton"
VerticalAlignment="Center"
Click="AddButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE710;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -117,18 +117,6 @@
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageDisplayTypeSwitcher"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
@@ -149,6 +137,63 @@
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageWindowBounds"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF16B;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="X">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Right, Mode=OneWay}"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Left, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="Y">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom, Mode=OneWay}"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Top, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageWidth">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageHeight">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsExpander
x:Uid="SettingsPageAOT"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},

View File

@@ -38,5 +38,25 @@ namespace BetterLyrics.WinUI3.Helper
rect.Height
);
}
public static Windows.Foundation.Rect WithX(this Windows.Foundation.Rect rect, double x)
{
return new Windows.Foundation.Rect(
x,
rect.Y,
rect.Width,
rect.Height
);
}
public static Windows.Foundation.Rect WithY(this Windows.Foundation.Rect rect, double y)
{
return new Windows.Foundation.Rect(
rect.X,
y,
rect.Width,
rect.Height
);
}
}
}

View File

@@ -291,13 +291,15 @@ namespace BetterLyrics.WinUI3.Helper
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
y -= 1;
User32.SetWindowPos(
hwnd,
IntPtr.Zero,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
(int)y,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
User32.SetWindowPosFlags.SWP_SHOWWINDOW
);
}
@@ -309,7 +311,7 @@ namespace BetterLyrics.WinUI3.Helper
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.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 = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight : _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom;
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
Shell32.APPBARDATA abd = new()
{
@@ -366,9 +368,7 @@ namespace BetterLyrics.WinUI3.Helper
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
double bottom = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom;
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
Shell32.APPBARDATA abd = new()
{
@@ -392,9 +392,9 @@ namespace BetterLyrics.WinUI3.Helper
hwnd,
IntPtr.Zero,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
(int)top,
(int)top - 1,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
User32.SetWindowPosFlags.SWP_SHOWWINDOW
);

View File

@@ -36,6 +36,10 @@ namespace BetterLyrics.WinUI3.Models
[ObservableProperty][NotifyPropertyChangedRecipients] public partial WindowPixelSampleMode EnvironmentSampleMode { get; set; } = WindowPixelSampleMode.WindowEdge;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoShowOrHideWindow { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TitleBarArea TitleBarArea { get; set; } = TitleBarArea.Top;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowX { get; set; } = 100;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowY { get; set; } = 100;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowWidth { get; set; } = 800;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowHeight { get; set; } = 500;
public LyricsWindowStatus()
{
@@ -43,6 +47,26 @@ namespace BetterLyrics.WinUI3.Models
UpdateDemoWindowAndMonitorBounds();
}
partial void OnWindowXChanged(double value)
{
WindowBounds = WindowBounds.WithX(value);
}
partial void OnWindowYChanged(double value)
{
WindowBounds = WindowBounds.WithY(value);
}
partial void OnWindowWidthChanged(double value)
{
WindowBounds = WindowBounds.WithWidth(value);
}
partial void OnWindowHeightChanged(double value)
{
WindowBounds = WindowBounds.WithHeight(value);
}
partial void OnLyricsStyleSettingsChanged(LyricsStyleSettings oldValue, LyricsStyleSettings newValue)
{
oldValue.PropertyChanged -= OldLyricsStyleSettings_PropertyChanged;
@@ -168,12 +192,19 @@ namespace BetterLyrics.WinUI3.Models
return new LyricsWindowStatus
{
Name = App.ResourceLoader!.GetString("DesktopMode"),
WindowBounds = new Rect(100, 100, 400, 250),
LyricsDisplayType = LyricsDisplayType.LyricsOnly,
WindowBounds = new Rect(100, 100, 600, 250),
IsAlwaysOnTop = true,
IsAlwaysOnTopPolling = true,
IsBorderless = true,
IsClickThrough = true,
IsAdaptToEnvironment = true,
EnvironmentSampleMode = Enums.WindowPixelSampleMode.WindowEdge,
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
LyricsStyleSettings = new()
{
LyricsFontSize = 20,
LyricsAlignmentType = TextAlignmentType.Center,
},
LyricsBackgroundSettings = new LyricsBackgroundSettings
{
IsPureColorOverlayEnabled = false,

View File

@@ -36,7 +36,7 @@ namespace BetterLyrics.WinUI3.Models
PositionOffset = 0;
}
public MediaSourceProviderInfo(string provider, bool isEnable = true) : base()
public MediaSourceProviderInfo(string provider, bool isEnable = true)
{
IsEnabled = isEnable;
switch (provider)
@@ -54,6 +54,12 @@ namespace BetterLyrics.WinUI3.Models
}
Provider = provider;
AlbumArtSearchProvidersInfo.ItemPropertyChanged += AlbumArtSearchProvidersInfo_ItemPropertyChanged;
AlbumArtSearchProvidersInfo.CollectionChanged += AlbumArtSearchProvidersInfo_CollectionChanged;
LyricsSearchProvidersInfo.ItemPropertyChanged += LyricsSearchProvidersInfo_ItemPropertyChanged;
LyricsSearchProvidersInfo.CollectionChanged += LyricsSearchProvidersInfo_CollectionChanged;
}
partial void OnAlbumArtSearchProvidersInfoChanged(FullyObservableCollection<AlbumArtSearchProviderInfo> oldValue, FullyObservableCollection<AlbumArtSearchProviderInfo> newValue)

View File

@@ -13,7 +13,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Language Language { get; set; } = Language.FollowSystem;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LXMusicServer { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ShowOrHideLyricsWindowShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "H" };
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsImmersiveMode { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ListenOnNewPlaybackSource { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> BorderlessShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "B" };

View File

@@ -38,7 +38,7 @@ namespace BetterLyrics.WinUI3.Renderer
private async void LyricsCanvas_CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{
await ViewModel.CreateResourcesAsync();
await ViewModel.CreateResourcesAsync(sender);
}
}
}

View File

@@ -721,6 +721,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>Fullscreen mode</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>Height</value>
</data>
<data name="SettingsPageHideWindow.Description" xml:space="preserve">
<value>Automatically hide/show lyric window when music is not playing</value>
</data>
@@ -1207,6 +1210,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>Version</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>Width</value>
</data>
<data name="SettingsPageWindowBounds.Header" xml:space="preserve">
<value>Window bounds</value>
</data>
<data name="SettingsPageWorkArea.Description" xml:space="preserve">
<value>As a separate work area docked to the upper/lower edge of the screen</value>
</data>

View File

@@ -721,6 +721,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>フルスクリーンモード</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高さ</value>
</data>
<data name="SettingsPageHideWindow.Description" xml:space="preserve">
<value>音楽が再生されていないときに、自動的に歌詞ウィンドウを非表示/表示します</value>
</data>
@@ -1207,6 +1210,12 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>バージョン</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>幅</value>
</data>
<data name="SettingsPageWindowBounds.Header" xml:space="preserve">
<value>ウィンドウ境界</value>
</data>
<data name="SettingsPageWorkArea.Description" xml:space="preserve">
<value>画面の上下端にドッキングされた別の作業エリアとして</value>
</data>

View File

@@ -721,6 +721,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>전체화면 모드</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>신장</value>
</data>
<data name="SettingsPageHideWindow.Description" xml:space="preserve">
<value>음악이 재생되지 않을 때 자동으로 가사 창 숨기기/표시</value>
</data>
@@ -1207,6 +1210,12 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>버전</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>너비</value>
</data>
<data name="SettingsPageWindowBounds.Header" xml:space="preserve">
<value>창 범위</value>
</data>
<data name="SettingsPageWorkArea.Description" xml:space="preserve">
<value>화면의 상단/하단 가장자리에 고정된 별도의 작업 영역으로</value>
</data>

View File

@@ -721,6 +721,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>全屏模式</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高度</value>
</data>
<data name="SettingsPageHideWindow.Description" xml:space="preserve">
<value>音乐未播放/播放时自动隐藏/显示歌词窗口</value>
</data>
@@ -1207,6 +1210,12 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本号</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>宽度</value>
</data>
<data name="SettingsPageWindowBounds.Header" xml:space="preserve">
<value>窗口边界</value>
</data>
<data name="SettingsPageWorkArea.Description" xml:space="preserve">
<value>作为一个独立的工作区域停靠在屏幕的上/下边缘</value>
</data>

View File

@@ -721,6 +721,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>全螢幕模式</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高度</value>
</data>
<data name="SettingsPageHideWindow.Description" xml:space="preserve">
<value>音樂未播放/播放時自動隱藏/顯示歌詞視窗</value>
</data>
@@ -1207,6 +1210,12 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本號</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>寬度</value>
</data>
<data name="SettingsPageWindowBounds.Header" xml:space="preserve">
<value>窗戶邊界</value>
</data>
<data name="SettingsPageWorkArea.Description" xml:space="preserve">
<value>作為一個獨立的工作區域停靠在螢幕的上/下邊緣</value>
</data>

View File

@@ -23,7 +23,6 @@ using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class LyricsPageViewModel : BaseViewModel,
IRecipient<PropertyChangedMessage<bool>>,
IRecipient<PropertyChangedMessage<TimeSpan>>
{
private readonly IMediaSessionsService _mediaSessionsService;
@@ -39,10 +38,6 @@ namespace BetterLyrics.WinUI3.ViewModels
LiveStates = _liveStatesService.LiveStates;
IsImmersiveMode = _settingsService.AppSettings.GeneralSettings.IsImmersiveMode;
OnIsImmersiveModeChanged(IsImmersiveMode);
//Volume = SystemVolumeHelper.GetMasterVolume();
//SystemVolumeHelper.VolumeChanged += SystemVolumeHelper_VolumeChanged;
@@ -87,9 +82,6 @@ namespace BetterLyrics.WinUI3.ViewModels
[ObservableProperty]
public partial int Volume { get; set; }
[ObservableProperty]
public partial bool IsImmersiveMode { get; set; }
[ObservableProperty]
public partial double BottomCommandGridOpacity { get; set; }
@@ -111,16 +103,6 @@ namespace BetterLyrics.WinUI3.ViewModels
[ObservableProperty]
public partial double TimelineSliderThumbSeconds { get; set; } = 0;
public void Receive(PropertyChangedMessage<bool> message)
{
if (message.Sender is LyricsWindowViewModel)
{
if (message.PropertyName == nameof(LyricsWindowViewModel.IsImmersiveMode))
{
IsImmersiveMode = message.NewValue;
}
}
}
[RelayCommand]
private static void OpenSettingsWindow()
@@ -152,20 +134,6 @@ namespace BetterLyrics.WinUI3.ViewModels
await _mediaSessionsService.NextAsync();
}
partial void OnIsImmersiveModeChanged(bool value)
{
if (value)
{
BottomCommandGridOpacity = 0f;
BottomCommandFlyoutTriggerOpacity = 0f;
}
else
{
BottomCommandGridOpacity = 1f;
BottomCommandFlyoutTriggerOpacity = 1f;
}
}
partial void OnTimelineSliderThumbSecondsChanged(double value)
{
TimelineSliderThumbLyricsLine = _mediaSessionsService.CurrentLyricsData?.GetLyricsLine(value);

View File

@@ -1,6 +1,9 @@
using BetterLyrics.WinUI3.Helper;
using CommunityToolkit.WinUI;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
using Microsoft.UI;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -16,12 +19,18 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
private PixelShaderEffect? _effect;
public async Task CreateResourcesAsync()
public async Task CreateResourcesAsync(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl control)
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/effect.bin"));
IBuffer buffer = await FileIO.ReadBufferAsync(file);
var bytes = buffer.ToArray();
_effect = new PixelShaderEffect(bytes);
_effect.Properties["Width"] = Convert.ToSingle(control.ConvertDipsToPixels((float)control.Size.Width, CanvasDpiRounding.Round));
_effect.Properties["Height"] = Convert.ToSingle(control.ConvertDipsToPixels((float)control.Size.Height, CanvasDpiRounding.Round));
_effect.Properties["color1"] = Colors.Black.ToVector3RGB();
_effect.Properties["color2"] = Colors.Black.ToVector3RGB();
_effect.Properties["color3"] = Colors.Black.ToVector3RGB();
_effect.Properties["color4"] = Colors.Black.ToVector3RGB();
_effect.Properties["EnableLightWave"] = false;
}
}

View File

@@ -44,7 +44,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
}
else
{
FillBackground(control, combinedDs, _albumArtAccentColorTransition.Value, 0f,
FillBackground(control, combinedDs, _albumArtAccentColor1Transition.Value, 0f,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PureColorOverlayOpacity / 100.0);
}
}
@@ -153,7 +153,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
using var geometry = CanvasGeometry.CreatePath(pathBuilder);
var gradientStops = new CanvasGradientStop[]
{
new() { Position = 0.0f, Color = _albumArtAccentColorTransition.Value },
new() { Position = 0.0f, Color = _albumArtAccentColor1Transition.Value },
new() { Position = 1.0f, Color = Colors.Transparent }
};
@@ -360,7 +360,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
var shadowEffectMask = CanvasHelper.GetAlphaMask(control, charMask, lineStartToCharMask, lineMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsShadowScope);
using var foregroundShadowEffect = CanvasHelper.CreateForegroundShadowEffect(foregroundFontEffect, shadowEffectMask,
_albumArtAccentColorTransition.Value, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsShadowAmount);
_albumArtAccentColor1Transition.Value, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsShadowAmount);
effectLayerDs.DrawImage(foregroundShadowEffect);
}
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.IsLyricsGlowEffectEnabled)

View File

@@ -96,7 +96,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
/// <para><seealso cref="_isCoverAcrylicEffectAmountChanged"/> == true</para>
/// <para><seealso cref="_isAlbumArtBgOpacityChanged"/> == true</para>
/// <para><seealso cref="_albumArtBgTransition"/> 正在变化</para>
/// <para><seealso cref="_albumArtAccentColorTransition"/> 正在变化</para>
/// <para><seealso cref="_albumArtAccentColor1Transition"/> 正在变化</para>
/// 如果上述条件均不满足,需调用 <seealso cref="UpdateAlbumArtBgRenderTarget"/> 来更新渲染缓存
/// </summary>
/// <param name="control"></param>
@@ -190,7 +190,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
/// <para><seealso cref="_albumArtChanged"/> == true</para>
/// <para><seealso cref="_isAlbumArtShadowAmountChanged"/> == true</para>
/// <para><seealso cref="_albumArtBgTransition"/> 正在变化</para>
/// <para><seealso cref="_albumArtAccentColorTransition"/> 正在变化</para>
/// <para><seealso cref="_albumArtAccentColor1Transition"/> 正在变化</para>
/// 如果上述条件均不满足,需调用 <seealso cref="UpdateAlbumArtRenderTarget"/> 来更新渲染缓存
/// </summary>
/// <param name="control"></param>
@@ -223,7 +223,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
combinedDs.DrawImage(new ShadowEffect
{
Source = overlappedCovers,
ShadowColor = _albumArtAccentColorTransition.Value,
ShadowColor = _albumArtAccentColor1Transition.Value,
BlurAmount = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageShadowAmount,
Optimization = EffectOptimization.Speed,
});

View File

@@ -24,7 +24,25 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
);
private readonly ValueTransition<Color> _albumArtAccentColorTransition = new(
private readonly ValueTransition<Color> _albumArtAccentColor1Transition = new(
initialValue: Colors.Transparent,
durationSeconds: 0.3f,
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
);
private readonly ValueTransition<Color> _albumArtAccentColor2Transition = new(
initialValue: Colors.Transparent,
durationSeconds: 0.3f,
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
);
private readonly ValueTransition<Color> _albumArtAccentColor3Transition = new(
initialValue: Colors.Transparent,
durationSeconds: 0.3f,
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)
);
private readonly ValueTransition<Color> _albumArtAccentColor4Transition = new(
initialValue: Colors.Transparent,
durationSeconds: 0.3f,
interpolator: (from, to, progress) => Helper.ColorHelper.GetInterpolatedColor(progress, from, to)

View File

@@ -71,7 +71,31 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
}
}
_effect?.Properties["iTime"] = Convert.ToSingle(TotalTime.TotalSeconds);
//_effect?.Properties["iTime"] = Convert.ToSingle(TotalTime.TotalSeconds);
if (_effect != null)
{
var effectTime = Convert.ToSingle(_effect.Properties["iTime"]);
effectTime += Convert.ToSingle(_elapsedTime.TotalSeconds);
_effect.Properties["iTime"] = effectTime;
if (_albumArtAccentColor1Transition.IsTransitioning)
{
_effect.Properties["color1"] = _albumArtAccentColor1Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor2Transition.IsTransitioning)
{
_effect.Properties["color2"] = _albumArtAccentColor2Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor3Transition.IsTransitioning)
{
_effect.Properties["color3"] = _albumArtAccentColor3Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor4Transition.IsTransitioning)
{
_effect.Properties["color4"] = _albumArtAccentColor4Transition.Value.ToVector3RGB();
}
}
// 检测播放行变更
var playingLineIndex = GetCurrentPlayingLineIndex();
@@ -138,8 +162,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
_isCoverAcrylicEffectAmountChanged = true;
_effect?.Properties["Width"] = Convert.ToSingle(_canvasWidth);
_effect?.Properties["Height"] = Convert.ToSingle(_canvasHeight);
_effect?.Properties["Width"] = (float)control.ConvertDipsToPixels((float)_canvasWidth, CanvasDpiRounding.Round);
_effect?.Properties["Height"] = (float)control.ConvertDipsToPixels((float)_canvasHeight, CanvasDpiRounding.Round);
}
if (_isSongInfoFontSizeChanged || _isSongTitleVisibilityChanged || _isSongArtistsVisibilityChanged)
@@ -390,7 +414,12 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_albumArtOpacityTransition.Update(_elapsedTime);
_immersiveBgOpacityTransition.Update(_elapsedTime);
_immersiveBgColorTransition.Update(_elapsedTime);
_albumArtAccentColorTransition.Update(_elapsedTime);
_albumArtAccentColor1Transition.Update(_elapsedTime);
_albumArtAccentColor2Transition.Update(_elapsedTime);
_albumArtAccentColor3Transition.Update(_elapsedTime);
_albumArtAccentColor4Transition.Update(_elapsedTime);
_albumArtBgTransition.Update(_elapsedTime);
_lyricsBgBrightnessTransition.Update(_elapsedTime);
_songInfoOpacityTransition.Update(_elapsedTime);
@@ -558,24 +587,20 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_adaptiveGrayedFontColor = _darkColor;
brightness = 0.7f;
_grayedEnvironmentalColor = _lightColor;
_albumArtAccentColorTransition.StartTransition(_albumArtLightAccentColors.FirstOrDefault());
_effect?.Properties["color1"] = _albumArtLightAccentColors.ElementAtOrDefault(0).ToVector3RGB();
_effect?.Properties["color2"] = _albumArtLightAccentColors.ElementAtOrDefault(1).ToVector3RGB();
_effect?.Properties["color3"] = _albumArtLightAccentColors.ElementAtOrDefault(2).ToVector3RGB();
_effect?.Properties["color4"] = _albumArtLightAccentColors.ElementAtOrDefault(3).ToVector3RGB();
_albumArtAccentColor1Transition.StartTransition(_albumArtLightAccentColors.ElementAtOrDefault(0));
_albumArtAccentColor2Transition.StartTransition(_albumArtLightAccentColors.ElementAtOrDefault(1));
_albumArtAccentColor3Transition.StartTransition(_albumArtLightAccentColors.ElementAtOrDefault(2));
_albumArtAccentColor4Transition.StartTransition(_albumArtLightAccentColors.ElementAtOrDefault(3));
}
else
{
_adaptiveGrayedFontColor = _lightColor;
brightness = 0.3f;
_grayedEnvironmentalColor = _darkColor;
_albumArtAccentColorTransition.StartTransition(_albumArtDarkAccentColors.FirstOrDefault());
_effect?.Properties["color1"] = _albumArtDarkAccentColors.ElementAtOrDefault(0).ToVector3RGB();
_effect?.Properties["color2"] = _albumArtDarkAccentColors.ElementAtOrDefault(1).ToVector3RGB();
_effect?.Properties["color3"] = _albumArtDarkAccentColors.ElementAtOrDefault(2).ToVector3RGB();
_effect?.Properties["color4"] = _albumArtDarkAccentColors.ElementAtOrDefault(3).ToVector3RGB();
_albumArtAccentColor1Transition.StartTransition(_albumArtDarkAccentColors.ElementAtOrDefault(0));
_albumArtAccentColor2Transition.StartTransition(_albumArtDarkAccentColors.ElementAtOrDefault(1));
_albumArtAccentColor3Transition.StartTransition(_albumArtDarkAccentColors.ElementAtOrDefault(2));
_albumArtAccentColor4Transition.StartTransition(_albumArtDarkAccentColors.ElementAtOrDefault(3));
}
_lyricsBgBrightnessTransition.StartTransition(brightness);

View File

@@ -49,9 +49,6 @@ namespace BetterLyrics.WinUI3
AppSettings = _settingsService.AppSettings;
LiveStates = _liveStatesService.LiveStates;
IsImmersiveMode = _settingsService.AppSettings.GeneralSettings.IsImmersiveMode;
OnIsImmersiveModeChanged(_settingsService.AppSettings.GeneralSettings.IsImmersiveMode);
_mediaSessionsService.IsPlayingChanged += PlaybackService_IsPlayingChanged;
}
@@ -69,9 +66,7 @@ namespace BetterLyrics.WinUI3
/// </summary>
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Color BackdropAccentColor { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsImmersiveMode { get; set; }
[ObservableProperty] public partial double TopCommandGridOpacity { get; set; }
[ObservableProperty] public partial double TopCommandGridOpacity { get; set; } = 0;
[ObservableProperty] public partial ElementTheme ThemeType { get; set; } = ElementTheme.Default;
@@ -79,18 +74,6 @@ namespace BetterLyrics.WinUI3
[ObservableProperty] public partial Visibility CloseButtonVisibility { get; set; } = Visibility.Visible;
partial void OnIsImmersiveModeChanged(bool value)
{
if (value)
{
TopCommandGridOpacity = 0f;
}
else
{
TopCommandGridOpacity = 1f;
}
}
public void InitShortcuts()
{
UpdateLyricsWindowBorderlessShortcut();
@@ -205,12 +188,6 @@ namespace BetterLyrics.WinUI3
_liveStatesService.RefreshLyricsWindowStatus();
}
[RelayCommand]
private void OnImmersiveToggleButtonEnabledChanged()
{
_settingsService.AppSettings.GeneralSettings.IsImmersiveMode = IsImmersiveMode;
}
public void Receive(PropertyChangedMessage<List<string>> message)
{
if (message.Sender is GeneralSettings)

View File

@@ -34,7 +34,7 @@ namespace BetterLyrics.WinUI3.Views
private void BottomCommandGrid_PointerEntered(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode && BottomCommandGrid.Children.Count != 0)
if (BottomCommandGrid.Children.Count != 0)
{
ViewModel.BottomCommandGridOpacity = 1f;
}
@@ -43,7 +43,7 @@ namespace BetterLyrics.WinUI3.Views
private void BottomCommandGrid_PointerExited(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode && BottomCommandGrid.Children.Count != 0)
if (BottomCommandGrid.Children.Count != 0)
{
ViewModel.BottomCommandGridOpacity = 0f;
}
@@ -90,7 +90,7 @@ namespace BetterLyrics.WinUI3.Views
private void BottomCommandFlyoutTrigger_PointerEntered(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode && BottomCommandFlyoutContainer.Children.Count != 0)
if (BottomCommandFlyoutContainer.Children.Count != 0)
{
ViewModel.BottomCommandFlyoutTriggerOpacity = 1f;
}
@@ -98,7 +98,7 @@ namespace BetterLyrics.WinUI3.Views
private void BottomCommandFlyoutTrigger_PointerExited(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode && BottomCommandFlyoutContainer.Children.Count != 0)
if (BottomCommandFlyoutContainer.Children.Count != 0)
{
ViewModel.BottomCommandFlyoutTriggerOpacity = 0f;
}

View File

@@ -56,20 +56,6 @@
<ToolTip x:Uid="HostWindowMusicGalleryButtonToolTip" />
</ToolTipService.ToolTip>
</Button>
<!-- Immersive mode -->
<ToggleButton
x:Name="ImmersiveButton"
Command="{x:Bind ViewModel.ImmersiveToggleButtonEnabledChangedCommand}"
IsChecked="{x:Bind ViewModel.IsImmersiveMode, Mode=TwoWay}"
Style="{StaticResource TitleBarToggleButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip x:Uid="LyricsWindowImmersiveButtonToolTip" />
</ToolTipService.ToolTip>
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="{x:Bind ViewModel.TitleBarFontSize}"
Glyph="&#xED1A;" />
</ToggleButton>
</StackPanel>
</Grid>

View File

@@ -95,24 +95,22 @@ namespace BetterLyrics.WinUI3.Views
else
{
_liveStatesService.LiveStates.LyricsWindowStatus.WindowBounds = new Windows.Foundation.Rect(rect.X, rect.Y, size.Width, size.Height);
_liveStatesService.LiveStates.LyricsWindowStatus.WindowX = rect.X;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowY = rect.Y;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowWidth = size.Width;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowHeight = size.Height;
}
}
}
private void TopCommandGrid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode)
{
ViewModel.TopCommandGridOpacity = 1f;
}
ViewModel.TopCommandGridOpacity = 1f;
}
private void TopCommandGrid_PointerExited(object sender, PointerRoutedEventArgs e)
{
if (ViewModel.IsImmersiveMode)
{
ViewModel.TopCommandGridOpacity = 0f;
}
ViewModel.TopCommandGridOpacity = 0f;
}
private void MusicGalleryButton_Click(object sender, RoutedEventArgs e)

View File

@@ -182,7 +182,7 @@ Watch our introduction video (uploaded on 18 Aug 2025) on Bilibili [here](https:
If you are using a third-party modified Windows, you probably can not launch the app.
To solve this issue, please try to download from [Google Drive (v1.0.79.0)](https://drive.google.com/file/d/1YT8Cg5unPoNJO0FBR9s4w7T2pCLIZQz9/view?usp=sharing) (may not be the latest version) and follow the instructions [here](https://github.com/jayfunc/BetterLyrics/blob/dev/How2Install/How2Install.md).
To solve this issue, please try to download from [Google Drive (v1.0.82.0)](https://drive.google.com/file/d/1UtGmmDqD5SWGJpp4LmWycHUT9-Bb8fur/view?usp=sharing) (may not be the latest version) and follow the instructions [here](https://github.com/jayfunc/BetterLyrics/blob/dev/How2Install/How2Install.md).
## Build