This commit is contained in:
Zhe Fang
2025-11-28 18:25:20 -05:00
parent 2099332f02
commit bbda1cd797
31 changed files with 1758 additions and 1071 deletions

View File

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

View File

@@ -26,6 +26,7 @@
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
<None Remove="Controls\AppSettingsControl.xaml" />
<None Remove="Controls\DemoWindowGrid.xaml" />
<None Remove="Controls\Dragger.xaml" />
<None Remove="Controls\ExtendedSlider.xaml" />
<None Remove="Controls\FontFamilyAutoSuggestBox.xaml" />
<None Remove="Controls\LyricsSearchControl.xaml" />
@@ -57,6 +58,7 @@
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
@@ -334,6 +336,11 @@
<ItemGroup>
<Folder Include="TemplateSelector\" />
</ItemGroup>
<ItemGroup>
<Page Update="Controls\Dragger.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\PropertyRow.xaml">
<Generator>MSBuild:Compile</Generator>

View File

@@ -3,6 +3,7 @@
public class ExtendedGenreFiled
{
public const string NetEaseCloudMusicTrackID = "NCM-";
public const string QQMusicTrackID = "QQ-";
public const string FileName = "FILENAME-";
}
}

View File

@@ -4,7 +4,7 @@ namespace BetterLyrics.WinUI3.Constants
{
public static class Time
{
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(300);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(500);
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(250);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(250);
}
}

View File

@@ -18,26 +18,13 @@
<TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander
x:Uid="SettingsPageAlbumArtSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE744;}"
IsExpanded="True">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider
Frequency="2"
Maximum="800"
Minimum="10"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind AlbumArtLayoutSettings.AlbumArtSize, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind AlbumArtLayoutSettings.AlbumArtAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLeft" />
<ComboBoxItem x:Uid="SettingsPageCenter" />
<ComboBoxItem x:Uid="SettingsPageRight" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEA3A;}">
<local:ExtendedSlider
@@ -58,11 +45,11 @@
<TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<dev:SettingsCard x:Uid="SettingsPageAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageSongInfoLeft" />
<ComboBoxItem x:Uid="SettingsPageSongInfoCenter" />
<ComboBoxItem x:Uid="SettingsPageSongInfoRight" />
<ComboBoxItem x:Uid="SettingsPageLeft" />
<ComboBoxItem x:Uid="SettingsPageCenter" />
<ComboBoxItem x:Uid="SettingsPageRight" />
</ComboBox>
</dev:SettingsCard>

View File

@@ -0,0 +1,25 @@
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.Dragger"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
Background="Transparent"
PointerCanceled="Grid_PointerReleased"
PointerEntered="Grid_PointerEntered"
PointerExited="Grid_PointerExited"
PointerMoved="Grid_PointerMoved"
PointerPressed="Grid_PointerPressed"
PointerReleased="Grid_PointerReleased">
<Border x:Name="HitArea" Background="{ThemeResource SystemControlForegroundBaseMediumLowBrush}">
<Grid
x:Name="HandlePill"
Background="{ThemeResource TextFillColorSecondaryBrush}"
CornerRadius="4" />
</Border>
</Grid>
</UserControl>

View File

@@ -0,0 +1,136 @@
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System;
using Windows.Foundation;
namespace BetterLyrics.WinUI3.Controls
{
public class DragDeltaEventArgs : EventArgs
{
public double HorizontalChange { get; }
public double VerticalChange { get; }
public DragDeltaEventArgs(double hChange, double vChange)
{
HorizontalChange = hChange;
VerticalChange = vChange;
}
}
public sealed partial class Dragger : UserControl
{
public event EventHandler DragStarted;
public event EventHandler<DragDeltaEventArgs> DragDelta;
public event EventHandler DragCompleted;
private bool _isDragging = false;
private Point _lastPoint;
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register(nameof(Orientation), typeof(Orientation), typeof(Dragger),
new PropertyMetadata(Orientation.Vertical, OnOrientationChanged));
public Orientation Orientation
{
get => (Orientation)GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (Dragger)d;
control.UpdateVisuals();
}
public Dragger()
{
this.InitializeComponent();
this.Loaded += (s, e) => UpdateVisuals();
}
private void UpdateVisuals()
{
if (Orientation == Orientation.Vertical)
{
this.ProtectedCursor = InputSystemCursor.Create(InputSystemCursorShape.SizeWestEast);
this.Width = 16;
this.Height = double.NaN; // Auto
if (HitArea != null && HandlePill != null)
{
HitArea.Width = 16;
HitArea.Height = double.NaN;
HandlePill.Width = 8;
HandlePill.Height = 32;
}
}
else
{
this.ProtectedCursor = InputSystemCursor.Create(InputSystemCursorShape.SizeNorthSouth);
this.Height = 16;
this.Width = double.NaN; // Auto
if (HitArea != null && HandlePill != null)
{
HitArea.Height = 16;
HitArea.Width = double.NaN;
HandlePill.Height = 8;
HandlePill.Width = 32;
}
}
}
private void Grid_PointerEntered(object sender, PointerRoutedEventArgs e)
{
}
private void Grid_PointerExited(object sender, PointerRoutedEventArgs e)
{
}
private void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var element = sender as UIElement;
if (element.CapturePointer(e.Pointer))
{
_isDragging = true;
_lastPoint = e.GetCurrentPoint(this.XamlRoot.Content).Position;
DragStarted?.Invoke(this, EventArgs.Empty);
}
}
private void Grid_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (_isDragging)
{
var currentPoint = e.GetCurrentPoint(this.XamlRoot.Content).Position;
double dx = currentPoint.X - _lastPoint.X;
double dy = currentPoint.Y - _lastPoint.Y;
if (dx != 0 || dy != 0)
{
DragDelta?.Invoke(this, new DragDeltaEventArgs(dx, dy));
_lastPoint = currentPoint;
}
}
}
private void Grid_PointerReleased(object sender, PointerRoutedEventArgs e)
{
if (_isDragging)
{
var element = sender as UIElement;
_isDragging = false;
element.ReleasePointerCapture(e.Pointer);
DragCompleted?.Invoke(this, EventArgs.Empty);
}
}
}
}

View File

@@ -23,9 +23,9 @@
<dev:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
<ComboBoxItem x:Uid="SettingsPageLeft" />
<ComboBoxItem x:Uid="SettingsPageCenter" />
<ComboBoxItem x:Uid="SettingsPageRight" />
</ComboBox>
</dev:SettingsCard>

View File

@@ -171,6 +171,15 @@
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="Layout">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLayout"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="AlbumArtStyle">
<PivotItem.Header>
<TextBlock
@@ -207,15 +216,6 @@
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="Advanced">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAdvanced"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
</Pivot>
</StackPanel>
@@ -228,7 +228,7 @@
</TransitionCollection>
</controls:SwitchPresenter.ContentTransitions>
<!-- General -->
<!-- Window -->
<controls:Case Value="General">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
@@ -246,26 +246,6 @@
</StackPanel>
</dev:SettingsCard>
<dev:SettingsExpander
x:Uid="SettingsPageDisplayTypeSwitcher"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF246;}"
IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.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}}">
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
</ComboBox>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageWorkArea"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
@@ -375,37 +355,6 @@
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" />
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</controls:Case>
<!-- Album art area style -->
<controls:Case Value="AlbumArtStyle">
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics style -->
<controls:Case Value="LyricsStyle">
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics effect -->
<controls:Case Value="LyricsEffect">
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics background -->
<controls:Case Value="LyricsBackground">
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
</controls:Case>
<!-- Advanced -->
<controls:Case Value="Advanced">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<dev:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C4;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" />
</dev:SettingsCard>
@@ -431,6 +380,155 @@
</ScrollViewer>
</controls:Case>
<!-- Layout -->
<controls:Case Value="Layout">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander x:Uid="SettingsPageDisplayTypeSwitcher" IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.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}}">
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
</ComboBox>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageShowLayoutDragger">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.ShowLayoutIndicator, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageGeneralLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageLeftGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LeftGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageTopGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TopGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageRightGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.RightGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageBottomGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.BottomGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageHorizontalLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageTrackSummaryColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TrackSummaryColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageMiddleGapColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MiddleColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageVerticalLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageTrackSummaryRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TrackSummaryRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageMiddleGapRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MiddleRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</controls:Case>
<!-- Album art area style -->
<controls:Case Value="AlbumArtStyle">
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics style -->
<controls:Case Value="LyricsStyle">
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics effect -->
<controls:Case Value="LyricsEffect">
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics background -->
<controls:Case Value="LyricsBackground">
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
</controls:Case>
</controls:SwitchPresenter>
</Grid>

View File

@@ -5,11 +5,13 @@ using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Logic;
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.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
@@ -23,17 +25,23 @@ using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using Windows.Foundation;
using Windows.UI;
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class NowPlayingCanvas : UserControl,
IRecipient<PropertyChangedMessage<int>>,
IRecipient<PropertyChangedMessage<Color>>,
IRecipient<PropertyChangedMessage<BitmapImage?>>,
IRecipient<PropertyChangedMessage<TimeSpan>>,
IRecipient<PropertyChangedMessage<LyricsData?>>,
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>,
IRecipient<PropertyChangedMessage<double>>,
IRecipient<PropertyChangedMessage<bool>>,
IRecipient<PropertyChangedMessage<TextAlignmentType>>,
IRecipient<PropertyChangedMessage<SongInfo?>>
{
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
@@ -100,6 +108,8 @@ namespace BetterLyrics.WinUI3.Controls
private double _renderLyricsHeight = 0;
private double _renderLyricsOpacity = 0;
private LyricsData? _lyricsData;
private bool _isLayoutChanged = true;
private int _playingLineIndex;
private (int Start, int End) _visibleRange;
@@ -162,11 +172,16 @@ namespace BetterLyrics.WinUI3.Controls
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<int>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<Color>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<BitmapImage?>>(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);
_themeManager = new(_mediaSessionsService);
}
@@ -196,7 +211,7 @@ namespace BetterLyrics.WinUI3.Controls
canvas._renderLyricsOpacity = Convert.ToDouble(e.NewValue);
}
canvas.TriggerRelayout();
canvas._isLayoutChanged = true;
}
}
@@ -212,7 +227,7 @@ namespace BetterLyrics.WinUI3.Controls
var lyricsStyle = status.LyricsStyleSettings;
var lyricsEffect = status.LyricsEffectSettings;
var lyricsData = _mediaSessionsService.CurrentLyricsData;
var lyricsData = _lyricsData;
double songDuration = _mediaSessionsService.CurrentSongInfo?.DurationMs ?? 0;
bool isForceWordByWord = _settingsService.AppSettings.GeneralSettings.IsForceWordByWordEffect;
@@ -253,13 +268,15 @@ namespace BetterLyrics.WinUI3.Controls
_lyricsRenderer.Draw(
control: sender,
ds: args.DrawingSession,
lyricsData: _mediaSessionsService.CurrentLyricsData,
lyricsData: _lyricsData,
playingLineIndex: _playingLineIndex,
startVisibleIndex: _visibleRange.Start,
endVisibleIndex: _visibleRange.End,
canvasHeight: sender.Size.Height,
lyricsX: _renderLyricsStartX,
lyricsY: _renderLyricsStartY,
lyricsWidth: _renderLyricsWidth,
lyricsHeight: _renderLyricsHeight,
lyricsOpacity: _renderLyricsOpacity,
windowStatus: status,
strokeColor: _currentThemeColors.StrokeFontColor,
bgColor: _currentThemeColors.BgFontColor,
@@ -297,6 +314,19 @@ namespace BetterLyrics.WinUI3.Controls
);
}
#if DEBUG
args.DrawingSession.DrawText(
$"[DEBUG]\n" +
$"Lyrics start pos: ({(int)_renderLyricsStartX}, {(int)_renderLyricsStartY})\n" +
$"Lyrics size: [{(int)_renderLyricsWidth} x {(int)_renderLyricsHeight}]\n" +
$"Playing line (idx): {_playingLineIndex}\n" +
$"Visible lines range (idx): [{_visibleRange.Start}, {_visibleRange.End}]\n" +
$"Total line count: {GetMaxLyricsLineIndexBoundaries().Item2 + 1}\n" +
$"Played: {TimeSpan.FromMilliseconds(fixedSongPositionMs)} / {TimeSpan.FromMilliseconds(_mediaSessionsService.CurrentSongInfo?.DurationMs ?? 0)}\n" +
$"Y offset: {_canvasYScrollTransition.Value}",
new Vector2(10, 40), Colors.Red);
#endif
}
private void Canvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs args)
@@ -316,9 +346,11 @@ namespace BetterLyrics.WinUI3.Controls
UpdatePlaybackState(elapsedTime);
TriggerRelayout();
#region UpdatePlayingLineIndex
int newPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPosition.TotalMilliseconds, _mediaSessionsService.CurrentLyricsData);
int newPlayingIndex = _synchronizer.GetCurrentLineIndex(_songPosition.TotalMilliseconds, _lyricsData);
bool isPlayingLineChanged = newPlayingIndex != _playingLineIndex;
_playingLineIndex = newPlayingIndex;
@@ -326,22 +358,27 @@ namespace BetterLyrics.WinUI3.Controls
#region UpdateTargetScrollOffset
var targetScroll = _layoutManager.CalculateTargetScrollOffset(_mediaSessionsService.CurrentLyricsData, _playingLineIndex);
if (targetScroll.HasValue) _canvasTargetScrollOffset = targetScroll.Value;
if (isPlayingLineChanged || _isLayoutChanged)
{
var targetScroll = _layoutManager.CalculateTargetScrollOffset(_lyricsData, _playingLineIndex);
if (targetScroll.HasValue) _canvasTargetScrollOffset = targetScroll.Value;
_canvasYScrollTransition.StartTransition(_canvasTargetScrollOffset);
_canvasYScrollTransition.StartTransition(_canvasTargetScrollOffset, _isLayoutChanged);
}
_canvasYScrollTransition.Update(elapsedTime);
#endregion
_visibleRange = _layoutManager.CalculateVisibleRange(
_mediaSessionsService.CurrentLyricsData?.LyricsLines,
_lyricsData?.LyricsLines,
_canvasYScrollTransition.Value, // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
_renderLyricsStartY,
_renderLyricsHeight,
sender.Size.Height
);
_animator.UpdateVisibleLines(
_mediaSessionsService.CurrentLyricsData,
_lyricsData,
_visibleRange.Start,
_visibleRange.End,
_playingLineIndex,
@@ -415,6 +452,7 @@ namespace BetterLyrics.WinUI3.Controls
_snowRenderer.LoadResources();
_fogRenderer.LoadResources();
_isLayoutChanged = true;
TriggerRelayout();
}
@@ -450,19 +488,18 @@ namespace BetterLyrics.WinUI3.Controls
private void TriggerRelayout()
{
if (_layoutManager == null || _mediaSessionsService.CurrentLyricsData == null) return;
if (_layoutManager == null || _lyricsData == null || !_isLayoutChanged) return;
_layoutManager.MeasureAndArrange(
resourceCreator: Canvas,
lyricsData: _mediaSessionsService.CurrentLyricsData,
lyricsData: _lyricsData,
status: _liveStatesService.LiveStates.LyricsWindowStatus,
appSettings: _settingsService.AppSettings,
canvasWidth: Canvas.Size.Width,
canvasHeight: Canvas.Size.Height,
lyricsWidth: _renderLyricsWidth
lyricsWidth: _renderLyricsWidth,
lyricsHeight: _renderLyricsHeight
);
_isLayoutChanged = true;
}
private void UpdatePlaybackState(TimeSpan elapsedTime)
@@ -500,13 +537,13 @@ namespace BetterLyrics.WinUI3.Controls
private Tuple<int, int> GetMaxLyricsLineIndexBoundaries()
{
if (_mediaSessionsService.CurrentSongInfo == null
|| _mediaSessionsService.CurrentLyricsData == null
|| _mediaSessionsService.CurrentLyricsData.LyricsLines.Count == 0)
|| _lyricsData == null
|| _lyricsData.LyricsLines.Count == 0)
{
return new Tuple<int, int>(-1, -1);
}
return new Tuple<int, int>(0, _mediaSessionsService.CurrentLyricsData.LyricsLines.Count - 1);
return new Tuple<int, int>(0, _lyricsData.LyricsLines.Count - 1);
}
public void Receive(PropertyChangedMessage<Color> message)
@@ -575,13 +612,8 @@ namespace BetterLyrics.WinUI3.Controls
{
if (message.PropertyName == nameof(IMediaSessionsService.CurrentLyricsData))
{
DispatcherQueue.TryEnqueue(() =>
{
if (IsLoaded)
{
TriggerRelayout();
}
});
_lyricsData = message.NewValue;
_isLayoutChanged = true;
}
}
}
@@ -592,16 +624,110 @@ namespace BetterLyrics.WinUI3.Controls
{
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
{
DispatcherQueue.TryEnqueue(() =>
{
if (IsLoaded)
{
TriggerRelayout();
}
});
_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.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.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))
{
_isLayoutChanged = true;
}
}
}
public void Receive(PropertyChangedMessage<SongInfo?> message)
{
if (message.Sender is IMediaSessionsService)
{
if (message.PropertyName == nameof(IMediaSessionsService.CurrentSongInfo))
{
ResetPlaybackState();
}
}
}
}
}

View File

@@ -17,314 +17,6 @@ namespace BetterLyrics.WinUI3.Helper
{
public class CanvasHelper
{
public static CanvasLinearGradientBrush CreateHorizontalFillBrush(
ICanvasAnimatedControl control,
List<(double position, double opacity)> stops,
double startX,
double width
)
{
return new CanvasLinearGradientBrush(control, stops.Select(stops => new CanvasGradientStop
{
Position = (float)stops.position,
Color = Color.FromArgb((byte)(stops.opacity * 255), 128, 128, 128),
}).ToArray())
{
StartPoint = new Vector2((float)startX, 0),
EndPoint = new Vector2((float)(startX + width), 0),
};
}
/// <summary>
/// 背景层
/// </summary>
/// <param name="lyricsLayerOpacity">_lyricsOpacityTransition.Value</param>
public static OpacityEffect CreateBackgroundEffect(LyricsLine lyricsLine, CanvasCommandList backgroundFontEffect, double lyricsLayerOpacity)
{
if (lyricsLine.BlurAmountTransition.Value == 0)
{
return new OpacityEffect
{
Source = backgroundFontEffect,
Opacity = (float)Math.Clamp(lyricsLine.OriginalTextOpacityTransition.Value * lyricsLayerOpacity, 0, 1),
};
}
else
{
return new OpacityEffect
{
Source = new GaussianBlurEffect
{
Source = backgroundFontEffect,
BlurAmount = (float)Math.Max(lyricsLine.BlurAmountTransition.Value, 0),
BorderMode = EffectBorderMode.Soft,
Optimization = EffectOptimization.Speed,
},
Opacity = (float)Math.Clamp(lyricsLine.OriginalTextOpacityTransition.Value * lyricsLayerOpacity, 0, 1),
};
}
}
public static CanvasCommandList CreateFontEffect(LyricsLine lyricsLine, ICanvasAnimatedControl control, Color strokeColor, int strokeWidth, Color fontColor)
{
CanvasCommandList list = new(control);
using var ds = list.CreateDrawingSession();
return list;
}
/// <summary>
/// 创建辉光效果层
/// 仅需在布局重构 (Relayout) 时调用
/// </summary>
/// <param name="lineRenderingType">_lyricsGlowEffectScope</param>
/// <param name="glowEffectAmount">_lyricsGlowEffectAmount</param>
public static GaussianBlurEffect CreateForegroundBlurEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double glowEffectAmount)
{
return new GaussianBlurEffect
{
Source = new AlphaMaskEffect
{
Source = foregroundFontEffect,
AlphaMask = mask,
},
BlurAmount = (float)Math.Clamp(glowEffectAmount, 0, 100),
Optimization = EffectOptimization.Speed,
};
}
public static CanvasCommandList CreateCharMask(ICanvasAnimatedControl control, LyricsLine lyricsLine, int charStartIndex, int charLength, double charProgress)
{
var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession();
if (lyricsLine.OriginalCanvasTextLayout == null)
{
return mask;
}
var highlightRegion = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault();
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
// Draw the highlight for the current character
double highlightWidth = highlightTotalWidth * charProgress;
double fadingWidth = (double)highlightRegion.LayoutBounds.Height / 2;
// Rects
var highlightRect = new Rect(
highlightRegion.LayoutBounds.X,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
highlightWidth,
highlightRegion.LayoutBounds.Height
);
var fadeInRect = new Rect(
highlightRect.Right - fadingWidth,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth,
highlightRegion.LayoutBounds.Height
);
var fadeOutRect = new Rect(
highlightRect.Right,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth,
highlightRegion.LayoutBounds.Height
);
// Brushes
using var fadeInBrush = CanvasHelper.CreateHorizontalFillBrush(
control,
[(0f, 0f), (1f, 1f)],
(double)highlightRect.Right - fadingWidth,
fadingWidth
);
using var fadeOutBrush = CanvasHelper.CreateHorizontalFillBrush(
control,
[(0f, 1f), (1f, 0f)],
(double)highlightRect.Right,
fadingWidth
);
ds.FillRectangle(fadeInRect, fadeInBrush);
ds.FillRectangle(fadeOutRect, fadeOutBrush);
return mask;
}
public static CanvasCommandList CreateLineStartToCharMask(ICanvasAnimatedControl control, LyricsLine lyricsLine, int charStartIndex, int charLength, double charProgress, bool fade)
{
var mask = new CanvasCommandList(control);
if (lyricsLine.OriginalCanvasTextLayout == null)
{
return mask;
}
using var ds = mask.CreateDrawingSession();
var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, charStartIndex);
var highlightRegion = lyricsLine.OriginalCanvasTextLayout
.GetCharacterRegions(charStartIndex, charLength)
.FirstOrDefault();
if (regions.Length > 0)
{
// Draw the mask for the current line
for (int j = 0; j < regions.Length; j++)
{
var region = regions[j];
var rect = new Rect(
region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
region.LayoutBounds.Width,
region.LayoutBounds.Height
);
ds.FillRectangle(rect, Color.FromArgb(255, 128, 128, 128));
}
}
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
// Draw the highlight for the current character
double highlightWidth = highlightTotalWidth * charProgress;
double fadingWidth = (double)highlightRegion.LayoutBounds.Height / 2;
// Rects
var highlightRect = new Rect(
highlightRegion.LayoutBounds.X,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
highlightWidth,
highlightRegion.LayoutBounds.Height
);
var fadeInRect = new Rect(
highlightRect.Right - fadingWidth,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth,
highlightRegion.LayoutBounds.Height
);
ds.FillRectangle(highlightRect, Color.FromArgb(255, 128, 128, 128));
if (fade)
{
var fadeOutRect = new Rect(
highlightRect.Right,
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth,
highlightRegion.LayoutBounds.Height
);
using var fadeOutBrush = CreateHorizontalFillBrush(
control,
[(0f, 1f), (1f, 0f)],
(double)highlightRect.Right,
fadingWidth
);
ds.FillRectangle(fadeOutRect, fadeOutBrush);
}
return mask;
}
//public static Rect? GetLineRect(LyricsLine lyricsLine)
//{
// if (lyricsLine.OriginalCanvasTextLayout == null) return null;
// var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length);
// if (regions.Length > 0)
// {
// for (int j = 0; j < regions.Length; j++)
// {
// var region = regions[j];
// var rect = new Rect(
// region.LayoutBounds.X,
// region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
// region.LayoutBounds.Width,
// region.LayoutBounds.Height
// );
// ds.FillRectangle(rect, Colors.White);
// }
// }
// return mask;
//}
public static CanvasCommandList CreatePhoneticHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
{
var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession();
if (lyricsLine.PhoneticCanvasTextLayout == null)
{
return mask;
}
var regions = lyricsLine.PhoneticCanvasTextLayout.GetCharacterRegions(0, lyricsLine.PhoneticText.Length);
if (regions.Length > 0)
{
for (int j = 0; j < regions.Length; j++)
{
var region = regions[j];
var rect = new Rect(
region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.PhoneticPosition.Y,
region.LayoutBounds.Width,
region.LayoutBounds.Height
);
ds.FillRectangle(rect, Colors.White);
}
}
return mask;
}
public static CanvasCommandList CreateTranslatedHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
{
var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession();
if (lyricsLine.TranslatedCanvasTextLayout == null)
{
return mask;
}
var regions = lyricsLine.TranslatedCanvasTextLayout.GetCharacterRegions(0, lyricsLine.TranslatedText.Length);
if (regions.Length > 0)
{
for (int j = 0; j < regions.Length; j++)
{
var region = regions[j];
var rect = new Rect(
region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.TranslatedPosition.Y,
region.LayoutBounds.Width,
region.LayoutBounds.Height
);
ds.FillRectangle(rect, Colors.White);
}
}
return mask;
}
/// <summary>
/// 创建高亮效果层
/// </summary>
/// <param name="control"></param>
/// <param name="lineRenderingType"></param>
public static OpacityEffect CreateForegroundHighlightEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
{
return new OpacityEffect
{
Source = new AlphaMaskEffect
{
Source = foregroundFontEffect,
AlphaMask = mask,
},
Opacity = (float)Math.Clamp(opacity, 0, 1),
};
}
public static ShadowEffect CreateForegroundShadowEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, Color shadowColor, double shadowAmount)
{
return new ShadowEffect
@@ -340,29 +32,5 @@ namespace BetterLyrics.WinUI3.Helper
};
}
public static OpacityEffect CreateForegroundTranslationEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
{
return new OpacityEffect
{
Source = new AlphaMaskEffect
{
Source = foregroundFontEffect,
AlphaMask = mask,
},
Opacity = (float)Math.Clamp(opacity, 0, 1),
};
}
public static IGraphicsEffectSource GetAlphaMask(ICanvasAnimatedControl control, IGraphicsEffectSource charMask, IGraphicsEffectSource lineStartToCharMask, IGraphicsEffectSource lineMask, LineRenderingType lineRenderingType)
{
var result = lineRenderingType switch
{
LineRenderingType.CurrentChar => charMask,
LineRenderingType.LineStartToCurrentChar => lineStartToCharMask,
LineRenderingType.CurrentLine => lineMask,
_ => new CanvasCommandList(control),
};
return result;
}
}
}

View File

@@ -54,9 +54,7 @@ namespace BetterLyrics.WinUI3.Logic
line.BlurAmountTransition.StartTransition(5 * distanceFactor);
line.ScaleTransition.StartTransition(_highlightedScale - distanceFactor * (_highlightedScale - _defaultScale));
line.PhoneticTextOpacityTransition.StartTransition(absLineCountDelta == 0 ? 0.3 : (1 - distanceFactor) * 0.3);
line.OriginalTextOpacityTransition.StartTransition(absLineCountDelta == 0 ? 1 : (1 - distanceFactor) * 0.3);
line.TranslatedTextOpacityTransition.StartTransition(absLineCountDelta == 0 ? 0.3 : (1 - distanceFactor) * 0.3);
line.OpacityTransition.StartTransition(absLineCountDelta == 0 ? 1 : (1 - distanceFactor) * 0.3);
double yScrollDuration;
double yScrollDelay;
@@ -88,16 +86,13 @@ namespace BetterLyrics.WinUI3.Logic
line.YOffsetTransition.SetEasingType(canvasYScrollTransition.EasingType);
line.YOffsetTransition.SetDuration(yScrollDuration);
line.YOffsetTransition.SetDelay(yScrollDelay);
//line.YOffsetTransition.StartTransition(_canvasTargetYScrollOffset, _isLayoutChanged);
line.YOffsetTransition.StartTransition(targetYScrollOffset);
}
line.AngleTransition.Update(elapsedTime);
line.ScaleTransition.Update(elapsedTime);
line.BlurAmountTransition.Update(elapsedTime);
line.PhoneticTextOpacityTransition.Update(elapsedTime);
line.OriginalTextOpacityTransition.Update(elapsedTime);
line.TranslatedTextOpacityTransition.Update(elapsedTime);
line.OpacityTransition.Update(elapsedTime);
line.YOffsetTransition.Update(elapsedTime);
}
}

View File

@@ -12,6 +12,17 @@ namespace BetterLyrics.WinUI3.Logic
{
public class LyricsLayoutManager
{
/// <summary>
/// 重排歌词Y 轴从 0 刻度开始算
/// </summary>
/// <param name="resourceCreator"></param>
/// <param name="lyricsData"></param>
/// <param name="status"></param>
/// <param name="appSettings"></param>
/// <param name="canvasWidth"></param>
/// <param name="canvasHeight"></param>
/// <param name="lyricsWidth"></param>
/// <param name="lyricsHeight"></param>
public void MeasureAndArrange(
ICanvasAnimatedControl resourceCreator,
LyricsData? lyricsData,
@@ -19,7 +30,8 @@ namespace BetterLyrics.WinUI3.Logic
AppSettings appSettings,
double canvasWidth,
double canvasHeight,
double lyricsWidth)
double lyricsWidth,
double lyricsHeight)
{
if (lyricsData == null || resourceCreator == null) return;
@@ -55,13 +67,16 @@ namespace BetterLyrics.WinUI3.Logic
phoneticFontSize, originalFontSize, translatedFontSize,
fontWeight,
style.LyricsCJKFontFamily, style.LyricsWesternFontFamily,
lyricsWidth, canvasHeight, style.LyricsAlignmentType
lyricsWidth, lyricsHeight, style.LyricsAlignmentType
);
line.RecreateTextGeometry();
// 顶部坐标
line.TopPosition = new Vector2(0, (float)currentY);
// 注音层
line.PhoneticPosition = new Vector2(0, (float)currentY);
line.PhoneticPosition = line.TopPosition;
if (line.PhoneticCanvasTextLayout != null)
{
currentY += line.PhoneticCanvasTextLayout.LayoutBounds.Height;
@@ -88,6 +103,9 @@ namespace BetterLyrics.WinUI3.Logic
currentY += line.TranslatedCanvasTextLayout.LayoutBounds.Height;
}
// 底部坐标
line.BottomPosition = new Vector2(0, (float)currentY);
// 行间距
if (line.OriginalCanvasTextLayout != null)
{
@@ -100,7 +118,7 @@ namespace BetterLyrics.WinUI3.Logic
}
/// <summary>
/// 计算当前应该滚动到的目标 Y 轴偏移量
/// 计算为了让当前歌词行的竖直几何中心点对齐到 0原点画布应该移动的距离从画布最初始状态计算的值
/// </summary>
public double? CalculateTargetScrollOffset(
LyricsData? lyricsData,
@@ -115,10 +133,10 @@ namespace BetterLyrics.WinUI3.Logic
if (currentLine?.OriginalCanvasTextLayout == null || firstLine == null) return null;
return -currentLine.OriginalPosition.Y
+ firstLine.OriginalPosition.Y
- (currentLine.TranslatedPosition.Y
+ (currentLine.TranslatedCanvasTextLayout?.LayoutBounds.Height ?? 0)
- currentLine.PhoneticPosition.Y) / 2.0;
+ firstLine.OriginalPosition.Y
- (currentLine.TranslatedPosition.Y
+ (currentLine.TranslatedCanvasTextLayout?.LayoutBounds.Height ?? 0)
- currentLine.PhoneticPosition.Y) / 2.0;
}
/// <summary>
@@ -128,14 +146,16 @@ namespace BetterLyrics.WinUI3.Logic
public (int Start, int End) CalculateVisibleRange(
IList<LyricsLine>? lines,
double currentScrollOffset,
double lyricsY,
double lyricsHeight,
double canvasHeight)
{
if (lines == null || lines.Count == 0) return (-1, -1);
double offset = currentScrollOffset + canvasHeight / 2;
double offset = currentScrollOffset + lyricsY + lyricsHeight / 2;
int start = FindFirstVisibleLine(lines, offset);
int end = FindLastVisibleLine(lines, offset, canvasHeight);
int start = FindFirstVisibleLine(lines, offset, lyricsY);
int end = FindLastVisibleLine(lines, offset, lyricsY, lyricsHeight, canvasHeight);
// 修正边界情况
if (start != -1 && end == -1)
@@ -146,7 +166,7 @@ namespace BetterLyrics.WinUI3.Logic
return (start, end);
}
private int FindFirstVisibleLine(IList<LyricsLine> lines, double offset)
private int FindFirstVisibleLine(IList<LyricsLine> lines, double offset, double lyricsY)
{
int left = 0, right = lines.Count - 1, result = -1;
while (left <= right)
@@ -154,14 +174,16 @@ namespace BetterLyrics.WinUI3.Logic
int mid = (left + right) / 2;
var line = lines[mid];
if (line.OriginalCanvasTextLayout == null) break;
double value = offset + line.OriginalPosition.Y + (double)line.OriginalCanvasTextLayout.LayoutBounds.Height;
double value = offset + line.BottomPosition.Y;
// 理论上说应该使用下面这一行来精确计算视野内的首个可见行,但是考虑到动画视觉效果,还是注释掉了
//if (value >= lyricsY) { result = mid; right = mid - 1; }
if (value >= 0) { result = mid; right = mid - 1; }
else { left = mid + 1; }
}
return result;
}
private int FindLastVisibleLine(IList<LyricsLine> lines, double offset, double canvasHeight)
private int FindLastVisibleLine(IList<LyricsLine> lines, double offset, double lyricsY, double lyricsHeight, double canvasHeight)
{
int left = 0, right = lines.Count - 1, result = -1;
while (left <= right)
@@ -169,7 +191,9 @@ namespace BetterLyrics.WinUI3.Logic
int mid = (left + right) / 2;
var line = lines[mid];
if (line.OriginalCanvasTextLayout == null) break;
double value = offset + line.OriginalPosition.Y + (double)line.OriginalCanvasTextLayout.LayoutBounds.Height;
double value = offset + line.BottomPosition.Y;
// 同理
//if (value >= lyricsY + lyricsHeight) { result = mid; right = mid - 1; }
if (value >= canvasHeight) { result = mid; right = mid - 1; }
else { left = mid + 1; }
}

View File

@@ -19,13 +19,13 @@ namespace BetterLyrics.WinUI3.Logic
if (lyricsData == null || lyricsData.LyricsLines.Count == 0) return 0;
var lines = lyricsData.LyricsLines;
//// Cache hit
//if (IsTimeInLine(currentTimeMs, lines, _lastFoundIndex)) return _lastFoundIndex;
//if (_lastFoundIndex + 1 < lines.Count && IsTimeInLine(currentTimeMs, lines, _lastFoundIndex + 1))
//{
// _lastFoundIndex++;
// return _lastFoundIndex;
//}
// Cache hit
if (IsTimeInLine(currentTimeMs, lines, _lastFoundIndex)) return _lastFoundIndex;
if (_lastFoundIndex + 1 < lines.Count && IsTimeInLine(currentTimeMs, lines, _lastFoundIndex + 1))
{
_lastFoundIndex++;
return _lastFoundIndex;
}
// Cache miss
for (int i = 0; i < lines.Count; i++)

View File

@@ -17,9 +17,7 @@ namespace BetterLyrics.WinUI3.Models
public double AnimationDuration { get; set; } = 0.3;
public ValueTransition<double> AngleTransition { get; set; }
public ValueTransition<double> BlurAmountTransition { get; set; }
public ValueTransition<double> PhoneticTextOpacityTransition { get; set; }
public ValueTransition<double> OriginalTextOpacityTransition { get; set; }
public ValueTransition<double> TranslatedTextOpacityTransition { get; set; }
public ValueTransition<double> OpacityTransition { get; set; }
public ValueTransition<double> ScaleTransition { get; set; }
public ValueTransition<double> YOffsetTransition { get; set; }
@@ -27,20 +25,32 @@ namespace BetterLyrics.WinUI3.Models
public CanvasTextLayout? TranslatedCanvasTextLayout { get; private set; }
public CanvasTextLayout? PhoneticCanvasTextLayout { get; private set; }
public Vector2 CenterPosition { get; private set; }
/// <summary>
/// 原文位置
/// 原文坐标(相对于坐标原点)
/// </summary>
public Vector2 OriginalPosition { get; set; }
/// <summary>
/// 译文位置
/// 译文坐标(相对于坐标原点)
/// </summary>
public Vector2 TranslatedPosition { get; set; }
/// <summary>
/// 注音位置
/// 注音坐标(相对于坐标原点)
/// </summary>
public Vector2 PhoneticPosition { get; set; }
/// <summary>
/// 顶部坐标(相对于坐标原点)
/// </summary>
public Vector2 TopPosition { get; set; }
/// <summary>
/// 中心坐标(相对于坐标原点)
/// </summary>
public Vector2 CenterPosition { get; private set; }
/// <summary>
/// 底部坐标(相对于坐标原点)
/// </summary>
public Vector2 BottomPosition { get; set; }
public List<LyricsSyllable> LyricsSyllables { get; set; } = [];
public int? DurationMs => EndMs - StartMs;
@@ -76,17 +86,7 @@ namespace BetterLyrics.WinUI3.Models
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutQuad
);
PhoneticTextOpacityTransition = new(
initialValue: 0,
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutQuad
);
OriginalTextOpacityTransition = new(
initialValue: 0,
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutQuad
);
TranslatedTextOpacityTransition = new(
OpacityTransition = new(
initialValue: 0,
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutQuad
@@ -110,13 +110,13 @@ namespace BetterLyrics.WinUI3.Models
return;
}
double centerY = OriginalPosition.Y + (OriginalCanvasTextLayout?.LayoutBounds.Height ?? 0) / 2;
double centerY = (TopPosition.Y + BottomPosition.Y) / 2;
CenterPosition = type switch
{
TextAlignmentType.Left => new Vector2(OriginalPosition.X, (float)centerY),
TextAlignmentType.Center => new Vector2((float)(OriginalPosition.X + maxWidth / 2.0), (float)centerY),
TextAlignmentType.Right => new Vector2((float)(OriginalPosition.X + maxWidth), (float)centerY),
TextAlignmentType.Left => new Vector2(0, (float)centerY),
TextAlignmentType.Center => new Vector2((float)(0 + maxWidth / 2.0), (float)centerY),
TextAlignmentType.Right => new Vector2((float)(0 + maxWidth), (float)centerY),
_ => throw new System.ArgumentOutOfRangeException(nameof(type), type, null),
};
}

View File

@@ -3,6 +3,7 @@ using BetterLyrics.WinUI3.Hooks;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using System;
using Windows.Foundation;
@@ -35,11 +36,28 @@ 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;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LeftGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TopGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double RightGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double BottomGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double MiddleColGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double MiddleRowGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TrackSummaryColGapFactor { get; set; } = 38;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TrackSummaryRowGapFactor { get; set; } = 19;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsColGapFactor { get; set; } = 38;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsRowGapFactor { get; set; } = 57;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowLayoutIndicator { get; set; } = false;
public LyricsWindowStatus()
{
UpdateMonitorNameAndBounds();
@@ -191,11 +209,27 @@ namespace BetterLyrics.WinUI3.Models
EnvironmentSampleMode = this.EnvironmentSampleMode,
AutoShowOrHideWindow = this.AutoShowOrHideWindow,
TitleBarArea = this.TitleBarArea,
WindowX = this.WindowX,
WindowY = this.WindowY,
WindowWidth = this.WindowWidth,
WindowHeight = this.WindowHeight,
LeftGapFactor = this.LeftGapFactor,
TopGapFactor = this.TopGapFactor,
RightGapFactor = this.RightGapFactor,
BottomGapFactor = this.BottomGapFactor,
MiddleColGapFactor = this.MiddleColGapFactor,
MiddleRowGapFactor = this.MiddleRowGapFactor,
TrackSummaryColGapFactor = this.TrackSummaryColGapFactor,
TrackSummaryRowGapFactor = this.TrackSummaryRowGapFactor,
LyricsColGapFactor = this.LyricsColGapFactor,
LyricsRowGapFactor = this.LyricsRowGapFactor,
};
}
}
}

View File

@@ -1,5 +1,6 @@
using BetterLyrics.WinUI3.Enums;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using System;
namespace BetterLyrics.WinUI3.Models.Settings
@@ -7,16 +8,17 @@ namespace BetterLyrics.WinUI3.Models.Settings
public partial class AlbumArtLayoutSettings : ObservableRecipient, ICloneable
{
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType SongInfoAlignmentType { get; set; } = TextAlignmentType.Left;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial HorizontalAlignment AlbumArtAlignmentType { get; set; } = HorizontalAlignment.Center;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageRadius { get; set; } = 12; // 12 % of the cover image size
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageShadowAmount { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsAutoSongInfoFontSize { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SongInfoFontSize { get; set; } = 18;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowTitle { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowArtists { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowAlbum { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int AlbumArtSize { get; set; } = 64;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoAlbumArtSize { get; set; } = true;
public AlbumArtLayoutSettings() { }
public object Clone()
@@ -24,6 +26,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
return new AlbumArtLayoutSettings
{
SongInfoAlignmentType = this.SongInfoAlignmentType,
AlbumArtAlignmentType = this.AlbumArtAlignmentType,
CoverImageRadius = this.CoverImageRadius,
CoverImageShadowAmount = this.CoverImageShadowAmount,
IsAutoSongInfoFontSize = this.IsAutoSongInfoFontSize,
@@ -31,8 +34,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
ShowTitle = this.ShowTitle,
ShowArtists = this.ShowArtists,
ShowAlbum = this.ShowAlbum,
AlbumArtSize = this.AlbumArtSize,
AutoAlbumArtSize = this.AutoAlbumArtSize,
};
}
}

View File

@@ -28,59 +28,66 @@ namespace BetterLyrics.WinUI3.Renderer
int playingLineIndex,
int startVisibleIndex,
int endVisibleIndex,
double canvasHeight,
double lyricsX,
double lyricsY,
double lyricsWidth,
double lyricsHeight,
double lyricsOpacity,
LyricsWindowStatus windowStatus,
Color strokeColor,
Color bgColor,
Func<int, LinePlaybackState> getPlaybackState)
{
if (windowStatus.LyricsEffectSettings.Is3DLyricsEnabled)
using (var opacityLayer = ds.CreateLayer((float)lyricsOpacity))
{
using (var layer = new CanvasCommandList(control))
if (windowStatus.LyricsEffectSettings.Is3DLyricsEnabled)
{
using (var layerDs = layer.CreateDrawingSession())
using (var layer = new CanvasCommandList(control))
{
DrawLyrics(
control,
layerDs,
lyricsData,
playingLineIndex,
startVisibleIndex,
endVisibleIndex,
canvasHeight,
lyricsX,
lyricsWidth,
windowStatus,
strokeColor,
bgColor,
getPlaybackState);
}
using (var layerDs = layer.CreateDrawingSession())
{
DrawLyrics(
control,
layerDs,
lyricsData,
playingLineIndex,
startVisibleIndex,
endVisibleIndex,
lyricsX,
lyricsY,
lyricsWidth,
lyricsHeight,
windowStatus,
strokeColor,
bgColor,
getPlaybackState);
}
ds.DrawImage(new Transform3DEffect
{
Source = layer,
TransformMatrix = _threeDimMatrix
});
ds.DrawImage(new Transform3DEffect
{
Source = layer,
TransformMatrix = _threeDimMatrix
});
}
}
else
{
DrawLyrics(
control,
ds,
lyricsData,
playingLineIndex,
startVisibleIndex,
endVisibleIndex,
lyricsX,
lyricsY,
lyricsWidth,
lyricsHeight,
windowStatus,
strokeColor,
bgColor,
getPlaybackState);
}
}
else
{
DrawLyrics(
control,
ds,
lyricsData,
playingLineIndex,
startVisibleIndex,
endVisibleIndex,
canvasHeight,
lyricsX,
lyricsWidth,
windowStatus,
strokeColor,
bgColor,
getPlaybackState);
}
}
@@ -91,9 +98,10 @@ namespace BetterLyrics.WinUI3.Renderer
int playingLineIndex,
int startVisibleIndex,
int endVisibleIndex,
double canvasHeight,
double lyricsX,
double lyricsY,
double lyricsWidth,
double lyricsHeight,
LyricsWindowStatus windowStatus,
Color strokeColor,
Color bgColor,
@@ -117,7 +125,7 @@ namespace BetterLyrics.WinUI3.Renderer
if (line.OriginalCanvasTextLayout == null) continue;
if (line.OriginalCanvasTextLayout.LayoutBounds.Width <= 0) continue;
double yOffset = line.YOffsetTransition.Value + canvasHeight / 2;
double yOffset = line.YOffsetTransition.Value + lyricsY + lyricsHeight / 2;
var transform =
Matrix3x2.CreateScale((float)line.ScaleTransition.Value, line.CenterPosition) *

View File

@@ -14,6 +14,7 @@ using System.Numerics;
using System.Text;
using Windows.Foundation;
using Windows.UI;
using static Vanara.PInvoke.Kernel32;
namespace BetterLyrics.WinUI3.Renderer
{
@@ -36,7 +37,7 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (line.PhoneticCanvasTextLayout == null) return;
var opacity = line.PhoneticTextOpacityTransition.Value;
var opacity = line.OpacityTransition.Value * 0.3;
var blur = line.BlurAmountTransition.Value;
var bounds = line.PhoneticCanvasTextLayout.LayoutBounds;
@@ -62,7 +63,7 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (line.TranslatedCanvasTextLayout == null) return;
var opacity = line.TranslatedTextOpacityTransition.Value;
var opacity = line.OpacityTransition.Value * 0.3;
var blur = line.BlurAmountTransition.Value;
var bounds = line.TranslatedCanvasTextLayout.LayoutBounds;
@@ -94,7 +95,7 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (line.OriginalCanvasTextLayout == null) return;
var originalTextOpacity = line.OriginalTextOpacityTransition.Value;
var opacity = line.OpacityTransition.Value;
var curCharIndex = state.SyllableStartIndex + state.SyllableLength * state.SyllableProgress;
float fadeWidth = (1f / Math.Max(1, line.OriginalText.Length)) * 0.5f;
@@ -103,7 +104,7 @@ namespace BetterLyrics.WinUI3.Renderer
foreach (var subLineRegion in lineRegions)
{
DrawSubLineRegion(resourceCreator, ds, source, line, subLineRegion, curCharIndex, fadeWidth, originalTextOpacity, state, settings);
DrawSubLineRegion(resourceCreator, ds, source, line, subLineRegion, curCharIndex, fadeWidth, opacity, state, settings);
}
}
@@ -115,7 +116,7 @@ namespace BetterLyrics.WinUI3.Renderer
CanvasTextLayoutRegion subLineRegion,
double curCharIndex,
float fadeWidth,
double originalTextOpacity,
double opacity,
LinePlaybackState state,
LyricsEffectSettings settings)
{
@@ -134,13 +135,13 @@ namespace BetterLyrics.WinUI3.Renderer
float progressInRegion = (float)((curCharIndex - subLineRegion.CharacterIndex) / subLineRegion.CharacterCount);
progressInRegion = Math.Clamp(progressInRegion, 0, 1 + fadeWidth);
var stop1 = Colors.White.WithAlpha((byte)(255 * originalTextOpacity));
var stop2 = Color.FromArgb((byte)(255 * Math.Min(0.3, originalTextOpacity)), 255, 255, 255);
var stop1 = Colors.White.WithAlpha((byte)(255 * opacity));
var stop2 = Color.FromArgb((byte)(255 * Math.Min(0.3, opacity)), 255, 255, 255);
using (var maskBrush = new CanvasLinearGradientBrush(resourceCreator,
[
new CanvasGradientStop { Position = 0, Color = stop1 },
new CanvasGradientStop { Position = progressInRegion, Color = stop1 },
new CanvasGradientStop { Position = - fadeWidth, Color = stop1 },
new CanvasGradientStop { Position = - fadeWidth + progressInRegion, Color = stop1 },
new CanvasGradientStop { Position = progressInRegion + fadeWidth, Color = stop2 },
new CanvasGradientStop { Position = 1 + fadeWidth, Color = stop2 }
]))

View File

@@ -15,6 +15,7 @@ namespace BetterLyrics.WinUI3.Renderer
LyricsLine line)
{
var blurAmount = (float)line.BlurAmountTransition.Value;
var opacity = line.OpacityTransition.Value;
if (line.PhoneticCanvasTextLayout != null)
{
@@ -22,7 +23,7 @@ namespace BetterLyrics.WinUI3.Renderer
line.PhoneticCanvasTextLayout,
line.PhoneticPosition,
blurAmount,
(float)line.PhoneticTextOpacityTransition.Value);
(float)opacity * 0.3f);
}
if (line.OriginalCanvasTextLayout != null)
@@ -31,7 +32,7 @@ namespace BetterLyrics.WinUI3.Renderer
line.OriginalCanvasTextLayout,
line.OriginalPosition,
blurAmount,
(float)line.OriginalTextOpacityTransition.Value);
(float)opacity);
}
if (line.TranslatedCanvasTextLayout != null)
@@ -40,7 +41,7 @@ namespace BetterLyrics.WinUI3.Renderer
line.TranslatedCanvasTextLayout,
line.TranslatedPosition,
blurAmount,
(float)line.TranslatedTextOpacityTransition.Value);
(float)opacity * 0.3f);
}
}

View File

@@ -562,7 +562,11 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
ISearchResult? result;
if (searcher == Searchers.Netease && songInfo.SongId != null)
{
result = new NeteaseSearchResult(songInfo.Title, songInfo.Artists, songInfo.Album, songInfo.Artists, (int)songInfo.DurationMs, songInfo.SongId);
result = new NeteaseSearchResult("", [], "", [], 0, songInfo.SongId);
}
else if (searcher == Searchers.QQMusic && songInfo.SongId != null)
{
result = new QQMusicSearchResult("", [], "", [], 0, songInfo.SongId, "");
}
else
{

View File

@@ -45,7 +45,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
TranslationSearchProvider = null;
_lyricsDataArr.ElementAtOrDefault(0)?.ClearTranslatedText();
SetCurrentLyricsData();
App.Current.Resources.DispatcherQueue.TryEnqueue(SetCurrentLyricsData);
IsTranslating = true;
@@ -55,7 +55,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
IsTranslating = false;
SetCurrentLyricsData();
App.Current.Resources.DispatcherQueue.TryEnqueue(SetCurrentLyricsData);
}
@@ -153,7 +153,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
CurrentLyricsSearchResult = null;
_lyricsDataArr = [LyricsData.GetLoadingPlaceholder()];
SetCurrentLyricsData();
App.Current.Resources.DispatcherQueue.TryEnqueue(SetCurrentLyricsData);
if (CurrentSongInfo != null)
{
@@ -176,10 +176,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
// Show original first while loading phonetic and translated
ApplyChinesePreference();
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
});
App.Current.Resources.DispatcherQueue.TryEnqueue(SetCurrentLyricsData);
UpdateTranslations();
}

View File

@@ -335,6 +335,12 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
.FirstOrDefault(x => x.StartsWith(ExtendedGenreFiled.NetEaseCloudMusicTrackID))?
.Replace(ExtendedGenreFiled.NetEaseCloudMusicTrackID, "");
}
else if (sessionId == PlayerID.QQMusic)
{
songId = mediaProperties?.Genres
.FirstOrDefault(x => x.StartsWith(ExtendedGenreFiled.QQMusicTrackID))?
.Replace(ExtendedGenreFiled.QQMusicTrackID, "");
}
var linkedFileName = mediaProperties?.Genres
.FirstOrDefault(x => x.StartsWith(ExtendedGenreFiled.FileName))?

View File

@@ -130,7 +130,7 @@
<value>Picture-in-picture mode</value>
</data>
<data name="AppSettingsControlGeneral.Text" xml:space="preserve">
<value>General</value>
<value>Window</value>
</data>
<data name="ArtistsSplitHint.Text" xml:space="preserve">
<value>When typing multiple artists, please separate them with one of the following delimiters (do not mix them)</value>
@@ -607,6 +607,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>Album art area style</value>
</data>
<data name="SettingsPageAlignment.Header" xml:space="preserve">
<value>Alignment</value>
</data>
<data name="SettingsPageAmllTtmlDbBaseUrl.Header" xml:space="preserve">
<value>Base URL</value>
</data>
@@ -664,12 +667,18 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageBorderlessHotKey.Header" xml:space="preserve">
<value>Borderless lyrics window shortcut</value>
</data>
<data name="SettingsPageBottomGapFactor.Header" xml:space="preserve">
<value>Bottom gap height factor</value>
</data>
<data name="SettingsPageCache.Description" xml:space="preserve">
<value>Including log files, network lyrics cache</value>
</data>
<data name="SettingsPageCache.Header" xml:space="preserve">
<value>Cache</value>
</data>
<data name="SettingsPageCenter.Content" xml:space="preserve">
<value>Center</value>
</data>
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>Chinese pronunciation</value>
</data>
@@ -859,6 +868,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="SettingsPageGeneralLayoutFactor.Text" xml:space="preserve">
<value>General layout factor</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>Height</value>
</data>
@@ -871,6 +883,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageHoldDragSort.Content" xml:space="preserve">
<value>Hold here and drag to sort</value>
</data>
<data name="SettingsPageHorizontalLayoutFactor.Text" xml:space="preserve">
<value>Horizontal layout factor</value>
</data>
<data name="SettingsPageImport.Content" xml:space="preserve">
<value>Import</value>
</data>
@@ -925,6 +940,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLastFMUsername.Header" xml:space="preserve">
<value>Username</value>
</data>
<data name="SettingsPageLayout.Text" xml:space="preserve">
<value>Layout</value>
</data>
<data name="SettingsPageLayoutOrientation.Header" xml:space="preserve">
<value>Layout orientation</value>
</data>
@@ -934,6 +952,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>Vertical</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>Left</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>Left gap area width factor</value>
</data>
<data name="SettingsPageLibreTranslateServer.Header" xml:space="preserve">
<value>Server address</value>
</data>
@@ -982,8 +1006,8 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>Bold</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>Center</value>
<data name="SettingsPageLyricsColFactor.Header" xml:space="preserve">
<value>Lyrics area width factor</value>
</data>
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>Lyrics effect</value>
@@ -1075,8 +1099,8 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsRendingScopeLineStartToCurrentChar.Content" xml:space="preserve">
<value>Current line start to current char</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>Right</value>
<data name="SettingsPageLyricsRowFactor.Header" xml:space="preserve">
<value>Lyrics area height factor</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Description" xml:space="preserve">
<value>Enable scaling for syllables with long duration</value>
@@ -1165,6 +1189,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>Mica Alt</value>
</data>
<data name="SettingsPageMiddleGapColFactor.Header" xml:space="preserve">
<value>Middle area gap width factor</value>
</data>
<data name="SettingsPageMiddleGapRowFactor.Header" xml:space="preserve">
<value>Middle gap area height factor</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>Play test music</value>
</data>
@@ -1282,6 +1312,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>Restart app to apply change</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>Right</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>Right gap area width factor</value>
</data>
<data name="SettingsPageRomaji.Header" xml:space="preserve">
<value>Japanese annotation</value>
</data>
@@ -1351,6 +1387,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageShowInSwitchers.Header" xml:space="preserve">
<value>Show in system environment</value>
</data>
<data name="SettingsPageShowLayoutDragger.Header" xml:space="preserve">
<value>Show layout splitter</value>
</data>
<data name="SettingsPageShowTitle.Header" xml:space="preserve">
<value>Show title</value>
</data>
@@ -1363,18 +1402,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>Song info</value>
</data>
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
<value>Alignment</value>
</data>
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
<value>Center</value>
</data>
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
<value>Left</value>
</data>
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
<value>Right</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
<value>Current song</value>
</data>
@@ -1435,6 +1462,15 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>Switch in and cut out shortcut keys</value>
</data>
<data name="SettingsPageTopGapFactor.Header" xml:space="preserve">
<value>Top gap area height factor</value>
</data>
<data name="SettingsPageTrackSummaryColFactor.Header" xml:space="preserve">
<value>Track summary area width factor</value>
</data>
<data name="SettingsPageTrackSummaryRowFactor.Header" xml:space="preserve">
<value>Track summary area height factor</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>Translated text</value>
</data>
@@ -1453,6 +1489,9 @@ 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="SettingsPageVerticalLayoutFactor.Text" xml:space="preserve">
<value>Vertical layout factor</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>Latin alphabet</value>
</data>

View File

@@ -130,7 +130,7 @@
<value>ピクチャーインピクチャーモード</value>
</data>
<data name="AppSettingsControlGeneral.Text" xml:space="preserve">
<value>一般的な</value>
<value>ウィンドウ</value>
</data>
<data name="ArtistsSplitHint.Text" xml:space="preserve">
<value>複数のアーティストを入力する場合は、次の区切り記号のいずれかで区切ってください(混在しないでください)</value>
@@ -607,6 +607,9 @@
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>アルバムエリアスタイル</value>
</data>
<data name="SettingsPageAlignment.Header" xml:space="preserve">
<value>アライメント</value>
</data>
<data name="SettingsPageAmllTtmlDbBaseUrl.Header" xml:space="preserve">
<value>ベースURL</value>
</data>
@@ -664,12 +667,18 @@
<data name="SettingsPageBorderlessHotKey.Header" xml:space="preserve">
<value>ボーダーレス歌詞ウィンドウショートカット</value>
</data>
<data name="SettingsPageBottomGapFactor.Header" xml:space="preserve">
<value>ボトムギャップハイトファクター</value>
</data>
<data name="SettingsPageCache.Description" xml:space="preserve">
<value>ログファイル、ネットワーク歌詞キャッシュを含む</value>
</data>
<data name="SettingsPageCache.Header" xml:space="preserve">
<value>キャッシュ</value>
</data>
<data name="SettingsPageCenter.Content" xml:space="preserve">
<value>中心</value>
</data>
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中国の発音</value>
</data>
@@ -859,6 +868,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>フルスクリーンモード</value>
</data>
<data name="SettingsPageGeneralLayoutFactor.Text" xml:space="preserve">
<value>一般的なレイアウトファクター</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高さ</value>
</data>
@@ -871,6 +883,9 @@
<data name="SettingsPageHoldDragSort.Content" xml:space="preserve">
<value>ここを長押ししてドラッグして並べ替えましょう</value>
</data>
<data name="SettingsPageHorizontalLayoutFactor.Text" xml:space="preserve">
<value>水平レイアウト係数</value>
</data>
<data name="SettingsPageImport.Content" xml:space="preserve">
<value>インポート</value>
</data>
@@ -925,6 +940,9 @@
<data name="SettingsPageLastFMUsername.Header" xml:space="preserve">
<value>ユーザー名</value>
</data>
<data name="SettingsPageLayout.Text" xml:space="preserve">
<value>レイアウト</value>
</data>
<data name="SettingsPageLayoutOrientation.Header" xml:space="preserve">
<value>レイアウトの向き</value>
</data>
@@ -934,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>垂直方向</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左ギャップエリア幅係数</value>
</data>
<data name="SettingsPageLibreTranslateServer.Header" xml:space="preserve">
<value>サーバーアドレス</value>
</data>
@@ -982,8 +1003,8 @@
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>大胆な</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>中心</value>
<data name="SettingsPageLyricsColFactor.Header" xml:space="preserve">
<value>歌詞エリア幅係数</value>
</data>
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>歌詞効果</value>
@@ -1045,9 +1066,6 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>オリジナルのハイライト範囲</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>ライト</value>
</data>
@@ -1075,8 +1093,14 @@
<data name="SettingsPageLyricsRendingScopeLineStartToCurrentChar.Content" xml:space="preserve">
<value>現在のラインが現在の文字から始まります</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value></value>
<data name="SettingsPageLyricsRowFactor.Header" xml:space="preserve">
<value>歌詞エリアの高さ係数</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Description" xml:space="preserve">
<value>長時間の音節のスケーリングを有効にします</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Header" xml:space="preserve">
<value>スケール効果</value>
</data>
<data name="SettingsPageLyricsSearchBestMatch.Content" xml:space="preserve">
<value>ベストマッチ</value>
@@ -1159,6 +1183,12 @@
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>マイカル</value>
</data>
<data name="SettingsPageMiddleGapColFactor.Header" xml:space="preserve">
<value>ミドルエリアギャップ幅係数</value>
</data>
<data name="SettingsPageMiddleGapRowFactor.Header" xml:space="preserve">
<value>ミドルギャップエリアハイトファクター</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>テスト音楽を再生します</value>
</data>
@@ -1276,6 +1306,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>変更を適用するためのアプリを再起動します</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右ギャップエリア幅係数</value>
</data>
<data name="SettingsPageRomaji.Header" xml:space="preserve">
<value>日本の注釈</value>
</data>
@@ -1345,6 +1378,9 @@
<data name="SettingsPageShowInSwitchers.Header" xml:space="preserve">
<value>システム環境に表示します</value>
</data>
<data name="SettingsPageShowLayoutDragger.Header" xml:space="preserve">
<value>レイアウトスプリッターを表示</value>
</data>
<data name="SettingsPageShowTitle.Header" xml:space="preserve">
<value>タイトルを表示</value>
</data>
@@ -1357,16 +1393,10 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>曲情報</value>
</data>
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
<value>アライメント</value>
</data>
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
<value>中心</value>
</data>
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
@@ -1429,6 +1459,15 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>ショートカットキーを切り込んで切り取ります</value>
</data>
<data name="SettingsPageTopGapFactor.Header" xml:space="preserve">
<value>トップギャップエリアの高さ係数</value>
</data>
<data name="SettingsPageTrackSummaryColFactor.Header" xml:space="preserve">
<value>トラックサマリーエリア幅係数</value>
</data>
<data name="SettingsPageTrackSummaryRowFactor.Header" xml:space="preserve">
<value>トラックサマリーエリアの高さ係数</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
@@ -1447,6 +1486,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>バージョン</value>
</data>
<data name="SettingsPageVerticalLayoutFactor.Text" xml:space="preserve">
<value>垂直レイアウト係数</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>英字</value>
</data>
@@ -1513,4 +1555,7 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>利用案内</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>左</value>
</data>
</root>

View File

@@ -130,7 +130,7 @@
<value>사진 인당 모드</value>
</data>
<data name="AppSettingsControlGeneral.Text" xml:space="preserve">
<value>일반적인</value>
<value>윈도우</value>
</data>
<data name="ArtistsSplitHint.Text" xml:space="preserve">
<value>여러 아티스트를 입력할 때 다음 구분 기호 중 하나로 구분하십시오 (혼합하지 마십시오)</value>
@@ -607,6 +607,9 @@
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>앨범 영역 스타일</value>
</data>
<data name="SettingsPageAlignment.Header" xml:space="preserve">
<value>조정</value>
</data>
<data name="SettingsPageAmllTtmlDbBaseUrl.Header" xml:space="preserve">
<value>기본 URL</value>
</data>
@@ -664,12 +667,18 @@
<data name="SettingsPageBorderlessHotKey.Header" xml:space="preserve">
<value>테두리 없는 가사 창 단축키</value>
</data>
<data name="SettingsPageBottomGapFactor.Header" xml:space="preserve">
<value>하단 간격 높이 계수</value>
</data>
<data name="SettingsPageCache.Description" xml:space="preserve">
<value>로그 파일, 네트워크 가사 캐시 포함</value>
</data>
<data name="SettingsPageCache.Header" xml:space="preserve">
<value>은닉처</value>
</data>
<data name="SettingsPageCenter.Content" xml:space="preserve">
<value>센터</value>
</data>
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>화음</value>
</data>
@@ -859,6 +868,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>전체화면 모드</value>
</data>
<data name="SettingsPageGeneralLayoutFactor.Text" xml:space="preserve">
<value>일반 레이아웃 요소</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>신장</value>
</data>
@@ -871,6 +883,9 @@
<data name="SettingsPageHoldDragSort.Content" xml:space="preserve">
<value>여기를 누른 상태에서 드래그하여 정렬하세요</value>
</data>
<data name="SettingsPageHorizontalLayoutFactor.Text" xml:space="preserve">
<value>수평 레이아웃 요소</value>
</data>
<data name="SettingsPageImport.Content" xml:space="preserve">
<value>가져오기</value>
</data>
@@ -925,6 +940,9 @@
<data name="SettingsPageLastFMUsername.Header" xml:space="preserve">
<value>사용자 이름</value>
</data>
<data name="SettingsPageLayout.Text" xml:space="preserve">
<value>레이아웃</value>
</data>
<data name="SettingsPageLayoutOrientation.Header" xml:space="preserve">
<value>레이아웃 방향</value>
</data>
@@ -934,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>세로</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>왼쪽 갭 영역 너비 계수</value>
</data>
<data name="SettingsPageLibreTranslateServer.Header" xml:space="preserve">
<value>서버 주소</value>
</data>
@@ -982,8 +1003,8 @@
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>용감한</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>센터</value>
<data name="SettingsPageLyricsColFactor.Header" xml:space="preserve">
<value>가사 영역 너비 계수</value>
</data>
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>가사 효과</value>
@@ -1045,9 +1066,6 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>원래 하이라이트 범위</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>빛</value>
</data>
@@ -1075,8 +1093,14 @@
<data name="SettingsPageLyricsRendingScopeLineStartToCurrentChar.Content" xml:space="preserve">
<value>현재 라인은 현재 숯으로 시작합니다</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>오른쪽</value>
<data name="SettingsPageLyricsRowFactor.Header" xml:space="preserve">
<value>가사 영역 높이 계수</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Description" xml:space="preserve">
<value>장시간 음절 배율을 조정할 수 있습니다</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Header" xml:space="preserve">
<value>스케일 효과</value>
</data>
<data name="SettingsPageLyricsSearchBestMatch.Content" xml:space="preserve">
<value>최상의 검색 결과</value>
@@ -1159,6 +1183,12 @@
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>운모 대체</value>
</data>
<data name="SettingsPageMiddleGapColFactor.Header" xml:space="preserve">
<value>중간 영역 갭 폭 계수</value>
</data>
<data name="SettingsPageMiddleGapRowFactor.Header" xml:space="preserve">
<value>중간 간격 영역 높이 계수</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>테스트 음악을 재생하십시오</value>
</data>
@@ -1276,6 +1306,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>변경 사항을 적용하려면 앱을 다시 시작하십시오</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>오른쪽 간격 영역 너비 계수</value>
</data>
<data name="SettingsPageRomaji.Header" xml:space="preserve">
<value>일본 주석</value>
</data>
@@ -1345,6 +1378,9 @@
<data name="SettingsPageShowInSwitchers.Header" xml:space="preserve">
<value>시스템 환경에서 보여주세요</value>
</data>
<data name="SettingsPageShowLayoutDragger.Header" xml:space="preserve">
<value>레이아웃 스플리터 표시</value>
</data>
<data name="SettingsPageShowTitle.Header" xml:space="preserve">
<value>제목 표시</value>
</data>
@@ -1357,16 +1393,10 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>노래 정보</value>
</data>
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
<value>조정</value>
</data>
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
<value>센터</value>
</data>
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>오른쪽</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
@@ -1429,6 +1459,15 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>바로 가기 키를 자르고 잘라냅니다</value>
</data>
<data name="SettingsPageTopGapFactor.Header" xml:space="preserve">
<value>상단 간격 영역 높이 계수</value>
</data>
<data name="SettingsPageTrackSummaryColFactor.Header" xml:space="preserve">
<value>트랙 요약 영역 너비 계수</value>
</data>
<data name="SettingsPageTrackSummaryRowFactor.Header" xml:space="preserve">
<value>트랙 요약 영역 높이 계수</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>번역</value>
</data>
@@ -1447,6 +1486,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>버전</value>
</data>
<data name="SettingsPageVerticalLayoutFactor.Text" xml:space="preserve">
<value>수직 레이아웃 요소</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>라틴 알파벳</value>
</data>
@@ -1513,4 +1555,7 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>사용 안내서</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
</root>

View File

@@ -130,7 +130,7 @@
<value>画中画模式</value>
</data>
<data name="AppSettingsControlGeneral.Text" xml:space="preserve">
<value>通用</value>
<value>窗口</value>
</data>
<data name="ArtistsSplitHint.Text" xml:space="preserve">
<value>键入多位艺术家时请以下述一种分隔符分隔(不要混用)</value>
@@ -607,6 +607,9 @@
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>专辑区域样式</value>
</data>
<data name="SettingsPageAlignment.Header" xml:space="preserve">
<value>对齐方式</value>
</data>
<data name="SettingsPageAmllTtmlDbBaseUrl.Header" xml:space="preserve">
<value>基本 URL</value>
</data>
@@ -664,12 +667,18 @@
<data name="SettingsPageBorderlessHotKey.Header" xml:space="preserve">
<value>无边框歌词窗口快捷方式</value>
</data>
<data name="SettingsPageBottomGapFactor.Header" xml:space="preserve">
<value>底部间隙高度因子</value>
</data>
<data name="SettingsPageCache.Description" xml:space="preserve">
<value>包括日志文件,网络歌词缓存</value>
</data>
<data name="SettingsPageCache.Header" xml:space="preserve">
<value>缓存</value>
</data>
<data name="SettingsPageCenter.Content" xml:space="preserve">
<value>居中</value>
</data>
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value>
</data>
@@ -859,6 +868,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>全屏模式</value>
</data>
<data name="SettingsPageGeneralLayoutFactor.Text" xml:space="preserve">
<value>一般布局系数</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高度</value>
</data>
@@ -871,6 +883,9 @@
<data name="SettingsPageHoldDragSort.Content" xml:space="preserve">
<value>按住此处并拖动以排序</value>
</data>
<data name="SettingsPageHorizontalLayoutFactor.Text" xml:space="preserve">
<value>水平布局系数</value>
</data>
<data name="SettingsPageImport.Content" xml:space="preserve">
<value>导入</value>
</data>
@@ -925,6 +940,9 @@
<data name="SettingsPageLastFMUsername.Header" xml:space="preserve">
<value>用户名</value>
</data>
<data name="SettingsPageLayout.Text" xml:space="preserve">
<value>布局</value>
</data>
<data name="SettingsPageLayoutOrientation.Header" xml:space="preserve">
<value>布局方向</value>
</data>
@@ -934,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>垂直</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左间隙区域宽度因子</value>
</data>
<data name="SettingsPageLibreTranslateServer.Header" xml:space="preserve">
<value>服务器地址</value>
</data>
@@ -982,8 +1003,8 @@
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>粗体</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>居中</value>
<data name="SettingsPageLyricsColFactor.Header" xml:space="preserve">
<value>歌词区域宽度因子</value>
</data>
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>歌词动效</value>
@@ -1045,9 +1066,6 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮显示范围</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>细体</value>
</data>
@@ -1075,8 +1093,14 @@
<data name="SettingsPageLyricsRendingScopeLineStartToCurrentChar.Content" xml:space="preserve">
<value>当前歌词开始到当前字符</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>靠右</value>
<data name="SettingsPageLyricsRowFactor.Header" xml:space="preserve">
<value>歌词区域高度因子</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Description" xml:space="preserve">
<value>为持续时间较长的音节启用缩放</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Header" xml:space="preserve">
<value>缩放效果</value>
</data>
<data name="SettingsPageLyricsSearchBestMatch.Content" xml:space="preserve">
<value>最佳匹配</value>
@@ -1159,6 +1183,12 @@
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>云母(替代样式)</value>
</data>
<data name="SettingsPageMiddleGapColFactor.Header" xml:space="preserve">
<value>中间区域间隙宽度系数</value>
</data>
<data name="SettingsPageMiddleGapRowFactor.Header" xml:space="preserve">
<value>中间间隙区域高度系数</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>播放测试音乐</value>
</data>
@@ -1276,6 +1306,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>重启应用以应用更改</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右间隙区域宽度因子</value>
</data>
<data name="SettingsPageRomaji.Header" xml:space="preserve">
<value>日语注音</value>
</data>
@@ -1345,6 +1378,9 @@
<data name="SettingsPageShowInSwitchers.Header" xml:space="preserve">
<value>在系统环境中显示</value>
</data>
<data name="SettingsPageShowLayoutDragger.Header" xml:space="preserve">
<value>显示布局拆分器</value>
</data>
<data name="SettingsPageShowTitle.Header" xml:space="preserve">
<value>显示标题</value>
</data>
@@ -1357,16 +1393,10 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲信息</value>
</data>
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
<value>对齐方式</value>
</data>
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
<value>居中</value>
</data>
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
@@ -1429,6 +1459,15 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入与切出快捷键</value>
</data>
<data name="SettingsPageTopGapFactor.Header" xml:space="preserve">
<value>顶部间隙区域高度因子</value>
</data>
<data name="SettingsPageTrackSummaryColFactor.Header" xml:space="preserve">
<value>曲目摘要区域宽度因子</value>
</data>
<data name="SettingsPageTrackSummaryRowFactor.Header" xml:space="preserve">
<value>曲目摘要区域高度系数</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
@@ -1447,6 +1486,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本号</value>
</data>
<data name="SettingsPageVerticalLayoutFactor.Text" xml:space="preserve">
<value>垂直布局系数</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
@@ -1513,4 +1555,7 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>使用指南</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
</root>

View File

@@ -130,7 +130,7 @@
<value>畫中畫模式</value>
</data>
<data name="AppSettingsControlGeneral.Text" xml:space="preserve">
<value>一般</value>
<value>视窗</value>
</data>
<data name="ArtistsSplitHint.Text" xml:space="preserve">
<value>鍵入多位藝術家時請以下述一種分隔符號分隔(不要混用)</value>
@@ -607,6 +607,9 @@
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>專輯區域樣式</value>
</data>
<data name="SettingsPageAlignment.Header" xml:space="preserve">
<value>對齊方式</value>
</data>
<data name="SettingsPageAmllTtmlDbBaseUrl.Header" xml:space="preserve">
<value>基本網址</value>
</data>
@@ -664,12 +667,18 @@
<data name="SettingsPageBorderlessHotKey.Header" xml:space="preserve">
<value>無邊框歌詞視窗捷徑</value>
</data>
<data name="SettingsPageBottomGapFactor.Header" xml:space="preserve">
<value>底部間隙高度因子</value>
</data>
<data name="SettingsPageCache.Description" xml:space="preserve">
<value>包括日誌文件,網絡歌詞緩存</value>
</data>
<data name="SettingsPageCache.Header" xml:space="preserve">
<value>快取</value>
</data>
<data name="SettingsPageCenter.Content" xml:space="preserve">
<value>居中</value>
</data>
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value>
</data>
@@ -859,6 +868,9 @@
<data name="SettingsPageFullscreenMode.Text" xml:space="preserve">
<value>全螢幕模式</value>
</data>
<data name="SettingsPageGeneralLayoutFactor.Text" xml:space="preserve">
<value>一般布局系數</value>
</data>
<data name="SettingsPageHeight.Header" xml:space="preserve">
<value>高度</value>
</data>
@@ -871,6 +883,9 @@
<data name="SettingsPageHoldDragSort.Content" xml:space="preserve">
<value>按住這裡並拖曳以進行排序</value>
</data>
<data name="SettingsPageHorizontalLayoutFactor.Text" xml:space="preserve">
<value>水平布局系數</value>
</data>
<data name="SettingsPageImport.Content" xml:space="preserve">
<value>匯入</value>
</data>
@@ -925,6 +940,9 @@
<data name="SettingsPageLastFMUsername.Header" xml:space="preserve">
<value>使用者名稱</value>
</data>
<data name="SettingsPageLayout.Text" xml:space="preserve">
<value>佈局</value>
</data>
<data name="SettingsPageLayoutOrientation.Header" xml:space="preserve">
<value>版面配置方向</value>
</data>
@@ -934,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>縱向</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左間隙區域寬度因子</value>
</data>
<data name="SettingsPageLibreTranslateServer.Header" xml:space="preserve">
<value>服務器地址</value>
</data>
@@ -982,8 +1003,8 @@
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>粗體</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>居中</value>
<data name="SettingsPageLyricsColFactor.Header" xml:space="preserve">
<value>歌詞區域寬度因子</value>
</data>
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>歌詞動效</value>
@@ -1045,9 +1066,6 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮顯示範圍</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>細體</value>
</data>
@@ -1075,8 +1093,14 @@
<data name="SettingsPageLyricsRendingScopeLineStartToCurrentChar.Content" xml:space="preserve">
<value>當前歌詞開始到當前字符</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>靠右</value>
<data name="SettingsPageLyricsRowFactor.Header" xml:space="preserve">
<value>歌詞區域高度因子</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Description" xml:space="preserve">
<value>啟用長期音節的縮放功能</value>
</data>
<data name="SettingsPageLyricsScaleEffect.Header" xml:space="preserve">
<value>縮放效果</value>
</data>
<data name="SettingsPageLyricsSearchBestMatch.Content" xml:space="preserve">
<value>最佳匹配</value>
@@ -1159,6 +1183,12 @@
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>雲母(替代樣式)</value>
</data>
<data name="SettingsPageMiddleGapColFactor.Header" xml:space="preserve">
<value>中間區域間隙寬度因子</value>
</data>
<data name="SettingsPageMiddleGapRowFactor.Header" xml:space="preserve">
<value>中間間隙區域高度因子</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>播放測試音樂</value>
</data>
@@ -1276,6 +1306,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>重啟應用程式以應用更改</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右間隙區域寬度因子</value>
</data>
<data name="SettingsPageRomaji.Header" xml:space="preserve">
<value>日語注音</value>
</data>
@@ -1334,7 +1367,7 @@
<value>顯示專輯</value>
</data>
<data name="SettingsPageShowArtists.Header" xml:space="preserve">
<value>界面設計</value>
<value>顯示藝術家</value>
</data>
<data name="SettingsPageShowHideHotKey.Header" xml:space="preserve">
<value>歌詞窗口顯示和隱藏快捷鍵</value>
@@ -1345,6 +1378,9 @@
<data name="SettingsPageShowInSwitchers.Header" xml:space="preserve">
<value>在系統環境中顯示</value>
</data>
<data name="SettingsPageShowLayoutDragger.Header" xml:space="preserve">
<value>顯示佈局拆分器</value>
</data>
<data name="SettingsPageShowTitle.Header" xml:space="preserve">
<value>顯示標題</value>
</data>
@@ -1357,16 +1393,10 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲資訊</value>
</data>
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
<value>對齊方式</value>
</data>
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
<value>居中</value>
</data>
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
@@ -1429,6 +1459,15 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入與切出快捷鍵</value>
</data>
<data name="SettingsPageTopGapFactor.Header" xml:space="preserve">
<value>頂部間隙區域高度因子</value>
</data>
<data name="SettingsPageTrackSummaryColFactor.Header" xml:space="preserve">
<value>曲目摘要區域寬度因子</value>
</data>
<data name="SettingsPageTrackSummaryRowFactor.Header" xml:space="preserve">
<value>曲目摘要區域高度因子</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>譯文</value>
</data>
@@ -1447,6 +1486,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本號</value>
</data>
<data name="SettingsPageVerticalLayoutFactor.Text" xml:space="preserve">
<value>垂直布局系數</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
@@ -1513,4 +1555,7 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>使用手冊</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
</root>

View File

@@ -26,35 +26,14 @@ using Windows.Storage.Streams;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class LyricsPageViewModel : BaseViewModel,
IRecipient<PropertyChangedMessage<BitmapImage?>>,
IRecipient<PropertyChangedMessage<LyricsLayoutOrientation>>,
IRecipient<PropertyChangedMessage<LyricsDisplayType>>
public partial class LyricsPageViewModel : BaseViewModel
{
public IMediaSessionsService MediaSessionsService { get; private set; }
private readonly ILiveStatesService _liveStatesService;
private readonly ThrottleHelper _timelineThrottle = new(TimeSpan.FromSeconds(1));
[ObservableProperty] public partial double AlbumArtWithSongInfoStackPanelHeight { get; set; } = 0;
[ObservableProperty] public partial double LastAlbumArtOpacity { get; set; } = 1;
[ObservableProperty] public partial double AlbumArtOpacity { get; set; } = 1;
[ObservableProperty] public partial BitmapImage? LastAlbumArtBitmapImage { get; set; }
[ObservableProperty] public partial BitmapImage? AlbumArtBitmapImage { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsX { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsY { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsWidth { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsOpacity { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Matrix4x4 Lyrics3DMatrix { get; set; } = Matrix4x4.Identity;
[ObservableProperty]
public partial LiveStates LiveStates { get; set; }
[ObservableProperty]
public partial double TimelinePositionSeconds { get; set; }
[ObservableProperty]
public partial int Volume { get; set; }
@@ -73,9 +52,6 @@ namespace BetterLyrics.WinUI3.ViewModels
[ObservableProperty]
public partial double TimelineSliderThumbSeconds { get; set; } = 0;
[ObservableProperty]
public partial double SongInfoOpacity { get; set; } = 1;
public LyricsPageViewModel(IMediaSessionsService mediaSessionsService, ILiveStatesService liveStatesService)
{
_liveStatesService = liveStatesService;
@@ -127,47 +103,5 @@ namespace BetterLyrics.WinUI3.ViewModels
await MediaSessionsService.NextAsync();
}
public async void Receive(PropertyChangedMessage<BitmapImage?> message)
{
if (message.Sender is IMediaSessionsService)
{
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtBitmapImage))
{
LastAlbumArtBitmapImage = AlbumArtBitmapImage;
LastAlbumArtOpacity = 1;
await Task.Delay(Constants.Time.AnimationDuration);
AlbumArtOpacity = 0;
await Task.Delay(Constants.Time.AnimationDuration);
AlbumArtBitmapImage = message.NewValue;
LastAlbumArtOpacity = 0;
AlbumArtOpacity = 1;
}
}
}
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();
}
}
}
}
}

View File

@@ -29,184 +29,263 @@
<!-- Win2D drawing area -->
<uc:NowPlayingCanvas x:Name="NowPlayingCanvas" />
<!-- Album art and song info area -->
<StackPanel
x:Name="AlbumArtWithSongInfoStackPanel"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Orientation="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Converter={StaticResource LyricsLayoutOrientationNegationToOrientationConverter}, Mode=OneWay}"
SizeChanged="AlbumArtWithSongInfoStackPanel_SizeChanged"
Translation="0,0,0">
<StackPanel.TranslationTransition>
<Vector3Transition />
</StackPanel.TranslationTransition>
<Grid x:Name="TrackSummaryGridContainer" Loaded="TrackSummaryGridContainer_Loaded">
<Grid.RowDefinitions>
<RowDefinition x:Name="TopGapDef" Height="*" />
<RowDefinition x:Name="TrackSummaryRowDef" Height="*" />
<RowDefinition x:Name="MiddleGapRowDef" Height="*" />
<RowDefinition x:Name="LyricsRowDef" Height="*" />
<RowDefinition x:Name="BottomGapDef" Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftGapDef" Width="*" />
<ColumnDefinition x:Name="TrackSummaryColDef" Width="*" />
<ColumnDefinition x:Name="MiddleGapColDef" Width="*" />
<ColumnDefinition x:Name="LyricsColDef" Width="*" />
<ColumnDefinition x:Name="RightGapDef" Width="*" />
</Grid.ColumnDefinitions>
<!-- Album art -->
<Grid Padding="32">
<!-- Album art and song info area -->
<Grid
x:Name="TrackSummaryGrid"
Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.AlbumArtAlignmentType, Mode=OneWay}"
VerticalAlignment="Center"
SizeChanged="TrackSummaryGrid_SizeChanged">
<Grid.RowDefinitions>
<RowDefinition x:Name="AlbumArtRowDef" Height="*" />
<RowDefinition x:Name="SongInfoRowDef" Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="AlbumArtColDef" Width="*" />
<ColumnDefinition x:Name="SongInfoColDef" Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.OpacityTransition>
<ScalarTransition />
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Grid.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="0">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="1">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<Grid x:Name="ShadowCastGrid" CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}">
<Image
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Height="{x:Bind AlbumArtSize, Mode=OneWay}"
Opacity="{x:Bind ViewModel.LastAlbumArtOpacity, Mode=OneWay}"
Source="{x:Bind ViewModel.LastAlbumArtBitmapImage, Mode=OneWay}">
<Image.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Image.OpacityTransition>
</Image>
<Image
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Height="{x:Bind AlbumArtSize, Mode=OneWay}"
Opacity="{x:Bind ViewModel.AlbumArtOpacity, Mode=OneWay}"
Source="{x:Bind ViewModel.AlbumArtBitmapImage, Mode=OneWay}">
<Image.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Image.OpacityTransition>
</Image>
<dev:AnimatedImage ImageUrl="" />
<!-- Album art -->
<Grid
x:Name="AlbumArtGrid"
Grid.Row="0"
Padding="32"
HorizontalAlignment="Center">
<Grid.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Grid.OpacityTransition>
<Grid x:Name="ShadowCastGrid" CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}">
<Image x:Name="LastAlbumArtImage" Stretch="Uniform">
<Image.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Image.OpacityTransition>
</Image>
<Image x:Name="AlbumArtImage" Stretch="Uniform">
<Image.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Image.OpacityTransition>
</Image>
</Grid>
<Border
x:Name="ShadowRect"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}"
Loaded="ShadowRect_Loaded"
Translation="0,0,0">
<Border.Shadow>
<ThemeShadow x:Name="Shadow" />
</Border.Shadow>
</Border>
</Grid>
<Border
x:Name="ShadowRect"
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Height="{x:Bind AlbumArtSize, Mode=OneWay}"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}"
Loaded="ShadowRect_Loaded"
Translation="0,0,64">
<Border.Shadow>
<ThemeShadow x:Name="Shadow" />
</Border.Shadow>
</Border>
<!-- Song info -->
<StackPanel x:Name="SongInfoStackPanel">
<StackPanel.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</StackPanel.OpacityTransition>
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="TitleAutoScrollHoverEffectView"
IsPlaying="False"
PointerCanceled="TitleAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="TitleAutoScrollHoverEffectView_PointerEntered"
PointerExited="TitleAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="TitleTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowTitle, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="ArtistsAutoScrollHoverEffectView"
IsPlaying="False"
PointerCanceled="ArtistsAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="ArtistsAutoScrollHoverEffectView_PointerEntered"
PointerExited="ArtistsAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="ArtistsTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
Opacity="0.5"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowArtists, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="AlbumAutoScrollHoverEffectView"
IsPlaying="False"
PointerCanceled="AlbumAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="AlbumAutoScrollHoverEffectView_PointerEntered"
PointerExited="AlbumAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="AlbumTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
Opacity="0.5"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowAlbum, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
</StackPanel>
</Grid>
<!-- Song info -->
<StackPanel x:Name="SongInfoStackPanel" Width="{x:Bind AlbumArtSize, Mode=OneWay}">
<StackPanel.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</StackPanel.OpacityTransition>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="0">
<interactivity:ChangePropertyAction PropertyName="Margin" Value="32,-16,32,0" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="1">
<interactivity:ChangePropertyAction PropertyName="Margin" Value="-16,32,0,0" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<Grid
x:Name="LyricsPlaceholder"
Grid.Row="3"
Grid.Column="3"
SizeChanged="LyricsPlaceholder_SizeChanged" />
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="TitleAutoScrollHoverEffectView"
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Padding="5,0,0,0"
IsPlaying="False"
PointerCanceled="TitleAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="TitleAutoScrollHoverEffectView_PointerEntered"
PointerExited="TitleAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="TitleTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowTitle, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
<uc:Dragger
x:Name="LeftGapDragger"
Grid.RowSpan="5"
Grid.Column="0"
Margin="0,0,-8,0"
HorizontalAlignment="Right"
DragDelta="LeftGapDragger_DragDelta">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="TrackSummaryColDragger"
Grid.RowSpan="5"
Grid.Column="1"
Margin="0,0,-8,0"
HorizontalAlignment="Right"
DragDelta="TrackSummaryColDragger_DragDelta">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="MiddleColDragger"
Grid.RowSpan="5"
Grid.Column="2"
Margin="0,0,-8,0"
HorizontalAlignment="Right"
DragDelta="MiddleColDragger_DragDelta">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="LyricsColDragger"
Grid.RowSpan="5"
Grid.Column="3"
Margin="0,0,-8,0"
HorizontalAlignment="Right"
DragDelta="LyricsColDragger_DragDelta">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="ArtistsAutoScrollHoverEffectView"
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Padding="5,0,0,0"
IsPlaying="False"
PointerCanceled="ArtistsAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="ArtistsAutoScrollHoverEffectView_PointerEntered"
PointerExited="ArtistsAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="ArtistsTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
Opacity="0.5"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowArtists, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
<uc:Dragger
x:Name="TopGapDragger"
Grid.Row="0"
Grid.ColumnSpan="5"
Margin="0,0,0,-8"
VerticalAlignment="Bottom"
DragDelta="TopGapDragger_DragDelta"
Orientation="Horizontal">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="TrackSummaryRowDragger"
Grid.Row="1"
Grid.ColumnSpan="5"
Margin="0,0,0,-8"
VerticalAlignment="Bottom"
DragDelta="TrackSummaryRowDragger_DragDelta"
Orientation="Horizontal">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="MiddleRowDragger"
Grid.Row="2"
Grid.ColumnSpan="5"
Margin="0,0,0,-8"
VerticalAlignment="Bottom"
DragDelta="MiddleRowDragger_DragDelta"
Orientation="Horizontal">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<uc:Dragger
x:Name="LyricsRowDragger"
Grid.Row="3"
Grid.ColumnSpan="5"
Margin="0,0,0,-8"
VerticalAlignment="Bottom"
DragDelta="LyricsRowDragger_DragDelta"
Orientation="Horizontal">
<uc:Dragger.OpacityTransition>
<ScalarTransition />
</uc:Dragger.OpacityTransition>
</uc:Dragger>
<dev:OpacityMaskView>
<dev:OpacityMaskView.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Offset="0" Color="Transparent" />
<GradientStop Offset="0.02" Color="#FFFFFFFF" />
<GradientStop Offset="0.98" Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="Transparent" />
</LinearGradientBrush>
</dev:OpacityMaskView.OpacityMask>
<dev:AutoScrollView
x:Name="AlbumAutoScrollHoverEffectView"
Width="{x:Bind AlbumArtSize, Mode=OneWay}"
Padding="5,0,0,0"
IsPlaying="False"
PointerCanceled="AlbumAutoScrollHoverEffectView_PointerCanceled"
PointerEntered="AlbumAutoScrollHoverEffectView_PointerEntered"
PointerExited="AlbumAutoScrollHoverEffectView_PointerExited"
ScrollingPixelsPreSecond="20">
<TextBlock
x:Name="AlbumTextBlock"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoAlignmentType, Converter={StaticResource TextAlignmentTypeToHorizontalAlignmentConverter}, Mode=OneWay}"
FontWeight="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight, Converter={StaticResource LyricsFontWeightToFontWeightConverter}, Mode=OneWay}"
Opacity="0.5"
TextTrimming="None"
Visibility="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.ShowAlbum, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
</dev:AutoScrollView>
</dev:OpacityMaskView>
</StackPanel>
</StackPanel>
</Grid>
<!-- Bottom command area -->
<Grid

View File

@@ -20,7 +20,9 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Diagnostics;
using System.Numerics;
using System.Threading.Tasks;
@@ -30,28 +32,16 @@ namespace BetterLyrics.WinUI3.Views
IRecipient<PropertyChangedMessage<int>>,
IRecipient<PropertyChangedMessage<bool>>,
IRecipient<PropertyChangedMessage<string>>,
IRecipient<PropertyChangedMessage<SongInfo?>>
IRecipient<PropertyChangedMessage<double>>,
IRecipient<PropertyChangedMessage<SongInfo?>>,
IRecipient<PropertyChangedMessage<BitmapImage?>>,
IRecipient<PropertyChangedMessage<LyricsLayoutOrientation>>,
IRecipient<PropertyChangedMessage<LyricsDisplayType>>
{
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
private readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
private double _leftMargin = 36f;
private double _middleMargin = 36f;
private double _rightMargin = 36f;
private double _topMargin = 36f;
private double _bottomMargin = 36f;
private readonly DispatcherQueueTimer _rootGridSizeChangedTimer;
public double AlbumArtSize
{
get { return (double)GetValue(AlbumArtSizeProperty); }
set { SetValue(AlbumArtSizeProperty, value); }
}
public static readonly DependencyProperty AlbumArtSizeProperty =
DependencyProperty.Register(nameof(AlbumArtSize), typeof(double), typeof(NowPlayingCanvas), new PropertyMetadata(0.0));
private double _startWidth;
public CornerRadius AlbumArtCornerRadius
{
@@ -62,6 +52,16 @@ namespace BetterLyrics.WinUI3.Views
public static readonly DependencyProperty AlbumArtCornerRadiusProperty =
DependencyProperty.Register(nameof(AlbumArtCornerRadius), typeof(double), typeof(NowPlayingCanvas), new PropertyMetadata(new CornerRadius(0)));
public double AlbumArtSize
{
get { return (double)GetValue(AlbumArtSizeProperty); }
set { SetValue(AlbumArtSizeProperty, value); }
}
public static readonly DependencyProperty AlbumArtSizeProperty =
DependencyProperty.Register(nameof(AlbumArtSize), typeof(double), typeof(NowPlayingCanvas), new PropertyMetadata(0.0));
public LyricsPageViewModel ViewModel => (LyricsPageViewModel)DataContext;
public LyricsPage()
@@ -74,8 +74,10 @@ namespace BetterLyrics.WinUI3.Views
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<bool>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<string>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<SongInfo?>>(this);
_rootGridSizeChangedTimer = App.Current.Resources.DispatcherQueue.CreateTimer();
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<BitmapImage?>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsLayoutOrientation>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsDisplayType>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<double>>(this);
}
private void CompositionTarget_Rendering(object? sender, object e)
@@ -84,6 +86,26 @@ namespace BetterLyrics.WinUI3.Views
TimelineSlider.Value = currentTime;
}
// ==== SongInfo
private int GetTitleFontSize()
{
var albumArtLayoutSettings = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings;
if (albumArtLayoutSettings.IsAutoSongInfoFontSize)
{
return (int)Math.Clamp(Math.Min(RootGrid.ActualHeight, RootGrid.ActualWidth) / 20, 8, 72);
}
else
{
return albumArtLayoutSettings.SongInfoFontSize;
}
}
private int GetArtistsAlbumFontSize()
{
return (int)(GetTitleFontSize() * 0.8);
}
private void RenderTextBlock(TextBlock? sender, string? text, int fontSize)
{
if (sender == null || string.IsNullOrEmpty(text) || fontSize == 0) return;
@@ -119,131 +141,105 @@ namespace BetterLyrics.WinUI3.Views
RenderTextBlock(AlbumTextBlock, _mediaSessionsService.CurrentSongInfo?.Album, GetArtistsAlbumFontSize());
}
private void UpdateAlbumArtSize()
private void UpdateSongInfoOpacity()
{
var lyricsWindowStatus = _liveStatesService.LiveStates.LyricsWindowStatus;
var albumArtLayoutSettings = lyricsWindowStatus.AlbumArtLayoutSettings;
double temp = 0;
switch (lyricsWindowStatus.LyricsLayoutOrientation)
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
{
case LyricsLayoutOrientation.Horizontal:
if (albumArtLayoutSettings.AutoAlbumArtSize)
{
temp = Math.Min(
(RootGrid.ActualHeight - _topMargin - _bottomMargin) * 8.5 / 16.0,
(RootGrid.ActualWidth - _leftMargin - _middleMargin - _rightMargin) / 2.0);
}
else
{
temp = albumArtLayoutSettings.AlbumArtSize;
}
case LyricsDisplayType.AlbumArtOnly:
SongInfoStackPanel.Opacity = 1;
break;
case LyricsLayoutOrientation.Vertical:
if (albumArtLayoutSettings.AutoAlbumArtSize)
{
temp = Math.Min(
(RootGrid.ActualHeight - _topMargin - _bottomMargin) * 3.0 / 16.0,
(RootGrid.ActualWidth - _leftMargin - _middleMargin - _rightMargin) * 4.0 / 16.0);
}
else
{
temp = albumArtLayoutSettings.AlbumArtSize;
}
case LyricsDisplayType.LyricsOnly:
SongInfoStackPanel.Opacity = 0;
break;
case LyricsDisplayType.SplitView:
SongInfoStackPanel.Opacity = 1;
break;
default:
break;
}
AlbumArtSize = Math.Max(0, temp);
}
private void UpdateSongInfoMargin()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
SongInfoStackPanel.Margin = new(32, -16, 32, 0);
break;
case LyricsLayoutOrientation.Vertical:
SongInfoStackPanel.Margin = new(-16, 32, 0, 0);
break;
}
}
private void UpdateTrackSummaryGridMargin()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
TrackSummaryGrid.Margin = new(-32, -32, -32, 0);
break;
case LyricsLayoutOrientation.Vertical:
TrackSummaryGrid.Margin = new(-32, -32, 0, -32);
break;
}
}
// ==== AlbumArt
private void UpdateAlbumArtCornerRadius()
{
var factor = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageRadius / 100.0;
AlbumArtCornerRadius = new((AlbumArtSize / 2) * factor);
AlbumArtCornerRadius = new((AlbumArtImage.ActualHeight / 2) * factor);
}
private double GetAlbumArtY()
private void UpdateAlbumArtShadow()
{
double temp = 0;
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
var amount = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.CoverImageShadowAmount;
ShadowRect.Translation = new(0, 0, amount);
}
private void UpdateAlbumArtOpacity()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
{
case LyricsLayoutOrientation.Horizontal:
temp = (RootGrid.ActualHeight - AlbumArtWithSongInfoStackPanel.ActualHeight) / 2.0;
case LyricsDisplayType.AlbumArtOnly:
AlbumArtGrid.Opacity = 1;
break;
case LyricsLayoutOrientation.Vertical:
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
{
case LyricsDisplayType.AlbumArtOnly:
temp = (RootGrid.ActualHeight - AlbumArtSize) / 2.0;
break;
case LyricsDisplayType.SplitView:
temp = _topMargin;
break;
default:
break;
}
case LyricsDisplayType.LyricsOnly:
AlbumArtGrid.Opacity = 0;
break;
case LyricsDisplayType.SplitView:
AlbumArtGrid.Opacity = 1;
break;
default:
break;
}
return (float)temp - 32;
}
private double GetAlbumArtX()
// ====
private void UpdateTrackSummaryGridSpan()
{
double temp = 0;
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
switch (status.LyricsDisplayType)
{
case LyricsLayoutOrientation.Horizontal:
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
case LyricsDisplayType.AlbumArtOnly:
Grid.SetRowSpan(TrackSummaryGrid, 3);
Grid.SetColumnSpan(TrackSummaryGrid, 3);
break;
case LyricsDisplayType.LyricsOnly:
break;
case LyricsDisplayType.SplitView:
switch (status.LyricsLayoutOrientation)
{
case LyricsDisplayType.AlbumArtOnly:
temp = RootGrid.ActualWidth / 2.0 - AlbumArtSize / 2.0;
case LyricsLayoutOrientation.Horizontal:
Grid.SetRowSpan(TrackSummaryGrid, 3);
Grid.SetColumnSpan(TrackSummaryGrid, 1);
break;
case LyricsDisplayType.SplitView:
temp = _leftMargin + ((RootGrid.ActualWidth - _leftMargin - _middleMargin - _rightMargin) / 2.0 - AlbumArtSize) / 2.0;
break;
default:
break;
}
break;
case LyricsLayoutOrientation.Vertical:
temp = _leftMargin;
break;
default:
break;
}
return (float)temp - 32;
}
private void UpdateAlbumArtTranslation()
{
var x = GetAlbumArtX();
var y = GetAlbumArtY();
AlbumArtWithSongInfoStackPanel.Translation = new((float)x, (float)y, 0);
}
private void UpdateMargin()
{
_topMargin = _bottomMargin = _leftMargin = _middleMargin = _rightMargin = Math.Max(RootGrid.ActualWidth, RootGrid.ActualHeight) / 30.0;
}
private void UpdateLyricsStartY()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
NowPlayingCanvas.LyricsStartY = 0;
break;
case LyricsLayoutOrientation.Vertical:
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
{
case LyricsDisplayType.LyricsOnly:
NowPlayingCanvas.LyricsStartY = 0;
break;
case LyricsDisplayType.SplitView:
NowPlayingCanvas.LyricsStartY = _topMargin;
case LyricsLayoutOrientation.Vertical:
Grid.SetRowSpan(TrackSummaryGrid, 1);
Grid.SetColumnSpan(TrackSummaryGrid, 3);
break;
default:
break;
@@ -254,6 +250,52 @@ namespace BetterLyrics.WinUI3.Views
}
}
// ====
private void UpdateSongInfoStackPanelSpan()
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
switch (status.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
Grid.SetRow(SongInfoStackPanel, 1);
Grid.SetColumn(SongInfoStackPanel, 0);
Grid.SetRowSpan(SongInfoStackPanel, 1);
Grid.SetColumnSpan(SongInfoStackPanel, 2);
break;
case LyricsLayoutOrientation.Vertical:
Grid.SetRow(SongInfoStackPanel, 0);
Grid.SetColumn(SongInfoStackPanel, 1);
Grid.SetRowSpan(SongInfoStackPanel, 2);
Grid.SetColumnSpan(SongInfoStackPanel, 1);
break;
default:
break;
}
}
// ====
private void UpdateAlbumArtGridSpan()
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
switch (status.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
Grid.SetRowSpan(AlbumArtGrid, 1);
Grid.SetColumnSpan(AlbumArtGrid, 2);
break;
case LyricsLayoutOrientation.Vertical:
Grid.SetRowSpan(AlbumArtGrid, 2);
Grid.SetColumnSpan(AlbumArtGrid, 1);
break;
default:
break;
}
}
// ==== Lyrics
private void UpdateLyricsOpacity()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
@@ -270,98 +312,208 @@ namespace BetterLyrics.WinUI3.Views
}
}
private void UpdateLyricsStartX()
private void UpdateLyricsLayout()
{
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation)
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
switch (status.LyricsDisplayType)
{
case LyricsLayoutOrientation.Horizontal:
switch (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsDisplayType)
case LyricsDisplayType.AlbumArtOnly:
break;
case LyricsDisplayType.LyricsOnly:
NowPlayingCanvas.LyricsStartX = LeftGapDef.ActualWidth;
NowPlayingCanvas.LyricsStartY = TopGapDef.ActualHeight;
NowPlayingCanvas.LyricsWidth = TrackSummaryColDef.ActualWidth + MiddleGapColDef.ActualWidth + LyricsColDef.ActualWidth;
NowPlayingCanvas.LyricsHeight = TrackSummaryRowDef.ActualHeight + MiddleGapRowDef.ActualHeight + LyricsRowDef.ActualHeight;
break;
case LyricsDisplayType.SplitView:
switch (status.LyricsLayoutOrientation)
{
case LyricsDisplayType.LyricsOnly:
NowPlayingCanvas.LyricsStartX = _leftMargin;
case LyricsLayoutOrientation.Horizontal:
NowPlayingCanvas.LyricsStartX = LeftGapDef.ActualWidth + TrackSummaryColDef.ActualWidth + MiddleGapColDef.ActualWidth;
NowPlayingCanvas.LyricsStartY = TopGapDef.ActualHeight;
NowPlayingCanvas.LyricsWidth = LyricsColDef.ActualWidth;
NowPlayingCanvas.LyricsHeight = TrackSummaryRowDef.ActualHeight + MiddleGapRowDef.ActualHeight + LyricsRowDef.ActualHeight;
break;
case LyricsDisplayType.SplitView:
NowPlayingCanvas.LyricsStartX = (RootGrid.ActualWidth - _leftMargin - _middleMargin - _rightMargin) / 2.0 + _leftMargin + _middleMargin;
case LyricsLayoutOrientation.Vertical:
NowPlayingCanvas.LyricsStartX = LeftGapDef.ActualWidth;
NowPlayingCanvas.LyricsStartY = TopGapDef.ActualHeight + TrackSummaryRowDef.ActualHeight + MiddleGapRowDef.ActualHeight;
NowPlayingCanvas.LyricsWidth = TrackSummaryColDef.ActualWidth + MiddleGapColDef.ActualWidth + LyricsColDef.ActualWidth;
NowPlayingCanvas.LyricsHeight = LyricsRowDef.ActualHeight;
break;
default:
break;
}
break;
case LyricsLayoutOrientation.Vertical:
NowPlayingCanvas.LyricsStartX = _leftMargin;
break;
default:
break;
}
}
private void UpdateLyricsWidth()
{
NowPlayingCanvas.LyricsWidth = Math.Max(RootGrid.ActualWidth - NowPlayingCanvas.LyricsStartX - _rightMargin, 0);
}
// ====
private void OnLayoutChanged()
{
UpdateMargin();
UpdateSongInfoOpacity();
UpdateSongInfoMargin();
UpdateAlbumArtShadow();
UpdateAlbumArtOpacity();
UpdateTrackSummaryGridMargin();
UpdateTrackSummaryGridSpan();
UpdateAlbumArtGridSpan();
UpdateSongInfoStackPanelSpan();
UpdateLyricsOpacity();
UpdateLyricsLayout();
UpdateAlbumArtSize();
UpdateAlbumArtCornerRadius();
UpdateAlbumArtTranslation();
UpdateLyricsStartX();
UpdateLyricsStartY();
UpdateLyricsWidth();
UpdateLayoutDraggerOpacity();
}
private int GetTitleFontSize()
private void UpdateGapFactor()
{
var albumArtLayoutSettings = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings;
if (albumArtLayoutSettings.IsAutoSongInfoFontSize)
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
status.LeftGapFactor = LeftGapDef.ActualWidth;
status.TopGapFactor = TopGapDef.ActualHeight;
status.RightGapFactor = RightGapDef.ActualWidth;
status.BottomGapFactor = BottomGapDef.ActualHeight;
status.TrackSummaryColGapFactor = TrackSummaryColDef.ActualWidth;
status.MiddleColGapFactor = MiddleGapColDef.ActualWidth;
status.LyricsColGapFactor = LyricsColDef.ActualWidth;
status.TrackSummaryRowGapFactor = TrackSummaryRowDef.ActualHeight;
status.MiddleRowGapFactor = MiddleGapRowDef.ActualHeight;
status.LyricsRowGapFactor = LyricsRowDef.ActualHeight;
}
private void OnRowDraggerDragDelta(RowDefinition sender, DragDeltaEventArgs e)
{
double current = sender.ActualHeight;
current += e.VerticalChange;
if (current <= 16) return;
sender.Height = new GridLength(current);
UpdateGapFactor();
}
private void OnColDraggerDragDelta(ColumnDefinition sender, DragDeltaEventArgs e)
{
double current = sender.ActualWidth;
current += e.HorizontalChange;
if (current <= 16) return;
sender.Width = new GridLength(current);
UpdateGapFactor();
}
private void UpdateLayoutDraggerOpacity()
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
if (status.ShowLayoutIndicator)
{
return (int)Math.Clamp(Math.Min(RootGrid.ActualHeight, RootGrid.ActualWidth) / 20, 8, 72);
switch (status.LyricsDisplayType)
{
case LyricsDisplayType.AlbumArtOnly:
case LyricsDisplayType.LyricsOnly:
LeftGapDragger.Opacity = 1;
TrackSummaryColDragger.Opacity = 0;
MiddleColDragger.Opacity = 0;
LyricsColDragger.Opacity = 1;
TopGapDragger.Opacity = 1;
TrackSummaryRowDragger.Opacity = 0;
MiddleRowDragger.Opacity = 0;
LyricsRowDragger.Opacity = 1;
break;
case LyricsDisplayType.SplitView:
switch (status.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
LeftGapDragger.Opacity = 1;
TrackSummaryColDragger.Opacity = 1;
MiddleColDragger.Opacity = 1;
LyricsColDragger.Opacity = 1;
TopGapDragger.Opacity = 1;
TrackSummaryRowDragger.Opacity = 0;
MiddleRowDragger.Opacity = 0;
LyricsRowDragger.Opacity = 1;
break;
case LyricsLayoutOrientation.Vertical:
LeftGapDragger.Opacity = 1;
TrackSummaryColDragger.Opacity = 0;
MiddleColDragger.Opacity = 0;
LyricsColDragger.Opacity = 1;
TopGapDragger.Opacity = 1;
TrackSummaryRowDragger.Opacity = 1;
MiddleRowDragger.Opacity = 1;
LyricsRowDragger.Opacity = 1;
break;
default:
break;
}
break;
default:
break;
}
}
else
{
return albumArtLayoutSettings.SongInfoFontSize;
}
}
LeftGapDragger.Opacity = 0;
TrackSummaryColDragger.Opacity = 0;
MiddleColDragger.Opacity = 0;
LyricsColDragger.Opacity = 0;
TopGapDragger.Opacity = 0;
TrackSummaryRowDragger.Opacity = 0;
MiddleRowDragger.Opacity = 0;
LyricsRowDragger.Opacity = 0;
}
private int GetArtistsAlbumFontSize()
{
return (int)(GetTitleFontSize() * 0.8);
}
// ====
private void RootGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
_rootGridSizeChangedTimer.Debounce(() =>
RenderSongInfo();
OnLayoutChanged();
if (e.NewSize.Width < 500 || e.NewSize.Height < 100)
{
RenderSongInfo();
OnLayoutChanged();
if (e.NewSize.Width < 500 || e.NewSize.Height < 100)
if (BottomCommandGrid.Children.Count != 0)
{
if (BottomCommandGrid.Children.Count != 0)
{
BottomCommandGrid.Children.Remove(BottomCommandContent);
BottomCommandFlyoutContainer.Children.Add(BottomCommandContent);
}
BottomCommandFlyoutTriggerHint.Translation = new Vector3(0, 0, 0);
BottomCommandGrid.Children.Remove(BottomCommandContent);
BottomCommandFlyoutContainer.Children.Add(BottomCommandContent);
}
else
BottomCommandFlyoutTriggerHint.Translation = new Vector3(0, 0, 0);
}
else
{
if (BottomCommandFlyoutContainer.Children.Count != 0)
{
if (BottomCommandFlyoutContainer.Children.Count != 0)
{
BottomCommandFlyout.Hide();
BottomCommandFlyoutContainer.Children.Remove(BottomCommandContent);
BottomCommandGrid.Children.Add(BottomCommandContent);
}
BottomCommandFlyoutTriggerHint.Translation = new Vector3(0, 12, 0);
BottomCommandFlyout.Hide();
BottomCommandFlyoutContainer.Children.Remove(BottomCommandContent);
BottomCommandGrid.Children.Add(BottomCommandContent);
}
}, Constants.Time.DebounceTimeout);
BottomCommandFlyoutTriggerHint.Translation = new Vector3(0, 12, 0);
}
}
private void BottomCommandGrid_PointerEntered(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
@@ -500,11 +652,6 @@ namespace BetterLyrics.WinUI3.Views
Shadow.Receivers.Add(ShadowCastGrid);
}
private void AlbumArtWithSongInfoStackPanel_SizeChanged(object sender, SizeChangedEventArgs e)
{
ViewModel.AlbumArtWithSongInfoStackPanelHeight = e.NewSize.Height;
}
private void TitleAutoScrollHoverEffectView_PointerCanceled(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
TitleAutoScrollHoverEffectView.IsPlaying = false;
@@ -560,6 +707,76 @@ namespace BetterLyrics.WinUI3.Views
CompositionTarget.Rendering -= CompositionTarget_Rendering;
}
private void LyricsPlaceholder_SizeChanged(object sender, SizeChangedEventArgs e)
{
OnLayoutChanged();
}
private void TrackSummaryGridContainer_Loaded(object sender, RoutedEventArgs e)
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
LeftGapDef.Width = new(status.LeftGapFactor, GridUnitType.Star);
TopGapDef.Height = new(status.TopGapFactor, GridUnitType.Star);
RightGapDef.Width = new(status.RightGapFactor, GridUnitType.Star);
BottomGapDef.Height = new(status.BottomGapFactor, GridUnitType.Star);
MiddleGapColDef.Width = new(status.MiddleColGapFactor, GridUnitType.Star);
MiddleGapRowDef.Height = new(status.MiddleRowGapFactor, GridUnitType.Star);
TrackSummaryColDef.Width = new(status.TrackSummaryColGapFactor, GridUnitType.Star);
TrackSummaryRowDef.Height = new(status.TrackSummaryRowGapFactor, GridUnitType.Star);
LyricsColDef.Width = new(status.LyricsColGapFactor, GridUnitType.Star);
LyricsRowDef.Height = new(status.LyricsRowGapFactor, GridUnitType.Star);
OnLayoutChanged();
}
private void TrackSummaryGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
}
private void LeftGapDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnColDraggerDragDelta(LeftGapDef, e);
}
private void TrackSummaryColDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnColDraggerDragDelta(TrackSummaryColDef, e);
}
private void MiddleColDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnColDraggerDragDelta(MiddleGapColDef, e);
}
private void LyricsColDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnColDraggerDragDelta(LyricsColDef, e);
}
private void TopGapDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnRowDraggerDragDelta(TopGapDef, e);
}
private void TrackSummaryRowDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnRowDraggerDragDelta(TrackSummaryRowDef, e);
}
private void MiddleRowDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnRowDraggerDragDelta(MiddleGapRowDef, e);
}
private void LyricsRowDragger_DragDelta(object sender, DragDeltaEventArgs e)
{
OnRowDraggerDragDelta(LyricsRowDef, e);
}
// ====
public void Receive(PropertyChangedMessage<int> message)
@@ -570,6 +787,14 @@ namespace BetterLyrics.WinUI3.Views
{
RenderSongInfo();
}
else if (message.PropertyName == nameof(AlbumArtLayoutSettings.CoverImageRadius))
{
UpdateAlbumArtCornerRadius();
}
else if (message.PropertyName == nameof(AlbumArtLayoutSettings.CoverImageShadowAmount))
{
UpdateAlbumArtShadow();
}
}
}
@@ -582,6 +807,13 @@ namespace BetterLyrics.WinUI3.Views
RenderSongInfo();
}
}
if (message.Sender is LyricsWindowStatus)
{
if (message.PropertyName == nameof(LyricsWindowStatus.ShowLayoutIndicator))
{
UpdateLayoutDraggerOpacity();
}
}
}
public void Receive(PropertyChangedMessage<string> message)
@@ -613,5 +845,109 @@ namespace BetterLyrics.WinUI3.Views
}
}
public async void Receive(PropertyChangedMessage<BitmapImage?> message)
{
if (message.Sender is IMediaSessionsService)
{
if (message.PropertyName == nameof(IMediaSessionsService.AlbumArtBitmapImage))
{
LastAlbumArtImage.Source = AlbumArtImage.Source;
LastAlbumArtImage.Opacity = 1;
await Task.Delay(Constants.Time.AnimationDuration);
AlbumArtImage.Opacity = 0;
await Task.Delay(Constants.Time.AnimationDuration);
AlbumArtImage.Source = message.NewValue;
LastAlbumArtImage.Opacity = 0;
AlbumArtImage.Opacity = 1;
UpdateAlbumArtCornerRadius();
}
}
}
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<double> message)
{
if (message.Sender is LyricsWindowStatus)
{
// ====
if (message.PropertyName == nameof(LyricsWindowStatus.LeftGapFactor))
{
LeftGapDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.LeftGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.TopGapFactor))
{
TopGapDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.TopGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.RightGapFactor))
{
RightGapDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.RightGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.BottomGapFactor))
{
BottomGapDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.BottomGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.MiddleColGapFactor))
{
MiddleGapColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.MiddleColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.MiddleRowGapFactor))
{
MiddleGapRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.MiddleRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.TrackSummaryColGapFactor))
{
TrackSummaryColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.TrackSummaryColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.TrackSummaryRowGapFactor))
{
TrackSummaryRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.TrackSummaryRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.LyricsColGapFactor))
{
LyricsColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.LyricsRowGapFactor))
{
LyricsRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsRowGapFactor, GridUnitType.Star);
}
}
}
}
}