Compare commits

..

69 Commits

Author SHA1 Message Date
Zhe Fang
a19a97345c chores: bump version code 2025-11-09 17:12:23 -05:00
Zhe Fang
8f12c27d2a chores 2025-11-09 17:00:54 -05:00
Zhe Fang
92f2f20957 fix: lyrics window white space 2025-11-09 14:23:22 -05:00
Zhe Fang
272802214b chores: fix readme 2025-11-08 19:40:39 -05:00
Zhe Fang
7f8455b14e chores: update readme 2025-11-08 19:38:04 -05:00
Zhe Fang
ad421a5541 chores: update readme 2025-11-08 19:33:23 -05:00
Zhe Fang
1eb1d2d72b feat: track stop; chores: ui/ux adjustments, bump version code. 2025-11-08 11:41:59 -05:00
Zhe Fang
252b7e4b25 chores: bump version code 2025-11-08 08:45:27 -05:00
Zhe Fang
bebcfa7819 fix: thread access issue related to ISettingsService 2025-11-08 08:21:31 -05:00
Zhe Fang
073ddfcaee fix: player fail to pass thumbnails 2025-11-07 21:06:37 -05:00
Zhe Fang
1775d947f9 chores: bump version code 2025-11-07 16:26:05 -05:00
Zhe Fang
a5d1831717 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-07 15:51:23 -05:00
Zhe Fang
d4a924accf feat: support presistent play queue and index, add settings item: auto open music gallery and auto play music; fix: auto scroll to playing track in play queue; 2025-11-07 15:51:21 -05:00
Zhe Fang
5d65314522 更新 README.md 2025-11-07 07:00:25 -05:00
Zhe Fang
0684069e52 更新 README.CN.md 2025-11-07 06:59:24 -05:00
Zhe Fang
fea617ff98 chores: edit readme 2025-11-06 17:17:44 -05:00
Zhe Fang
4b33776340 chores: update readme 2025-11-06 17:12:56 -05:00
Zhe Fang
ea73d7ed3b chores: add all deps link in readme 2025-11-06 14:23:40 -05:00
Zhe Fang
b8fd51cbe8 chores: bump version 2025-11-06 11:45:51 -05:00
Zhe Fang
004079a7ee feat: support create and import playlist; fix text in textbox overflow issue in search window; change in-app push style 2025-11-06 11:27:59 -05:00
Zhe Fang
30d1ccf67f chores: fix ui, add lyrics search window entry in system tray 2025-11-04 09:33:01 -05:00
Zhe Fang
a24885c277 chores: update readme 2025-11-03 19:37:46 -05:00
Zhe Fang
a207224bbf chores: add zh edition 2025-11-03 12:36:16 -05:00
Zhe Fang
2c80e0815a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-03 11:31:09 -05:00
Zhe Fang
7f65b4addb fix: handle device lost event 2025-11-03 11:31:07 -05:00
Zhe Fang
210df4dd61 Update README.md 2025-11-02 21:33:45 -05:00
Zhe Fang
3c82908890 Update README.md 2025-11-02 21:01:01 -05:00
Zhe Fang
597cc1ec9b Update README.md 2025-11-02 20:59:29 -05:00
Zhe Fang
e354e29ec1 chores: update version code 2025-11-02 19:10:46 -05:00
Zhe Fang
dd5fb91764 chores: add delay when automatically show and hide window 2025-11-02 17:16:40 -05:00
Zhe Fang
041459e564 chores: remove gain 2025-11-02 11:26:27 -05:00
Zhe Fang
7de813b645 fix: audio graph 2025-11-02 11:05:13 -05:00
Zhe Fang
838d663834 chores: add null check in SearchQQNeteaseKugouAsync; fix search page result display issue 2025-11-02 08:47:49 -05:00
Zhe Fang
9add190383 chores: add logo for some music players 2025-11-01 21:20:47 -04:00
Zhe Fang
fa58360884 chores: add pic in faq 2025-11-01 19:27:08 -04:00
Zhe Fang
4dd032655c fix: translation issue caused by mapping 2025-11-01 19:13:10 -04:00
Zhe Fang
80984218ec add: folder filter in music gallery page; chores: add pic screenshoots; 2025-11-01 15:53:15 -04:00
Zhe Fang
df45026638 chores: update readme 2025-10-31 21:04:29 -04:00
Zhe Fang
aafc5c9fb5 chores: update readme 2025-10-31 20:59:24 -04:00
Zhe Fang
c5fccfbb63 Update README.md 2025-10-31 20:44:57 -04:00
Zhe Fang
42f03b4291 chores: relayout pics in readme 2025-10-31 19:30:25 -04:00
Zhe Fang
3339bb0d41 chores: add screenshots in readme 2025-10-31 19:26:47 -04:00
Zhe Fang
7d60f29845 chores: fix kugou translation issue; fix audio graph issue; fix lyrics status switching between different monitors issue 2025-10-31 17:10:10 -04:00
Zhe Fang
bd7e93f3e6 chores: fix i18n issue 2025-10-30 21:29:08 -04:00
Zhe Fang
c37c6ab489 Update README.md 2025-10-30 21:24:50 -04:00
Zhe Fang
125794c44f Update README.md 2025-10-30 21:22:42 -04:00
Zhe Fang
f5bdb3a431 update readme and add snow flake effect 2025-10-30 21:20:06 -04:00
Zhe Fang
e15699bb11 fix: language display 2025-10-30 17:33:13 -04:00
Zhe Fang
780cd302f0 fix: pivot issue 2025-10-30 15:52:43 -04:00
Zhe Fang
345949f536 fix: windows status switching issues 2025-10-30 15:29:31 -04:00
Zhe Fang
8dd178991a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-29 20:05:52 -04:00
Zhe Fang
834d0bf5cc fix: search page language name display 2025-10-29 20:05:50 -04:00
Zhe Fang
6d6ecb39b6 Update README.md 2025-10-29 12:07:49 -04:00
Zhe Fang
7db7c68acc Update README.md 2025-10-29 12:06:04 -04:00
Zhe Fang
7fea4ac900 Update README.md 2025-10-29 09:24:50 -04:00
Zhe Fang
3783227f43 Update README.md 2025-10-29 09:06:44 -04:00
Zhe Fang
222c1d9aa1 chores: replace romaji convert package with a lightweight one; fix search control result lacking languages 2025-10-28 15:28:45 -04:00
Zhe Fang
4e668c9890 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-27 17:31:39 -04:00
Zhe Fang
a823901b13 fix: use x:Bind to prevent properties get function got lost after compiling 2025-10-27 17:31:38 -04:00
Zhe Fang
2f9b3df92c Update README.md 2025-10-27 15:01:36 -04:00
Zhe Fang
5f65021400 chores: support volume adjustment; add more lyrics language preview in search panel; fix audio graph not shown in release mode. 2025-10-27 14:52:32 -04:00
Zhe Fang
c28866fdbe fix: sc and tc convert issue 2025-10-26 22:46:34 -04:00
Zhe Fang
fc606f9d30 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-26 22:11:46 -04:00
Zhe Fang
e5d33177d4 feat: phonetic, original and translated text can be displayed at the same time; support set cjk and western font family individually; phonetic and translated font size can be adjusted 2025-10-26 22:11:44 -04:00
Zhe Fang
ab029c9da3 Update index.md 2025-10-26 10:13:29 -04:00
Zhe Fang
a28eef85a5 Update index.md 2025-10-26 10:12:55 -04:00
Zhe Fang
9905d7642c feature: 3d lyrics (x, y, z and depth) 2025-10-25 18:57:34 -04:00
Zhe Fang
02341ecc4a feature: add angle config for fan lyrics effect 2025-10-25 16:59:03 -04:00
Zhe Fang
13802e7d16 chores: update faq 2025-10-25 16:13:39 -04:00
145 changed files with 5643 additions and 2938 deletions

View File

@@ -44,7 +44,7 @@
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName> <EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile> <GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm> <AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision> <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts> <GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms> <AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate> <GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>

View File

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

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converter="using:BetterLyrics.WinUI3.Converter" xmlns:converter="using:BetterLyrics.WinUI3.Converter"
xmlns:converters="using:CommunityToolkit.WinUI.Converters" xmlns:converters="using:CommunityToolkit.WinUI.Converters"
xmlns:globalization="using:Windows.Globalization"
xmlns:local="using:BetterLyrics.WinUI3" xmlns:local="using:BetterLyrics.WinUI3"
xmlns:media="using:CommunityToolkit.WinUI.Media"> xmlns:media="using:CommunityToolkit.WinUI.Media">
<Application.Resources> <Application.Resources>
@@ -12,8 +13,8 @@
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<!-- Merged dictionaries here --> <!-- Merged dictionaries here -->
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" /> <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.Segmented/Segmented/Segmented.xaml" /> <ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.Segmented/Segmented/Segmented.xaml" />
<ResourceDictionary Source="ms-appx:///DevWinUI.Controls/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<!-- Theme --> <!-- Theme -->
@@ -58,11 +59,21 @@
<converter:ShortcutToStringConverter x:Key="ShortcutToStringConverter" /> <converter:ShortcutToStringConverter x:Key="ShortcutToStringConverter" />
<converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" /> <converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" />
<converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" /> <converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" />
<converter:BoolToPartialOpacityConverter x:Key="BoolToPartialOpacityConverter" />
<converter:BoolNegationToOpacityConverter x:Key="BoolNegationToOpacityConverter" />
<converter:RectToMarginConverter x:Key="RectToMarginConverter" /> <converter:RectToMarginConverter x:Key="RectToMarginConverter" />
<converter:LanguageCodeToDisplayedNameConverter x:Key="LanguageCodeToDisplayedNameConverter" />
<converter:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
<converter:DisplayLanguageCodeToIndexConverter x:Key="DisplayLanguageCodeToIndexConverter" />
<converter:PathToParentFolderConverter x:Key="PathToParentFolderConverter" />
<converter:TrackToLyricsConverter x:Key="TrackToLyricsConverter" />
<converter:IntToBoolConverter x:Key="IntToBoolConverter" />
<converter:IndexToDisplayConverter x:Key="IndexToDisplayConverter" />
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" /> <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:BoolNegationConverter x:Key="BoolNegationConverter" /> <converters:BoolNegationConverter x:Key="BoolNegationConverter" />
<converters:ColorToDisplayNameConverter x:Key="ColorToDisplayNameConverter" /> <converters:ColorToDisplayNameConverter x:Key="ColorToDisplayNameConverter" />
<converters:CollectionVisibilityConverter x:Key="CollectionVisibilityConverter" />
<x:Double x:Key="SettingsCardSpacing">4</x:Double> <x:Double x:Key="SettingsCardSpacing">4</x:Double>
@@ -298,8 +309,12 @@
</Setter> </Setter>
</Style> </Style>
<Style x:Key="ListViewStretchedItemContainerStyle" TargetType="ListViewItem"> <Style
x:Key="ListViewStretchedItemContainerStyle"
BasedOn="{StaticResource DefaultListViewItemStyle}"
TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0" /> <Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" /> <Setter Property="Padding" Value="0" />
</Style> </Style>
@@ -327,6 +342,16 @@
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" /> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
</Style> </Style>
<Style
x:Key="FlyoutGhostStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
</Style>
<StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" /> <StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" /> <StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" />
<StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" /> <StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" />
@@ -335,6 +360,7 @@
<!-- Fonts --> <!-- Fonts -->
<FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily> <FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>

View File

@@ -9,6 +9,7 @@ using BetterLyrics.WinUI3.Services.LibWatcherService;
using BetterLyrics.WinUI3.Services.LiveStatesService; using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.LyricsSearchService; using BetterLyrics.WinUI3.Services.LyricsSearchService;
using BetterLyrics.WinUI3.Services.MediaSessionsService; using BetterLyrics.WinUI3.Services.MediaSessionsService;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.TranslateService; using BetterLyrics.WinUI3.Services.TranslateService;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
@@ -22,7 +23,6 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources; using Microsoft.Windows.ApplicationModel.Resources;
using Serilog; using Serilog;
using ShadowViewer.Controls;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@@ -39,12 +39,6 @@ namespace BetterLyrics.WinUI3
private readonly ILogger<App> _logger; private readonly ILogger<App> _logger;
public static new App Current => (App)Application.Current; public static new App Current => (App)Application.Current;
public static DispatcherQueue? DispatcherQueue { get; private set; }
public static DispatcherQueueTimer? DispatcherQueueTimer { get; private set; }
public static ResourceLoader? ResourceLoader { get; private set; }
public NotificationPanel? LyricsWindowNotificationPanel { get; set; }
public NotificationPanel? SettingsWindowNotificationPanel { get; set; }
private static Mutex? _instanceMutex; private static Mutex? _instanceMutex;
@@ -52,10 +46,6 @@ namespace BetterLyrics.WinUI3
{ {
this.InitializeComponent(); this.InitializeComponent();
DispatcherQueue = DispatcherQueue.GetForCurrentThread();
DispatcherQueueTimer = DispatcherQueue.CreateTimer();
ResourceLoader = new ResourceLoader();
EnsureSingleInstance(); EnsureSingleInstance();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@@ -72,12 +62,11 @@ namespace BetterLyrics.WinUI3
private void EnsureSingleInstance() private void EnsureSingleInstance()
{ {
bool createdNew; _instanceMutex = new Mutex(true, Constants.App.AppName, out bool createdNew);
_instanceMutex = new Mutex(true, Constants.App.AppName, out createdNew);
if (!createdNew) if (!createdNew)
{ {
User32.MessageBox(HWND.NULL, ResourceLoader!.GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL); User32.MessageBox(HWND.NULL, new ResourceLoader().GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL);
Environment.Exit(0); Environment.Exit(0);
} }
} }
@@ -85,6 +74,10 @@ namespace BetterLyrics.WinUI3
protected override void OnLaunched(LaunchActivatedEventArgs args) protected override void OnLaunched(LaunchActivatedEventArgs args)
{ {
WindowHelper.OpenOrShowWindow<LyricsWindow>(); WindowHelper.OpenOrShowWindow<LyricsWindow>();
if (Ioc.Default.GetRequiredService<ISettingsService>().AppSettings.MusicGallerySettings.AutoOpen)
{
WindowHelper.OpenOrShowWindow<MusicGalleryWindow>();
}
} }
private static void ConfigureServices() private static void ConfigureServices()
@@ -111,6 +104,7 @@ namespace BetterLyrics.WinUI3
.AddSingleton<ILibWatcherService, LibWatcherService>() .AddSingleton<ILibWatcherService, LibWatcherService>()
.AddSingleton<ITranslateService, TranslateService>() .AddSingleton<ITranslateService, TranslateService>()
.AddSingleton<ILastFMService, LastFMService>() .AddSingleton<ILastFMService, LastFMService>()
.AddSingleton<IResourceService, ResourceService>()
// ViewModels // ViewModels
.AddSingleton<AppSettingsControlViewModel>() .AddSingleton<AppSettingsControlViewModel>()
.AddSingleton<PlaybackSettingsControlViewModel>() .AddSingleton<PlaybackSettingsControlViewModel>()

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -20,15 +20,15 @@
<PRIResource Remove="ViewModels\Lyrics\**" /> <PRIResource Remove="ViewModels\Lyrics\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Remove="Assets\effect.bin" />
<None Remove="Assets\Segoe Fluent Icons.ttf" /> <None Remove="Assets\Segoe Fluent Icons.ttf" />
<None Remove="Assets\Wiki82.profile.xml" /> <None Remove="Assets\Wiki82.profile.xml" />
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" /> <None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
<None Remove="Controls\AppSettingsControl.xaml" /> <None Remove="Controls\AppSettingsControl.xaml" />
<None Remove="Controls\DemoWindowGrid.xaml" /> <None Remove="Controls\DemoWindowGrid.xaml" />
<None Remove="Controls\ExtendedSlider.xaml" /> <None Remove="Controls\ExtendedSlider.xaml" />
<None Remove="Controls\FontFamilyAutoSuggestBox.xaml" />
<None Remove="Controls\LyricsSearchControl.xaml" /> <None Remove="Controls\LyricsSearchControl.xaml" />
<None Remove="Controls\LyricsSettingsControl.xaml" /> <None Remove="Controls\LyricsStyleSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSettingsControl.xaml" /> <None Remove="Controls\LyricsWindowSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSwitchControl.xaml" /> <None Remove="Controls\LyricsWindowSwitchControl.xaml" />
<None Remove="Controls\MediaSettingsControl.xaml" /> <None Remove="Controls\MediaSettingsControl.xaml" />
@@ -49,21 +49,20 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="3v.EvtSource" Version="2.0.0" /> <PackageReference Include="3v.EvtSource" Version="2.0.0" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.MarqueeText" Version="0.1.230830" /> <PackageReference Include="CommunityToolkit.Labs.WinUI.Controls.OpacityMaskView" Version="0.1.251021-build.2365" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.OpacityMaskView" Version="0.1.250703-build.2173" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" /> <PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" /> <PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.MetadataControl" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" 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.Segmented" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" 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.Converters" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" /> <PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" /> <PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" /> <PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.2.250402" />
<PackageReference Include="csharp-kana" Version="1.0.2" />
<PackageReference Include="csharp-pinyin" Version="1.0.1" /> <PackageReference Include="csharp-pinyin" Version="1.0.1" />
<PackageReference Include="DevWinUI.Controls" Version="9.4.2" />
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" /> <PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.2" /> <PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.2" />
<PackageReference Include="Hqub.Last.fm" Version="2.5.1" /> <PackageReference Include="Hqub.Last.fm" Version="2.5.1" />
@@ -71,27 +70,24 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" /> <PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6584" /> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6901" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251003001" /> <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251003001" />
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" /> <PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" /> <PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" /> <PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
<PackageReference Include="NTextCat" Version="0.3.65" /> <PackageReference Include="NTextCat" Version="0.3.65" />
<PackageReference Include="RomajiConverter.Core" Version="1.0.9" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.3-dev-02320" /> <PackageReference Include="Serilog.Extensions.Logging" Version="9.0.3-dev-02320" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
<PackageReference Include="System.Drawing.Common" Version="9.0.10" /> <PackageReference Include="System.Drawing.Common" Version="9.0.10" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.10" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.10" />
<PackageReference Include="TagLibSharp" Version="2.3.0" /> <PackageReference Include="TagLibSharp" Version="2.3.0" />
<PackageReference Include="Ude.NetStandard" Version="1.2.0" /> <PackageReference Include="Ude.NetStandard" Version="1.2.0" />
<PackageReference Include="Vanara.PInvoke.CoreAudio" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.2.1" /> <PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.2.1" /> <PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.2.1" /> <PackageReference Include="Vanara.PInvoke.Shell32" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" /> <PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" />
<PackageReference Include="WinUIEx" Version="2.9.0" /> <PackageReference Include="WinUIEx" Version="2.9.0" />
<PackageReference Include="z440.atl.core" Version="7.5.0" /> <PackageReference Include="z440.atl.core" Version="7.6.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" /> <ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
@@ -110,11 +106,18 @@
<!--Disable Trimming for Specific Packages--> <!--Disable Trimming for Specific Packages-->
<ItemGroup> <ItemGroup>
<TrimmerRootAssembly Include="TagLibSharp" /> <TrimmerRootAssembly Include="TagLibSharp" />
<TrimmerRootAssembly Include="NAudio.Wasapi" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Update="Assets\AIMP.png"> <Content Update="Assets\AIMP.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="Assets\AlbumArtPlaceholder.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\AMLLPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\AppleMusic.png"> <Content Update="Assets\AppleMusic.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@@ -124,7 +127,7 @@
<Content Update="Assets\Edge.png"> <Content Update="Assets\Edge.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="Assets\effect.bin"> <Content Update="Assets\FluidEffect.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="Assets\Empty.png"> <Content Update="Assets\Empty.png">
@@ -139,6 +142,9 @@
<Content Update="Assets\foobar2000.png"> <Content Update="Assets\foobar2000.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="Assets\HyPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\iTunes.png"> <Content Update="Assets\iTunes.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@@ -178,6 +184,9 @@
<Content Update="Assets\Page.png"> <Content Update="Assets\Page.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Update="Assets\PlanetMusic.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\PotPlayer.png"> <Content Update="Assets\PotPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@@ -200,6 +209,16 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Update="Controls\FontFamilyAutoSuggestBox.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsStyleSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="Views\LyricsWindowSwitchWindow.xaml"> <Page Update="Views\LyricsWindowSwitchWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -241,7 +260,7 @@
</Page> </Page>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="Controls\LyricsSettingsControl.xaml"> <Page Update="Controls\LyricsEffectSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup> </ItemGroup>
@@ -295,6 +314,9 @@
<Generator></Generator> <Generator></Generator>
</PRIResource> </PRIResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="TemplateSelector\" />
</ItemGroup>
<!-- Publish Properties --> <!-- Publish Properties -->
<PropertyGroup> <PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun> <PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>

View File

@@ -9,6 +9,8 @@ namespace BetterLyrics.WinUI3.Constants
public static class Link public static class Link
{ {
public const string GitHubUrl = "https://github.com/jayfunc/BetterLyrics"; public const string GitHubUrl = "https://github.com/jayfunc/BetterLyrics";
public const string WikiUrl = "https://github.com/jayfunc/BetterLyrics/wiki";
public const string AppleMusicCfgUrl = $"{WikiUrl}/%5BEN%5D-Lyrics-provider-configuration#apple-music";
public const string FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/index.md"; public const string FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/index.md";
public const string QQGroupUrl = "https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info"; public const string QQGroupUrl = "https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info";
public const string DiscordUrl = "https://discord.gg/5yAQPnyCKv"; public const string DiscordUrl = "https://discord.gg/5yAQPnyCKv";

View File

@@ -7,6 +7,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dev="using:DevWinUI"
xmlns:ui="using:CommunityToolkit.WinUI" xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d"> mc:Ignorable="d">
@@ -17,16 +18,16 @@
<TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageAlbumArtSize" x:Uid="SettingsPageAlbumArtSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE744;}" Glyph=&#xE744;}"
IsExpanded="True"> IsExpanded="True">
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust"> <dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"> <dev:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider <local:ExtendedSlider
Frequency="2" Frequency="2"
Maximum="800" Maximum="800"
@@ -34,49 +35,49 @@
ResetButtonVisibility="Collapsed" ResetButtonVisibility="Collapsed"
Unit="px" Unit="px"
Value="{x:Bind AlbumArtLayoutSettings.AlbumArtSize, Mode=TwoWay}" /> Value="{x:Bind AlbumArtLayoutSettings.AlbumArtSize, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEA3A;}"> <dev:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEA3A;}">
<local:ExtendedSlider <local:ExtendedSlider
Default="12" Default="12"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Unit="%" Unit="%"
Value="{x:Bind AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" /> Value="{x:Bind AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF5EF;}"> <dev:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF5EF;}">
<local:ExtendedSlider <local:ExtendedSlider
Default="12" Default="12"
Frequency="1"
Maximum="64" Maximum="64"
Minimum="0" Minimum="0"
Value="{x:Bind AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" /> Value="{x:Bind AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}"> <dev:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox SelectedIndex="{x:Bind AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageSongInfoLeft" /> <ComboBoxItem x:Uid="SettingsPageSongInfoLeft" />
<ComboBoxItem x:Uid="SettingsPageSongInfoCenter" /> <ComboBoxItem x:Uid="SettingsPageSongInfoCenter" />
<ComboBoxItem x:Uid="SettingsPageSongInfoRight" /> <ComboBoxItem x:Uid="SettingsPageSongInfoRight" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageLyricsFontSize" x:Uid="SettingsPageLyricsFontSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8E9;}" Glyph=&#xE8E9;}"
IsExpanded="True"> IsExpanded="True">
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust"> <dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.IsAutoSongInfoFontSize, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.IsAutoSongInfoFontSize, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard> <dev:SettingsCard>
<local:ExtendedSlider <local:ExtendedSlider
Default="18" Default="18"
Frequency="2" Frequency="2"
@@ -84,22 +85,22 @@
Maximum="72" Maximum="72"
Minimum="8" Minimum="8"
Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" /> Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageShowTitle" x:Uid="SettingsPageShowTitle"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEF3D;}" Glyph=&#xEF3D;}"
IsExpanded="True"> IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageShowArtists"> <dev:SettingsCard x:Uid="SettingsPageShowArtists">
<ToggleSwitch IsEnabled="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=OneWay}" IsOn="{x:Bind AlbumArtLayoutSettings.ShowArtists, Mode=TwoWay}" /> <ToggleSwitch IsEnabled="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=OneWay}" IsOn="{x:Bind AlbumArtLayoutSettings.ShowArtists, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -5,8 +5,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:globalization="using:Windows.Globalization"
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:ui="using:CommunityToolkit.WinUI" xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d"> mc:Ignorable="d">
@@ -19,76 +23,85 @@
<TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageLanguage" x:Uid="SettingsPageLanguage"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF2B7;}" Glyph=&#xF2B7;}"
IsExpanded="True"> IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.Language, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedDisplayLanguages}" SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.LanguageCode, Mode=TwoWay, Converter={StaticResource DisplayLanguageCodeToIndexConverter}}">
<ComboBoxItem x:Uid="SettingsPageSystemLanguage" /> <ComboBox.ItemTemplate>
<ComboBoxItem x:Uid="SettingsPageEN" /> <DataTemplate x:DataType="models:ExtendedLanguage">
<ComboBoxItem x:Uid="SettingsPageSC" /> <StackPanel Orientation="Horizontal" Spacing="6">
<ComboBoxItem x:Uid="SettingsPageTC" /> <TextBlock Text="{x:Bind Name}" />
<ComboBoxItem x:Uid="SettingsPageJA" /> </StackPanel>
<ComboBoxItem x:Uid="SettingsPageKO" /> </DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard> <dev:SettingsCard>
<Button x:Uid="SettingsPageRestart" Command="{x:Bind ViewModel.RestartAppCommand}" /> <Button x:Uid="SettingsPageRestart" Command="{x:Bind ViewModel.RestartAppCommand}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<!-- App behavior --> <!-- App behavior -->
<TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF71C;}"> <dev:SettingsCard x:Uid="SettingsPageAutoStart">
<ToggleSwitch <ToggleSwitch
x:Name="AutoStartupToggleSwitch" x:Name="AutoStartupToggleSwitch"
Loaded="AutoStartupToggleSwitch_Loaded" Loaded="AutoStartupToggleSwitch_Loaded"
Unloaded="AutoStartupToggleSwitch_Unloaded" /> Unloaded="AutoStartupToggleSwitch_Unloaded" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E8;}"> <dev:SettingsCard x:Uid="SettingsPageAutoOpenMusicGalleryWindow">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoOpen, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAutoPlayWhenOpenMusicGalleryWindow">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoPlay, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF270;}"> <dev:SettingsCard x:Uid="SettingsPageListenNewSession">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPageShowHideHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<!-- Playback shortcut --> <!-- Playback shortcut -->
<TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPageNextSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}"> <dev:SettingsCard x:Uid="SettingsPagePreviousSongHotKey">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" /> <local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -66,10 +66,18 @@
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}" Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4" CornerRadius="4"
Opacity="0.7"> Opacity="0.7">
<TextBlock <StackPanel Orientation="Horizontal">
FontSize="12" <TextBlock
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}" Margin="0,0,3,0"
TextWrapping="Wrap" /> FontSize="12"
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}"
TextWrapping="Wrap" />
<TextBlock FontSize="12" Text="[" />
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}" />
<TextBlock FontSize="12" Text="×" />
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}" />
<TextBlock FontSize="12" Text="]" />
</StackPanel>
</Grid> </Grid>
<!-- Config name --> <!-- Config name -->
<Grid <Grid

View File

@@ -13,10 +13,12 @@
<StackPanel> <StackPanel>
<Slider <Slider
IsEnabled="{x:Bind IsSliderEnabled, Mode=OneWay}"
Maximum="{x:Bind Maximum, Mode=OneWay}" Maximum="{x:Bind Maximum, Mode=OneWay}"
Minimum="{x:Bind Minimum, Mode=OneWay}" Minimum="{x:Bind Minimum, Mode=OneWay}"
SnapsTo="Ticks" SnapsTo="Ticks"
StepFrequency="{x:Bind Frequency, Mode=OneWay}" StepFrequency="{x:Bind Frequency, Mode=OneWay}"
Tapped="Slider_Tapped"
TickFrequency="{x:Bind Frequency, Mode=OneWay}" TickFrequency="{x:Bind Frequency, Mode=OneWay}"
TickPlacement="None" TickPlacement="None"
Value="{x:Bind Value, Mode=TwoWay}" /> Value="{x:Bind Value, Mode=TwoWay}" />

View File

@@ -1,3 +1,4 @@
using BetterLyrics.WinUI3.Events;
using Microsoft.UI.Input; using Microsoft.UI.Input;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
@@ -21,6 +22,8 @@ namespace BetterLyrics.WinUI3.Controls
{ {
public sealed partial class ExtendedSlider : UserControl public sealed partial class ExtendedSlider : UserControl
{ {
public event EventHandler<ExtendedSliderValueChangedByUserEventArgs>? ValueChangedByUser;
public ExtendedSlider() public ExtendedSlider()
{ {
InitializeComponent(); InitializeComponent();
@@ -61,7 +64,7 @@ namespace BetterLyrics.WinUI3.Controls
} }
public static readonly DependencyProperty FrequencyProperty = public static readonly DependencyProperty FrequencyProperty =
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default)); DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(1.0));
public static readonly DependencyProperty MinimumProperty = public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default)); DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
public static readonly DependencyProperty MaximumProperty = public static readonly DependencyProperty MaximumProperty =
@@ -76,6 +79,8 @@ namespace BetterLyrics.WinUI3.Controls
DependencyProperty.Register(nameof(ResetButtonVisibility), typeof(Visibility), typeof(ExtendedSlider), new PropertyMetadata(Visibility.Visible)); DependencyProperty.Register(nameof(ResetButtonVisibility), typeof(Visibility), typeof(ExtendedSlider), new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty UnitProperty = public static readonly DependencyProperty UnitProperty =
DependencyProperty.Register(nameof(Unit), typeof(string), typeof(ExtendedSlider), new PropertyMetadata("")); DependencyProperty.Register(nameof(Unit), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(""));
public static readonly DependencyProperty IsSliderEnabledProperty =
DependencyProperty.Register(nameof(IsSliderEnabled), typeof(bool), typeof(ExtendedSlider), new PropertyMetadata(true));
public double Frequency public double Frequency
{ {
@@ -121,20 +126,33 @@ namespace BetterLyrics.WinUI3.Controls
get => (string)GetValue(UnitProperty); get => (string)GetValue(UnitProperty);
set => SetValue(UnitProperty, value); set => SetValue(UnitProperty, value);
} }
public bool IsSliderEnabled
{
get => (bool)GetValue(IsSliderEnabledProperty);
set => SetValue(IsSliderEnabledProperty, value);
}
private void ResetButton_Click(object sender, RoutedEventArgs e) private void ResetButton_Click(object sender, RoutedEventArgs e)
{ {
Value = Default; Value = Default;
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
} }
private void SubtractButton_Click(object sender, RoutedEventArgs e) private void SubtractButton_Click(object sender, RoutedEventArgs e)
{ {
Subtract(); Subtract();
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
} }
private void AddButton_Click(object sender, RoutedEventArgs e) private void AddButton_Click(object sender, RoutedEventArgs e)
{ {
Add(); Add();
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
}
private void Slider_Tapped(object sender, TappedRoutedEventArgs e)
{
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
} }
} }
} }

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.FontFamilyAutoSuggestBox"
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:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid>
<StackPanel Orientation="Horizontal" Spacing="6">
<AutoSuggestBox
x:Name="AutoSuggestBox"
Width="150"
GotFocus="AutoSuggestBox_GotFocus"
LostFocus="AutoSuggestBox_LostFocus"
SuggestionChosen="AutoSuggestBox_SuggestionChosen"
Text="{x:Bind SelectedFontFamily, Mode=OneWay}"
TextChanged="AutoSuggestBox_TextChanged" />
<Button
Click="Button_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</Grid>
</UserControl>

View File

@@ -0,0 +1,95 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models.Settings;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class FontFamilyAutoSuggestBox : UserControl
{
private List<string> SystemFontNames { get; set; } = [.. FontHelper.SystemFontFamilies];
public FontFamilyAutoSuggestBox()
{
InitializeComponent();
}
public static readonly DependencyProperty SelectedFontFamilyProperty =
DependencyProperty.Register(nameof(SelectedFontFamily), typeof(string), typeof(FontFamilyAutoSuggestBox), new PropertyMetadata(default));
public string SelectedFontFamily
{
get => (string)GetValue(SelectedFontFamilyProperty);
set => SetValue(SelectedFontFamilyProperty, value);
}
private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
SelectedFontFamily = args.SelectedItem.ToString() ?? "";
}
private void UpdateAutoSuggestBoxItemsSource()
{
var suitableItems = new List<string>();
var splitText = AutoSuggestBox.Text.ToLower().Split(" ");
foreach (var fontFamily in SystemFontNames)
{
var found = splitText.All((key) =>
{
return fontFamily.ToLower().Contains(key);
});
if (found)
{
suitableItems.Add(fontFamily);
}
}
if (suitableItems.Count == 0)
{
suitableItems.Add("N/A");
}
AutoSuggestBox.ItemsSource = suitableItems.Order();
}
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
// Since selecting an item will also change the text,
// only listen to changes caused by user entering text.
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{
UpdateAutoSuggestBoxItemsSource();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SystemFontNames = [.. FontHelper.SystemFontFamilies];
}
private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
{
UpdateAutoSuggestBoxItemsSource();
}
private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
{
AutoSuggestBox.Text = SelectedFontFamily;
}
}
}

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:enums="using:BetterLyrics.WinUI3.Enums" xmlns:enums="using:BetterLyrics.WinUI3.Enums"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:BetterLyrics.WinUI3.Controls" xmlns:uc="using:BetterLyrics.WinUI3.Controls"
@@ -18,119 +19,110 @@
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE790;}"> <dev:SettingsCard x:Uid="SettingsPageTheme">
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageFollowSystem" /> <ComboBoxItem x:Uid="SettingsPageFollowSystem" />
<ComboBoxItem x:Uid="SettingsPageLight" /> <ComboBoxItem x:Uid="SettingsPageLight" />
<ComboBoxItem x:Uid="SettingsPageDark" /> <ComboBoxItem x:Uid="SettingsPageDark" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsExpander <dev:SettingsExpander x:Uid="SettingsPagePureLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
x:Uid="SettingsPagePureLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEB42;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="100" Default="100"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Unit="%" Unit="%"
Value="{x:Bind LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander x:Uid="SettingsPageAlbumArtLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
x:Uid="SettingsPageAlbumArtLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE93C;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="100" Default="100"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Unit="%" Unit="%"
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageSpeed" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageSpeed" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="50" Default="50"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Unit="%" Unit="%"
Value="{x:Bind LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageBlurAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageBlurAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="100" Default="100"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="0" Default="0"
Frequency="1"
Maximum="10" Maximum="10"
Minimum="0" Minimum="0"
Value="{x:Bind LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander x:Uid="SettingsPageFluidLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
x:Uid="SettingsPageFluidLayer"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEDA8;}"
IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider <uc:ExtendedSlider
Default="100" Default="100"
Frequency="1"
Maximum="100" Maximum="100"
Minimum="0" Minimum="0"
Unit="%" Unit="%"
Value="{x:Bind LyricsBackgroundSettings.FluidOverlayOpacity, Mode=TwoWay}" /> Value="{x:Bind LyricsBackgroundSettings.FluidOverlayOpacity, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPagePaletteGeneratorType"> <dev:SettingsCard x:Uid="SettingsPagePaletteGeneratorType">
<ComboBox SelectedIndex="{x:Bind LyricsBackgroundSettings.PaletteGeneratorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox SelectedIndex="{x:Bind LyricsBackgroundSettings.PaletteGeneratorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageMedianCut" /> <ComboBoxItem x:Uid="SettingsPageMedianCut" />
<ComboBoxItem x:Uid="SettingsPageOctTree" /> <ComboBoxItem x:Uid="SettingsPageOctTree" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander x:Uid="SettingsPageSnowFlakeLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
x:Uid="SettingsPageSpectrumLayer" <ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=TwoWay}" />
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, <dev:SettingsExpander.Items>
Glyph=&#xF61F;}" <dev:SettingsCard x:Uid="SettingsPageAmount">
IsExpanded="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=OneWay}"> <uc:ExtendedSlider
Maximum="100"
Minimum="10"
ResetButtonVisibility="Collapsed"
Value="{x:Bind LyricsBackgroundSettings.SnowFlakeOverlayAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageSpectrumLayer">
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" />
</controls:SettingsExpander> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -0,0 +1,296 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsEffectSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid>
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<!-- Effect -->
<TextBlock
x:Uid="SettingsPageLyricsEffect"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
Text="Effect" />
<dev:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB42;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
Default="0"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE727;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
Default="5"
Maximum="10"
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED3A;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- 高亮 -->
<dev:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E6;}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPagePhoneticText">
<local:ExtendedSlider
Default="60"
Frequency="5"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.PhoneticLyricsHighlightAmount, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsHighlightScope">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageOriginalText">
<local:ExtendedSlider
Default="60"
Frequency="5"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightAmount, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageTranslatedText">
<local:ExtendedSlider
Default="60"
Frequency="5"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.TranslatedLyricsHighlightAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 阴影 -->
<dev:SettingsExpander
x:Uid="SettingsPageLyricsShadow"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF5EF;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 辉光效果 -->
<dev:SettingsExpander
x:Uid="SettingsPageLyricsGlowEffect"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE9A9;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 浮动动画 -->
<dev:SettingsExpander
x:Uid="SettingsPageLyricsFloatAnimation"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8C5;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="1"
Maximum="4"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 扇形歌词 -->
<dev:SettingsExpander
x:Uid="SettingsPageFan"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEBC5;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard IsEnabled="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="30"
Maximum="90"
Minimum="-90"
Unit="°"
Value="{x:Bind LyricsEffectSettings.FanLyricsAngle, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 3D 歌词 -->
<dev:SettingsExpander
x:Uid="SettingsPage3DLyrics"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE914;}"
IsExpanded="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard Header="X" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="0"
Maximum="90"
Minimum="-90"
Unit="°"
Value="{x:Bind LyricsEffectSettings.Lyrics3DXAngle, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard Header="Y" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="0"
Maximum="90"
Minimum="-90"
Unit="°"
Value="{x:Bind LyricsEffectSettings.Lyrics3DYAngle, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard Header="Z" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="0"
Maximum="90"
Minimum="-90"
Unit="°"
Value="{x:Bind LyricsEffectSettings.Lyrics3DZAngle, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPage3DLyricsDepth" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="1000"
Frequency="10"
Maximum="1000"
Minimum="100"
Unit="°"
Value="{x:Bind LyricsEffectSettings.Lyrics3DDepth, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 滚动动画 -->
<dev:SettingsExpander x:Uid="SettingsPageScrollEasing" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xECE7;}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
</ComboBox>
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageScrollTopDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageScrollDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageScrollTopDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDelay, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDelay, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -21,27 +21,15 @@ using Windows.Foundation.Collections;
namespace BetterLyrics.WinUI3.Controls namespace BetterLyrics.WinUI3.Controls
{ {
public sealed partial class LyricsSettingsControl : UserControl public sealed partial class LyricsEffectSettingsControl : UserControl
{ {
public ObservableCollection<string> SystemFontNames { get; set; } = [.. FontHelper.SystemFontFamilies]; public LyricsEffectSettingsControl()
public LyricsSettingsControl()
{ {
InitializeComponent(); InitializeComponent();
} }
public static readonly DependencyProperty LyricsStyleSettingsProperty =
DependencyProperty.Register(nameof(LyricsStyleSettings), typeof(LyricsStyleSettings), typeof(LyricsSettingsControl), new PropertyMetadata(default));
public LyricsStyleSettings LyricsStyleSettings
{
get => (LyricsStyleSettings)GetValue(LyricsStyleSettingsProperty);
set => SetValue(LyricsStyleSettingsProperty, value);
}
public static readonly DependencyProperty LyricsEffectSettingsProperty = public static readonly DependencyProperty LyricsEffectSettingsProperty =
DependencyProperty.Register(nameof(LyricsEffectSettings), typeof(LyricsEffectSettings), typeof(LyricsSettingsControl), new PropertyMetadata(default)); DependencyProperty.Register(nameof(LyricsEffectSettings), typeof(LyricsEffectSettings), typeof(LyricsEffectSettingsControl), new PropertyMetadata(default));
public LyricsEffectSettings LyricsEffectSettings public LyricsEffectSettings LyricsEffectSettings
{ {

View File

@@ -5,9 +5,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:ui="using:CommunityToolkit.WinUI" xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d"> mc:Ignorable="d">
@@ -23,81 +25,127 @@
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid Grid.Column="0"> <Grid Grid.Column="0">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"> <ScrollViewer>
<controls:SettingsExpander x:Uid="LyricsSearchControlSongInfoMapping" IsExpanded="True"> <StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsExpander.Items> <TextBlock x:Uid="LyricsSearchControlSongInfoMapping" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="LyricsSearchControlTitle" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="LyricsSearchControlArtist" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard>
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider"> <Grid
<Button Padding="16"
x:Uid="LyricsSearchControlSearch" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
Command="{x:Bind ViewModel.SearchCommand}" CornerRadius="4">
Style="{StaticResource AccentButtonStyle}" /> <StackPanel Spacing="6">
</controls:SettingsCard> <TextBlock x:Uid="LyricsSearchControlTitle" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}"
TextWrapping="Wrap" />
</StackPanel> <TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</Grid>
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4">
<StackPanel Spacing="6">
<TextBlock x:Uid="LyricsSearchControlArtist" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}"
TextWrapping="Wrap" />
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</Grid>
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4">
<StackPanel Spacing="6">
<TextBlock x:Uid="LyricsSearchControlAlbum" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
IsTextSelectionEnabled="True"
Text="{x:Bind ViewModel.MappedSongSearchQuery.OriginalAlbum, Mode=OneWay}"
TextWrapping="Wrap" />
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedAlbum, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedAlbumCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</Grid>
<dev:SettingsCard>
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
<Button
x:Uid="LyricsSearchControlSearch"
Command="{x:Bind ViewModel.SearchCommand}"
Style="{StaticResource AccentButtonStyle}" />
</dev:SettingsCard>
</StackPanel>
</ScrollViewer>
</Grid> </Grid>
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<ListView ItemsSource="{x:Bind ViewModel.LyricsSearchResults, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsSearchResult, Mode=TwoWay}"> <ListView ItemsSource="{x:Bind ViewModel.LyricsSearchResults, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsSearchResult, Mode=TwoWay}">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate> <DataTemplate x:DataType="models:LyricsSearchResult">
<ListViewItem IsEnabled="{Binding IsFound}"> <ListViewItem IsEnabled="{x:Bind IsFound}">
<Grid Opacity="{Binding IsFound, Converter={StaticResource BoolToOpacityConverter}}"> <StackPanel Padding="3,6" Opacity="{x:Bind IsFound, Converter={StaticResource BoolToPartialOpacityConverter}}">
<RelativePanel Padding="0,6"> <TextBlock Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}" Text="{x:Bind Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
<TextBlock <TextBlock
x:Name="SearchedTitle" Text="{x:Bind Title}"
RelativePanel.AlignLeftWithPanel="True" TextWrapping="Wrap"
Text="{Binding Title}" Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" /> <TextBlock
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}"
x:Name="SearchedArtists" Text="{x:Bind Artist}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" TextWrapping="Wrap"
RelativePanel.AlignLeftWithPanel="True" Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
RelativePanel.Below="SearchedTitle" <TextBlock
Text="{Binding Artist}" Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" /> Text="{x:Bind Album}"
<TextBlock TextWrapping="Wrap"
x:Name="SearchedProvider" Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
RelativePanel.AlignRightWithPanel="True"
RelativePanel.AlignVerticalCenterWithPanel="True"
Text="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
</RelativePanel>
<TextBlock <TextBlock
x:Uid="LyricsSearchControlNotFound" x:Uid="LyricsSearchControlNotFound"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="Not found" Visibility="{x:Bind IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
Visibility="{Binding IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" /> </StackPanel>
</Grid>
</ListViewItem> </ListViewItem>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
@@ -145,35 +193,46 @@
Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" /> Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Grid> </Grid>
<Grid Grid.Column="2"> <Grid Grid.Column="2">
<ListView ItemsSource="{x:Bind ViewModel.LyricsData.LyricsLines, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsLine, Mode=TwoWay}"> <Pivot ItemsSource="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}">
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior <interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}" Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="Equal" ComparisonCondition="Equal"
Value="{x:Null}"> Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" /> <interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior> </interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior <interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}" Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="NotEqual" ComparisonCondition="NotEqual"
Value="{x:Null}"> Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" /> <interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior> </interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors> </interactivity:Interaction.Behaviors>
<ListView.ItemTemplate> <Pivot.HeaderTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{Binding LanguageCode, Mode=OneWay, Converter={StaticResource LanguageCodeToDisplayedNameConverter}}" />
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock
Margin="1,0"
Foreground="{ThemeResource SystemFillColorNeutralBrush}"
Text="-" />
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding EndMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock Margin="6,0" Text="{Binding OriginalText}" />
</StackPanel>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </Pivot.HeaderTemplate>
</ListView> <Pivot.ItemTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding LyricsLines, Mode=OneWay}" SelectionChanged="ListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock
Margin="1,0"
Foreground="{ThemeResource SystemFillColorNeutralBrush}"
Text="-" />
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding EndMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock Margin="6,0" Text="{Binding OriginalText}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
<StackPanel <StackPanel
Padding="0,36" Padding="0,36"
HorizontalAlignment="Center" HorizontalAlignment="Center"
@@ -182,13 +241,13 @@
<Image MaxWidth="100" Source="/Assets/Page.png" /> <Image MaxWidth="100" Source="/Assets/Page.png" />
<interactivity:Interaction.Behaviors> <interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior <interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}" Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="NotEqual" ComparisonCondition="NotEqual"
Value="{x:Null}"> Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" /> <interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior> </interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior <interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}" Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="Equal" ComparisonCondition="Equal"
Value="{x:Null}"> Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" /> <interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />

View File

@@ -31,5 +31,10 @@ namespace BetterLyrics.WinUI3.Controls
InitializeComponent(); InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>(); DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>();
} }
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel.SelectedLyricsLine = e.OriginalSource as LyricsLine;
}
} }
} }

View File

@@ -1,438 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid>
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<!-- Lyrics style -->
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls: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" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D2;}">
<ComboBox ItemsSource="{x:Bind SystemFontNames, Mode=OneWay}" SelectedItem="{x:Bind LyricsStyleSettings.LyricsFontFamily, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8DD;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB42;}">
<local:ExtendedSlider
Default="30"
Frequency="1"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEC12;}">
<local:ExtendedSlider
Default="0"
Frequency="1"
Maximum="5"
Minimum="0"
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsStrokeFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D3;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</controls:SettingsCard>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ColorPicker>
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D3;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</controls:SettingsCard>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ColorPicker>
<controls:SettingsCard x:Uid="SettingsPageLyricsFgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D3;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</controls:SettingsCard>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ColorPicker>
<controls:SettingsExpander
x:Uid="SettingsPageLyricsFontSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8E9;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider
Frequency="2"
Maximum="96"
Minimum="12"
ResetButtonVisibility="Collapsed"
Value="{x:Bind LyricsStyleSettings.LyricsFontSize, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF579;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
Default="0.5"
Frequency="0.1"
Maximum="2"
Minimum="0"
Unit="x"
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF464;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<!-- Effect -->
<TextBlock
x:Uid="SettingsPageLyricsEffect"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
Text="Effect" />
<controls:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB42;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
Default="0"
Frequency="1"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE727;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
Default="5"
Frequency="1"
Maximum="10"
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED3A;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- 译文高亮 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsTranslationHighlight"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE7E6;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAmount">
<local:ExtendedSlider
Default="60"
Frequency="5"
Maximum="100"
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsTranslationHighlightAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 原文高亮 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsHighlightScope"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE7E6;}"
IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsHighlightScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAmount">
<local:ExtendedSlider
Default="100"
Frequency="5"
Maximum="100"
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsHighlightAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 阴影 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsShadow"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF5EF;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Frequency="1"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 辉光效果 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsGlowEffect"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE9A9;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Frequency="1"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 浮动动画 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsFloatAnimation"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8C5;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="1"
Frequency="1"
Maximum="4"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 扇形歌词 -->
<controls:SettingsCard x:Uid="SettingsPageFan" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEBC5;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- 滚动动画 -->
<controls:SettingsExpander
x:Uid="SettingsPageScrollEasing"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xECE7;}"
IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
</ComboBox>
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollTopDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDelay, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDelay, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsStyleSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid>
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<!-- Lyrics style -->
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<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" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsExpander x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D2;}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageCJK">
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsCJKFontFamily, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageWesternChar">
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsWesternFontFamily, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8DD;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB42;}">
<local:ExtendedSlider
Default="30"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEC12;}">
<local:ExtendedSlider
Default="0"
Maximum="10"
Minimum="0"
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- 字体颜色 -->
<dev:SettingsExpander x:Uid="SettingsPageFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D3;}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageStrokeFontColor">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard HorizontalContentAlignment="Left">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsBgFontColor">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsFgFontColor">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard>
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="Equal"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
ComparisonCondition="NotEqual"
Value="2">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ColorPicker
ColorSpectrumShape="Box"
IsAlphaEnabled="True"
IsAlphaSliderVisible="True"
IsAlphaTextInputVisible="True"
IsColorChannelTextInputVisible="True"
IsColorSliderVisible="True"
IsHexInputVisible="True"
IsMoreButtonVisible="True"
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 字体大小 -->
<dev:SettingsExpander x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E9;}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPagePhoneticText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider
Frequency="2"
Maximum="256"
Minimum="12"
ResetButtonVisibility="Collapsed"
Value="{x:Bind LyricsStyleSettings.PhoneticLyricsFontSize, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageOriginalText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider
Frequency="2"
Maximum="256"
Minimum="12"
ResetButtonVisibility="Collapsed"
Value="{x:Bind LyricsStyleSettings.OriginalLyricsFontSize, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageTranslatedText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
<local:ExtendedSlider
Frequency="2"
Maximum="256"
Minimum="12"
ResetButtonVisibility="Collapsed"
Value="{x:Bind LyricsStyleSettings.TranslatedLyricsFontSize, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF579;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
Default="0.5"
Frequency="0.1"
Maximum="2"
Minimum="0"
Unit="x"
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF464;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,40 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models.Settings;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class LyricsStyleSettingsControl : UserControl
{
public LyricsStyleSettingsControl()
{
InitializeComponent();
}
public static readonly DependencyProperty LyricsStyleSettingsProperty =
DependencyProperty.Register(nameof(LyricsStyleSettings), typeof(LyricsStyleSettings), typeof(LyricsStyleSettingsControl), new PropertyMetadata(default));
public LyricsStyleSettings LyricsStyleSettings
{
get => (LyricsStyleSettings)GetValue(LyricsStyleSettingsProperty);
set => SetValue(LyricsStyleSettingsProperty, value);
}
}
}

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:BetterLyrics.WinUI3.Controls" xmlns:uc="using:BetterLyrics.WinUI3.Controls"
@@ -26,11 +27,9 @@
x:Uid="SettingsPageRecordedWindowStatus" x:Uid="SettingsPageRecordedWindowStatus"
RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignLeftWithPanel="True"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Button x:Uid="SettingsPageCreateFromCurrent" Command="{x:Bind ViewModel.CopyLyricsWindowStatusCommand}" /> <Button x:Uid="SettingsPageCreateFromCurrent" Command="{x:Bind ViewModel.CopyLyricsWindowStatusCommand}" />
<Button <Button x:Uid="SettingsPageCreateFromTemplates">
x:Uid="SettingsPageCreateFromTemplates"
VerticalAlignment="Center"
RelativePanel.AlignRightWithPanel="True">
<Button.Flyout> <Button.Flyout>
<MenuFlyout> <MenuFlyout>
<MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" /> <MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" />
@@ -92,7 +91,73 @@
</Grid> </Grid>
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<controls:SwitchPresenter Margin="0,100,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}"> <Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Pivot SelectionChanged="Pivot_SelectionChanged">
<PivotItem Tag="General">
<PivotItem.Header>
<TextBlock
x:Uid="AppSettingsControlGeneral"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="AlbumArtStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAlbumStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsEffect">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsEffect"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsBackground">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageBackgroundOverlay"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="Advanced">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAdvanced"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
</Pivot>
</StackPanel>
</Grid>
<controls:SwitchPresenter Margin="0,110,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
<controls:SwitchPresenter.ContentTransitions> <controls:SwitchPresenter.ContentTransitions>
<TransitionCollection> <TransitionCollection>
<PopupThemeTransition /> <PopupThemeTransition />
@@ -107,7 +172,7 @@
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8AC;}"> <dev:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8AC;}">
<StackPanel <StackPanel
Margin="0,6,0,0" Margin="0,6,0,0"
Orientation="Horizontal" Orientation="Horizontal"
@@ -115,9 +180,9 @@
<TextBox Text="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.Name, Mode=TwoWay}" TextWrapping="Wrap" /> <TextBox Text="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.Name, Mode=TwoWay}" TextWrapping="Wrap" />
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" /> <Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" />
</StackPanel> </StackPanel>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageDisplayTypeSwitcher" x:Uid="SettingsPageDisplayTypeSwitcher"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF246;}" Glyph=&#xF246;}"
@@ -127,24 +192,62 @@
<ComboBoxItem x:Uid="MainPageLyriscOnly" /> <ComboBoxItem x:Uid="MainPageLyriscOnly" />
<ComboBoxItem x:Uid="MainPageSplitView" /> <ComboBoxItem x:Uid="MainPageSplitView" />
</ComboBox> </ComboBox>
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageLayoutOrientation"> <dev:SettingsCard x:Uid="SettingsPageLayoutOrientation">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" /> <ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" /> <ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageWorkArea"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE78B;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageWorkAreaHeight" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<uc:ExtendedSlider
Default="64"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
Minimum="64"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockHeight, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDockPlacement" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDockMonitor" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageAdaptEnvColor" x:Uid="SettingsPageAdaptEnvColor"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE88F;}" Glyph=&#xE88F;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}"> IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard <dev:SettingsCard
x:Uid="SettingsPageEnvColorSample" x:Uid="SettingsPageEnvColorSample"
Header="Environment color sample mode" Header="Environment color sample mode"
IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}"> IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
@@ -154,109 +257,59 @@
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" /> <ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" /> <ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}"> <dev:SettingsExpander
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageWindowBounds" x:Uid="SettingsPageWindowBounds"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF16B;}" Glyph=&#xF16B;}"
IsExpanded="True"> IsExpanded="True">
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard Header="X"> <dev:SettingsCard Header="X">
<uc:ExtendedSlider <NumberBox
Frequency="1" SmallChange="10"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Right, Mode=OneWay}" SpinButtonPlacementMode="Inline"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Left, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" /> Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard Header="Y"> <dev:SettingsCard Header="Y">
<uc:ExtendedSlider <NumberBox
Frequency="1" SmallChange="10"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom, Mode=OneWay}" SpinButtonPlacementMode="Inline"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Top, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" /> Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageWidth"> <dev:SettingsCard x:Uid="SettingsPageWidth">
<uc:ExtendedSlider <NumberBox
Frequency="1" SmallChange="10"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}" SpinButtonPlacementMode="Inline"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" /> Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageHeight"> <dev:SettingsCard x:Uid="SettingsPageHeight">
<uc:ExtendedSlider <NumberBox
Frequency="1" SmallChange="10"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}" SpinButtonPlacementMode="Inline"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" /> Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageAOT" x:Uid="SettingsPageAOT"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE718;}" Glyph=&#xE718;}"
IsExpanded="True"> IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander <dev:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED1A;}">
x:Uid="SettingsPageWorkArea"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE78B;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageWorkAreaHeight" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<uc:ExtendedSlider
Default="64"
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
Minimum="64"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockHeight, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDockPlacement" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
</ComboBox>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED1A;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>
@@ -268,9 +321,14 @@
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" /> <uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
</controls:Case> </controls:Case>
<!-- Lyrics style and effect --> <!-- Lyrics style -->
<controls:Case Value="Lyrics"> <controls:Case Value="LyricsStyle">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" /> <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> </controls:Case>
<!-- Lyrics background --> <!-- Lyrics background -->
@@ -284,25 +342,25 @@
<Grid Style="{StaticResource SettingsGridStyle}"> <Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"> <StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C4;}"> <dev:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C4;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C9;}"> <dev:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C9;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsClickThrough, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsClickThrough, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8B2;}"> <dev:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8B2;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB41;}"> <dev:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB41;}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}"> <ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" /> <ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" />
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaTop" /> <ComboBoxItem x:Uid="SettingsPageTitleBarAreaTop" />
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaWhole" /> <ComboBoxItem x:Uid="SettingsPageTitleBarAreaWhole" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>
@@ -311,81 +369,6 @@
</controls:SwitchPresenter> </controls:SwitchPresenter>
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<ListView
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollMode="Disabled"
SelectionChanged="ListView_SelectionChanged">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Items>
<ListViewItem Tag="General">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xECAA;" />
<TextBlock x:Uid="AppSettingsControlGeneral" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="AlbumArtStyle">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE93C;" />
<TextBlock x:Uid="SettingsPageAlbumStyle" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="Lyrics">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xEDC6;" />
<TextBlock x:Uid="SettingsPageLyrics" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="LyricsBackground">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xF5EF;" />
<TextBlock x:Uid="SettingsPageBackgroundOverlay" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="Advanced">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xEC7A;" />
<TextBlock x:Uid="SettingsPageAdvanced" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
</ListView.Items>
</ListView>
</StackPanel>
</Grid>
</Grid> </Grid>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -1,6 +1,7 @@
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings; using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views; using BetterLyrics.WinUI3.Views;
@@ -31,13 +32,13 @@ namespace BetterLyrics.WinUI3.Controls
{ {
public LyricsWindowSettingsControlViewModel ViewModel => (LyricsWindowSettingsControlViewModel)DataContext; public LyricsWindowSettingsControlViewModel ViewModel => (LyricsWindowSettingsControlViewModel)DataContext;
private ISettingsService _settingsService; private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
public LyricsWindowSettingsControl() public LyricsWindowSettingsControl()
{ {
InitializeComponent(); InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSettingsControlViewModel>(); DataContext = Ioc.Default.GetRequiredService<LyricsWindowSettingsControlViewModel>();
_settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
} }
private void DeleteMenuFlyoutItem_Click(object sender, RoutedEventArgs e) private void DeleteMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
@@ -52,11 +53,6 @@ namespace BetterLyrics.WinUI3.Controls
} }
} }
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel?.ListViewSelectedItemTag = ((sender as ListView)!.SelectedItem as ListViewItem)!.Tag;
}
private void SetDefaultMenuFlyoutItem_Click(object sender, RoutedEventArgs e) private void SetDefaultMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{ {
if (sender is MenuFlyoutItem menuFlyoutItem) if (sender is MenuFlyoutItem menuFlyoutItem)
@@ -80,5 +76,16 @@ namespace BetterLyrics.WinUI3.Controls
} }
} }
} }
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is Pivot pivot)
{
if (pivot.SelectedItem is PivotItem pivotItem)
{
ViewModel?.ListViewSelectedItemTag = pivotItem.Tag;
}
}
}
} }
} }

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -18,7 +19,7 @@
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageMusicLib" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8B7;}" /> <dev:SettingsCard x:Uid="SettingsPageMusicLib" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8B7;}" />
<InfoBar <InfoBar
x:Uid="SettingsPageRemoveInfo" x:Uid="SettingsPageRemoveInfo"
@@ -49,38 +50,38 @@
SelectionMode="None"> SelectionMode="None">
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate> <DataTemplate>
<controls:SettingsExpander> <dev:SettingsExpander>
<controls:SettingsExpander.Header> <dev:SettingsExpander.Header>
<HyperlinkButton <HyperlinkButton
Click="LocalFolderHyperlinkButton_Click" Click="LocalFolderHyperlinkButton_Click"
Content="{Binding Path, Mode=OneWay}" Content="{Binding Path, Mode=OneWay}"
Tag="{Binding Path, Mode=OneWay}" /> Tag="{Binding Path, Mode=OneWay}" />
</controls:SettingsExpander.Header> </dev:SettingsExpander.Header>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard> <dev:SettingsCard>
<controls:SettingsCard.Header> <dev:SettingsCard.Header>
<HyperlinkButton <HyperlinkButton
x:Uid="SettingsPageRemovePath" x:Uid="SettingsPageRemovePath"
Click="SettingsPageRemovePathButton_Click" Click="SettingsPageRemovePathButton_Click"
Tag="{Binding}" /> Tag="{Binding}" />
</controls:SettingsCard.Header> </dev:SettingsCard.Header>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageMusicLibRealTimeWatch"> <dev:SettingsCard x:Uid="SettingsPageMusicLibRealTimeWatch">
<ToggleSwitch IsOn="{Binding IsRealTimeWatchEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{Binding IsRealTimeWatchEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
<controls:SettingsCard x:Uid="SettingsPageAddFolder" Style="{StaticResource DefaultSettingsExpanderItemStyle}"> <dev:SettingsCard x:Uid="SettingsPageAddFolder" Style="{StaticResource DefaultSettingsExpanderItemStyle}">
<Button <Button
x:Uid="SettingsPageAddFolderButton" x:Uid="SettingsPageAddFolderButton"
Command="{x:Bind ViewModel.SelectAndAddFolderCommand}" Command="{x:Bind ViewModel.SelectAndAddFolderCommand}"
CommandParameter="{Binding ElementName=RootGrid}" /> CommandParameter="{Binding ElementName=RootGrid}" />
</controls:SettingsCard> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -3,8 +3,12 @@
x:Class="BetterLyrics.WinUI3.Controls.PlaybackSettingsControl" x:Class="BetterLyrics.WinUI3.Controls.PlaybackSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
xmlns:controls="using:CommunityToolkit.WinUI.Controls" xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:globalization="using:Windows.Globalization"
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity" xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls" xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -22,19 +26,19 @@
<Grid Style="{StaticResource SettingsGridStyle}"> <Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}"> <StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig"> <dev:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<!-- 时间轴相关配置 --> <!-- 时间轴相关配置 -->
<controls:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True"> <dev:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
<local:ExtendedSlider <local:ExtendedSlider
Frequency="100" Frequency="100"
Maximum="1000" Maximum="1000"
@@ -42,10 +46,10 @@
ResetButtonVisibility="Collapsed" ResetButtonVisibility="Collapsed"
Unit="ms" Unit="ms"
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" /> Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True"> <dev:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
<local:ExtendedSlider <local:ExtendedSlider
x:Uid="SettingsPagePositionOffsetReset" x:Uid="SettingsPagePositionOffsetReset"
Default="0" Default="0"
@@ -54,12 +58,12 @@
Minimum="-5000" Minimum="-5000"
Unit="ms" Unit="ms"
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.PositionOffset, Mode=TwoWay}" /> Value="{x:Bind ViewModel.SelectedMediaSourceProvider.PositionOffset, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="LyricsPagePositionOffsetHint"> <dev:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.ResetPositionOffsetOnSongChanged, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.ResetPositionOffsetOnSongChanged, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<!-- 专辑封面源配置 --> <!-- 专辑封面源配置 -->
<TextBlock x:Uid="SettingsPageAlbumArtSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageAlbumArtSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
@@ -77,12 +81,12 @@
</ListView.OpacityTransition> </ListView.OpacityTransition>
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate x:DataType="models:AlbumArtSearchProviderInfo"> <DataTemplate x:DataType="models:AlbumArtSearchProviderInfo">
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}"> <dev:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon> <dev:SettingsCard.HeaderIcon>
<FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" /> <FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" />
</controls:SettingsCard.HeaderIcon> </dev:SettingsCard.HeaderIcon>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
@@ -109,12 +113,12 @@
</ListView.ItemContainerStyle> </ListView.ItemContainerStyle>
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate x:DataType="models:LyricsSearchProviderInfo"> <DataTemplate x:DataType="models:LyricsSearchProviderInfo">
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}"> <dev:SettingsCard Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon> <dev:SettingsCard.HeaderIcon>
<FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" /> <FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" />
</controls:SettingsCard.HeaderIcon> </dev:SettingsCard.HeaderIcon>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
</DataTemplate> </DataTemplate>
</ListView.ItemTemplate> </ListView.ItemTemplate>
</ListView> </ListView>
@@ -206,87 +210,47 @@
<!-- Provider info --> <!-- Provider info -->
<TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix"> <dev:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" /> <HyperlinkButton
</controls:SettingsCard> Content="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}"
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix"> IsEnabled="False"
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" /> NavigateUri="{x:Bind ViewModel.OriginalLyricsRef, Mode=OneWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<dev:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
<HyperlinkButton
Content="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}"
IsEnabled="False"
NavigateUri="{x:Bind ViewModel.TranslatedLyricsRef, Mode=OneWay}" />
</dev:SettingsCard>
<!-- Lyrics translation --> <!-- Lyrics translation -->
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander <dev:SettingsExpander x:Uid="LyricsPageTranslationEnabled" IsExpanded="True">
x:Uid="LyricsPageTranslationEnabled"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE774;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}"> <ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedTranslationTargetLanguages}" SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
<ComboBoxItem Content="العربية" Tag="ar" /> <ComboBox.ItemTemplate>
<ComboBoxItem Content="Azərbaycan dili" Tag="az" /> <DataTemplate x:DataType="models:ExtendedLanguage">
<ComboBoxItem Content="Български" Tag="bg" /> <StackPanel Orientation="Horizontal" Spacing="6">
<ComboBoxItem Content="বাংলা" Tag="bn" /> <TextBlock Text="{x:Bind Name}" />
<ComboBoxItem Content="Català" Tag="ca" /> </StackPanel>
<ComboBoxItem Content="Čeština" Tag="cs" /> </DataTemplate>
<ComboBoxItem Content="Dansk" Tag="da" /> </ComboBox.ItemTemplate>
<ComboBoxItem Content="Deutsch" Tag="de" />
<ComboBoxItem Content="Ελληνικά" Tag="el" />
<ComboBoxItem Content="English" Tag="en" />
<ComboBoxItem Content="Esperanto" Tag="eo" />
<ComboBoxItem Content="Español" Tag="es" />
<ComboBoxItem Content="Eesti" Tag="et" />
<ComboBoxItem Content="Euskara" Tag="eu" />
<ComboBoxItem Content="فارسی" Tag="fa" />
<ComboBoxItem Content="Suomi" Tag="fi" />
<ComboBoxItem Content="Français" Tag="fr" />
<ComboBoxItem Content="Gaeilge" Tag="ga" />
<ComboBoxItem Content="Galego" Tag="gl" />
<ComboBoxItem Content="עברית" Tag="he" />
<ComboBoxItem Content="हिन्दी" Tag="hi" />
<ComboBoxItem Content="Magyar" Tag="hu" />
<ComboBoxItem Content="Bahasa Indonesia" Tag="id" />
<ComboBoxItem Content="Italiano" Tag="it" />
<ComboBoxItem Content="日本語" Tag="ja" />
<ComboBoxItem Content="한국어" Tag="ko" />
<ComboBoxItem Content="Кыргызча" Tag="ky" />
<ComboBoxItem Content="Lietuvių" Tag="lt" />
<ComboBoxItem Content="Latviešu" Tag="lv" />
<ComboBoxItem Content="Bahasa Melayu" Tag="ms" />
<ComboBoxItem Content="Norsk bokmål" Tag="nb" />
<ComboBoxItem Content="Nederlands" Tag="nl" />
<ComboBoxItem Content="Português (Brasil)" Tag="pt-BR" />
<ComboBoxItem Content="Polski" Tag="pl" />
<ComboBoxItem Content="Português" Tag="pt" />
<ComboBoxItem Content="Română" Tag="ro" />
<ComboBoxItem Content="Русский" Tag="ru" />
<ComboBoxItem Content="Slovenčina" Tag="sk" />
<ComboBoxItem Content="Slovenščina" Tag="sl" />
<ComboBoxItem Content="Shqip" Tag="sq" />
<ComboBoxItem Content="Српски" Tag="sr" />
<ComboBoxItem Content="Svenska" Tag="sv" />
<ComboBoxItem Content="ไทย" Tag="th" />
<ComboBoxItem Content="Filipino" Tag="tl" />
<ComboBoxItem Content="Türkçe" Tag="tr" />
<ComboBoxItem Content="Українська" Tag="uk" />
<ComboBoxItem Content="اردو" Tag="ur" />
<ComboBoxItem Content="Tiếng Việt" Tag="vi" />
<ComboBoxItem Content="中文" Tag="zh" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<controls:SettingsCard.Description> <dev:SettingsCard.Description>
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate"> <HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
<TextBlock <TextBlock
x:Uid="SettingsPageTranslationInfoLink" x:Uid="SettingsPageTranslationInfoLink"
FontSize="14" FontSize="14"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
</HyperlinkButton> </HyperlinkButton>
</controls:SettingsCard.Description> </dev:SettingsCard.Description>
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="12"> <StackPanel Orientation="Horizontal" Spacing="12">
<TextBox <TextBox
x:Name="LibreTranslateServerTextBox" x:Name="LibreTranslateServerTextBox"
@@ -298,40 +262,36 @@
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}" Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" /> IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</StackPanel> </StackPanel>
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"> </dev:SettingsExpander.Items>
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" /> </dev:SettingsExpander>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- Lyrics phonetic --> <!-- Lyrics phonetic -->
<controls:SettingsExpander <TextBlock x:Uid="SettingsPagePhonetic" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
x:Uid="SettingsPageChinese" <dev:SettingsExpander x:Uid="SettingsPageChinese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard> <dev:SettingsCard IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}"> <ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
<ComboBoxItem x:Uid="SettingsPagePinyin" /> <ComboBoxItem x:Uid="SettingsPagePinyin" />
<ComboBoxItem x:Uid="SettingsPageJyutping" /> <ComboBoxItem x:Uid="SettingsPageJyutping" />
</ComboBox> </ComboBox>
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageJapanese" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageJapanese">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<!-- 中文简体繁体偏好 --> <!-- 中文简体繁体偏好 -->
<controls:SettingsCard x:Uid="SettingsPageChinesePreference"> <TextBlock x:Uid="SettingsPageChineseLyrics" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageChinesePreference">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" /> <ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<!-- Last.fm --> <!-- Last.fm -->
<TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander <dev:SettingsExpander
x:Uid="SettingsPageLastFMManager" x:Uid="SettingsPageLastFMManager"
HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/LastFM.png}" HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/LastFM.png}"
IsExpanded="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> IsExpanded="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
@@ -345,25 +305,25 @@
Command="{x:Bind ViewModel.LastFMUnAuthCommand}" Command="{x:Bind ViewModel.LastFMUnAuthCommand}"
IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}" /> IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}" />
</StackPanel> </StackPanel>
<controls:SettingsExpander.Items> <dev:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<HyperlinkButton Content="{x:Bind ViewModel.LastFMUser.Name, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.LastFMUser.Url, Mode=OneWay}" /> <HyperlinkButton Content="{x:Bind ViewModel.LastFMUser.Name, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.LastFMUser.Url, Mode=OneWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Playcount, Mode=OneWay}" /> <TextBlock Text="{x:Bind ViewModel.LastFMUser.Playcount, Mode=OneWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLastFMRegistered" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> <dev:SettingsCard x:Uid="SettingsPageLastFMRegistered" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Registered.ToLongDateString(), Mode=OneWay}" /> <TextBlock Text="{x:Bind ViewModel.LastFMUser.Registered.ToLongDateString(), Mode=OneWay}" />
</controls:SettingsCard> </dev:SettingsCard>
<controls:SettingsCard IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}"> <dev:SettingsCard IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<Button x:Uid="SettingsPageLastFMRefresh" Command="{x:Bind ViewModel.LastFMRefreshCommand}" /> <Button x:Uid="SettingsPageLastFMRefresh" Command="{x:Bind ViewModel.LastFMRefreshCommand}" />
</controls:SettingsCard> </dev:SettingsCard>
</controls:SettingsExpander.Items> </dev:SettingsExpander.Items>
</controls:SettingsExpander> </dev:SettingsExpander>
<!-- LX music server --> <!-- LX music server -->
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" /> <TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard> <dev:SettingsCard x:Uid="SettingsPageServerAddress">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
<TextBox <TextBox
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
@@ -374,20 +334,22 @@
Command="{x:Bind ViewModel.LXMusicServerTestCommand}" Command="{x:Bind ViewModel.LXMusicServerTestCommand}"
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" /> IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</StackPanel> </StackPanel>
</controls:SettingsCard> </dev:SettingsCard>
<!-- Apple Music token --> <!-- Apple Music token -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="media-user-token (for Apple Muisc)" /> <TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="Apple Muisc media-user-token" />
<controls:SettingsCard <dev:SettingsCard
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}" Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
Description="Use at your own risk"
Foreground="{ThemeResource SystemFillColorCautionBrush}" Foreground="{ThemeResource SystemFillColorCautionBrush}"
Header="Use at your own risk"> Header="WARNING">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
<TextBox <TextBox
MaxWidth="250" MaxWidth="250"
PlaceholderText="media-user-token" PlaceholderText="media-user-token"
Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}" Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}"
TextWrapping="Wrap" /> TextWrapping="Wrap" />
<HyperlinkButton Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE897;}" NavigateUri="{x:Bind constants:Link.AppleMusicCfgUrl}" />
<Button <Button
Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}" Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
@@ -395,7 +357,7 @@
Glyph=&#xE8FB;}" Glyph=&#xE8FB;}"
Style="{StaticResource GhostButtonStyle}" /> Style="{StaticResource GhostButtonStyle}" />
</StackPanel> </StackPanel>
</controls:SettingsCard> </dev:SettingsCard>
</StackPanel> </StackPanel>
</Grid> </Grid>

View File

@@ -1,4 +1,6 @@
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Input; using Microsoft.UI.Input;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
@@ -23,6 +25,8 @@ namespace BetterLyrics.WinUI3.Controls
{ {
public sealed partial class ShortcutTextBox : UserControl public sealed partial class ShortcutTextBox : UserControl
{ {
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public ShortcutTextBox() public ShortcutTextBox()
{ {
InitializeComponent(); InitializeComponent();
@@ -98,15 +102,11 @@ namespace BetterLyrics.WinUI3.Controls
bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut); bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut);
if (registered) if (registered)
{ {
App.Current.SettingsWindowNotificationPanel?.Notify( DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageShortcutRegSuccessInfo"));
App.ResourceLoader!.GetString("SettingsPageShortcutRegSuccessInfo"),
InfoBarSeverity.Success);
} }
else else
{ {
App.Current.SettingsWindowNotificationPanel?.Notify( DevWinUI.Growl.Success(_resourceService.GetLocalizedString("SettingsPageShortcutRegFailInfo"));
App.ResourceLoader!.GetString("SettingsPageShortcutRegFailInfo"),
InfoBarSeverity.Error);
} }
} }
} }

View File

@@ -34,6 +34,11 @@
Command="{x:Bind ViewModel.OpenLyricsWindowSwitchCommand}" Command="{x:Bind ViewModel.OpenLyricsWindowSwitchCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8AB;}" /> Glyph=&#xE8AB;}" />
<MenuFlyoutItem
x:Uid="SystemTraySearch"
Command="{x:Bind ViewModel.OpenLyricsSearchWindowCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE721;}" />
<MenuFlyoutItem <MenuFlyoutItem
x:Uid="SystemTrayLyrics" x:Uid="SystemTrayLyrics"
Command="{x:Bind ViewModel.OpenLyricsCommand}" Command="{x:Bind ViewModel.OpenLyricsCommand}"

View File

@@ -1,4 +1,6 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -10,14 +12,16 @@ namespace BetterLyrics.WinUI3.Converter
{ {
public partial class AlbumArtSearchProviderToDisplayNameConverter : IValueConverter public partial class AlbumArtSearchProviderToDisplayNameConverter : IValueConverter
{ {
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
if (value is AlbumArtSearchProvider provider) if (value is AlbumArtSearchProvider provider)
{ {
return provider switch return provider switch
{ {
AlbumArtSearchProvider.Local => App.ResourceLoader!.GetString("AlbumArtSearchLocalProvider"), AlbumArtSearchProvider.Local => _resourceService.GetLocalizedString("AlbumArtSearchLocalProvider"),
AlbumArtSearchProvider.SMTC => App.ResourceLoader!.GetString("AlbumArtSearchSMTCProvider"), AlbumArtSearchProvider.SMTC => _resourceService.GetLocalizedString("AlbumArtSearchSMTCProvider"),
AlbumArtSearchProvider.iTunes => "iTunes", AlbumArtSearchProvider.iTunes => "iTunes",
_ => throw new Exception($"Unknown AlbumArtSearchProvider: {provider}"), _ => throw new Exception($"Unknown AlbumArtSearchProvider: {provider}"),
}; };

View File

@@ -0,0 +1,27 @@
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class BoolNegationToOpacityConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is bool boolValue)
{
return boolValue ? 0.0 : 1.0;
}
return 0.0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -7,13 +7,13 @@ using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter namespace BetterLyrics.WinUI3.Converter
{ {
public class BoolToOpacityConverter : IValueConverter public partial class BoolToOpacityConverter : IValueConverter
{ {
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
if (value is bool boolValue) if (value is bool boolValue)
{ {
return boolValue ? 1.0 : 0.3; return boolValue ? 1.0 : 0.0;
} }
return 1.0; return 1.0;
} }

View File

@@ -0,0 +1,26 @@
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public class BoolToPartialOpacityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is bool boolValue)
{
return boolValue ? 1.0 : 0.3;
}
return 1.0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,45 @@
using BetterLyrics.WinUI3.Helper;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class ByteArrayToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is byte[] byteArray && byteArray.Length > 0)
{
try
{
using (var ms = new MemoryStream(byteArray))
{
var stream = ms.AsRandomAccessStream();
var bitmapImage = new BitmapImage();
bitmapImage.SetSource(stream);
return bitmapImage;
}
}
catch
{
return PathHelper.AlbumArtPlaceholderPath;
}
}
return PathHelper.AlbumArtPlaceholderPath;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,32 @@
using BetterLyrics.WinUI3.Helper;
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Globalization;
namespace BetterLyrics.WinUI3.Converter
{
public partial class DisplayLanguageCodeToIndexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string langCode)
{
return LanguageHelper.SupportedDisplayLanguages.FindIndex(x => x.LanguageCode == langCode);
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
if (value is int index)
{
return LanguageHelper.SupportedDisplayLanguages.ElementAt(index).LanguageCode;
}
return "";
}
}
}

View File

@@ -0,0 +1,27 @@
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class IndexToDisplayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
int display = 0;
if (value is int index)
{
display = index + 1;
}
return display.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,26 @@
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class IntToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is int intValue)
{
return intValue != 0;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,36 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services;
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Globalization;
namespace BetterLyrics.WinUI3.Converter
{
public partial class LanguageCodeToDisplayedNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string langCode)
{
if (PhoneticHelper.IsPhoneticCode(langCode))
{
return PhoneticHelper.GetDisplayName(langCode);
}
else
{
return new Language(langCode).DisplayName ?? langCode;
}
}
return value?.ToString() ?? "";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,13 +1,17 @@
// 2025/6/23 by Zhe Fang // 2025/6/23 by Zhe Fang
using System;
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter namespace BetterLyrics.WinUI3.Converter
{ {
public partial class LyricsSearchProviderToDisplayNameConverter : IValueConverter public partial class LyricsSearchProviderToDisplayNameConverter : IValueConverter
{ {
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
if (value is LyricsSearchProvider provider) if (value is LyricsSearchProvider provider)
@@ -20,10 +24,10 @@ namespace BetterLyrics.WinUI3.Converter
LyricsSearchProvider.Kugou => "酷狗音乐", LyricsSearchProvider.Kugou => "酷狗音乐",
LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db", LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db",
LyricsSearchProvider.AppleMusic => "Apple Music", LyricsSearchProvider.AppleMusic => "Apple Music",
LyricsSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"), LyricsSearchProvider.LocalLrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalLrcFile"),
LyricsSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"), LyricsSearchProvider.LocalMusicFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalMusicFile"),
LyricsSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"), LyricsSearchProvider.LocalEslrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderEslrcFile"),
LyricsSearchProvider.LocalTtmlFile => App.ResourceLoader!.GetString("LyricsSearchProviderTtmlFile"), LyricsSearchProvider.LocalTtmlFile => _resourceService.GetLocalizedString("LyricsSearchProviderTtmlFile"),
_ => "N/A", _ => "N/A",
}; };
} }

View File

@@ -1,18 +1,22 @@
// 2025/6/23 by Zhe Fang // 2025/6/23 by Zhe Fang
using System; using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter namespace BetterLyrics.WinUI3.Converter
{ {
public partial class MatchedLocalFilesPathToVisibilityConverter : IValueConverter public partial class MatchedLocalFilesPathToVisibilityConverter : IValueConverter
{ {
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
if (value is string path) if (value is string path)
{ {
if (path == App.ResourceLoader!.GetString("MainPageNoLocalFilesMatched")) if (path == _resourceService.GetLocalizedString("MainPageNoLocalFilesMatched"))
{ {
return Visibility.Collapsed; return Visibility.Collapsed;
} }

View File

@@ -0,0 +1,27 @@
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class PathToParentFolderConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is string path)
{
return Directory.GetParent(path)?.Name ?? "";
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -11,15 +11,27 @@ namespace BetterLyrics.WinUI3.Converter
{ {
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
TimeSpan timeSpan = TimeSpan.Zero;
if (value is double seconds) if (value is double seconds)
{ {
return TimeSpan.FromSeconds(seconds).ToString(@"mm\:ss"); timeSpan = TimeSpan.FromSeconds(seconds);
} }
else if (value is int secondsInt) else if (value is int secondsInt)
{ {
return TimeSpan.FromSeconds(secondsInt).ToString(@"mm\:ss"); timeSpan = TimeSpan.FromSeconds(secondsInt);
}
if (timeSpan.Days > 0)
{
return timeSpan.ToString(@"dd\.hh\:mm\:ss");
}
else if (timeSpan.Hours > 0)
{
return timeSpan.ToString(@"hh\:mm\:ss");
}
else
{
return timeSpan.ToString(@"mm\:ss");
} }
return value?.ToString() ?? "";
} }
public object ConvertBack(object value, Type targetType, object parameter, string language) public object ConvertBack(object value, Type targetType, object parameter, string language)

View File

@@ -0,0 +1,28 @@
using ATL;
using BetterLyrics.WinUI3.Helper;
using Microsoft.UI.Xaml.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Converter
{
public partial class TrackToLyricsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is Track track)
{
return track.GetLyrics();
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -1,13 +1,17 @@
// 2025/6/23 by Zhe Fang // 2025/6/23 by Zhe Fang
using System;
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter namespace BetterLyrics.WinUI3.Converter
{ {
public partial class TranslationSearchProviderToDisplayNameConverter : IValueConverter public partial class TranslationSearchProviderToDisplayNameConverter : IValueConverter
{ {
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public object Convert(object value, Type targetType, object parameter, string language) public object Convert(object value, Type targetType, object parameter, string language)
{ {
if (value is TranslationSearchProvider provider) if (value is TranslationSearchProvider provider)
@@ -20,10 +24,10 @@ namespace BetterLyrics.WinUI3.Converter
TranslationSearchProvider.Kugou => "酷狗音乐", TranslationSearchProvider.Kugou => "酷狗音乐",
TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db", TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db",
TranslationSearchProvider.AppleMusic => "Apple Music", TranslationSearchProvider.AppleMusic => "Apple Music",
TranslationSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"), TranslationSearchProvider.LocalLrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalLrcFile"),
TranslationSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"), TranslationSearchProvider.LocalMusicFile => _resourceService.GetLocalizedString("LyricsSearchProviderLocalMusicFile"),
TranslationSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"), TranslationSearchProvider.LocalEslrcFile => _resourceService.GetLocalizedString("LyricsSearchProviderEslrcFile"),
TranslationSearchProvider.LocalTtmlFile => App.ResourceLoader!.GetString("LyricsSearchProviderTtmlFile"), TranslationSearchProvider.LocalTtmlFile => _resourceService.GetLocalizedString("LyricsSearchProviderTtmlFile"),
TranslationSearchProvider.LibreTranslate => "LibreTranslate", TranslationSearchProvider.LibreTranslate => "LibreTranslate",
_ => "N/A", _ => "N/A",
}; };

View File

@@ -1,4 +1,5 @@
using System; using BetterLyrics.WinUI3.Helper;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -11,4 +12,17 @@ namespace BetterLyrics.WinUI3.Enums
Pinyin, Pinyin,
Jyutping, Jyutping,
} }
public static class ChineseRomanizationExtensions
{
public static string ToPhoneticCode(this ChineseRomanization chineseRomanization)
{
return chineseRomanization switch
{
ChineseRomanization.Pinyin => PhoneticHelper.PinyinCode,
ChineseRomanization.Jyutping => PhoneticHelper.JyutpingCode,
_ => throw new ArgumentOutOfRangeException(nameof(chineseRomanization))
};
}
}
} }

View File

@@ -10,6 +10,8 @@ namespace BetterLyrics.WinUI3.Enums
{ {
Title, Title,
Album, Album,
Artist Artist,
Folder,
M3UFilePath
} }
} }

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Events
{
public class ExtendedSliderValueChangedByUserEventArgs : EventArgs
{
public double Value { get; set; }
public ExtendedSliderValueChangedByUserEventArgs(double value)
{
Value = value;
}
}
}

View File

@@ -3,6 +3,7 @@ using BetterLyrics.WinUI3.Models;
using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Brushes;
using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Geometry;
using Microsoft.Graphics.Canvas.Text; using Microsoft.Graphics.Canvas.Text;
using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.Graphics.Canvas.UI.Xaml;
using Microsoft.UI; using Microsoft.UI;
@@ -72,19 +73,38 @@ namespace BetterLyrics.WinUI3.Helper
{ {
CanvasCommandList list = new(control); CanvasCommandList list = new(control);
using var ds = list.CreateDrawingSession(); using var ds = list.CreateDrawingSession();
// 描边
if (strokeWidth > 0) if (strokeWidth > 0)
{ {
if (lyricsLine.TextGeometry == null) if (lyricsLine.PhoneticCanvasGeometry != null)
{ {
return list; ds.DrawGeometry(lyricsLine.PhoneticCanvasGeometry, lyricsLine.PhoneticPosition, strokeColor, strokeWidth);
}
if (lyricsLine.OriginalCanvasGeometry != null)
{
ds.DrawGeometry(lyricsLine.OriginalCanvasGeometry, lyricsLine.OriginalPosition, strokeColor, strokeWidth);
}
if (lyricsLine.TranslatedCanvasGeometry != null)
{
ds.DrawGeometry(lyricsLine.TranslatedCanvasGeometry, lyricsLine.TranslatedPosition, strokeColor, strokeWidth);
} }
ds.DrawGeometry(lyricsLine.TextGeometry, lyricsLine.Position, strokeColor, strokeWidth); // 描边
} }
if (lyricsLine.CanvasTextLayout == null)
// 绘制文本(填充)
if (lyricsLine.PhoneticCanvasTextLayout != null)
{ {
return list; ds.DrawTextLayout(lyricsLine.PhoneticCanvasTextLayout, lyricsLine.PhoneticPosition, fontColor);
} }
ds.DrawTextLayout(lyricsLine.CanvasTextLayout, lyricsLine.Position, fontColor); // 绘制文本(填充) if (lyricsLine.OriginalCanvasTextLayout != null)
{
ds.DrawTextLayout(lyricsLine.OriginalCanvasTextLayout, lyricsLine.OriginalPosition, fontColor);
}
if (lyricsLine.TranslatedCanvasTextLayout != null)
{
ds.DrawTextLayout(lyricsLine.TranslatedCanvasTextLayout, lyricsLine.TranslatedPosition, fontColor);
}
return list; return list;
} }
@@ -113,12 +133,12 @@ namespace BetterLyrics.WinUI3.Helper
var mask = new CanvasCommandList(control); var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession(); using var ds = mask.CreateDrawingSession();
if (lyricsLine.CanvasTextLayout == null) if (lyricsLine.OriginalCanvasTextLayout == null)
{ {
return mask; return mask;
} }
var highlightRegion = lyricsLine.CanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault(); var highlightRegion = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault();
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width; double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
// Draw the highlight for the current character // Draw the highlight for the current character
@@ -129,20 +149,20 @@ namespace BetterLyrics.WinUI3.Helper
// Rects // Rects
var highlightRect = new Rect( var highlightRect = new Rect(
highlightRegion.LayoutBounds.X, highlightRegion.LayoutBounds.X,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
highlightWidth, highlightWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
var fadeInRect = new Rect( var fadeInRect = new Rect(
highlightRect.Right - fadingWidth, highlightRect.Right - fadingWidth,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth, fadingWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
var fadeOutRect = new Rect( var fadeOutRect = new Rect(
highlightRect.Right, highlightRect.Right,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth, fadingWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
@@ -171,15 +191,15 @@ namespace BetterLyrics.WinUI3.Helper
{ {
var mask = new CanvasCommandList(control); var mask = new CanvasCommandList(control);
if (lyricsLine.CanvasTextLayout == null) if (lyricsLine.OriginalCanvasTextLayout == null)
{ {
return mask; return mask;
} }
using var ds = mask.CreateDrawingSession(); using var ds = mask.CreateDrawingSession();
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, charStartIndex); var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, charStartIndex);
var highlightRegion = lyricsLine.CanvasTextLayout var highlightRegion = lyricsLine.OriginalCanvasTextLayout
.GetCharacterRegions(charStartIndex, charLength) .GetCharacterRegions(charStartIndex, charLength)
.FirstOrDefault(); .FirstOrDefault();
if (regions.Length > 0) if (regions.Length > 0)
@@ -190,7 +210,7 @@ namespace BetterLyrics.WinUI3.Helper
var region = regions[j]; var region = regions[j];
var rect = new Rect( var rect = new Rect(
region.LayoutBounds.X, region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.Position.Y, region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
region.LayoutBounds.Width, region.LayoutBounds.Width,
region.LayoutBounds.Height region.LayoutBounds.Height
); );
@@ -207,14 +227,14 @@ namespace BetterLyrics.WinUI3.Helper
// Rects // Rects
var highlightRect = new Rect( var highlightRect = new Rect(
highlightRegion.LayoutBounds.X, highlightRegion.LayoutBounds.X,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
highlightWidth, highlightWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
var fadeInRect = new Rect( var fadeInRect = new Rect(
highlightRect.Right - fadingWidth, highlightRect.Right - fadingWidth,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth, fadingWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
@@ -225,7 +245,7 @@ namespace BetterLyrics.WinUI3.Helper
{ {
var fadeOutRect = new Rect( var fadeOutRect = new Rect(
highlightRect.Right, highlightRect.Right,
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y, highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
fadingWidth, fadingWidth,
highlightRegion.LayoutBounds.Height highlightRegion.LayoutBounds.Height
); );
@@ -246,12 +266,12 @@ namespace BetterLyrics.WinUI3.Helper
var mask = new CanvasCommandList(control); var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession(); using var ds = mask.CreateDrawingSession();
if (lyricsLine.CanvasTextLayout == null) if (lyricsLine.OriginalCanvasTextLayout == null)
{ {
return mask; return mask;
} }
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length); var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length);
if (regions.Length > 0) if (regions.Length > 0)
{ {
for (int j = 0; j < regions.Length; j++) for (int j = 0; j < regions.Length; j++)
@@ -259,7 +279,7 @@ namespace BetterLyrics.WinUI3.Helper
var region = regions[j]; var region = regions[j];
var rect = new Rect( var rect = new Rect(
region.LayoutBounds.X, region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.Position.Y, region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
region.LayoutBounds.Width, region.LayoutBounds.Width,
region.LayoutBounds.Height region.LayoutBounds.Height
); );
@@ -270,17 +290,17 @@ namespace BetterLyrics.WinUI3.Helper
return mask; return mask;
} }
public static CanvasCommandList CreateTranslationHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine) public static CanvasCommandList CreatePhoneticHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
{ {
var mask = new CanvasCommandList(control); var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession(); using var ds = mask.CreateDrawingSession();
if (lyricsLine.CanvasTextLayout == null) if (lyricsLine.PhoneticCanvasTextLayout == null)
{ {
return mask; return mask;
} }
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(lyricsLine.OriginalText.Length, lyricsLine.DisplayedText.Length - lyricsLine.OriginalText.Length); var regions = lyricsLine.PhoneticCanvasTextLayout.GetCharacterRegions(0, lyricsLine.PhoneticText.Length);
if (regions.Length > 0) if (regions.Length > 0)
{ {
for (int j = 0; j < regions.Length; j++) for (int j = 0; j < regions.Length; j++)
@@ -288,7 +308,36 @@ namespace BetterLyrics.WinUI3.Helper
var region = regions[j]; var region = regions[j];
var rect = new Rect( var rect = new Rect(
region.LayoutBounds.X, region.LayoutBounds.X,
region.LayoutBounds.Y + lyricsLine.Position.Y, 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.Width,
region.LayoutBounds.Height region.LayoutBounds.Height
); );

View File

@@ -117,6 +117,11 @@ namespace BetterLyrics.WinUI3.Helper
return new Vector3((float)color.R / 0xff, (float)color.G / 0xff, (float)color.B / 0xff); return new Vector3((float)color.R / 0xff, (float)color.G / 0xff, (float)color.B / 0xff);
} }
public static Color GetRandomColor()
{
return Color.FromArgb(255, (byte)Random.Shared.Next(0, 256), (byte)Random.Shared.Next(0, 256), (byte)Random.Shared.Next(0, 256));
}
public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, string monitorDeviceName, WindowPixelSampleMode mode) public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, string monitorDeviceName, WindowPixelSampleMode mode)
{ {
if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent; if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent;

View File

@@ -8,6 +8,7 @@ namespace BetterLyrics.WinUI3.Helper
{ {
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -42,6 +43,29 @@ namespace BetterLyrics.WinUI3.Helper
} }
return files; return files;
} }
public static void DeleteAllFiles(string folderPath)
{
if (!Directory.Exists(folderPath))
{
return;
}
DirectoryInfo di = new DirectoryInfo(folderPath);
try
{
foreach (FileInfo file in di.GetFiles())
{
try
{
file.Delete();
}
catch (Exception ex) { }
}
}
catch (Exception) { }
}
} }
} }
} }

View File

@@ -0,0 +1,21 @@
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Models.Settings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Helper
{
public static class EnumExtensions
{
public static T GetNext<T>(this T value) where T : struct, Enum
{
T[] values = Enum.GetValues<T>();
int currentIndex = Array.IndexOf(values, value);
int nextIndex = (currentIndex + 1) % values.Length;
return values[nextIndex];
}
}
}

View File

@@ -1,6 +1,8 @@
// 2025/6/23 by Zhe Fang // 2025/6/23 by Zhe Fang
using ATL;
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -37,9 +39,9 @@ namespace BetterLyrics.WinUI3.Helper
return sb.ToString(); return sb.ToString();
} }
public static string? ReadLyricsCache(string title, string artist, LyricsFormat format, string cacheFolderPath) public static string? ReadLyricsCache(string title, string artist, string album, LyricsFormat format, string cacheFolderPath)
{ {
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}")); var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
if (File.Exists(cacheFilePath)) if (File.Exists(cacheFilePath))
{ {
return File.ReadAllText(cacheFilePath); return File.ReadAllText(cacheFilePath);
@@ -57,9 +59,9 @@ namespace BetterLyrics.WinUI3.Helper
return null; return null;
} }
public static void WriteLyricsCache(string title, string artist, string lyrics, LyricsFormat format, string cacheFolderPath) public static void WriteLyricsCache(string title, string artist, string album, string lyrics, LyricsFormat format, string cacheFolderPath)
{ {
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}")); var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
File.WriteAllText(cacheFilePath, lyrics); File.WriteAllText(cacheFilePath, lyrics);
} }
@@ -86,7 +88,5 @@ namespace BetterLyrics.WinUI3.Helper
".wav", ".aiff", ".aif", ".pcm", ".cda", ".dsf", ".dff", ".au", ".snd", ".wav", ".aiff", ".aif", ".pcm", ".cda", ".dsf", ".dff", ".au", ".snd",
".mid", ".midi", ".mod", ".xm", ".it", ".s3m" ".mid", ".midi", ".mod", ".xm", ".it", ".s3m"
}; };
public static string MusicSearchPattern => string.Join("|", MusicExtensions.Select(x => $"*{x}"));
} }
} }

View File

@@ -18,6 +18,7 @@ using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.Graphics.Imaging; using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams; using Windows.Storage.Streams;
using Windows.UI; using Windows.UI;
using static Vanara.PInvoke.Ole32; using static Vanara.PInvoke.Ole32;
@@ -46,43 +47,13 @@ namespace BetterLyrics.WinUI3.Helper
return RandomAccessStreamReference.CreateFromStream(stream); return RandomAccessStreamReference.CreateFromStream(stream);
} }
public static async Task<IRandomAccessStream> CreateTextPlaceholderBytesAsync(int width, int height) public static async Task<IRandomAccessStream> GetAlbumArtPlaceholderAsync()
{ {
using var device = CanvasDevice.GetSharedDevice(); StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(PathHelper.AlbumArtPlaceholderPath));
using var renderTarget = new CanvasRenderTarget(device, width, height, 96); IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
// 随机生成渐变色
Windows.UI.Color RandomColor()
{
var rand = new Random(Guid.NewGuid().GetHashCode());
double h = rand.NextDouble() * 360;
double s = 0.35 + rand.NextDouble() * 0.3; // 0.35~0.65,适中饱和度
double l = 0.5 + rand.NextDouble() * 0.3; // 0.5~0.8,明亮
return CommunityToolkit.WinUI.Helpers.ColorHelper.FromHsl(h, s, l);
}
Windows.UI.Color color1 = RandomColor();
Windows.UI.Color color2 = RandomColor();
using (var ds = renderTarget.CreateDrawingSession())
{
// 绘制线性渐变背景
using var gradientBrush = new Microsoft.Graphics.Canvas.Brushes.CanvasLinearGradientBrush(ds, color1, color2)
{
StartPoint = new Vector2(0, 0),
EndPoint = new Vector2(width, height)
};
ds.FillRectangle(0, 0, width, height, gradientBrush);
}
// 保存为 PNG 并转为 byte[]
var stream = new InMemoryRandomAccessStream();
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
stream.Seek(0);
return stream; return stream;
} }
public static Task<ThemeColorResult> GetAccentColorAsync(BitmapDecoder decoder, PaletteGeneratorType generatorType) public static Task<ThemeColorResult> GetAccentColorAsync(BitmapDecoder decoder, PaletteGeneratorType generatorType)
{ {
return generatorType switch return generatorType switch

View File

@@ -1,93 +1,108 @@
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using NTextCat; using NTextCat;
using NTextCat.Commons;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Windows.Globalization; using Windows.Globalization;
namespace BetterLyrics.WinUI3.Services namespace BetterLyrics.WinUI3.Helper
{ {
public class LanguageHelper public class LanguageHelper
{ {
private static readonly RankedLanguageIdentifierFactory _factory = new(); private static readonly RankedLanguageIdentifierFactory _factory = new();
private static readonly RankedLanguageIdentifier _identifier; private static readonly RankedLanguageIdentifier _identifier;
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public static List<Models.LanguageInfo> SupportedTargetLanguages { get; set; } = public static List<ExtendedLanguage> SupportedTranslationTargetLanguages { get; set; } =
[ [
new Models.LanguageInfo("ar", "العربية"), new ExtendedLanguage("ar"),
new Models.LanguageInfo("az", "Azərbaycan dili"), new ExtendedLanguage("az"),
new Models.LanguageInfo("bg", "Български"), new ExtendedLanguage("bg"),
new Models.LanguageInfo("bn", "বাংলা"), new ExtendedLanguage("bn"),
new Models.LanguageInfo("ca", "Català"), new ExtendedLanguage("ca"),
new Models.LanguageInfo("cs", "Čeština"), new ExtendedLanguage("cs"),
new Models.LanguageInfo("da", "Dansk"), new ExtendedLanguage("da"),
new Models.LanguageInfo("de", "Deutsch"), new ExtendedLanguage("de"),
new Models.LanguageInfo("el", "Ελληνικά"), new ExtendedLanguage("el"),
new Models.LanguageInfo("en", "English"), new ExtendedLanguage("en"),
new Models.LanguageInfo("eo", "Esperanto"), new ExtendedLanguage("eo"),
new Models.LanguageInfo("es", "Español"), new ExtendedLanguage("es"),
new Models.LanguageInfo("et", "Eesti"), new ExtendedLanguage("et"),
new Models.LanguageInfo("eu", "Euskara"), new ExtendedLanguage("eu"),
new Models.LanguageInfo("fa", "فارسی"), new ExtendedLanguage("fa"),
new Models.LanguageInfo("fi", "Suomi"), new ExtendedLanguage("fi"),
new Models.LanguageInfo("fr", "Français"), new ExtendedLanguage("fr"),
new Models.LanguageInfo("ga", "Gaeilge"), new ExtendedLanguage("ga"),
new Models.LanguageInfo("gl", "Galego"), new ExtendedLanguage("gl"),
new Models.LanguageInfo("he", "עברית"), new ExtendedLanguage("he"),
new Models.LanguageInfo("hi", "हिन्दी"), new ExtendedLanguage("hi"),
new Models.LanguageInfo("hu", "Magyar"), new ExtendedLanguage("hu"),
new Models.LanguageInfo("id", "Bahasa Indonesia"), new ExtendedLanguage("id"),
new Models.LanguageInfo("it", "Italiano"), new ExtendedLanguage("it"),
new Models.LanguageInfo("ja", "日本語"), new ExtendedLanguage("ja"),
new Models.LanguageInfo("ko", "한국어"), new ExtendedLanguage("ko"),
new Models.LanguageInfo("ky", "Кыргызча"), new ExtendedLanguage("ky"),
new Models.LanguageInfo("lt", "Lietuvių"), new ExtendedLanguage("lt"),
new Models.LanguageInfo("lv", "Latviešu"), new ExtendedLanguage("lv"),
new Models.LanguageInfo("ms", "Bahasa Melayu"), new ExtendedLanguage("ms"),
new Models.LanguageInfo("nb", "Norsk bokmål"), new ExtendedLanguage("nb"),
new Models.LanguageInfo("nl", "Nederlands"), new ExtendedLanguage("nl"),
new Models.LanguageInfo("pt-BR", "Português (Brasil)"), new ExtendedLanguage("pt-BR"),
new Models.LanguageInfo("pl", "Polski"), new ExtendedLanguage("pl"),
new Models.LanguageInfo("pt", "Português"), new ExtendedLanguage("pt"),
new Models.LanguageInfo("ro", "Română"), new ExtendedLanguage("ro"),
new Models.LanguageInfo("ru", "Русский"), new ExtendedLanguage("ru"),
new Models.LanguageInfo("sk", "Slovenčina"), new ExtendedLanguage("sk"),
new Models.LanguageInfo("sl", "Slovenščina"), new ExtendedLanguage("sl"),
new Models.LanguageInfo("sq", "Shqip"), new ExtendedLanguage("sq"),
new Models.LanguageInfo("sr", "Српски"), new ExtendedLanguage("sr"),
new Models.LanguageInfo("sv", "Svenska"), new ExtendedLanguage("sv"),
new Models.LanguageInfo("th", "ไทย"), new ExtendedLanguage("th"),
new Models.LanguageInfo("tl", "Filipino"), new ExtendedLanguage("tl"),
new Models.LanguageInfo("tr", "Türkçe"), new ExtendedLanguage("tr"),
new Models.LanguageInfo("uk", "Українська"), new ExtendedLanguage("uk"),
new Models.LanguageInfo("ur", "اردو"), new ExtendedLanguage("ur"),
new Models.LanguageInfo("vi", "Tiếng Việt"), new ExtendedLanguage("vi"),
new Models.LanguageInfo("zh", "中文"), new ExtendedLanguage("zh"),
];
public static List<ExtendedLanguage> SupportedDisplayLanguages { get; set; } =
[
new ExtendedLanguage("", _resourceService.GetLocalizedString("SettingsPageSystemLanguage")),
new ExtendedLanguage("en-US", "English"),
new ExtendedLanguage("ja-JP"),
new ExtendedLanguage("ko-KR"),
new ExtendedLanguage("zh-CN", "简体中文"),
new ExtendedLanguage("zh-TW", "繁體中文"),
]; ];
static LanguageHelper() static LanguageHelper()
{ {
_identifier = _factory.Load(PathHelper.LanguageProfilePath); _identifier = _factory.Load(PathHelper.LanguageProfilePath);
RomajiConverter.Core.Helpers.RomajiHelper.Init();
} }
public static string? DetectLanguageCode(string? text) public static string? DetectLanguageCode(string? text)
@@ -115,16 +130,16 @@ namespace BetterLyrics.WinUI3.Services
}; };
} }
public static string GetDefaultTargetLanguageCode() public static string GetDefaultTargetTranslationLanguageCode()
{ {
var found = SupportedTargetLanguages.Find(x => ApplicationLanguages.Languages.FirstOrDefault()?.Contains(x.Code) == true); var found = SupportedTranslationTargetLanguages.Find(x => ApplicationLanguages.Languages.FirstOrDefault()?.Contains(x.LanguageCode) == true);
if (found == null) if (found == null)
{ {
return "en"; return "en";
} }
else else
{ {
return found.Code; return found.LanguageCode;
} }
} }
@@ -135,17 +150,22 @@ namespace BetterLyrics.WinUI3.Services
if (char.IsLetter(c) && c < 128) if (char.IsLetter(c) && c < 128)
return char.ToUpper(c).ToString(); return char.ToUpper(c).ToString();
if (Pinyin.Pinyin.Instance.IsHanzi(c.ToString())) if (IsHanzi(c.ToString()))
{ {
return Pinyin.Pinyin.Instance.HanziToPinyin(c.ToString(), Pinyin.ManTone.Style.NORMAL).ToStr().ToUpper().FirstOrDefault().ToString(); return PhoneticHelper.ToPinyin(c.ToString(), Pinyin.ManTone.Style.NORMAL).ToUpper().FirstOrDefault().ToString();
} }
return "#"; return "#";
} }
public static string ToRomaji(string text) public static bool IsHanzi(char ch)
{ {
return string.Join(" ", RomajiConverter.Core.Helpers.RomajiHelper.SentenceToRomaji(text).Select(x => x.Romaji)); return IsHanzi(ch.ToString());
}
public static bool IsHanzi(string text)
{
return Pinyin.Pinyin.Instance.IsHanzi(text);
} }
} }
} }

View File

@@ -9,22 +9,39 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq; using System.Xml.Linq;
using Vanara.PInvoke;
using LyricsData = BetterLyrics.WinUI3.Models.LyricsData; using LyricsData = BetterLyrics.WinUI3.Models.LyricsData;
namespace BetterLyrics.WinUI3.Helper namespace BetterLyrics.WinUI3.Helper
{ {
public partial class LyricsParser public partial class LyricsParser
{ {
private List<LyricsData> _lyricsDataArr = []; public List<LyricsData> LyricsDataArr { get; private set; } = [];
public List<LyricsData> Parse(string? raw, int? durationMs) public void Parse(List<MappedSongSearchQuery> mappedSongSearchQueries, string title, string artist, string album, string? raw, int? durationMs, LyricsSearchProvider? lyricsSearchProvider)
{ {
var overridenTitle = title;
var overridenArtist = artist;
var overridenAlbum = album;
var found = mappedSongSearchQueries
.Where(x => x.OriginalTitle == overridenTitle && x.OriginalArtist == overridenArtist && x.OriginalAlbum == overridenAlbum)
.FirstOrDefault();
if (found != null)
{
overridenTitle = found.MappedTitle;
overridenArtist = found.MappedArtist;
overridenAlbum = found.MappedAlbum;
}
LyricsDataArr = [];
durationMs ??= (int)TimeSpan.FromMinutes(99).TotalMilliseconds; durationMs ??= (int)TimeSpan.FromMinutes(99).TotalMilliseconds;
_lyricsDataArr = [];
if (raw == null) if (raw == null)
{ {
_lyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value)); LyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value));
} }
else else
{ {
@@ -48,66 +65,110 @@ namespace BetterLyrics.WinUI3.Helper
} }
} }
FillRomanizationLyricsData(); FillRomanizationLyricsData();
_lyricsDataArr.Add(new LyricsData()); // 为机翻预留 FillTranslationFromCache(overridenTitle, overridenArtist, overridenAlbum, lyricsSearchProvider);
return _lyricsDataArr; }
private void FillTranslationFromCache(string title, string artist, string album, LyricsSearchProvider? provider)
{
string? translationRaw = null;
switch (provider)
{
case LyricsSearchProvider.QQ:
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
break;
case LyricsSearchProvider.Kugou:
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
break;
case LyricsSearchProvider.Netease:
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
break;
case LyricsSearchProvider.LrcLib:
break;
case LyricsSearchProvider.AmllTtmlDb:
break;
case LyricsSearchProvider.LocalMusicFile:
break;
case LyricsSearchProvider.LocalLrcFile:
break;
case LyricsSearchProvider.LocalEslrcFile:
break;
case LyricsSearchProvider.LocalTtmlFile:
break;
default:
break;
}
if (translationRaw != null)
{
switch (provider)
{
case LyricsSearchProvider.QQ:
case LyricsSearchProvider.Kugou:
case LyricsSearchProvider.Netease:
ParseLrc(translationRaw);
break;
default:
break;
}
}
} }
private void FillRomanizationLyricsData() private void FillRomanizationLyricsData()
{ {
var chinese = _lyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault(); var chinese = LyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
if (chinese != null) if (chinese != null)
{ {
_lyricsDataArr.Add(new LyricsData LyricsDataArr.Add(new LyricsData
{ {
LanguageCode = "pinyin", LanguageCode = PhoneticHelper.PinyinCode,
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
{ {
StartMs = line.StartMs, StartMs = line.StartMs,
EndMs = line.EndMs, EndMs = line.EndMs,
OriginalText = Pinyin.Pinyin.Instance.HanziToPinyin(line.OriginalText).ToStr(), OriginalText = PhoneticHelper.ToPinyin(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{ {
StartMs = c.StartMs, StartMs = c.StartMs,
EndMs = c.EndMs, EndMs = c.EndMs,
Text = Pinyin.Pinyin.Instance.HanziToPinyin(c.Text).ToStr(), Text = PhoneticHelper.ToPinyin(c.Text),
StartIndex = c.StartIndex StartIndex = c.StartIndex
}).ToList() }).ToList()
}).ToList() }).ToList()
}); });
_lyricsDataArr.Add(new LyricsData LyricsDataArr.Add(new LyricsData
{ {
LanguageCode = "jyutping", LanguageCode = PhoneticHelper.JyutpingCode,
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
{ {
StartMs = line.StartMs, StartMs = line.StartMs,
EndMs = line.EndMs, EndMs = line.EndMs,
OriginalText = Pinyin.Jyutping.Instance.HanziToPinyin(line.OriginalText).ToStr(), OriginalText = PhoneticHelper.ToJyutping(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{ {
StartMs = c.StartMs, StartMs = c.StartMs,
EndMs = c.EndMs, EndMs = c.EndMs,
Text = Pinyin.Jyutping.Instance.HanziToPinyin(c.Text).ToStr(), Text = PhoneticHelper.ToJyutping(c.Text),
StartIndex = c.StartIndex StartIndex = c.StartIndex
}).ToList() }).ToList()
}).ToList() }).ToList()
}); });
} }
var japanese = _lyricsDataArr.Where(x => x.LanguageCode == "ja").FirstOrDefault(); var japanese = LyricsDataArr.Where(x => x.LanguageCode == "ja").FirstOrDefault();
if (japanese != null) if (japanese != null)
{ {
_lyricsDataArr.Add(new LyricsData LyricsDataArr.Add(new LyricsData
{ {
LanguageCode = "romaji", LanguageCode = PhoneticHelper.RomajiCode,
LyricsLines = japanese.LyricsLines.Select(line => new LyricsLine LyricsLines = japanese.LyricsLines.Select(line => new LyricsLine
{ {
StartMs = line.StartMs, StartMs = line.StartMs,
EndMs = line.EndMs, EndMs = line.EndMs,
OriginalText = LanguageHelper.ToRomaji(line.OriginalText), OriginalText = PhoneticHelper.ToRomaji(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{ {
StartMs = c.StartMs, StartMs = c.StartMs,
EndMs = c.EndMs, EndMs = c.EndMs,
Text = LanguageHelper.ToRomaji(c.Text), Text = PhoneticHelper.ToRomaji(c.Text),
StartIndex = c.StartIndex StartIndex = c.StartIndex
}).ToList() }).ToList()
}).ToList() }).ToList()
@@ -165,6 +226,7 @@ namespace BetterLyrics.WinUI3.Helper
int ms = int.Parse(m.Groups[4].Value.PadRight(3, '0')); int ms = int.Parse(m.Groups[4].Value.PadRight(3, '0'));
lineStartTime = min * 60_000 + sec * 1000 + ms; lineStartTime = min * 60_000 + sec * 1000 + ms;
content = bracketRegex!.Replace(line, ""); content = bracketRegex!.Replace(line, "");
if (content == "//") content = "";
lrcLines.Add((lineStartTime.Value, content, new List<(int, string)>())); lrcLines.Add((lineStartTime.Value, content, new List<(int, string)>()));
} }
} }
@@ -180,8 +242,9 @@ namespace BetterLyrics.WinUI3.Helper
} }
// 初始化每种语言的歌词列表 // 初始化每种语言的歌词列表
_lyricsDataArr.Clear(); //LyricsDataArr.Clear();
for (int i = 0; i < languageCount; i++) _lyricsDataArr.Add(new LyricsData()); int langStartIndex = LyricsDataArr.Count;
for (int i = 0; i < languageCount; i++) LyricsDataArr.Add(new LyricsData());
// 遍历每个时间分组 // 遍历每个时间分组
if (grouped != null) if (grouped != null)
@@ -219,7 +282,7 @@ namespace BetterLyrics.WinUI3.Helper
currentIndex += charText?.Length ?? 0; currentIndex += charText?.Length ?? 0;
} }
} }
_lyricsDataArr[langIdx].LyricsLines.Add(line); LyricsDataArr[langStartIndex + langIdx].LyricsLines.Add(line);
} }
// 没有翻译行则不补原文,直接跳过 // 没有翻译行则不补原文,直接跳过
} }
@@ -331,9 +394,9 @@ namespace BetterLyrics.WinUI3.Helper
}); });
} }
} }
_lyricsDataArr.Add(new LyricsData(originalLines)); LyricsDataArr.Add(new LyricsData(originalLines));
if (translationLines.Count > 0) if (translationLines.Count > 0)
_lyricsDataArr.Add(new LyricsData(translationLines)); LyricsDataArr.Add(new LyricsData(translationLines));
} }
catch catch
{ {
@@ -448,7 +511,7 @@ namespace BetterLyrics.WinUI3.Helper
} }
} }
_lyricsDataArr.Add(new LyricsData(lyricsLines)); LyricsDataArr.Add(new LyricsData(lyricsLines));
} }
[GeneratedRegex(@"\[(\d*):(\d*)(\.|\:)(\d*)\]")] [GeneratedRegex(@"\[(\d*):(\d*)(\.|\:)(\d*)\]")]

View File

@@ -20,6 +20,7 @@ namespace BetterLyrics.WinUI3.Helper
public static string LanguageProfilePath => Path.Combine(AssetsFolder, "Wiki82.profile.xml"); public static string LanguageProfilePath => Path.Combine(AssetsFolder, "Wiki82.profile.xml");
public static string LogoPath => Path.Combine(AssetsFolder, "Logo.ico"); public static string LogoPath => Path.Combine(AssetsFolder, "Logo.ico");
public static string AlbumArtPlaceholderPath => "ms-appx:///Assets/AlbumArtPlaceholder.png";
public static string AIMPLogoPath => Path.Combine(AssetsFolder, "AIMP.png"); public static string AIMPLogoPath => Path.Combine(AssetsFolder, "AIMP.png");
public static string Foobar2000LogoPath => Path.Combine(AssetsFolder, "foobar2000.png"); public static string Foobar2000LogoPath => Path.Combine(AssetsFolder, "foobar2000.png");
public static string MusicBeeLogoPath => Path.Combine(AssetsFolder, "MusicBee.png"); public static string MusicBeeLogoPath => Path.Combine(AssetsFolder, "MusicBee.png");
@@ -37,14 +38,12 @@ namespace BetterLyrics.WinUI3.Helper
public static string SaltPlayerForWindowsLogoPath => Path.Combine(AssetsFolder, "SaltPlayerForWindows.png"); public static string SaltPlayerForWindowsLogoPath => Path.Combine(AssetsFolder, "SaltPlayerForWindows.png");
public static string MoeKoeMusicLogoPath => Path.Combine(AssetsFolder, "MoeKoeMusic.png"); public static string MoeKoeMusicLogoPath => Path.Combine(AssetsFolder, "MoeKoeMusic.png");
public static string Listen1LogoPath => Path.Combine(AssetsFolder, "Listen1.png"); public static string Listen1LogoPath => Path.Combine(AssetsFolder, "Listen1.png");
public static string UnknownPlayerLogoPath => Path.Combine(AssetsFolder, "Question.png"); public static string UnknownPlayerLogoPath => Path.Combine(AssetsFolder, "Question.png");
public static string LogDirectory => Path.Combine(CacheFolder, "logs"); public static string LogDirectory => Path.Combine(CacheFolder, "logs");
public static string LogFilePattern => Path.Combine(LogDirectory, "log-.txt"); public static string LogFilePattern => Path.Combine(LogDirectory, "log-.txt");
public static string LyricsCacheDirectory => Path.Combine(CacheFolder, "lyrics"); public static string LyricsCacheDirectory => Path.Combine(CacheFolder, "lyrics");
public static string LrcLibLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "lrclib"); public static string LrcLibLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "lrclib");
public static string NeteaseLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "netease"); public static string NeteaseLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "netease");
public static string QQLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "qq"); public static string QQLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "qq");
@@ -55,15 +54,15 @@ namespace BetterLyrics.WinUI3.Helper
public static string AmllTtmlDbLastUpdatedPath => Path.Combine(LyricsCacheDirectory, "amll-ttml-db-last-updated.txt"); public static string AmllTtmlDbLastUpdatedPath => Path.Combine(LyricsCacheDirectory, "amll-ttml-db-last-updated.txt");
public static string TranslationCacheDirectory => Path.Combine(CacheFolder, "translations"); public static string TranslationCacheDirectory => Path.Combine(CacheFolder, "translations");
public static string QQTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "qq"); public static string QQTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "qq");
public static string NeteaseTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "netease"); public static string NeteaseTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "netease");
public static string KugouTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "kugou"); public static string KugouTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "kugou");
public static string AlbumArtCacheDirectory => Path.Combine(CacheFolder, "album-art"); public static string AlbumArtCacheDirectory => Path.Combine(CacheFolder, "album-art");
public static string iTunesAlbumArtCacheDirectory => Path.Combine(AlbumArtCacheDirectory, "itunes"); public static string iTunesAlbumArtCacheDirectory => Path.Combine(AlbumArtCacheDirectory, "itunes");
public static string PlayQueuePath => Path.Combine(CacheFolder, "play-queue.m3u");
public static void EnsureDirectories() public static void EnsureDirectories()
{ {
Directory.CreateDirectory(SettingsDirectory); Directory.CreateDirectory(SettingsDirectory);

View File

@@ -0,0 +1,54 @@
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Helper
{
public static class PhoneticHelper
{
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public const string PinyinCode = "zh-pinyin";
public const string JyutpingCode = "zh-jyutping";
public const string RomajiCode = "ja-romaji";
public static bool IsPhoneticCode(string code)
{
return code == PinyinCode || code == JyutpingCode || code == RomajiCode;
}
public static string GetDisplayName(string code)
{
switch (code)
{
case PinyinCode:
return _resourceService.GetLocalizedString("Pinyin");
case JyutpingCode:
return _resourceService.GetLocalizedString("Jyutping");
case RomajiCode:
return _resourceService.GetLocalizedString("Romaji");
default:
throw new ArgumentOutOfRangeException(nameof(code));
}
}
public static string ToRomaji(string text)
{
return Kana.Kana.KanaToRomaji(text, Kana.Error.Ignore).ToStr();
}
public static string ToPinyin(string text, Pinyin.ManTone.Style style = Pinyin.ManTone.Style.TONE)
{
return Pinyin.Pinyin.Instance.HanziToPinyin(text, style).ToStr();
}
public static string ToJyutping(string text)
{
return Pinyin.Jyutping.Instance.HanziToPinyin(text).ToStr();
}
}
}

View File

@@ -1,37 +1,35 @@
using BetterLyrics.WinUI3.Models.Settings; using NAudio.Dsp;
using NAudio.Dsp;
using NAudio.Wave; using NAudio.Wave;
using System; using System;
using System.Diagnostics;
namespace BetterLyrics.WinUI3.Helper namespace BetterLyrics.WinUI3.Helper
{ {
public class SpectrumAnalyzer : IDisposable public partial class SpectrumAnalyzer : IDisposable
{ {
private WasapiLoopbackCapture _capture; private WasapiLoopbackCapture? _capture;
private int _sampleRate = 48000; private int _sampleRate = 48000;
private readonly int _fftLength = 2048; private readonly int _fftLength = 2048;
private readonly float[] _fftLeftBuffer; private readonly float[] _fftLeftBuffer;
private readonly float[] _fftRightBuffer; private readonly float[] _fftRightBuffer;
private readonly Complex[] _fftLeftData; private readonly Complex[] _fftLeftData;
private readonly Complex[] _fftRightData; private readonly Complex[] _fftRightData;
private float[] _spectrumLeftData; private float[]? _spectrumLeftData;
private float[] _spectrumRightData; private float[]? _spectrumRightData;
private float[] _spectrumData; private float[]? _spectrumData;
private bool _disposed = false; private bool _disposed = false;
private double[] _hammingWindow; private double[] _hammingWindow;
private float[] _currentSpectrum; private float[]? _currentSpectrum;
public float[] SmoothSpectrum { get; private set; } public float[]? SmoothSpectrum { get; private set; }
public int BarCount { get; set; } = 32; public int BarCount { get; set; } = 16;
public int Sensitivity { get; set; } = 10; public int Sensitivity { get; set; } = 100;
public float SmoothingFactor { get; set; } = 0.95f; public float SmoothingFactor { get; set; } = 0.95f;
public bool IsCapturing { get; private set; } = false; public bool IsCapturing { get; private set; } = false;
@@ -51,12 +49,13 @@ namespace BetterLyrics.WinUI3.Helper
public void StartCapture() public void StartCapture()
{ {
_currentSpectrum = new float[BarCount];
SmoothSpectrum = new float[BarCount];
try try
{ {
_capture = new WasapiLoopbackCapture(); _currentSpectrum = new float[BarCount];
SmoothSpectrum = new float[BarCount];
_capture = new();
_sampleRate = _capture.WaveFormat.SampleRate; _sampleRate = _capture.WaveFormat.SampleRate;
_spectrumLeftData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2]; _spectrumLeftData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2];
_spectrumRightData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2]; _spectrumRightData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2];
@@ -67,9 +66,7 @@ namespace BetterLyrics.WinUI3.Helper
IsCapturing = true; IsCapturing = true;
} }
catch (Exception) catch (Exception) { }
{
}
} }
public void StopCapture() public void StopCapture()
@@ -100,10 +97,15 @@ namespace BetterLyrics.WinUI3.Helper
_fftRightData[i].Y = 0; _fftRightData[i].Y = 0;
} }
if (_spectrumData == null || _spectrumRightData == null || _currentSpectrum == null)
{
return;
}
// FFT // FFT
FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftLeftData); FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftLeftData);
FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftRightData); FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftRightData);
for (int i = 0; i < _spectrumLeftData.Length; i++) for (int i = 0; i < _spectrumLeftData?.Length; i++)
{ {
float real = (float)_fftLeftData[i].X; float real = (float)_fftLeftData[i].X;
float imaginary = (float)_fftLeftData[i].Y; float imaginary = (float)_fftLeftData[i].Y;
@@ -132,6 +134,11 @@ namespace BetterLyrics.WinUI3.Helper
public void UpdateSmoothSpectrum() public void UpdateSmoothSpectrum()
{ {
if (SmoothSpectrum == null || _currentSpectrum == null)
{
return;
}
for (int i = 0; i < BarCount; i++) for (int i = 0; i < BarCount; i++)
{ {
SmoothSpectrum[i] = SmoothSpectrum[i] * SmoothingFactor + SmoothSpectrum[i] = SmoothSpectrum[i] * SmoothingFactor +
@@ -143,7 +150,8 @@ namespace BetterLyrics.WinUI3.Helper
{ {
// 补偿曲线 // 补偿曲线
float[] frequencies = { 20, 50, 100, 200, 500, 1000, 2000, 4000, 8000, 16000, 20000 }; float[] frequencies = { 20, 50, 100, 200, 500, 1000, 2000, 4000, 8000, 16000, 20000 };
float[] gains = { 0.5f, 0.3f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.3f, 1.1f, 0.9f, 0.8f }; //float[] gains = { 0.5f, 0.3f, 0.4f, 0.6f, 0.8f, 1.0f, 1.2f, 1.3f, 1.1f, 0.9f, 0.8f };
float[] gains = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
if (freq <= frequencies[0]) if (freq <= frequencies[0])
{ {
return gains[0]; return gains[0];

View File

@@ -1,74 +1,62 @@
using Microsoft.UI.Dispatching; using Microsoft.UI.Dispatching;
using NAudio.CoreAudioApi;
using System; using System;
using Vanara.Extensions; using System.Collections.Generic;
using Vanara.PInvoke; using System.Linq;
using static Vanara.PInvoke.CoreAudio; using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Helper namespace BetterLyrics.WinUI3.Helper
{ {
public static class SystemVolumeHelper public static class SystemVolumeHelper
{ {
private readonly static IMMDeviceEnumerator _deviceEnumerator = new(); private static MMDeviceEnumerator? _deviceEnumerator;
private static IAudioEndpointVolume? _endpointVolume = null; private static MMDevice? _defaultDevice;
private static VolumeCallbackImpl? _callbackImpl;
private static int _masterVolume = 0;
private static DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); private static DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
public static event Action<int>? VolumeChanged; /// <summary>
/// 当系统音量或静音状态改变时触发。
/// </summary>
public static event EventHandler<int>? VolumeNotification;
static SystemVolumeHelper() static SystemVolumeHelper()
{ {
var device = _deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia); _deviceEnumerator = new MMDeviceEnumerator();
if (device != null) _defaultDevice = _deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
if (_defaultDevice != null)
{ {
device.Activate(typeof(IAudioEndpointVolume).GUID, 0, null, out var obj); _defaultDevice.AudioEndpointVolume.OnVolumeNotification += AudioEndpointVolume_OnVolumeNotification;
if (obj is IAudioEndpointVolume endpointVolume)
{
_endpointVolume = endpointVolume;
_callbackImpl = new VolumeCallbackImpl();
_endpointVolume.RegisterControlChangeNotify(_callbackImpl);
}
} }
} }
/// <summary> private static void AudioEndpointVolume_OnVolumeNotification(AudioVolumeNotificationData data)
/// 获取当前系统主音量0~100
/// </summary>
public static int GetMasterVolume()
{ {
if (_endpointVolume != null) _dispatcherQueue?.TryEnqueue(() =>
{ {
double level = _endpointVolume.GetMasterVolumeLevelScalar(); VolumeNotification?.Invoke(null, (int)(data.MasterVolume * 100));
_masterVolume = (int)(level * 100); });
}
/// <summary>
/// 获取或设置系统主音量 (0 到 100)。
/// </summary>
public static int MasterVolume
{
get
{
if (_defaultDevice == null)
return 0;
return (int)(_defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
} }
set
return _masterVolume;
}
/// <summary>
/// 设置当前系统主音量0~100
/// </summary>
public static void SetMasterVolume(int volume)
{
if (_masterVolume == volume) return;
_masterVolume = volume;
_endpointVolume?.SetMasterVolumeLevelScalar(_masterVolume / 100f, Guid.Empty);
}
// 内部回调实现
private class VolumeCallbackImpl : IAudioEndpointVolumeCallback
{
HRESULT IAudioEndpointVolumeCallback.OnNotify(nint pNotify)
{ {
var data = pNotify.ToStructure<AUDIO_VOLUME_NOTIFICATION_DATA>(); if (_defaultDevice == null)
_masterVolume = (int)(data.fMasterVolume * 100); return;
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ _defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar = value / 100f;
VolumeChanged?.Invoke(_masterVolume);
});
return HRESULT.S_OK;
} }
} }
} }
} }

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Helper
{
public static class TrackHelper
{
public static string GetParentFolderName(this ATL.Track track)
{
return Directory.GetParent(track.Path)?.Name ?? "";
}
public static string GetParentFolderPath(this ATL.Track track)
{
return Directory.GetParent(track.Path)?.FullName ?? "";
}
public static string GetLyrics(this ATL.Track track)
{
if (track.Path is string path)
{
return TagLib.File.Create(path).Tag.Lyrics;
}
return "";
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Helper
{
public static class VectorHelper
{
public static Vector2 WithX(this Vector2 source, float x)
{
return new Vector2(x, source.Y);
}
public static Vector2 WithY(this Vector2 source, float y)
{
return new Vector2(source.X, y);
}
}
}

View File

@@ -6,6 +6,7 @@ using BetterLyrics.WinUI3.Services.MediaSessionsService;
using BetterLyrics.WinUI3.Views; using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Windowing; using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using System; using System;
@@ -31,6 +32,8 @@ namespace BetterLyrics.WinUI3.Helper
private static readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>(); private static readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
private static readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>(); private static readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
private static DispatcherQueueTimer? _setLyricsWindowVisibilityByPlayingStatusTimer;
public static void HideWindow<T>() public static void HideWindow<T>()
{ {
var window = _activeWindows.Find(w => w is T); var window = _activeWindows.Find(w => w is T);
@@ -114,16 +117,8 @@ namespace BetterLyrics.WinUI3.Helper
else else
{ {
var castedWindow = (Window)window; var castedWindow = (Window)window;
if (typeof(T) == typeof(LyricsWindow)) castedWindow.Activate();
{ castedWindow.AppWindow.MoveInZOrderAtTop();
var lyricsWindow = (LyricsWindow)window;
lyricsWindow.Show();
}
else
{
castedWindow.Restore();
castedWindow.Activate();
}
} }
} }
@@ -202,13 +197,15 @@ namespace BetterLyrics.WinUI3.Helper
Window? window = GetWindowByWindowType<T>() as Window; Window? window = GetWindowByWindowType<T>() as Window;
if (window == null) return; if (window == null) return;
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (enable) if (enable)
{ {
EnableWorkArea(window); RegisterWorkArea(hwnd);
} }
else else
{ {
DisableWorkArea(window); UnregisterWorkArea(hwnd);
} }
} }
@@ -253,7 +250,8 @@ namespace BetterLyrics.WinUI3.Helper
var window = GetWindowByWindowType<T>() as Window; var window = GetWindowByWindowType<T>() as Window;
if (window == null) return; if (window == null) return;
window.AppWindow.MoveAndResize(rect.ToRectInt32()); window.AppWindow.Move(new Windows.Graphics.PointInt32((int)rect.X, (int)rect.Y));
window.AppWindow.Resize(new Windows.Graphics.SizeInt32((int)rect.Width, (int)rect.Height));
} }
public static void SetTitleBarArea<T>(TitleBarArea titleBarArea) public static void SetTitleBarArea<T>(TitleBarArea titleBarArea)
@@ -269,24 +267,6 @@ namespace BetterLyrics.WinUI3.Helper
} }
} }
private static void DisableWorkArea(Window window)
{
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (!_workAreas.Contains(hwnd)) return;
UnregisterWorkArea(hwnd);
}
private static void EnableWorkArea(Window window)
{
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (_workAreas.Contains(hwnd)) return;
RegisterWorkArea(hwnd);
}
private static void RegisterWorkArea(IntPtr hwnd) private static void RegisterWorkArea(IntPtr hwnd)
{ {
if (_workAreas.Contains(hwnd)) return; if (_workAreas.Contains(hwnd)) return;
@@ -369,27 +349,36 @@ namespace BetterLyrics.WinUI3.Helper
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd); Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
} }
public static void SetLyricsWindowVisibilityByPlayingStatus() /// <summary>
///
/// </summary>
/// <param name="dispatcherQueue">请确保此参数指向同一个对象,建议传值 BaseViewModel._dispatcherQueue</param>
public static void SetLyricsWindowVisibilityByPlayingStatus(DispatcherQueue dispatcherQueue)
{ {
var window = GetWindowByWindowType<LyricsWindow>(); _setLyricsWindowVisibilityByPlayingStatusTimer ??= dispatcherQueue.CreateTimer();
if (window == null) return;
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.IsPlaying) _setLyricsWindowVisibilityByPlayingStatusTimer.Debounce(() =>
{ {
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea) var window = GetWindowByWindowType<LyricsWindow>();
if (window == null) return;
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.IsPlaying)
{ {
SetIsWorkArea<LyricsWindow>(false); if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
{
SetIsWorkArea<LyricsWindow>(false);
}
HideWindow<LyricsWindow>();
} }
HideWindow<LyricsWindow>(); else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.IsPlaying)
}
else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.IsPlaying)
{
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
{ {
SetIsWorkArea<LyricsWindow>(true); if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
{
SetIsWorkArea<LyricsWindow>(true);
}
OpenOrShowWindow<LyricsWindow>();
} }
OpenOrShowWindow<LyricsWindow>(); }, Constants.Time.DebounceTimeout);
}
} }
} }

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Globalization;
namespace BetterLyrics.WinUI3.Models
{
public class ExtendedLanguage
{
public string Name { get; private set; }
public string LanguageCode { get; private set; }
public ExtendedLanguage(string languageCode, string? name = null)
{
LanguageCode = languageCode;
Name = name ?? new Language(languageCode).NativeName;
}
}
}

View File

@@ -1,23 +0,0 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Models
{
public partial class LanguageInfo : ObservableObject
{
[ObservableProperty]
public partial string Code { get; set; }
[ObservableProperty]
public partial string Name { get; set; }
public LanguageInfo(string code, string name)
{
Code = code;
Name = name;
}
}
}

View File

@@ -18,6 +18,8 @@ namespace BetterLyrics.WinUI3.Models
{ {
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowStatus LyricsWindowStatus { get; set; } [ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowStatus LyricsWindowStatus { get; set; }
public bool IsLyricsWindowStatusRefreshing { get; set; } = false;
public LiveStates() public LiveStates()
{ {
LyricsWindowStatus = new LyricsWindowStatus(); LyricsWindowStatus = new LyricsWindowStatus();

View File

@@ -1,6 +1,8 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services; using BetterLyrics.WinUI3.Services;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Lyricify.Lyrics.Helpers.General; using Lyricify.Lyrics.Helpers.General;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -13,6 +15,8 @@ namespace BetterLyrics.WinUI3.Models
{ {
public class LyricsData public class LyricsData
{ {
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public List<LyricsLine> LyricsLines { get; set; } public List<LyricsLine> LyricsLines { get; set; }
private string? _languageCode; private string? _languageCode;
public string? LanguageCode public string? LanguageCode
@@ -32,7 +36,23 @@ namespace BetterLyrics.WinUI3.Models
LyricsLines = lyricsLines; LyricsLines = lyricsLines;
} }
public void SetDisplayedTextAlongWith(LyricsData translationData, string separator, int toleranceMs = 0) public void ClearTranslatedText()
{
foreach (var line in LyricsLines)
{
line.TranslatedText = "";
}
}
public void ClearPhoneticText()
{
foreach (var line in LyricsLines)
{
line.PhoneticText = "";
}
}
public void SetTranslatedText(LyricsData translationData, string separator, int toleranceMs = 0)
{ {
foreach (var line in LyricsLines) foreach (var line in LyricsLines)
{ {
@@ -42,17 +62,39 @@ namespace BetterLyrics.WinUI3.Models
if (transLine != null) if (transLine != null)
{ {
line.DisplayedText = $"{line.OriginalText}{separator}{transLine.OriginalText}"; // 此处 transLine.OriginalText 指翻译中的“原文”属性
line.TranslatedText = transLine.OriginalText;
} }
else else
{ {
// 没有匹配的翻译,翻译部分留空 // 没有匹配的翻译
line.DisplayedText = $"{line.OriginalText}"; line.TranslatedText = "";
} }
} }
} }
public void SetDisplayedTextAlongWith(string translation, string separator) public void SetPhoneticText(LyricsData phoneticData, string separator, int toleranceMs = 0)
{
foreach (var line in LyricsLines)
{
// 在音译歌词中查找与当前行开始时间最接近且在容忍范围内的行
var transLine = phoneticData.LyricsLines
.FirstOrDefault(t => Math.Abs(t.StartMs - line.StartMs) <= toleranceMs);
if (transLine != null)
{
// 此处 transLine.OriginalText 指音译中的“原文”属性
line.PhoneticText = transLine.OriginalText;
}
else
{
// 没有匹配的音译
line.PhoneticText = "";
}
}
}
public void SetTranslation(string translation, string separator)
{ {
List<string> translationArr = translation.Split(StringHelper.NewLine).ToList(); List<string> translationArr = translation.Split(StringHelper.NewLine).ToList();
int i = 0; int i = 0;
@@ -60,24 +102,16 @@ namespace BetterLyrics.WinUI3.Models
{ {
if (i >= translationArr.Count) if (i >= translationArr.Count)
{ {
line.DisplayedText = line.OriginalText; // No translation available, keep original text line.TranslatedText = ""; // No translation available, keep empty
} }
else else
{ {
line.DisplayedText = $"{line.OriginalText}{separator}{translationArr[i]}"; line.TranslatedText = translationArr[i];
} }
i++; i++;
} }
} }
public void SetDisplayedTextInOriginalText()
{
foreach (var line in LyricsLines)
{
line.DisplayedText = line.OriginalText;
}
}
public LyricsData CreateLyricsDataFrom(string translation) public LyricsData CreateLyricsDataFrom(string translation)
{ {
var result = new LyricsData(LyricsLines.Select(line => new LyricsLine var result = new LyricsData(LyricsLines.Select(line => new LyricsLine
@@ -108,7 +142,7 @@ namespace BetterLyrics.WinUI3.Models
{ {
StartMs = 0, StartMs = 0,
EndMs = durationMs, EndMs = durationMs,
OriginalText = App.ResourceLoader!.GetString("LyricsNotFound"), OriginalText = _resourceService.GetLocalizedString("LyricsNotFound"),
LyricsChars = [], LyricsChars = [],
}]); }]);
} }
@@ -120,8 +154,9 @@ namespace BetterLyrics.WinUI3.Models
{ {
StartMs = 0, StartMs = 0,
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds, EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
PhoneticText = "",
OriginalText = "● ● ●", OriginalText = "● ● ●",
DisplayedText = "● ● ●", TranslatedText = "",
LyricsChars = [], LyricsChars = [],
}, },
]); ]);

View File

@@ -2,6 +2,7 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services;
using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects; using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Geometry; using Microsoft.Graphics.Canvas.Geometry;
@@ -53,10 +54,23 @@ namespace BetterLyrics.WinUI3.Models
easingType: EasingType.EaseInOutQuad easingType: EasingType.EaseInOutQuad
); );
public CanvasTextLayout? CanvasTextLayout { get; private set; } public CanvasTextLayout? OriginalCanvasTextLayout { get; private set; }
public CanvasTextLayout? TranslatedCanvasTextLayout { get; private set; }
public CanvasTextLayout? PhoneticCanvasTextLayout { get; private set; }
public Vector2 CenterPosition { get; private set; } public Vector2 CenterPosition { get; private set; }
public Vector2 Position { get; set; } /// <summary>
/// 原文位置
/// </summary>
public Vector2 OriginalPosition { get; set; }
/// <summary>
/// 译文位置
/// </summary>
public Vector2 TranslatedPosition { get; set; }
/// <summary>
/// 注音位置
/// </summary>
public Vector2 PhoneticPosition { get; set; }
public List<LyricsChar> LyricsChars { get; set; } = []; public List<LyricsChar> LyricsChars { get; set; } = [];
@@ -64,54 +78,136 @@ namespace BetterLyrics.WinUI3.Models
public int? EndMs { get; set; } public int? EndMs { get; set; }
public int StartMs { get; set; } public int StartMs { get; set; }
public string DisplayedText { get; set; } = ""; /// <summary>
/// 原文
/// </summary>
public string OriginalText { get; set; } = ""; public string OriginalText { get; set; } = "";
/// <summary>
/// 译文
/// </summary>
public string TranslatedText { get; set; } = "";
/// <summary>
/// 注音
/// </summary>
public string PhoneticText { get; set; } = "";
public CanvasGeometry? TextGeometry { get; private set; } public CanvasGeometry? OriginalCanvasGeometry { get; private set; }
public CanvasGeometry? TranslatedCanvasGeometry { get; private set; }
public CanvasGeometry? PhoneticCanvasGeometry { get; private set; }
public void UpdateCenterPosition(double maxWidth, TextAlignmentType type) public void UpdateCenterPosition(double maxWidth, TextAlignmentType type)
{ {
if (CanvasTextLayout == null) if (OriginalCanvasTextLayout == null)
{ {
return; return;
} }
double centerY = Position.Y + (double)CanvasTextLayout.LayoutBounds.Height;
double centerY = OriginalPosition.Y + (OriginalCanvasTextLayout?.LayoutBounds.Height ?? 0) / 2;
CenterPosition = type switch CenterPosition = type switch
{ {
TextAlignmentType.Left => new Vector2(Position.X, (float)centerY), TextAlignmentType.Left => new Vector2(OriginalPosition.X, (float)centerY),
TextAlignmentType.Center => new Vector2((float)(Position.X + maxWidth / 2.0), (float)centerY), TextAlignmentType.Center => new Vector2((float)(OriginalPosition.X + maxWidth / 2.0), (float)centerY),
TextAlignmentType.Right => new Vector2((float)(Position.X + maxWidth), (float)centerY), TextAlignmentType.Right => new Vector2((float)(OriginalPosition.X + maxWidth), (float)centerY),
_ => throw new System.ArgumentOutOfRangeException(nameof(type), type, null), _ => throw new System.ArgumentOutOfRangeException(nameof(type), type, null),
}; };
} }
public void DisposeTextLayout() public void DisposeTextLayout()
{ {
CanvasTextLayout?.Dispose(); PhoneticCanvasTextLayout?.Dispose();
CanvasTextLayout = null; PhoneticCanvasTextLayout = null;
OriginalCanvasTextLayout?.Dispose();
OriginalCanvasTextLayout = null;
TranslatedCanvasTextLayout?.Dispose();
TranslatedCanvasTextLayout = null;
} }
public void RecreateTextLayout(ICanvasAnimatedControl control, CanvasTextFormat textFormat, double maxWidth, double maxHeight, TextAlignmentType type) public void RecreateTextLayout(
ICanvasAnimatedControl control,
bool createPhonetic, bool createTranslated,
int phoneticTextFontSize, int originalTextFontSize, int translatedTextFontSize,
LyricsFontWeight fontWeight,
string fontFamilyCJK, string fontFamilyWestern,
double maxWidth, double maxHeight, TextAlignmentType type)
{ {
DisposeTextLayout(); DisposeTextLayout();
CanvasTextLayout = new CanvasTextLayout(control, DisplayedText, textFormat, (float)maxWidth, (float)maxHeight);
CanvasTextLayout.HorizontalAlignment = type.ToCanvasHorizontalAlignment(); if (createPhonetic && PhoneticText != "")
{
PhoneticCanvasTextLayout = new CanvasTextLayout(control, PhoneticText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
FontSize = phoneticTextFontSize,
FontWeight = fontWeight.ToFontWeight(),
FontFamily = LanguageHelper.IsCJK(PhoneticText) ? fontFamilyCJK : fontFamilyWestern,
}, (float)maxWidth, (float)maxHeight)
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment(),
};
}
OriginalCanvasTextLayout = new CanvasTextLayout(control, OriginalText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
FontSize = originalTextFontSize,
FontWeight = fontWeight.ToFontWeight(),
FontFamily = LanguageHelper.IsCJK(OriginalText) ? fontFamilyCJK : fontFamilyWestern,
}, (float)maxWidth, (float)maxHeight)
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
};
if (createTranslated && TranslatedText != "")
{
TranslatedCanvasTextLayout = new CanvasTextLayout(control, TranslatedText, new CanvasTextFormat
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
FontSize = translatedTextFontSize,
FontWeight = fontWeight.ToFontWeight(),
FontFamily = LanguageHelper.IsCJK(TranslatedText) ? fontFamilyCJK : fontFamilyWestern,
}, (float)maxWidth, (float)maxHeight)
{
HorizontalAlignment = type.ToCanvasHorizontalAlignment()
};
}
} }
public void DisposeTextGeometry() public void DisposeTextGeometry()
{ {
TextGeometry?.Dispose(); PhoneticCanvasGeometry?.Dispose();
TextGeometry = null; PhoneticCanvasGeometry = null;
OriginalCanvasGeometry?.Dispose();
OriginalCanvasGeometry = null;
TranslatedCanvasGeometry?.Dispose();
TranslatedCanvasGeometry = null;
} }
public void RecreateTextGeometry() public void RecreateTextGeometry()
{ {
DisposeTextGeometry(); DisposeTextGeometry();
if (CanvasTextLayout == null)
if (PhoneticCanvasTextLayout != null)
{ {
return; PhoneticCanvasGeometry = CanvasGeometry.CreateText(PhoneticCanvasTextLayout);
}
if (OriginalCanvasTextLayout != null)
{
OriginalCanvasGeometry = CanvasGeometry.CreateText(OriginalCanvasTextLayout);
}
if (TranslatedCanvasTextLayout != null)
{
TranslatedCanvasGeometry = CanvasGeometry.CreateText(TranslatedCanvasTextLayout);
} }
TextGeometry = CanvasGeometry.CreateText(CanvasTextLayout);
} }
} }
} }

View File

@@ -16,5 +16,6 @@ namespace BetterLyrics.WinUI3.Models
public string? Title { get; set; } public string? Title { get; set; }
public string? Artist { get; set; } public string? Artist { get; set; }
public string? Album { get; set; }
} }
} }

View File

@@ -1,8 +1,10 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models.Settings; using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.Views; using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Windowing; using Microsoft.UI.Windowing;
using System; using System;
using Windows.Foundation; using Windows.Foundation;
@@ -47,26 +49,6 @@ namespace BetterLyrics.WinUI3.Models
UpdateDemoWindowAndMonitorBounds(); UpdateDemoWindowAndMonitorBounds();
} }
partial void OnWindowXChanged(double value)
{
WindowBounds = WindowBounds.WithX(value);
}
partial void OnWindowYChanged(double value)
{
WindowBounds = WindowBounds.WithY(value);
}
partial void OnWindowWidthChanged(double value)
{
WindowBounds = WindowBounds.WithWidth(value);
}
partial void OnWindowHeightChanged(double value)
{
WindowBounds = WindowBounds.WithHeight(value);
}
partial void OnLyricsStyleSettingsChanged(LyricsStyleSettings oldValue, LyricsStyleSettings newValue) partial void OnLyricsStyleSettingsChanged(LyricsStyleSettings oldValue, LyricsStyleSettings newValue)
{ {
oldValue.PropertyChanged -= OldLyricsStyleSettings_PropertyChanged; oldValue.PropertyChanged -= OldLyricsStyleSettings_PropertyChanged;
@@ -91,6 +73,16 @@ namespace BetterLyrics.WinUI3.Models
newValue.PropertyChanged += OldAlbumArtLayoutSettings_PropertyChanged; newValue.PropertyChanged += OldAlbumArtLayoutSettings_PropertyChanged;
} }
partial void OnWindowBoundsChanged(Rect value)
{
UpdateMonitorNameAndBounds();
UpdateDemoWindowAndMonitorBounds();
WindowX = WindowBounds.X;
WindowY = WindowBounds.Y;
WindowWidth = WindowBounds.Width;
WindowHeight = WindowBounds.Height;
}
private void OldLyricsStyleSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) private void OldLyricsStyleSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
this.OnPropertyChanged(nameof(LyricsStyleSettings)); this.OnPropertyChanged(nameof(LyricsStyleSettings));
@@ -111,17 +103,6 @@ namespace BetterLyrics.WinUI3.Models
this.OnPropertyChanged(nameof(AlbumArtLayoutSettings)); this.OnPropertyChanged(nameof(AlbumArtLayoutSettings));
} }
partial void OnWindowBoundsChanged(Rect value)
{
UpdateMonitorNameAndBounds();
UpdateDemoWindowAndMonitorBounds();
}
partial void OnAutoShowOrHideWindowChanged(bool value)
{
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
}
public void UpdateMonitorNameAndBounds() public void UpdateMonitorNameAndBounds()
{ {
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>(); var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
@@ -137,6 +118,17 @@ namespace BetterLyrics.WinUI3.Models
); );
} }
public void UpdateMonitorBounds()
{
var mointor = MonitorHelper.GetMonitorInfoExFromDeviceName(MonitorDeviceName);
MonitorBounds = new Rect(
mointor.rcMonitor.Left,
mointor.rcMonitor.Top,
mointor.rcMonitor.Width,
mointor.rcMonitor.Height
);
}
public void UpdateDemoWindowAndMonitorBounds(double factor = 0.1) public void UpdateDemoWindowAndMonitorBounds(double factor = 0.1)
{ {
DemoWindowBounds = new Rect( DemoWindowBounds = new Rect(
@@ -153,6 +145,26 @@ namespace BetterLyrics.WinUI3.Models
); );
} }
public Rect GetWindowBoundsWhenWorkArea()
{
return new Rect(
MonitorBounds.X,
DockPlacement switch
{
DockPlacement.Top => MonitorBounds.Top,
DockPlacement.Bottom => MonitorBounds.Bottom - DockHeight,
_ => MonitorBounds.Top,
} - 1,
MonitorBounds.Width,
DockPlacement switch
{
DockPlacement.Top => DockHeight,
DockPlacement.Bottom => DockHeight,
_ => DockHeight,
} + 1
);
}
public object Clone() public object Clone()
{ {
return new LyricsWindowStatus return new LyricsWindowStatus
@@ -181,17 +193,23 @@ namespace BetterLyrics.WinUI3.Models
EnvironmentSampleMode = this.EnvironmentSampleMode, EnvironmentSampleMode = this.EnvironmentSampleMode,
AutoShowOrHideWindow = this.AutoShowOrHideWindow, AutoShowOrHideWindow = this.AutoShowOrHideWindow,
TitleBarArea = this.TitleBarArea, TitleBarArea = this.TitleBarArea,
WindowX = this.WindowX,
WindowY = this.WindowY,
WindowWidth = this.WindowWidth,
WindowHeight = this.WindowHeight,
}; };
} }
} }
public static class LyricsWindowStatusExtensions public static class LyricsWindowStatusExtensions
{ {
private static readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public static LyricsWindowStatus DesktopMode() public static LyricsWindowStatus DesktopMode()
{ {
return new LyricsWindowStatus return new LyricsWindowStatus
{ {
Name = App.ResourceLoader!.GetString("DesktopMode"), Name = _resourceService.GetLocalizedString("DesktopMode"),
LyricsDisplayType = LyricsDisplayType.LyricsOnly, LyricsDisplayType = LyricsDisplayType.LyricsOnly,
WindowBounds = new Rect(100, 100, 600, 250), WindowBounds = new Rect(100, 100, 600, 250),
IsAlwaysOnTop = true, IsAlwaysOnTop = true,
@@ -203,7 +221,6 @@ namespace BetterLyrics.WinUI3.Models
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge, EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
LyricsStyleSettings = new() LyricsStyleSettings = new()
{ {
LyricsFontSize = 20,
LyricsAlignmentType = TextAlignmentType.Center, LyricsAlignmentType = TextAlignmentType.Center,
}, },
LyricsBackgroundSettings = new LyricsBackgroundSettings LyricsBackgroundSettings = new LyricsBackgroundSettings
@@ -215,9 +232,9 @@ namespace BetterLyrics.WinUI3.Models
public static LyricsWindowStatus DockedMode() public static LyricsWindowStatus DockedMode()
{ {
return new LyricsWindowStatus var status = new LyricsWindowStatus
{ {
Name = App.ResourceLoader!.GetString("DockedMode"), Name = _resourceService.GetLocalizedString("DockedMode"),
IsWorkArea = true, IsWorkArea = true,
IsAlwaysOnTop = true, IsAlwaysOnTop = true,
IsAlwaysOnTopPolling = true, IsAlwaysOnTopPolling = true,
@@ -230,7 +247,6 @@ namespace BetterLyrics.WinUI3.Models
LyricsStyleSettings = new LyricsStyleSettings LyricsStyleSettings = new LyricsStyleSettings
{ {
LyricsAlignmentType = TextAlignmentType.Center, LyricsAlignmentType = TextAlignmentType.Center,
LyricsFontSize = 18,
}, },
LyricsBackgroundSettings = new LyricsBackgroundSettings LyricsBackgroundSettings = new LyricsBackgroundSettings
{ {
@@ -238,38 +254,32 @@ namespace BetterLyrics.WinUI3.Models
IsPureColorOverlayEnabled = true, IsPureColorOverlayEnabled = true,
} }
}; };
status.WindowBounds = status.GetWindowBoundsWhenWorkArea();
return status;
} }
public static LyricsWindowStatus FullscreenMode(Rect monitorBounds) public static LyricsWindowStatus FullscreenMode()
{ {
return new LyricsWindowStatus var status = new LyricsWindowStatus
{ {
Name = App.ResourceLoader!.GetString("FullscreenMode"), Name = _resourceService.GetLocalizedString("FullscreenMode"),
WindowBounds = monitorBounds,
IsAlwaysOnTop = true,
IsBorderless = true, IsBorderless = true,
IsShownInSwitchers = false, TitleBarArea = TitleBarArea.None,
TitleBarArea = Enums.TitleBarArea.None, LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical,
LyricsLayoutOrientation = Enums.LyricsLayoutOrientation.Vertical,
LyricsStyleSettings = new LyricsStyleSettings LyricsStyleSettings = new LyricsStyleSettings
{ {
LyricsFontSize = 72, LyricsAlignmentType = TextAlignmentType.Center,
LyricsAlignmentType = Enums.TextAlignmentType.Center,
}, },
AlbumArtLayoutSettings = new AlbumArtLayoutSettings
{
AutoAlbumArtSize = false,
AlbumArtSize = 128,
SongInfoFontSize = 36,
}
}; };
status.WindowBounds = status.MonitorBounds;
return status;
} }
public static LyricsWindowStatus StandardMode() public static LyricsWindowStatus StandardMode()
{ {
return new LyricsWindowStatus return new LyricsWindowStatus
{ {
Name = App.ResourceLoader!.GetString("StandardMode"), Name = _resourceService.GetLocalizedString("StandardMode"),
}; };
} }
@@ -277,7 +287,7 @@ namespace BetterLyrics.WinUI3.Models
{ {
return new LyricsWindowStatus return new LyricsWindowStatus
{ {
Name = App.ResourceLoader!.GetString("NarrowMode"), Name = _resourceService.GetLocalizedString("NarrowMode"),
WindowBounds = new Rect(100, 100, 400, 800), WindowBounds = new Rect(100, 100, 400, 800),
LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical, LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical,
}; };

View File

@@ -12,9 +12,11 @@ namespace BetterLyrics.WinUI3.Models
{ {
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalTitle { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalTitle { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalArtist { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalArtist { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string OriginalAlbum { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedTitle { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedTitle { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedArtist { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedArtist { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedAlbum { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMarkedAsPureMusic { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMarkedAsPureMusic { get; set; } = false;
@@ -26,8 +28,10 @@ namespace BetterLyrics.WinUI3.Models
{ {
OriginalTitle = this.OriginalTitle, OriginalTitle = this.OriginalTitle,
OriginalArtist = this.OriginalArtist, OriginalArtist = this.OriginalArtist,
OriginalAlbum = this.OriginalAlbum,
MappedTitle = this.MappedTitle, MappedTitle = this.MappedTitle,
MappedArtist = this.MappedArtist, MappedArtist = this.MappedArtist,
MappedAlbum = this.MappedAlbum,
IsMarkedAsPureMusic = this.IsMarkedAsPureMusic, IsMarkedAsPureMusic = this.IsMarkedAsPureMusic,
LyricsSearchProvider = this.LyricsSearchProvider LyricsSearchProvider = this.LyricsSearchProvider
}; };

View File

@@ -19,6 +19,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MediaSourceProviderInfo> MediaSourceProvidersInfo { get; set; } = []; [ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MediaSourceProviderInfo> MediaSourceProvidersInfo { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MappedSongSearchQuery> MappedSongSearchQueries { get; set; } = []; [ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<MappedSongSearchQuery> MappedSongSearchQueries { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsWindowStatus> WindowBoundsRecords { get; set; } = []; [ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsWindowStatus> WindowBoundsRecords { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<SongsTabInfo> StarredPlaylists { get; set; } = [];
public AppSettings() { } public AppSettings() { }
} }

View File

@@ -1,16 +1,19 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Windows.Globalization;
namespace BetterLyrics.WinUI3.Models.Settings namespace BetterLyrics.WinUI3.Models.Settings
{ {
public partial class GeneralSettings : ObservableRecipient public partial class GeneralSettings : ObservableRecipient
{ {
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Language Language { get; set; } = Language.FollowSystem; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string LanguageCode { get; set; } = "";
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LXMusicServer { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string LXMusicServer { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ShowOrHideLyricsWindowShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "H" }; [ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ShowOrHideLyricsWindowShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "H" };
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = false;

View File

@@ -29,6 +29,9 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSpectrumOverlayEnabled { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSpectrumOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSnowFlakeOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SnowFlakeOverlayAmount { get; set; } = 50;
public LyricsBackgroundSettings() { } public LyricsBackgroundSettings() { }

View File

@@ -22,11 +22,11 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsShadowScope { get; set; } = LineRenderingType.LineStartToCurrentChar; [ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsShadowScope { get; set; } = LineRenderingType.LineStartToCurrentChar;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsShadowAmount { get; set; } = 8; [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsShadowAmount { get; set; } = 8;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsHighlightScope { get; set; } = LineRenderingType.LineStartToCurrentChar; [ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType OriginalLyricsHighlightScope { get; set; } = LineRenderingType.LineStartToCurrentChar;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsHighlightAmount { get; set; } = 100; // 100% 是上界 [ObservableProperty][NotifyPropertyChangedRecipients] public partial int PhoneticLyricsHighlightAmount { get; set; } = 60; // 100% 是上界
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int OriginalLyricsHighlightAmount { get; set; } = 100; // 100% 是上界
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int TranslatedLyricsHighlightAmount { get; set; } = 60; // 100% 是上界
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsTranslationHighlightAmount { get; set; } = 60; // 100% 是上界
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAmount { get; set; } = 1; [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAmount { get; set; } = 1;
@@ -38,7 +38,15 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollBottomDelay { get; set; } = 0; [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollBottomDelay { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsVerticalEdgeOpacity { get; set; } = 0; // 0% opacity [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsVerticalEdgeOpacity { get; set; } = 0; // 0% opacity
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsFanLyricsEnabled { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsFanLyricsEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int FanLyricsAngle { get; set; } = 30;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool Is3DLyricsEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int Lyrics3DXAngle { get; set; } = 30;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int Lyrics3DYAngle { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int Lyrics3DZAngle { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int Lyrics3DDepth { get; set; } = 1000;
public LyricsEffectSettings(int lyricsScrollTopDuration, int lyricsScrollDuration, int lyricsScrollBottomDuration, EasingType lyricsScrollEasingType) public LyricsEffectSettings(int lyricsScrollTopDuration, int lyricsScrollDuration, int lyricsScrollBottomDuration, EasingType lyricsScrollEasingType)
{ {
@@ -60,15 +68,17 @@ namespace BetterLyrics.WinUI3.Models.Settings
IsLyricsShadowEnabled = this.IsLyricsShadowEnabled, IsLyricsShadowEnabled = this.IsLyricsShadowEnabled,
LyricsShadowScope = this.LyricsShadowScope, LyricsShadowScope = this.LyricsShadowScope,
LyricsShadowAmount = this.LyricsShadowAmount, LyricsShadowAmount = this.LyricsShadowAmount,
LyricsHighlightScope = this.LyricsHighlightScope, OriginalLyricsHighlightScope = this.OriginalLyricsHighlightScope,
LyricsHighlightAmount = this.LyricsHighlightAmount, PhoneticLyricsHighlightAmount = this.PhoneticLyricsHighlightAmount,
LyricsTranslationHighlightAmount = this.LyricsTranslationHighlightAmount, OriginalLyricsHighlightAmount = this.OriginalLyricsHighlightAmount,
TranslatedLyricsHighlightAmount = this.TranslatedLyricsHighlightAmount,
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled, IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
LyricsFloatAmount = this.LyricsFloatAmount, LyricsFloatAmount = this.LyricsFloatAmount,
LyricsScrollTopDelay = this.LyricsScrollTopDelay, LyricsScrollTopDelay = this.LyricsScrollTopDelay,
LyricsScrollBottomDelay = this.LyricsScrollBottomDelay, LyricsScrollBottomDelay = this.LyricsScrollBottomDelay,
LyricsVerticalEdgeOpacity = this.LyricsVerticalEdgeOpacity, LyricsVerticalEdgeOpacity = this.LyricsVerticalEdgeOpacity,
IsFanLyricsEnabled = this.IsFanLyricsEnabled IsFanLyricsEnabled = this.IsFanLyricsEnabled,
FanLyricsAngle = this.FanLyricsAngle,
}; };
} }
} }

View File

@@ -14,7 +14,9 @@ namespace BetterLyrics.WinUI3.Models.Settings
public partial class LyricsStyleSettings : ObservableRecipient, ICloneable public partial class LyricsStyleSettings : ObservableRecipient, ICloneable
{ {
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsDynamicLyricsFontSize { get; set; } = true; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsDynamicLyricsFontSize { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontSize { get; set; } = 24; [ObservableProperty][NotifyPropertyChangedRecipients] public partial int PhoneticLyricsFontSize { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int OriginalLyricsFontSize { get; set; } = 24;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int TranslatedLyricsFontSize { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType LyricsAlignmentType { get; set; } = TextAlignmentType.Left; [ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType LyricsAlignmentType { get; set; } = TextAlignmentType.Left;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsBgFontOpacity { get; set; } = 30; // 30% opacity [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsBgFontOpacity { get; set; } = 30; // 30% opacity
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontStrokeWidth { get; set; } = 0; [ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontStrokeWidth { get; set; } = 0;
@@ -27,23 +29,19 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsFontWeight LyricsFontWeight { get; set; } = LyricsFontWeight.Bold; [ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsFontWeight LyricsFontWeight { get; set; } = LyricsFontWeight.Bold;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsLineSpacingFactor { get; set; } = 0.5; [ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsLineSpacingFactor { get; set; } = 0.5;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LyricsTranslationSeparator { get; set; } = StringHelper.NewLine; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string LyricsTranslationSeparator { get; set; } = StringHelper.NewLine;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LyricsFontFamily { get; set; } = FontHelper.SystemFontFamilies.FirstOrDefault() ?? ""; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string LyricsCJKFontFamily { get; set; } = FontHelper.SystemFontFamilies.FirstOrDefault() ?? "";
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LyricsWesternFontFamily { get; set; } = FontHelper.SystemFontFamilies.FirstOrDefault() ?? "";
public LyricsStyleSettings() { } public LyricsStyleSettings() { }
public LyricsStyleSettings(int lyricsFontSize, TextAlignmentType lyricsAlignmentType, int lyricsFontStrokeWidth)
{
LyricsFontSize = lyricsFontSize;
LyricsAlignmentType = lyricsAlignmentType;
LyricsFontStrokeWidth = lyricsFontStrokeWidth;
}
public object Clone() public object Clone()
{ {
return new LyricsStyleSettings return new LyricsStyleSettings
{ {
IsDynamicLyricsFontSize = this.IsDynamicLyricsFontSize, IsDynamicLyricsFontSize = this.IsDynamicLyricsFontSize,
LyricsFontSize = this.LyricsFontSize, PhoneticLyricsFontSize = this.PhoneticLyricsFontSize,
OriginalLyricsFontSize = this.OriginalLyricsFontSize,
TranslatedLyricsFontSize = this.TranslatedLyricsFontSize,
LyricsAlignmentType = this.LyricsAlignmentType, LyricsAlignmentType = this.LyricsAlignmentType,
LyricsBgFontOpacity = this.LyricsBgFontOpacity, LyricsBgFontOpacity = this.LyricsBgFontOpacity,
LyricsFontStrokeWidth = this.LyricsFontStrokeWidth, LyricsFontStrokeWidth = this.LyricsFontStrokeWidth,
@@ -56,7 +54,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
LyricsFontWeight = this.LyricsFontWeight, LyricsFontWeight = this.LyricsFontWeight,
LyricsLineSpacingFactor = this.LyricsLineSpacingFactor, LyricsLineSpacingFactor = this.LyricsLineSpacingFactor,
LyricsTranslationSeparator = this.LyricsTranslationSeparator, LyricsTranslationSeparator = this.LyricsTranslationSeparator,
LyricsFontFamily = this.LyricsFontFamily LyricsCJKFontFamily = this.LyricsCJKFontFamily,
LyricsWesternFontFamily = this.LyricsWesternFontFamily,
}; };
} }
} }

View File

@@ -2,6 +2,7 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -11,6 +12,10 @@ namespace BetterLyrics.WinUI3.Models.Settings
public partial class MusicGallerySettings : ObservableRecipient public partial class MusicGallerySettings : ObservableRecipient
{ {
[ObservableProperty][NotifyPropertyChangedRecipients] public partial PlaybackOrder PlaybackOrder { get; set; } = PlaybackOrder.RepeatAll; [ObservableProperty][NotifyPropertyChangedRecipients] public partial PlaybackOrder PlaybackOrder { get; set; } = PlaybackOrder.RepeatAll;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ObservableCollection<string> PlayQueuePaths { get; set; } = [];
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PlayQueueIndex { get; set; } = -1;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoOpen { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoPlay { get; set; } = false;
public MusicGallerySettings() { } public MusicGallerySettings() { }
} }

View File

@@ -1,5 +1,5 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Services; using BetterLyrics.WinUI3.Helper;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -14,8 +14,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLibreTranslateEnabled { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLibreTranslateEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LibreTranslateServer { get; set; } = string.Empty; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string LibreTranslateServer { get; set; } = string.Empty;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTranslationEnabled { get; set; } = true; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTranslationEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowTranslationOnly { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial string SelectedTargetLanguageCode { get; set; } = LanguageHelper.GetDefaultTargetTranslationLanguageCode();
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string SelectedTargetLanguageCode { get; set; } = LanguageHelper.GetDefaultTargetLanguageCode();
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsJyutpingEnabled { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsJyutpingEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ChineseRomanization ChineseRomanization { get; set; } [ObservableProperty][NotifyPropertyChangedRecipients] public partial ChineseRomanization ChineseRomanization { get; set; }
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsChineseRomanizationEnabled { get; set; } = false; [ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsChineseRomanizationEnabled { get; set; } = false;

View File

@@ -1,6 +1,7 @@
// 2025/6/23 by Zhe Fang // 2025/6/23 by Zhe Fang
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System;
using Windows.Graphics.Imaging; using Windows.Graphics.Imaging;
using Windows.UI; using Windows.UI;
@@ -9,7 +10,7 @@ namespace BetterLyrics.WinUI3.Models
public partial class SongInfo : ObservableObject public partial class SongInfo : ObservableObject
{ {
[ObservableProperty] [ObservableProperty]
public partial string? Album { get; set; } public partial string Album { get; set; }
[ObservableProperty] [ObservableProperty]
public partial string Artist { get; set; } public partial string Artist { get; set; }
@@ -31,4 +32,14 @@ namespace BetterLyrics.WinUI3.Models
public SongInfo() { } public SongInfo() { }
} }
public static class SongInfoExtensions
{
public static SongInfo Placeholder => new()
{
Title = "N/A",
Album = "N/A",
Artist = "N/A",
};
}
} }

View File

@@ -1,8 +1,10 @@
using BetterLyrics.WinUI3.Enums; using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.ComponentModel;
namespace BetterLyrics.WinUI3.Models namespace BetterLyrics.WinUI3.Models
{ {
public class SongsTabInfo public partial class SongsTabInfo : BaseViewModel
{ {
public string Name { get; set; } public string Name { get; set; }
@@ -10,6 +12,9 @@ namespace BetterLyrics.WinUI3.Models
public bool IsClosable { get; set; } public bool IsClosable { get; set; }
[ObservableProperty]
public partial bool IsStarred { get; set; }
public CommonSongProperty FilterProperty { get; set; } public CommonSongProperty FilterProperty { get; set; }
public string FilterValue { get; set; } public string FilterValue { get; set; }
@@ -19,17 +24,19 @@ namespace BetterLyrics.WinUI3.Models
Name = string.Empty; Name = string.Empty;
Icon = string.Empty; Icon = string.Empty;
IsClosable = true; IsClosable = true;
IsStarred = false;
FilterProperty = CommonSongProperty.Title; FilterProperty = CommonSongProperty.Title;
FilterValue = string.Empty; FilterValue = string.Empty;
} }
public SongsTabInfo(string name, string icon, bool isClosable, CommonSongProperty filterProperty, string filterValue) public SongsTabInfo(string name, string icon, bool isClosable, bool isStarred, CommonSongProperty filterProperty, string filterValue)
{ {
Name = name; Name = name;
Icon = icon; Icon = icon;
IsClosable = isClosable; IsClosable = isClosable;
IsStarred = isStarred;
FilterProperty = filterProperty; FilterProperty = filterProperty;
FilterValue = filterValue; FilterValue = filterValue;
} }
} }
} }

View File

@@ -36,9 +36,9 @@ namespace BetterLyrics.WinUI3.Renderer
LyricsCanvas = null; LyricsCanvas = null;
} }
private async void LyricsCanvas_CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args) private void LyricsCanvas_CreateResources(Microsoft.Graphics.Canvas.UI.Xaml.CanvasAnimatedControl sender, Microsoft.Graphics.Canvas.UI.CanvasCreateResourcesEventArgs args)
{ {
await ViewModel.CreateResourcesAsync(sender); ViewModel.CreateResources(sender, args);
} }
} }
} }

View File

@@ -1,10 +1,12 @@
using BetterLyrics.WinUI3.Events; using BetterLyrics.WinUI3.Events;
using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views; using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages; using CommunityToolkit.Mvvm.Messaging.Messages;
@@ -25,6 +27,8 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
public partial class LastFMService : ILastFMService public partial class LastFMService : ILastFMService
{ {
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly IResourceService _resourceService;
private readonly LastfmClient _client; private readonly LastfmClient _client;
public event EventHandler<LastFMUserChangedEventArgs>? UserChanged; public event EventHandler<LastFMUserChangedEventArgs>? UserChanged;
@@ -34,9 +38,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
public bool IsAuthenticated { get; private set; } public bool IsAuthenticated { get; private set; }
public LastFMService(ISettingsService settingsService) public LastFMService(ISettingsService settingsService, IResourceService resourceService)
{ {
_settingsService = settingsService; _settingsService = settingsService;
_resourceService = resourceService;
_client = new LastfmClient(Constants.LastFM.ApiKey, Constants.LastFM.SharedSecret); _client = new LastfmClient(Constants.LastFM.ApiKey, Constants.LastFM.SharedSecret);
_client.Session.SessionKey = PasswordVaultHelper.Get(Constants.App.AppName, Constants.LastFM.SessionKeyCredentialKey) ?? string.Empty; _client.Session.SessionKey = PasswordVaultHelper.Get(Constants.App.AppName, Constants.LastFM.SessionKeyCredentialKey) ?? string.Empty;
@@ -53,7 +58,7 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
} }
catch (Exception) catch (Exception)
{ {
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader?.GetString("LastFMAuthFailed") ?? "", InfoBarSeverity.Error); DevWinUI.Growl.Error(_resourceService.GetLocalizedString("LastFMAuthFailed") ?? "");
} }
} }
@@ -74,10 +79,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
var dialog = new ContentDialog var dialog = new ContentDialog
{ {
Title = App.ResourceLoader?.GetString("LastFMRequestAuthTitle") ?? "", Title = _resourceService.GetLocalizedString("LastFMRequestAuthTitle") ?? "",
Content = App.ResourceLoader?.GetString("LastFMRequestAuthDesc") ?? "", Content = _resourceService.GetLocalizedString("LastFMRequestAuthDesc") ?? "",
PrimaryButtonText = App.ResourceLoader?.GetString("LastFMRequestAuthConfirm") ?? "", PrimaryButtonText = _resourceService.GetLocalizedString("LastFMRequestAuthConfirm") ?? "",
CloseButtonText = App.ResourceLoader?.GetString("Cancel") ?? "", CloseButtonText = _resourceService.GetLocalizedString("Cancel") ?? "",
DefaultButton = ContentDialogButton.Close, DefaultButton = ContentDialogButton.Close,
XamlRoot = dialogXamlRoot, XamlRoot = dialogXamlRoot,
}; };
@@ -101,10 +106,10 @@ namespace BetterLyrics.WinUI3.Services.LastFMService
var dialog = new ContentDialog var dialog = new ContentDialog
{ {
Title = App.ResourceLoader?.GetString("LastFMRequestUnAuthTitle") ?? "", Title = _resourceService.GetLocalizedString("LastFMRequestUnAuthTitle") ?? "",
Content = App.ResourceLoader?.GetString("LastFMRequestUnAuthDesc") ?? "", Content = _resourceService.GetLocalizedString("LastFMRequestUnAuthDesc") ?? "",
PrimaryButtonText = App.ResourceLoader?.GetString("LastFMRequestUnAuthConfirm") ?? "", PrimaryButtonText = _resourceService.GetLocalizedString("LastFMRequestUnAuthConfirm") ?? "",
CloseButtonText = App.ResourceLoader?.GetString("Cancel") ?? "", CloseButtonText = _resourceService.GetLocalizedString("Cancel") ?? "",
DefaultButton = ContentDialogButton.Close, DefaultButton = ContentDialogButton.Close,
XamlRoot = dialogXamlRoot, XamlRoot = dialogXamlRoot,
}; };

View File

@@ -4,7 +4,10 @@ using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views; using BetterLyrics.WinUI3.Views;
using CommunityToolkit.WinUI.Controls; using CommunityToolkit.WinUI.Controls;
using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
namespace BetterLyrics.WinUI3.Services.LiveStatesService namespace BetterLyrics.WinUI3.Services.LiveStatesService
{ {
@@ -30,24 +33,29 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
} }
} }
private void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) private async void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
LiveStates.IsLyricsWindowStatusRefreshing = true;
switch (e.PropertyName) switch (e.PropertyName)
{ {
case nameof(LyricsWindowStatus.IsWorkArea): case nameof(LyricsWindowStatus.IsWorkArea):
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea); WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
if (LiveStates.LyricsWindowStatus.IsWorkArea) if (LiveStates.LyricsWindowStatus.IsWorkArea)
{ {
UpdateWindowBoundsWhenWorkArea(); await Task.Delay(300);
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
} }
break; break;
case nameof(LyricsWindowStatus.DockHeight): case nameof(LyricsWindowStatus.DockHeight):
case nameof(LyricsWindowStatus.DockPlacement): case nameof(LyricsWindowStatus.DockPlacement):
case nameof(LyricsWindowStatus.MonitorDeviceName): case nameof(LyricsWindowStatus.MonitorDeviceName):
WindowHelper.UpdateWorkArea<LyricsWindow>(); LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
if (LiveStates.LyricsWindowStatus.IsWorkArea) if (LiveStates.LyricsWindowStatus.IsWorkArea)
{ {
UpdateWindowBoundsWhenWorkArea(); WindowHelper.UpdateWorkArea<LyricsWindow>();
await Task.Delay(300);
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea());
} }
break; break;
case nameof(LyricsWindowStatus.IsShownInSwitchers): case nameof(LyricsWindowStatus.IsShownInSwitchers):
@@ -62,15 +70,29 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
case nameof(LyricsWindowStatus.IsBorderless): case nameof(LyricsWindowStatus.IsBorderless):
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless); WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
break; break;
case nameof(LyricsWindowStatus.WindowBounds): case nameof(LyricsWindowStatus.WindowX):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds); WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithX(LiveStates.LyricsWindowStatus.WindowX));
break;
case nameof(LyricsWindowStatus.WindowY):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithY(LiveStates.LyricsWindowStatus.WindowY));
break;
case nameof(LyricsWindowStatus.WindowWidth):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithWidth(LiveStates.LyricsWindowStatus.WindowWidth));
break;
case nameof(LyricsWindowStatus.WindowHeight):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithHeight(LiveStates.LyricsWindowStatus.WindowHeight));
break; break;
case nameof(LyricsWindowStatus.TitleBarArea): case nameof(LyricsWindowStatus.TitleBarArea):
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea); WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
break; break;
case nameof(LyricsWindowStatus.AutoShowOrHideWindow):
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
break;
default: default:
break; break;
} }
LiveStates.IsLyricsWindowStatusRefreshing = false;
} }
private void LiveStates_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) private void LiveStates_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
@@ -94,45 +116,40 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus; LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus;
} }
public void RefreshLyricsWindowStatus() public async void RefreshLyricsWindowStatus()
{ {
LiveStates.IsLyricsWindowStatusRefreshing = true;
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea); WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
await Task.Delay(300);
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
UpdateWindowBoundsWhenWorkArea();
}
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
LiveStates.LyricsWindowStatus.UpdateMonitorNameAndBounds();
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers); WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
WindowHelper.SetIsAlwaysOnTop<LyricsWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop); WindowHelper.SetIsAlwaysOnTop<LyricsWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
WindowHelper.SetIsClickThrough<LyricsWindow>(LiveStates.LyricsWindowStatus.IsClickThrough); WindowHelper.SetIsClickThrough<LyricsWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless); WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus(_dispatcherQueue);
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea); WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
// 下述代码可以删除,但是为了避免给用户造成操作上的疑虑,暂时保留
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
LiveStates.LyricsWindowStatus.WindowBounds = LiveStates.LyricsWindowStatus.GetWindowBoundsWhenWorkArea();
}
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
LiveStates.LyricsWindowStatus.WindowX = LiveStates.LyricsWindowStatus.WindowBounds.X;
LiveStates.LyricsWindowStatus.WindowY = LiveStates.LyricsWindowStatus.WindowBounds.Y;
LiveStates.LyricsWindowStatus.WindowWidth = LiveStates.LyricsWindowStatus.WindowBounds.Width;
LiveStates.LyricsWindowStatus.WindowHeight = LiveStates.LyricsWindowStatus.WindowBounds.Height;
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
LiveStates.IsLyricsWindowStatusRefreshing = false;
} }
private void UpdateWindowBoundsWhenWorkArea()
{
LiveStates.LyricsWindowStatus.WindowBounds = new Windows.Foundation.Rect(
LiveStates.LyricsWindowStatus.MonitorBounds.X,
LiveStates.LyricsWindowStatus.DockPlacement switch
{
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - LiveStates.LyricsWindowStatus.DockHeight - 1,
_ => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
},
LiveStates.LyricsWindowStatus.MonitorBounds.Width,
LiveStates.LyricsWindowStatus.DockPlacement switch
{
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.DockHeight,
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.DockHeight + 1,
_ => LiveStates.LyricsWindowStatus.DockHeight,
}
);
}
} }
} }

View File

@@ -7,6 +7,7 @@ using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Services.SettingsService;
using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.Mvvm.DependencyInjection;
using Lyricify.Lyrics.Helpers;
using Lyricify.Lyrics.Providers.Web.Kugou; using Lyricify.Lyrics.Providers.Web.Kugou;
using Lyricify.Lyrics.Searchers; using Lyricify.Lyrics.Searchers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -97,17 +98,19 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
string overridenTitle = title; string overridenTitle = title;
string overridenArtist = artist; string overridenArtist = artist;
string overridenAlbum = album;
_logger.LogInformation("Searching img for: {Title} - {Artist} (Album: {Album}, Duration: {DurationMs}ms)", title, artist, album, durationMs); _logger.LogInformation("Searching img for: {Title} - {Artist} (Album: {Album}, Duration: {DurationMs}ms)", title, artist, album, durationMs);
var found = _settingsService.AppSettings.MappedSongSearchQueries var found = _settingsService.AppSettings.MappedSongSearchQueries
.Where(x => x.OriginalTitle == title && x.OriginalArtist == artist) .Where(x => x.OriginalTitle == overridenTitle && x.OriginalArtist == overridenArtist && x.OriginalAlbum == overridenAlbum)
.FirstOrDefault(); .FirstOrDefault();
if (found != null) if (found != null)
{ {
overridenTitle = found.MappedTitle; overridenTitle = found.MappedTitle;
overridenArtist = found.MappedArtist; overridenArtist = found.MappedArtist;
overridenAlbum = found.MappedAlbum;
_logger.LogInformation("Found mapped song search query: {MappedSongSearchQuery}", found); _logger.LogInformation("Found mapped song search query: {MappedSongSearchQuery}", found);
@@ -116,6 +119,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{ {
lyricsSearchResult.Title = overridenTitle; lyricsSearchResult.Title = overridenTitle;
lyricsSearchResult.Artist = overridenArtist; lyricsSearchResult.Artist = overridenArtist;
lyricsSearchResult.Album = overridenAlbum;
lyricsSearchResult.Raw = "[99:00.000]🎶🎶🎶"; lyricsSearchResult.Raw = "[99:00.000]🎶🎶🎶";
return lyricsSearchResult; return lyricsSearchResult;
} }
@@ -123,7 +127,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
var targetProvider = found.LyricsSearchProvider; var targetProvider = found.LyricsSearchProvider;
if (targetProvider != null) if (targetProvider != null)
{ {
return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, album, durationMs, songId, token); return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, overridenAlbum, durationMs, songId, token);
} }
} }
@@ -134,7 +138,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
continue; continue;
} }
lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, album, durationMs, null, token); lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, overridenAlbum, durationMs, null, token);
if (lyricsSearchResult.IsFound) if (lyricsSearchResult.IsFound)
{ {
@@ -171,12 +175,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
// Check cache first // Check cache first
if (provider.IsRemote()) if (provider.IsRemote())
{ {
var cachedLyrics = FileHelper.ReadLyricsCache(title, artist, lyricsFormat, provider.GetCacheDirectory()); var cachedLyrics = FileHelper.ReadLyricsCache(title, artist, album, lyricsFormat, provider.GetCacheDirectory());
if (!string.IsNullOrWhiteSpace(cachedLyrics)) if (!string.IsNullOrWhiteSpace(cachedLyrics))
{ {
lyricsSearchResult.Raw = cachedLyrics; lyricsSearchResult.Raw = cachedLyrics;
lyricsSearchResult.Title = title; lyricsSearchResult.Title = title;
lyricsSearchResult.Artist = artist; lyricsSearchResult.Artist = artist;
lyricsSearchResult.Album = album;
return lyricsSearchResult; return lyricsSearchResult;
} }
} }
@@ -185,11 +190,11 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{ {
if (provider == LyricsSearchProvider.LocalMusicFile) if (provider == LyricsSearchProvider.LocalMusicFile)
{ {
lyricsSearchResult = SearchEmbedded(title, artist); lyricsSearchResult = SearchEmbedded(title, artist, album);
} }
else else
{ {
lyricsSearchResult = await SearchFile(title, artist, lyricsFormat); lyricsSearchResult = await SearchFile(title, artist, album, lyricsFormat);
} }
} }
else else
@@ -209,7 +214,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.Netease); lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.Netease);
break; break;
case LyricsSearchProvider.AmllTtmlDb: case LyricsSearchProvider.AmllTtmlDb:
lyricsSearchResult = await SearchAmllTtmlDbAsync(title, artist); lyricsSearchResult = await SearchAmllTtmlDbAsync(title, artist, album);
break; break;
case LyricsSearchProvider.AppleMusic: case LyricsSearchProvider.AppleMusic:
lyricsSearchResult = await SearchAppleMusicAsync(title, artist, album, (int)durationMs); lyricsSearchResult = await SearchAppleMusicAsync(title, artist, album, (int)durationMs);
@@ -228,7 +233,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{ {
if (provider.IsRemote()) if (provider.IsRemote())
{ {
FileHelper.WriteLyricsCache(title, artist, lyricsSearchResult.Raw!, lyricsFormat, provider.GetCacheDirectory()); FileHelper.WriteLyricsCache(title, artist, album, lyricsSearchResult.Raw!, lyricsFormat, provider.GetCacheDirectory());
} }
} }
} }
@@ -239,7 +244,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
return lyricsSearchResult; return lyricsSearchResult;
} }
private async Task<LyricsSearchResult> SearchFile(string title, string artist, LyricsFormat format) private async Task<LyricsSearchResult> SearchFile(string title, string artist, string album, LyricsFormat format)
{ {
var lyricsSearchResult = new LyricsSearchResult var lyricsSearchResult = new LyricsSearchResult
{ {
@@ -262,6 +267,9 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
lyricsSearchResult.Raw = raw; lyricsSearchResult.Raw = raw;
lyricsSearchResult.Title = title; lyricsSearchResult.Title = title;
lyricsSearchResult.Artist = artist; lyricsSearchResult.Artist = artist;
lyricsSearchResult.Album = album;
return lyricsSearchResult;
} }
} }
} }
@@ -274,7 +282,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
return lyricsSearchResult; return lyricsSearchResult;
} }
private LyricsSearchResult SearchEmbedded(string title, string artist) private LyricsSearchResult SearchEmbedded(string title, string artist, string album)
{ {
var lyricsSearchResult = new LyricsSearchResult var lyricsSearchResult = new LyricsSearchResult
{ {
@@ -290,14 +298,19 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
if (FileHelper.MusicExtensions.Contains(Path.GetExtension(file))) if (FileHelper.MusicExtensions.Contains(Path.GetExtension(file)))
{ {
var track = new Track(file); var track = new Track(file);
if ((track.Title == title && track.Artist == artist) || FileHelper.IsSwitchableNormalizedMatch(Path.GetFileNameWithoutExtension(file), title, artist)) if ((album != "" && track.Title == title && track.Artist == artist && track.Album == album)
|| (album == "" && track.Title == title && track.Artist == artist)
|| (album == "" && FileHelper.IsSwitchableNormalizedMatch(Path.GetFileNameWithoutExtension(file), title, artist)))
{ {
var plain = TagLib.File.Create(file).Tag.Lyrics; var plain = track.GetLyrics();
if (!plain.IsNullOrEmpty()) if (!plain.IsNullOrEmpty())
{ {
lyricsSearchResult.Raw = plain; lyricsSearchResult.Raw = plain;
lyricsSearchResult.Title = track.Title; lyricsSearchResult.Title = track.Title;
lyricsSearchResult.Artist = artist; lyricsSearchResult.Artist = track.Artist;
lyricsSearchResult.Album = track.Album;
return lyricsSearchResult;
} }
} }
} }
@@ -307,7 +320,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
return lyricsSearchResult; return lyricsSearchResult;
} }
private async Task<LyricsSearchResult> SearchAmllTtmlDbAsync(string title, string artist) private async Task<LyricsSearchResult> SearchAmllTtmlDbAsync(string title, string artist, string album)
{ {
var lyricsSearchResult = new LyricsSearchResult var lyricsSearchResult = new LyricsSearchResult
{ {
@@ -381,6 +394,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
lyricsSearchResult.Raw = lyrics; lyricsSearchResult.Raw = lyrics;
lyricsSearchResult.Title = title; lyricsSearchResult.Title = title;
lyricsSearchResult.Artist = artist; lyricsSearchResult.Artist = artist;
lyricsSearchResult.Album = album;
} }
catch catch
{ {
@@ -420,6 +434,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
string? original = null; string? original = null;
string? searchedTitle = null; string? searchedTitle = null;
string? searchedArtist = null; string? searchedArtist = null;
string? searchedAlbum = null;
if (jArr.ValueKind == JsonValueKind.Array && jArr.GetArrayLength() > 0) if (jArr.ValueKind == JsonValueKind.Array && jArr.GetArrayLength() > 0)
{ {
@@ -427,20 +442,22 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
original = first.GetProperty("syncedLyrics").GetString(); original = first.GetProperty("syncedLyrics").GetString();
searchedTitle = first.GetProperty("trackName").GetString(); searchedTitle = first.GetProperty("trackName").GetString();
searchedArtist = first.GetProperty("artistName").GetString(); searchedArtist = first.GetProperty("artistName").GetString();
searchedAlbum = first.GetProperty("albumName").GetString();
} }
lyricsSearchResult.Raw = original; lyricsSearchResult.Raw = original;
lyricsSearchResult.Title = searchedTitle; lyricsSearchResult.Title = searchedTitle;
lyricsSearchResult.Artist = searchedArtist; lyricsSearchResult.Artist = searchedArtist;
lyricsSearchResult.Album = searchedAlbum;
return lyricsSearchResult; return lyricsSearchResult;
} }
private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, string? songId, Searchers searchers) private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, string? songId, Searchers searcher)
{ {
var lyricsSearchResult = new LyricsSearchResult(); var lyricsSearchResult = new LyricsSearchResult();
switch (searchers) switch (searcher)
{ {
case Searchers.QQMusic: case Searchers.QQMusic:
lyricsSearchResult.Provider = LyricsSearchProvider.QQ; lyricsSearchResult.Provider = LyricsSearchProvider.QQ;
@@ -458,91 +475,109 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
} }
ISearchResult? result; ISearchResult? result;
if (searchers == Searchers.Netease && songId != null) if (searcher == Searchers.Netease && songId != null)
{ {
result = new NeteaseSearchResult(title, [artist], album, null, durationMs, songId); result = new NeteaseSearchResult(title, [artist], album, null, durationMs, songId);
} }
else else
{ {
result = await SearchersHelper.GetSearcher(searchers).SearchForResult( result = await SearchHelper.Search(new Lyricify.Lyrics.Models.TrackMultiArtistMetadata()
new Lyricify.Lyrics.Models.TrackMultiArtistMetadata() {
DurationMs = durationMs,
Album = album,
AlbumArtists = [artist],
Artists = [artist],
Title = title,
}, searcher);
}
if (result != null)
{
if (result is QQMusicSearchResult qqResult)
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.QQMusicApi.GetLyricsAsync(qqResult.Id);
var original = response?.Lyrics;
var translated = response?.Trans;
if (!string.IsNullOrEmpty(translated))
{ {
DurationMs = durationMs, FileHelper.WriteLyricsCache(
Album = album, title,
Artists = [artist], artist,
Title = title, album,
translated,
LyricsFormat.Lrc,
PathHelper.QQTranslationCacheDirectory
);
} }
);
}
if (result is QQMusicSearchResult qqResult) lyricsSearchResult.Raw = original;
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.QQMusicApi.GetLyricsAsync(qqResult.Id);
var original = response?.Lyrics;
var translated = response?.Trans;
if (!string.IsNullOrEmpty(translated))
{
FileHelper.WriteLyricsCache(
title,
artist,
translated,
LyricsFormat.Lrc,
PathHelper.QQTranslationCacheDirectory
);
} }
else if (result is NeteaseSearchResult neteaseResult)
lyricsSearchResult.Raw = original;
lyricsSearchResult.Title = qqResult.Title;
lyricsSearchResult.Artist = qqResult.Artists.Join(" | ");
}
else if (result is NeteaseSearchResult neteaseResult)
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyric(neteaseResult.Id);
var original = response?.Lrc?.Lyric;
var translated = response?.Tlyric?.Lyric;
if (!string.IsNullOrEmpty(translated))
{ {
FileHelper.WriteLyricsCache( var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyric(neteaseResult.Id);
title, var original = response?.Lrc?.Lyric;
artist, var translated = response?.Tlyric?.Lyric;
translated, if (!string.IsNullOrEmpty(translated))
LyricsFormat.Lrc,
PathHelper.NeteaseTranslationCacheDirectory
);
}
lyricsSearchResult.Raw = original;
lyricsSearchResult.Title = neteaseResult.Title;
lyricsSearchResult.Artist = neteaseResult.Artists.Join(" | ");
}
else if (result is KugouSearchResult kugouResult)
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
string? original = null;
if (response?.Candidates.FirstOrDefault() is SearchLyricsResponse.Candidate candidate)
{
original = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.Id, candidate.AccessKey);
if (candidate.TransId != null)
{ {
string? translated = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.TransId, candidate.AccessKey); FileHelper.WriteLyricsCache(
if (!string.IsNullOrEmpty(translated)) title,
artist,
album,
translated,
LyricsFormat.Lrc,
PathHelper.NeteaseTranslationCacheDirectory
);
}
lyricsSearchResult.Raw = original;
}
else if (result is KugouSearchResult kugouResult)
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
string? original = null;
var candidate = response?.Candidates.FirstOrDefault();
if (candidate != null)
{
original = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.Id, candidate.AccessKey);
if (original != null)
{ {
FileHelper.WriteLyricsCache( var parsedList = Lyricify.Lyrics.Parsers.KrcParser.ParseLyrics(original);
title, if (parsedList != null)
artist, {
translated, string translated = "";
LyricsFormat.Lrc, foreach (var item in parsedList)
PathHelper.KugouTranslationCacheDirectory {
); if (item is Lyricify.Lyrics.Models.FullSyllableLineInfo fullSyllableLineInfo)
{
var startTimeSpan = TimeSpan.FromMilliseconds(fullSyllableLineInfo.StartTime ?? 0);
string startTimeStr = startTimeSpan.ToString(@"mm\:ss\.ff");
string chTranslation = fullSyllableLineInfo.Translations.GetValueOrDefault("zh") ?? "";
translated += $"[{startTimeStr}]{chTranslation}\n";
}
}
if (!string.IsNullOrEmpty(translated))
{
FileHelper.WriteLyricsCache(
title,
artist,
album,
translated,
LyricsFormat.Lrc,
PathHelper.KugouTranslationCacheDirectory
);
}
}
} }
} }
}
lyricsSearchResult.Raw = original; lyricsSearchResult.Raw = original;
lyricsSearchResult.Title = kugouResult.Title; }
lyricsSearchResult.Artist = kugouResult.Artists.Join(" | ");
} }
lyricsSearchResult.Title = result?.Title;
lyricsSearchResult.Artist = result?.Artists.Join(" | ");
lyricsSearchResult.Album = result?.Album;
return lyricsSearchResult; return lyricsSearchResult;
} }
@@ -560,6 +595,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
lyricsSearchResult.Raw = raw; lyricsSearchResult.Raw = raw;
lyricsSearchResult.Title = title; lyricsSearchResult.Title = title;
lyricsSearchResult.Artist = artist; lyricsSearchResult.Artist = artist;
lyricsSearchResult.Album = "";
} }
return lyricsSearchResult; return lyricsSearchResult;

View File

@@ -37,7 +37,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
SongInfo?.PlayerId ?? "", SongInfo?.PlayerId ?? "",
_cachedSongInfo.Title, _cachedSongInfo.Title,
_cachedSongInfo.Artist, _cachedSongInfo.Artist,
_cachedSongInfo?.Album ?? string.Empty, _cachedSongInfo.Album,
_SMTCAlbumArtBuffer, _SMTCAlbumArtBuffer,
token token
), token); ), token);
@@ -46,7 +46,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
if (buffer == null) if (buffer == null)
{ {
using var placeHolderStream = await ImageHelper.CreateTextPlaceholderBytesAsync(500, 500); using var placeHolderStream = await ImageHelper.GetAlbumArtPlaceholderAsync();
var tempBuffer = new Windows.Storage.Streams.Buffer((uint)placeHolderStream.Size); var tempBuffer = new Windows.Storage.Streams.Buffer((uint)placeHolderStream.Size);
await placeHolderStream.ReadAsync(tempBuffer, (uint)placeHolderStream.Size, InputStreamOptions.None); await placeHolderStream.ReadAsync(tempBuffer, (uint)placeHolderStream.Size, InputStreamOptions.None);
buffer = tempBuffer; buffer = tempBuffer;

View File

@@ -5,6 +5,7 @@ using BetterLyrics.WinUI3.Models;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Lyricify.Lyrics.Helpers.General; using Lyricify.Lyrics.Helpers.General;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.UI.Dispatching;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -36,27 +37,31 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
private async Task RefreshTranslationAsync(CancellationToken token) private async Task RefreshTranslationAsync(CancellationToken token)
{ {
TranslationSearchProvider = null; TranslationSearchProvider = null;
_lyricsDataArr.ElementAtOrDefault(0)?.SetDisplayedTextInOriginalText(); _lyricsDataArr.ElementAtOrDefault(0)?.ClearTranslatedText();
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
});
IsTranslating = true; IsTranslating = true;
if (_settingsService.AppSettings.TranslationSettings.IsTranslationEnabled) await SetPhoneticTextAsync(token);
{ await SetTranslatedTextAsync(token);
await SetDisplayedAlongWithTranslationsAsync(token); if (token.IsCancellationRequested) return;
if (token.IsCancellationRequested) return;
}
else
{
_logger.LogInformation("Translation is disabled, showing original lyrics only.");
_lyricsDataArr.ElementAtOrDefault(0)?.SetDisplayedTextInOriginalText();
_langIndex = 0;
}
IsTranslating = false; IsTranslating = false;
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
});
} }
private async Task SetDisplayedAlongWithTranslationsAsync(CancellationToken token) private async Task SetTranslatedTextAsync(CancellationToken token)
{ {
if (!_settingsService.AppSettings.TranslationSettings.IsTranslationEnabled) return;
_logger.LogInformation("Showing translation for lyrics..."); _logger.LogInformation("Showing translation for lyrics...");
string targetLangCode = _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode; string targetLangCode = _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode;
_logger.LogInformation("Target language code: {TargetLangCode}", targetLangCode); _logger.LogInformation("Target language code: {TargetLangCode}", targetLangCode);
@@ -64,32 +69,13 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
if (originalText == null) return; if (originalText == null) return;
string? originalLangCode = LanguageHelper.DetectLanguageCode(originalText); string? originalLangCode = LanguageHelper.DetectLanguageCode(originalText);
_logger.LogInformation("Original language code: {OriginalLangCode}", originalLangCode ?? "null"); _logger.LogInformation("Original language code: {OriginalLangCode}", originalLangCode);
if (originalLangCode == "zh" && _settingsService.AppSettings.TranslationSettings.IsChineseRomanizationEnabled)
{
switch (_settingsService.AppSettings.TranslationSettings.ChineseRomanization)
{
case ChineseRomanization.Pinyin:
targetLangCode = "pinyin";
break;
case ChineseRomanization.Jyutping:
targetLangCode = "jyutping";
break;
default:
break;
}
}
else if (originalLangCode == "ja" && _settingsService.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled)
{
targetLangCode = "romaji";
}
if (originalLangCode == targetLangCode) if (originalLangCode == targetLangCode)
{ {
_logger.LogInformation("Original lyrics already in target language: {TargetLangCode}", targetLangCode); _logger.LogInformation("Original lyrics already in target language: {TargetLangCode}", targetLangCode);
_lyricsDataArr[0].SetDisplayedTextInOriginalText(); _lyricsDataArr[0].ClearTranslatedText();
} }
else else
{ {
@@ -97,18 +83,10 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
int found = _translateService.SearchTranslatedLyricsItself(_lyricsDataArr, targetLangCode); int found = _translateService.SearchTranslatedLyricsItself(_lyricsDataArr, targetLangCode);
if (found >= 0) if (found >= 0)
{ {
_logger.LogInformation("Found translation in lyrics data at index {FoundIndex}", found); _logger.LogInformation("Found translated text in lyrics data at index {FoundIndex}", found);
if (_settingsService.AppSettings.TranslationSettings.ShowTranslationOnly)
{ _lyricsDataArr[0].SetTranslatedText(_lyricsDataArr[found], _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator, 50);
_lyricsDataArr[found].SetDisplayedTextInOriginalText(); TranslationSearchProvider = LyricsSearchProvider.ToTranslationSearchProvider();
_langIndex = found;
}
else
{
_lyricsDataArr[0].SetDisplayedTextAlongWith(_lyricsDataArr[found], _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator, 50);
_langIndex = 0;
TranslationSearchProvider = LyricsSearchProvider.ToTranslationSearchProvider();
}
} }
else if (_settingsService.AppSettings.TranslationSettings.IsLibreTranslateEnabled) else if (_settingsService.AppSettings.TranslationSettings.IsLibreTranslateEnabled)
{ {
@@ -120,27 +98,53 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
if (token.IsCancellationRequested) return; if (token.IsCancellationRequested) return;
if (translated == string.Empty) return; if (translated == string.Empty) return;
if (_settingsService.AppSettings.TranslationSettings.ShowTranslationOnly) _lyricsDataArr[0].SetTranslation(translated, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator);
{
_lyricsDataArr[^1] = _lyricsDataArr[0].CreateLyricsDataFrom(translated);
_lyricsDataArr[^1].SetDisplayedTextInOriginalText();
_langIndex = _lyricsDataArr.Count - 1;
}
else
{
_lyricsDataArr[0].SetDisplayedTextAlongWith(translated, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator);
_langIndex = 0;
}
TranslationSearchProvider = Enums.TranslationSearchProvider.LibreTranslate; TranslationSearchProvider = Enums.TranslationSearchProvider.LibreTranslate;
} }
catch (Exception) catch (Exception)
{ {
App.Current.LyricsWindowNotificationPanel?.Notify(App.ResourceLoader?.GetString("LibreTranslateFailed")!, Microsoft.UI.Xaml.Controls.InfoBarSeverity.Error); DevWinUI.Growl.Error(_resourceService.GetLocalizedString("LibreTranslateFailed")!);
} }
} }
} }
} }
private async Task SetPhoneticTextAsync(CancellationToken token)
{
_logger.LogInformation("Showing phonetic text for lyrics...");
string targetPhoneticCode = "";
_logger.LogInformation("Target phonetic code: {TargetPhonetic}", targetPhoneticCode);
string? originalText = _lyricsDataArr.FirstOrDefault()?.WrappedOriginalText;
if (originalText == null) return;
string? originalLangCode = LanguageHelper.DetectLanguageCode(originalText);
_logger.LogInformation("Original phonetic code: {OriginalLangCode}", originalLangCode);
if (originalLangCode == "zh" && _settingsService.AppSettings.TranslationSettings.IsChineseRomanizationEnabled)
{
targetPhoneticCode = _settingsService.AppSettings.TranslationSettings.ChineseRomanization.ToPhoneticCode();
}
else if (originalLangCode == "ja" && _settingsService.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled)
{
targetPhoneticCode = PhoneticHelper.RomajiCode;
}
if (targetPhoneticCode == "")
{
_lyricsDataArr[0].ClearPhoneticText();
}
// Try get phonetic text from itself
int found = _translateService.SearchTranslatedLyricsItself(_lyricsDataArr, targetPhoneticCode);
if (found >= 0)
{
_logger.LogInformation("Found phonetic text in lyrics data at index {FoundIndex}", found);
_lyricsDataArr[0].SetPhoneticText(_lyricsDataArr[found], _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsTranslationSeparator, 50);
}
}
private async Task RefreshLyricsAsync(CancellationToken token) private async Task RefreshLyricsAsync(CancellationToken token)
{ {
_logger.LogInformation("Refreshing lyrics..."); _logger.LogInformation("Refreshing lyrics...");
@@ -148,7 +152,10 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
LyricsSearchProvider = null; LyricsSearchProvider = null;
_lyricsDataArr = [LyricsData.GetLoadingPlaceholder()]; _lyricsDataArr = [LyricsData.GetLoadingPlaceholder()];
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData)); _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
});
if (SongInfo != null) if (SongInfo != null)
{ {
@@ -159,7 +166,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
SongInfo.PlayerId ?? "", SongInfo.PlayerId ?? "",
SongInfo.Title, SongInfo.Title,
SongInfo.Artist, SongInfo.Artist,
SongInfo.Album ?? "", SongInfo.Album,
SongInfo.DurationMs ?? 0, SongInfo.DurationMs ?? 0,
SongInfo.SongId, SongInfo.SongId,
token token
@@ -167,11 +174,14 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
if (token.IsCancellationRequested) return; if (token.IsCancellationRequested) return;
LyricsSearchProvider = lyricsSearchResult?.Provider; LyricsSearchProvider = lyricsSearchResult?.Provider;
_logger.LogInformation("Lyrics was found? {Found}, Provider: {LyricsSearchProvider}", lyricsSearchResult?.IsFound, LyricsSearchProvider?.ToString() ?? "null"); _logger.LogInformation("Lyrics was found? {Found}, Provider: {LyricsSearchProvider}", lyricsSearchResult?.IsFound, LyricsSearchProvider);
_lyricsDataArr = new LyricsParser().Parse(lyricsSearchResult?.Raw, (int?)SongInfo?.DurationMs); var lyricsParser = new LyricsParser();
lyricsParser.Parse(
_settingsService.AppSettings.MappedSongSearchQueries.ToList(),
SongInfo.Title, SongInfo.Artist, SongInfo.Album, lyricsSearchResult?.Raw, (int?)SongInfo?.DurationMs, LyricsSearchProvider);
_lyricsDataArr = lyricsParser.LyricsDataArr;
ApplyChinesePreference(); ApplyChinesePreference();
FillTranslationFromCache(LyricsSearchProvider);
} }
else else
{ {
@@ -180,10 +190,14 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_logger.LogInformation("Parsed lyrics: {MultiLangLyricsCount} languages", _lyricsDataArr.Count); _logger.LogInformation("Parsed lyrics: {MultiLangLyricsCount} languages", _lyricsDataArr.Count);
// This ensures that original lyrics are always shown while waiting for translations // Show original first while loading phonetic and translated
_lyricsDataArr[0].SetDisplayedTextInOriginalText();
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
ApplyChinesePreference(); ApplyChinesePreference();
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{
LyricsChanged?.Invoke(this, new LyricsChangedEventArgs(CurrentLyricsData));
});
UpdateTranslations(); UpdateTranslations();
} }
@@ -195,61 +209,11 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
foreach (var item in _lyricsDataArr[found].LyricsLines) foreach (var item in _lyricsDataArr[found].LyricsLines)
{ {
item.OriginalText = traditionalChinesePreferred ? ChineseHelper.S2T(item.OriginalText) : ChineseHelper.T2S(item.OriginalText); item.OriginalText = traditionalChinesePreferred ? ChineseHelper.ToTC(item.OriginalText) : ChineseHelper.ToSC(item.OriginalText);
} }
} }
} }
private void FillTranslationFromCache(LyricsSearchProvider? provider)
{
string? translationRaw = null;
switch (provider)
{
case Enums.LyricsSearchProvider.QQ:
translationRaw = FileHelper.ReadLyricsCache(SongInfo!.Title, SongInfo.Artist, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
break;
case Enums.LyricsSearchProvider.Kugou:
translationRaw = FileHelper.ReadLyricsCache(SongInfo!.Title, SongInfo.Artist, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
break;
case Enums.LyricsSearchProvider.Netease:
translationRaw = FileHelper.ReadLyricsCache(SongInfo!.Title, SongInfo.Artist, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
break;
case Enums.LyricsSearchProvider.LrcLib:
break;
case Enums.LyricsSearchProvider.AmllTtmlDb:
break;
case Enums.LyricsSearchProvider.LocalMusicFile:
break;
case Enums.LyricsSearchProvider.LocalLrcFile:
break;
case Enums.LyricsSearchProvider.LocalEslrcFile:
break;
case Enums.LyricsSearchProvider.LocalTtmlFile:
break;
default:
break;
}
if (translationRaw != null)
{
var translationData = new LyricsParser().Parse(translationRaw, (int?)SongInfo?.DurationMs);
if (provider == Enums.LyricsSearchProvider.QQ)
{
foreach (var data in translationData)
{
foreach (var item in data.LyricsLines)
{
if (item.OriginalText == "//")
{
item.OriginalText = "";
}
}
}
}
_lyricsDataArr = _lyricsDataArr.Concat(translationData).ToList();
}
}
public void UpdateLyrics() public void UpdateLyrics()
{ {
_refreshLyricsRunner.RunAsync(RefreshLyricsAsync); _refreshLyricsRunner.RunAsync(RefreshLyricsAsync);

View File

@@ -10,6 +10,7 @@ using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
using BetterLyrics.WinUI3.Services.LibWatcherService; using BetterLyrics.WinUI3.Services.LibWatcherService;
using BetterLyrics.WinUI3.Services.LiveStatesService; using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.LyricsSearchService; using BetterLyrics.WinUI3.Services.LyricsSearchService;
using BetterLyrics.WinUI3.Services.ResourceService;
using BetterLyrics.WinUI3.Services.SettingsService; using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.TranslateService; using BetterLyrics.WinUI3.Services.TranslateService;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
@@ -46,6 +47,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly ILibWatcherService _libWatcherService; private readonly ILibWatcherService _libWatcherService;
private readonly ILiveStatesService _liveStatesService; private readonly ILiveStatesService _liveStatesService;
private readonly IResourceService _resourceService;
private readonly ILogger<MediaSessionsService> _logger; private readonly ILogger<MediaSessionsService> _logger;
private double _lxMusicPositionSeconds = 0; private double _lxMusicPositionSeconds = 0;
@@ -77,7 +79,8 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
ILyricsSearchService musicSearchService, ILyricsSearchService musicSearchService,
ILibWatcherService libWatcherService, ILibWatcherService libWatcherService,
ILiveStatesService liveStatesService, ILiveStatesService liveStatesService,
ITranslateService libreTranslateService) ITranslateService libreTranslateService,
IResourceService resourceService)
{ {
_settingsService = settingsService; _settingsService = settingsService;
_albumArtSearchService = albumArtSearchService; _albumArtSearchService = albumArtSearchService;
@@ -85,6 +88,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_libWatcherService = libWatcherService; _libWatcherService = libWatcherService;
_translateService = libreTranslateService; _translateService = libreTranslateService;
_liveStatesService = liveStatesService; _liveStatesService = liveStatesService;
_resourceService = resourceService;
_logger = Ioc.Default.GetRequiredService<ILogger<MediaSessionsService>>(); _logger = Ioc.Default.GetRequiredService<ILogger<MediaSessionsService>>();
_settingsService.AppSettings.MediaSourceProvidersInfo.ItemPropertyChanged += MediaSourceProvidersInfo_ItemPropertyChanged; _settingsService.AppSettings.MediaSourceProvidersInfo.ItemPropertyChanged += MediaSourceProvidersInfo_ItemPropertyChanged;
@@ -213,14 +217,14 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_mediaManager.CurrentMediaSessions.ToList().ForEach(x => RecordMediaSourceProviderInfo(x.Value)); _mediaManager.CurrentMediaSessions.ToList().ForEach(x => RecordMediaSourceProviderInfo(x.Value));
} }
private void MediaManager_OnFocusedSessionChanged(MediaManager.MediaSession? mediaSession) private async void MediaManager_OnFocusedSessionChanged(MediaManager.MediaSession? mediaSession)
{ {
if (!_mediaManager.IsStarted) return; if (!_mediaManager.IsStarted) return;
SendFocusedMessagesAsync(); await SendFocusedMessagesAsync();
} }
private void MediaManager_OnAnyTimelinePropertyChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionTimelineProperties timelineProperties) private void MediaManager_OnAnyTimelinePropertyChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionTimelineProperties? timelineProperties)
{ {
if (!_mediaManager.IsStarted) return; if (!_mediaManager.IsStarted) return;
if (mediaSession == null) return; if (mediaSession == null) return;
@@ -241,16 +245,16 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
if (IsMediaSourceTimelineSyncEnabled(mediaSession.Id)) if (IsMediaSourceTimelineSyncEnabled(mediaSession.Id))
{ {
_cachedPosition = timelineProperties.Position; _cachedPosition = timelineProperties?.Position ?? TimeSpan.Zero;
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ {
TimelineChanged?.Invoke(this, new TimelineChangedEventArgs(_cachedPosition, timelineProperties.EndTime)); TimelineChanged?.Invoke(this, new TimelineChangedEventArgs(_cachedPosition, timelineProperties?.EndTime ?? TimeSpan.Zero));
}); });
} }
} }
} }
private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo) private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionPlaybackInfo? playbackInfo)
{ {
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ {
@@ -268,7 +272,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
} }
else else
{ {
_cachedIsPlaying = playbackInfo.PlaybackStatus switch _cachedIsPlaying = playbackInfo?.PlaybackStatus switch
{ {
GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing => true, GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing => true,
_ => false, _ => false,
@@ -279,26 +283,28 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
}); });
} }
private void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties) private void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession? mediaSession, GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProperties)
{ {
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
{ {
if (!_mediaManager.IsStarted) return; if (!_mediaManager.IsStarted) return;
if (mediaSession == null) return; if (mediaSession == null)
{
_cachedSongInfo = SongInfoExtensions.Placeholder;
}
string sessionId = mediaSession.Id; string? sessionId = mediaSession?.Id;
var desiredSession = GetCurrentSession(); var desiredSession = GetCurrentSession();
//RecordMediaSourceProviderInfo(mediaSession);
if (mediaSession != desiredSession) return; if (mediaSession != desiredSession) return;
if (!IsMediaSourceEnabled(sessionId)) if (sessionId != null && !IsMediaSourceEnabled(sessionId))
{ {
_cachedSongInfo = null; _cachedSongInfo = SongInfoExtensions.Placeholder;
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}", _logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle); mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
if (sessionId == Constants.PlayerID.LXMusic) if (sessionId == Constants.PlayerID.LXMusic)
{ {
@@ -315,33 +321,33 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
currentMediaSourceProviderInfo?.PositionOffset = 0; currentMediaSourceProviderInfo?.PositionOffset = 0;
} }
string fixedArtist = mediaProperties.Artist; string fixedArtist = mediaProperties?.Artist ?? "N/A";
string fixedAlbum = mediaProperties.AlbumTitle; string fixedAlbum = mediaProperties?.AlbumTitle ?? "N/A";
string? songId = null; string? songId = null;
if (sessionId == Constants.PlayerID.AppleMusic || sessionId == Constants.PlayerID.AppleMusicAlternative) if (sessionId == Constants.PlayerID.AppleMusic || sessionId == Constants.PlayerID.AppleMusicAlternative)
{ {
fixedArtist = mediaProperties.Artist.Split(" — ").FirstOrDefault() ?? mediaProperties.Artist; fixedArtist = mediaProperties?.Artist.Split(" — ").FirstOrDefault() ?? (mediaProperties?.Artist ?? "N/A");
fixedAlbum = mediaProperties.Artist.Split(" — ").LastOrDefault() ?? mediaProperties.AlbumTitle; fixedAlbum = mediaProperties?.Artist.Split(" — ").LastOrDefault() ?? (mediaProperties?.AlbumTitle ?? "N/A");
} }
else if (PlayerIdMatcher.IsNeteaseFamily(sessionId)) else if (PlayerIdMatcher.IsNeteaseFamily(sessionId ?? ""))
{ {
songId = mediaProperties.Genres.FirstOrDefault()?.Replace("NCM-", ""); songId = mediaProperties?.Genres.FirstOrDefault()?.Replace("NCM-", "");
} }
_cachedSongInfo = new SongInfo _cachedSongInfo = new SongInfo
{ {
Title = mediaProperties.Title, Title = mediaProperties?.Title ?? "N/A",
Artist = fixedArtist, Artist = fixedArtist,
Album = fixedAlbum, Album = fixedAlbum,
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds, DurationMs = mediaSession?.ControlSession?.GetTimelineProperties().EndTime.TotalMilliseconds,
PlayerId = sessionId, PlayerId = sessionId,
SongId = songId SongId = songId
}; };
_cachedSongInfo.Duration = (int)(_cachedSongInfo.DurationMs / 1000f); _cachedSongInfo.Duration = (int)((_cachedSongInfo.DurationMs ?? 0) / 1000f);
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}", _logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle); mediaProperties?.Title, mediaProperties?.Artist, mediaProperties?.AlbumTitle);
if (sessionId == Constants.PlayerID.LXMusic) if (sessionId == Constants.PlayerID.LXMusic)
{ {
@@ -356,7 +362,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer(); _SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
} }
else if (mediaProperties.Thumbnail is IRandomAccessStreamReference streamReference) else if (mediaProperties?.Thumbnail is IRandomAccessStreamReference streamReference)
{ {
_SMTCAlbumArtBuffer = await ImageHelper.ToBufferAsync(streamReference); _SMTCAlbumArtBuffer = await ImageHelper.ToBufferAsync(streamReference);
} }
@@ -438,7 +444,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ {
_cachedSongInfo = null; _cachedSongInfo = SongInfoExtensions.Placeholder;
_cachedIsPlaying = false; _cachedIsPlaying = false;
SongInfoChanged?.Invoke(this, new SongInfoChangedEventArgs(_cachedSongInfo)); SongInfoChanged?.Invoke(this, new SongInfoChangedEventArgs(_cachedSongInfo));
IsPlayingChanged?.Invoke(this, new IsPlayingChangedEventArgs(_cachedIsPlaying)); IsPlayingChanged?.Invoke(this, new IsPlayingChangedEventArgs(_cachedIsPlaying));
@@ -448,14 +454,21 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
private async Task SendFocusedMessagesAsync() private async Task SendFocusedMessagesAsync()
{ {
var desiredSession = GetCurrentSession(); GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps = null;
if (desiredSession == null || desiredSession.ControlSession == null) return;
var mediaProps = await desiredSession.ControlSession.TryGetMediaPropertiesAsync(); var desiredSession = GetCurrentSession();
if (desiredSession == null || desiredSession.ControlSession == null) return; //if (desiredSession == null || desiredSession.ControlSession == null) return;
MediaManager_OnAnyTimelinePropertyChanged(desiredSession, desiredSession.ControlSession.GetTimelineProperties());
try
{
mediaProps = await desiredSession?.ControlSession?.TryGetMediaPropertiesAsync();
}
catch (Exception) { }
//if (desiredSession == null || desiredSession.ControlSession == null) return;
MediaManager_OnAnyTimelinePropertyChanged(desiredSession, desiredSession?.ControlSession?.GetTimelineProperties());
MediaManager_OnAnyMediaPropertyChanged(desiredSession, mediaProps); MediaManager_OnAnyMediaPropertyChanged(desiredSession, mediaProps);
MediaManager_OnAnyPlaybackStateChanged(desiredSession, desiredSession.ControlSession.GetPlaybackInfo()); MediaManager_OnAnyPlaybackStateChanged(desiredSession, desiredSession?.ControlSession?.GetPlaybackInfo());
} }
private void StartSSE() private void StartSSE()
@@ -476,7 +489,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
_logger.LogError("Failed to start SSE connection for LX Music."); _logger.LogError("Failed to start SSE connection for LX Music.");
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ {
App.Current.LyricsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("FailToStartLXMusicServer"), Microsoft.UI.Xaml.Controls.InfoBarSeverity.Error); DevWinUI.Growl.Error(_resourceService.GetLocalizedString("FailToStartLXMusicServer"));
}); });
StopSSE(); StopSSE();
} }
@@ -607,10 +620,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
UpdateTranslations(); UpdateTranslations();
} }
else if (message.PropertyName == nameof(TranslationSettings.ShowTranslationOnly))
{
UpdateTranslations();
}
else if (message.PropertyName == nameof(TranslationSettings.IsChineseRomanizationEnabled)) else if (message.PropertyName == nameof(TranslationSettings.IsChineseRomanizationEnabled))
{ {
UpdateTranslations(); UpdateTranslations();
@@ -658,7 +667,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{ {
if (message.PropertyName == nameof(TranslationSettings.SelectedTargetLanguageCode)) if (message.PropertyName == nameof(TranslationSettings.SelectedTargetLanguageCode))
{ {
_logger.LogInformation("Target language code changed: {code}", _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode); _logger.LogInformation("Target LibreTranslate language code changed: {code}", _settingsService.AppSettings.TranslationSettings.SelectedTargetLanguageCode);
UpdateTranslations(); UpdateTranslations();
} }
} }

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Services.ResourceService
{
public interface IResourceService
{
string GetLocalizedString(string id);
}
}

View File

@@ -0,0 +1,19 @@
using Microsoft.Windows.ApplicationModel.Resources;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Services.ResourceService
{
public class ResourceService : IResourceService
{
private readonly ResourceLoader _resourceLoader = new();
public string GetLocalizedString(string id)
{
return _resourceLoader.GetString(id);
}
}
}

View File

@@ -7,7 +7,6 @@ using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings; using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Serialization; using BetterLyrics.WinUI3.Serialization;
using BetterLyrics.WinUI3.ViewModels; using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.WinUI; using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching; using Microsoft.UI.Dispatching;
using System; using System;
@@ -17,14 +16,17 @@ using Windows.Globalization;
namespace BetterLyrics.WinUI3.Services.SettingsService namespace BetterLyrics.WinUI3.Services.SettingsService
{ {
// TODO 初始化时从文件读取到对象,后续独写操作先操纵对象,写入用 Debounce 写入文件
// 新建一个 AppSettings 类 // 新建一个 AppSettings 类
public partial class SettingsService : BaseViewModel, ISettingsService public partial class SettingsService : BaseViewModel, ISettingsService
{ {
private DispatcherQueueTimer _writeAppSettingsTimer;
public AppSettings AppSettings { get; set; } public AppSettings AppSettings { get; set; }
public SettingsService() public SettingsService()
{ {
_writeAppSettingsTimer = _dispatcherQueue.CreateTimer();
AppSettings = ReadAppSettings(); AppSettings = ReadAppSettings();
AppSettings.PropertyChanged += AppSettings_PropertyChanged; AppSettings.PropertyChanged += AppSettings_PropertyChanged;
@@ -46,6 +48,11 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
AppSettings.WindowBoundsRecords.CollectionChanged += AppSettings_CollectionChanged; AppSettings.WindowBoundsRecords.CollectionChanged += AppSettings_CollectionChanged;
AppSettings.WindowBoundsRecords.ItemPropertyChanged += AppSettings_ItemPropertyChanged; AppSettings.WindowBoundsRecords.ItemPropertyChanged += AppSettings_ItemPropertyChanged;
AppSettings.StarredPlaylists.CollectionChanged += AppSettings_CollectionChanged;
AppSettings.StarredPlaylists.ItemPropertyChanged += AppSettings_ItemPropertyChanged;
AppSettings.MusicGallerySettings.PlayQueuePaths.CollectionChanged += AppSettings_CollectionChanged;
AppSettings.Version = MetadataHelper.AppVersion; AppSettings.Version = MetadataHelper.AppVersion;
EnsureMediaSourceProvidersInfo(); EnsureMediaSourceProvidersInfo();
@@ -93,47 +100,25 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
private void AppSettings_ItemPropertyChanged(object? sender, ItemPropertyChangedEventArgs e) private void AppSettings_ItemPropertyChanged(object? sender, ItemPropertyChangedEventArgs e)
{ {
WriteAppSettingsDebounce(); WriteAppSettings();
} }
private void AppSettings_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) private void AppSettings_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{ {
WriteAppSettingsDebounce(); WriteAppSettings();
} }
private void AppSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) private void AppSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
switch (e.PropertyName) switch (e.PropertyName)
{ {
case nameof(GeneralSettings.Language): case nameof(GeneralSettings.LanguageCode):
switch (AppSettings.GeneralSettings.Language) ApplicationLanguages.PrimaryLanguageOverride = AppSettings.GeneralSettings.LanguageCode;
{
case Enums.Language.FollowSystem:
ApplicationLanguages.PrimaryLanguageOverride = "";
break;
case Enums.Language.English:
ApplicationLanguages.PrimaryLanguageOverride = "en-US";
break;
case Enums.Language.SimplifiedChinese:
ApplicationLanguages.PrimaryLanguageOverride = "zh-CN";
break;
case Enums.Language.TraditionalChinese:
ApplicationLanguages.PrimaryLanguageOverride = "zh-TW";
break;
case Enums.Language.Japanese:
ApplicationLanguages.PrimaryLanguageOverride = "ja-JP";
break;
case Enums.Language.Korean:
ApplicationLanguages.PrimaryLanguageOverride = "ko-KR";
break;
default:
break;
}
break; break;
default: default:
break; break;
} }
WriteAppSettingsDebounce(); WriteAppSettings();
} }
/// <summary> /// <summary>
@@ -154,7 +139,6 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
/// <returns></returns> /// <returns></returns>
public bool ImportSettings(string importPath) public bool ImportSettings(string importPath)
{ {
// TODO 导入有问题
if (!File.Exists(importPath)) if (!File.Exists(importPath))
return false; return false;
@@ -183,9 +167,9 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
return data; return data;
} }
private void WriteAppSettingsDebounce() private void WriteAppSettings()
{ {
_dispatcherQueueTimer.Debounce(() => _writeAppSettingsTimer.Debounce(() =>
{ {
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () => _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, () =>
{ {

View File

@@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Services.TranslateService namespace BetterLyrics.WinUI3.Services.TranslateService
{ {
public class TranslateService : BaseViewModel, ITranslateService public partial class TranslateService : BaseViewModel, ITranslateService
{ {
private readonly ISettingsService _settingsService; private readonly ISettingsService _settingsService;
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>Operation completed</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve"> <data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>Local music files</value> <value>Local music files</value>
</data> </data>
@@ -138,6 +141,9 @@
<data name="Cancel" xml:space="preserve"> <data name="Cancel" xml:space="preserve">
<value>Cancel</value> <value>Cancel</value>
</data> </data>
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
<value>Playlist was created successfully</value>
</data>
<data name="DemoWindowControlDefault.Text" xml:space="preserve"> <data name="DemoWindowControlDefault.Text" xml:space="preserve">
<value>Default</value> <value>Default</value>
</data> </data>
@@ -171,12 +177,18 @@
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve"> <data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
<value>Music gallery</value> <value>Music gallery</value>
</data> </data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve"> <data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
<value>Settings</value> <value>Settings</value>
</data> </data>
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
<value>Playlist was imported successfully</value>
</data>
<data name="ImportSettingsFailed" xml:space="preserve"> <data name="ImportSettingsFailed" xml:space="preserve">
<value>Settings file import failed, application settings remain unchanged</value> <value>Settings file import failed, application settings remain unchanged</value>
</data> </data>
<data name="Jyutping" xml:space="preserve">
<value>Cantonese pinyin</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve"> <data name="LastFMAuthFailed" xml:space="preserve">
<value>Authorization failed, please try again</value> <value>Authorization failed, please try again</value>
</data> </data>
@@ -243,7 +255,10 @@
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve"> <data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
<value>Translation provider</value> <value>Translation provider</value>
</data> </data>
<data name="LyricsSearchControlArtist.Header" xml:space="preserve"> <data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
<value>Album</value>
</data>
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
<value>Artist</value> <value>Artist</value>
</data> </data>
<data name="LyricsSearchControlHelp.Text" xml:space="preserve"> <data name="LyricsSearchControlHelp.Text" xml:space="preserve">
@@ -267,13 +282,13 @@
<data name="LyricsSearchControlSearch.Content" xml:space="preserve"> <data name="LyricsSearchControlSearch.Content" xml:space="preserve">
<value>Search</value> <value>Search</value>
</data> </data>
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve"> <data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
<value>Song info mapping</value> <value>Song info mapping</value>
</data> </data>
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve"> <data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
<value>Target lyrics search provider</value> <value>Target lyrics search provider</value>
</data> </data>
<data name="LyricsSearchControlTitle.Header" xml:space="preserve"> <data name="LyricsSearchControlTitle.Text" xml:space="preserve">
<value>Title</value> <value>Title</value>
</data> </data>
<data name="LyricsSearchPageTitle" xml:space="preserve"> <data name="LyricsSearchPageTitle" xml:space="preserve">
@@ -337,7 +352,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve"> <data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>Welcome to BetterLyrics</value> <value>Welcome to BetterLyrics</value>
</data> </data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>Add to playlist</value> <value>Add to playlist</value>
</data> </data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
@@ -346,13 +361,13 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
<value>Next items</value> <value>Next items</value>
</data> </data>
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
<value>Add to play queue</value> <value>Add to play queue</value>
</data> </data>
<data name="MusicGalleryPageAllSongs" xml:space="preserve"> <data name="MusicGalleryPageAllSongs" xml:space="preserve">
<value>All songs</value> <value>All songs</value>
</data> </data>
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
<value>Clear play queue</value> <value>Clear play queue</value>
</data> </data>
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve"> <data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
@@ -379,6 +394,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
<value>Format</value> <value>Format</value>
</data> </data>
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
<value>Lyrics</value>
</data>
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
<value>Path</value> <value>Path</value>
</data> </data>
@@ -394,6 +412,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve"> <data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
<value>No songs were found in the media library</value> <value>No songs were found in the media library</value>
</data> </data>
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
<value>Import from file</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve"> <data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>Create a playlist</value> <value>Create a playlist</value>
</data> </data>
@@ -406,26 +427,32 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve"> <data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
<value>Play queue is empty</value> <value>Play queue is empty</value>
</data> </data>
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve"> <data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
<value>Playlists</value>
</data>
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
<value>List loop</value> <value>List loop</value>
</data> </data>
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve"> <data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
<value>Random</value> <value>Random</value>
</data> </data>
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
<value>Remove from playlists</value>
</data>
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve"> <data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
<value>Remove from play queue</value> <value>Remove from play queue</value>
</data> </data>
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve"> <data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
<value>Scroll to playing item</value> <value>Scroll to playing item</value>
</data> </data>
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve"> <data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
<value>Select all</value> <value>Select all</value>
</data> </data>
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve"> <data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
<value>Single loop</value> <value>Single loop</value>
</data> </data>
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve"> <data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
<value>Search songs</value> <value>Search for song title, artist, album or folder path</value>
</data> </data>
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
<value>Album</value> <value>Album</value>
@@ -433,12 +460,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
<value>Artist</value> <value>Artist</value>
</data> </data>
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
<value>Folder</value>
</data>
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
<value>Title</value> <value>Title</value>
</data> </data>
<data name="MusicGalleryPageSortType.Text" xml:space="preserve"> <data name="MusicGalleryPageSortType.Text" xml:space="preserve">
<value>Sort type</value> <value>Sort type</value>
</data> </data>
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
<value>Starred playlists</value>
</data>
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
<value>Stop</value>
</data>
<data name="MusicGalleryPageTitle" xml:space="preserve"> <data name="MusicGalleryPageTitle" xml:space="preserve">
<value>Music gallery - BetterLyrics</value> <value>Music gallery - BetterLyrics</value>
</data> </data>
@@ -448,6 +484,15 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="PictureInPictureMode" xml:space="preserve"> <data name="PictureInPictureMode" xml:space="preserve">
<value>Picture-in-picture mode</value> <value>Picture-in-picture mode</value>
</data> </data>
<data name="Pinyin" xml:space="preserve">
<value>Mandarin pinyin</value>
</data>
<data name="PlaylistViewFailed" xml:space="preserve">
<value>Unable to view tracks since the path is not existed</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>Romaji</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve"> <data name="SetingsPageContributors.Text" xml:space="preserve">
<value>Contributors</value> <value>Contributors</value>
</data> </data>
@@ -457,9 +502,18 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SetingsPageFeedback.Text" xml:space="preserve"> <data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>Feedback</value> <value>Feedback</value>
</data> </data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>Instructions</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve"> <data name="SetingsPageThanks.Text" xml:space="preserve">
<value>If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.</value> <value>If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.</value>
</data> </data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D lyrics</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>Depth</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve"> <data name="SettingsPageAbout.Content" xml:space="preserve">
<value>About</value> <value>About</value>
</data> </data>
@@ -529,6 +583,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve"> <data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>Automatic adjustment</value> <value>Automatic adjustment</value>
</data> </data>
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>Open the music library window when the app starts</value>
</data>
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>Automatically continue playing when the music library window is opened</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve"> <data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>Automatic startup</value> <value>Automatic startup</value>
</data> </data>
@@ -562,9 +622,18 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageChinese.Header" xml:space="preserve"> <data name="SettingsPageChinese.Header" xml:space="preserve">
<value>Chinese pronunciation</value> <value>Chinese pronunciation</value>
</data> </data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>Chinese lyrics</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve"> <data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>Convert Chinese to Traditional Chinese</value> <value>Convert Chinese to Traditional Chinese</value>
</data> </data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>CJK Unified Ideograph</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>Clear cache files</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve"> <data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>Click-through</value> <value>Click-through</value>
</data> </data>
@@ -712,6 +781,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageFollowSystem.Content" xml:space="preserve"> <data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>Follow system</value> <value>Follow system</value>
</data> </data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>Font color</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve"> <data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>Keep the lyrics window on top by polling</value> <value>Keep the lyrics window on top by polling</value>
</data> </data>
@@ -808,9 +880,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve"> <data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX Music Server</value> <value>LX Music Server</value>
</data> </data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>Lyrics style and effect</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve"> <data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>Alignment</value> <value>Alignment</value>
</data> </data>
@@ -818,7 +887,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<value>Lyrics background</value> <value>Lyrics background</value>
</data> </data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>Font color (Non-current playback area)</value> <value>Non-current playback area</value>
</data> </data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>Font opacity (Non-current playback area)</value> <value>Font opacity (Non-current playback area)</value>
@@ -854,7 +923,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<value>Extra Light</value> <value>Extra Light</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>Font color (Current playback area)</value> <value>Current playback area</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>Adaptive to lyrics background (Colored)</value> <value>Adaptive to lyrics background (Colored)</value>
@@ -892,6 +961,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve"> <data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>Glow effect</value> <value>Glow effect</value>
</data> </data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>Highlight</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve"> <data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>Original highlight range</value> <value>Original highlight range</value>
</data> </data>
@@ -940,9 +1012,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve"> <data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>Shadows</value> <value>Shadows</value>
</data> </data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>Lyrics stroke color</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve"> <data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>Lyrics style</value> <value>Lyrics style</value>
</data> </data>
@@ -1021,6 +1090,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve"> <data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>Open in file explorer</value> <value>Open in file explorer</value>
</data> </data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>Original text</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve"> <data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>Color picker style</value> <value>Color picker style</value>
</data> </data>
@@ -1036,6 +1108,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPagePathNotFound.Text" xml:space="preserve"> <data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>The path cannot be found on your computer</value> <value>The path cannot be found on your computer</value>
</data> </data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>Lyric annotation</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>Phonetic symbols</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve"> <data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>Pinyin of Mandarin</value> <value>Pinyin of Mandarin</value>
</data> </data>
@@ -1111,6 +1189,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve"> <data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>The duration of the first line</value> <value>The duration of the first line</value>
</data> </data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>Server address</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve"> <data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>Test server</value> <value>Test server</value>
</data> </data>
@@ -1150,6 +1231,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve"> <data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>Current value: </value> <value>Current value: </value>
</data> </data>
<data name="SettingsPageSnowFlakeLayer.Header" xml:space="preserve">
<value>Snow flake layer</value>
</data>
<data name="SettingsPageSongInfo.Text" xml:space="preserve"> <data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>Song title &amp; artist</value> <value>Song title &amp; artist</value>
</data> </data>
@@ -1174,7 +1258,10 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageStandardMode.Text" xml:space="preserve"> <data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>Standard mode</value> <value>Standard mode</value>
</data> </data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve"> <data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>Stroke color</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>Default</value> <value>Default</value>
</data> </data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve"> <data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1207,6 +1294,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve"> <data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>Switch in and cut out shortcut keys</value> <value>Switch in and cut out shortcut keys</value>
</data> </data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>Translated text</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve"> <data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>Lyrics translation</value> <value>Lyrics translation</value>
</data> </data>
@@ -1222,6 +1312,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageVersion.Text" xml:space="preserve"> <data name="SettingsPageVersion.Text" xml:space="preserve">
<value>Version</value> <value>Version</value>
</data> </data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>Latin alphabet</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve"> <data name="SettingsPageWidth.Header" xml:space="preserve">
<value>Width</value> <value>Width</value>
</data> </data>
@@ -1258,12 +1351,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SystemTrayRestart.Text" xml:space="preserve"> <data name="SystemTrayRestart.Text" xml:space="preserve">
<value>Restart</value> <value>Restart</value>
</data> </data>
<data name="SystemTraySearch.Text" xml:space="preserve">
<value>Lyrics search window</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve"> <data name="SystemTraySettings.Text" xml:space="preserve">
<value>Settings</value> <value>Settings</value>
</data> </data>
<data name="SystemTraySwitch.Text" xml:space="preserve"> <data name="SystemTraySwitch.Text" xml:space="preserve">
<value>Lyrics window switcher</value> <value>Lyrics window switcher</value>
</data> </data>
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
<value>Unable to add tracks since the path is not existed</value>
</data>
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
<value>Selected tracks have been added to this playlist</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve"> <data name="TranslateServerNotSet" xml:space="preserve">
<value>Translate server is not set, please configure it in settings first</value> <value>Translate server is not set, please configure it in settings first</value>
</data> </data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作が完了しました</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve"> <data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>ローカル音楽ファイル</value> <value>ローカル音楽ファイル</value>
</data> </data>
@@ -138,6 +141,9 @@
<data name="Cancel" xml:space="preserve"> <data name="Cancel" xml:space="preserve">
<value>キャンセル</value> <value>キャンセル</value>
</data> </data>
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
<value>正常に作成されました</value>
</data>
<data name="DemoWindowControlDefault.Text" xml:space="preserve"> <data name="DemoWindowControlDefault.Text" xml:space="preserve">
<value>デフォルト</value> <value>デフォルト</value>
</data> </data>
@@ -171,12 +177,18 @@
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve"> <data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
<value>ミュージックギャラリー</value> <value>ミュージックギャラリー</value>
</data> </data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve"> <data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
<value>設定</value> <value>設定</value>
</data> </data>
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
<value>プレイリストが正常にインポートされました</value>
</data>
<data name="ImportSettingsFailed" xml:space="preserve"> <data name="ImportSettingsFailed" xml:space="preserve">
<value>設定ファイルのインポートに失敗し、アプリケーション設定は変更されません</value> <value>設定ファイルのインポートに失敗し、アプリケーション設定は変更されません</value>
</data> </data>
<data name="Jyutping" xml:space="preserve">
<value>広東語のピンイン</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve"> <data name="LastFMAuthFailed" xml:space="preserve">
<value>承認が失敗しました、もう一度やり直してください</value> <value>承認が失敗しました、もう一度やり直してください</value>
</data> </data>
@@ -243,7 +255,10 @@
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve"> <data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
<value>翻訳プロバイダー</value> <value>翻訳プロバイダー</value>
</data> </data>
<data name="LyricsSearchControlArtist.Header" xml:space="preserve"> <data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
<value>アルバム</value>
</data>
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
<value>アーティスト</value> <value>アーティスト</value>
</data> </data>
<data name="LyricsSearchControlHelp.Text" xml:space="preserve"> <data name="LyricsSearchControlHelp.Text" xml:space="preserve">
@@ -267,13 +282,13 @@
<data name="LyricsSearchControlSearch.Content" xml:space="preserve"> <data name="LyricsSearchControlSearch.Content" xml:space="preserve">
<value>検索する</value> <value>検索する</value>
</data> </data>
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve"> <data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
<value>曲情報マッピング</value> <value>曲情報マッピング</value>
</data> </data>
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve"> <data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
<value>ターゲット歌詞検索プロバイダー</value> <value>ターゲット歌詞検索プロバイダー</value>
</data> </data>
<data name="LyricsSearchControlTitle.Header" xml:space="preserve"> <data name="LyricsSearchControlTitle.Text" xml:space="preserve">
<value>タイトル</value> <value>タイトル</value>
</data> </data>
<data name="LyricsSearchPageTitle" xml:space="preserve"> <data name="LyricsSearchPageTitle" xml:space="preserve">
@@ -337,8 +352,8 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve"> <data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>BetterLyrics へようこそ</value> <value>BetterLyrics へようこそ</value>
</data> </data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>プレイリストに追加します</value> <value>プレイリストに追加</value>
</data> </data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>リストの終わり</value> <value>リストの終わり</value>
@@ -346,13 +361,13 @@
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
<value>次のアイテム</value> <value>次のアイテム</value>
</data> </data>
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
<value>キューを再生するために追加します</value> <value>キューを再生するために追加します</value>
</data> </data>
<data name="MusicGalleryPageAllSongs" xml:space="preserve"> <data name="MusicGalleryPageAllSongs" xml:space="preserve">
<value>すべての曲</value> <value>すべての曲</value>
</data> </data>
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
<value>クリアプレイキュー</value> <value>クリアプレイキュー</value>
</data> </data>
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve"> <data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
@@ -379,6 +394,9 @@
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
<value>形式</value> <value>形式</value>
</data> </data>
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
<value>歌詞</value>
</data>
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
<value>パス</value> <value>パス</value>
</data> </data>
@@ -394,8 +412,11 @@
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve"> <data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
<value>メディアライブラリには歌が見つかりませんでした</value> <value>メディアライブラリには歌が見つかりませんでした</value>
</data> </data>
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
<value>ファイルからのインポート</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve"> <data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>プレイリストを作成しま</value> <value>プレイリストを作成しましょう</value>
</data> </data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve"> <data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>すべてを再生します</value> <value>すべてを再生します</value>
@@ -406,26 +427,32 @@
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve"> <data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
<value>キューを再生するのは空です</value> <value>キューを再生するのは空です</value>
</data> </data>
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve"> <data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
<value>プレイリスト</value>
</data>
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
<value>ループをリストします</value> <value>ループをリストします</value>
</data> </data>
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve"> <data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
<value>ランダム</value> <value>ランダム</value>
</data> </data>
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
<value>プレイリストから削除</value>
</data>
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve"> <data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
<value>プレイリストから取り外します</value> <value>プレイリストから取り外します</value>
</data> </data>
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve"> <data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
<value>アイテムを再生するための位置</value> <value>アイテムを再生するための位置</value>
</data> </data>
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve"> <data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
<value>すべてを選択します</value> <value>すべてを選択します</value>
</data> </data>
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve"> <data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
<value>シングルループ</value> <value>シングルループ</value>
</data> </data>
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve"> <data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
<value>曲を検索します</value> <value>曲名、アーティスト、アルバム、フォルダパスを検索してください</value>
</data> </data>
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
<value>アルバム</value> <value>アルバム</value>
@@ -433,12 +460,21 @@
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
<value>アーティスト</value> <value>アーティスト</value>
</data> </data>
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
<value>フォルダー</value>
</data>
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
<value>タイトル</value> <value>タイトル</value>
</data> </data>
<data name="MusicGalleryPageSortType.Text" xml:space="preserve"> <data name="MusicGalleryPageSortType.Text" xml:space="preserve">
<value>並べ替えタイプ</value> <value>並べ替えタイプ</value>
</data> </data>
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
<value>スター付きプレイリスト</value>
</data>
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
<value>立ち止まる</value>
</data>
<data name="MusicGalleryPageTitle" xml:space="preserve"> <data name="MusicGalleryPageTitle" xml:space="preserve">
<value>音楽ギャラリー - BetterLyrics</value> <value>音楽ギャラリー - BetterLyrics</value>
</data> </data>
@@ -448,6 +484,15 @@
<data name="PictureInPictureMode" xml:space="preserve"> <data name="PictureInPictureMode" xml:space="preserve">
<value>ピクチャーインピクチャーモード</value> <value>ピクチャーインピクチャーモード</value>
</data> </data>
<data name="Pinyin" xml:space="preserve">
<value>マンダリンのピンイン</value>
</data>
<data name="PlaylistViewFailed" xml:space="preserve">
<value>パスが存在しないため、トラックを表示できません</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>ローマン</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve"> <data name="SetingsPageContributors.Text" xml:space="preserve">
<value>投稿者</value> <value>投稿者</value>
</data> </data>
@@ -457,9 +502,18 @@
<data name="SetingsPageFeedback.Text" xml:space="preserve"> <data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>フィードバック</value> <value>フィードバック</value>
</data> </data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>手順</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve"> <data name="SetingsPageThanks.Text" xml:space="preserve">
<value>このプロジェクトが気に入っている場合は、寄付してサポートすることを検討してください。あなたのサポートは、プロジェクトを生かし続け、さらなる開発を促進するのに役立ちます。</value> <value>このプロジェクトが気に入っている場合は、寄付してサポートすることを検討してください。あなたのサポートは、プロジェクトを生かし続け、さらなる開発を促進するのに役立ちます。</value>
</data> </data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3 D 歌詞</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve"> <data name="SettingsPageAbout.Content" xml:space="preserve">
<value>について</value> <value>について</value>
</data> </data>
@@ -529,6 +583,12 @@
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve"> <data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自動調整</value> <value>自動調整</value>
</data> </data>
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>アプリが起動したら、音楽ライブラリウィンドウを開きます</value>
</data>
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>音楽ライブラリウィンドウを開くと、自動的に再生が続行されます</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve"> <data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自動起動</value> <value>自動起動</value>
</data> </data>
@@ -562,9 +622,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve"> <data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中国の発音</value> <value>中国の発音</value>
</data> </data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中国語の歌詞</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve"> <data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中国人を伝統的な中国人に変換します</value> <value>中国人を伝統的な中国人に変換します</value>
</data> </data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>CJK統一漢字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>キャッシュファイルをクリア</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve"> <data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>クリックスルー</value> <value>クリックスルー</value>
</data> </data>
@@ -712,6 +781,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve"> <data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>システムをフォローします</value> <value>システムをフォローします</value>
</data> </data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>フォントの色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve"> <data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>ポーリングで歌詞ウィンドウを一番上に保ちましょう</value> <value>ポーリングで歌詞ウィンドウを一番上に保ちましょう</value>
</data> </data>
@@ -808,9 +880,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve"> <data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX Music Server</value> <value>LX Music Server</value>
</data> </data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌詞のスタイルと効果</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve"> <data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>アライメント</value> <value>アライメント</value>
</data> </data>
@@ -818,7 +887,7 @@
<value>歌詞の背景</value> <value>歌詞の背景</value>
</data> </data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>フォントカラー(非電流再生エリア</value> <value>非電流再生エリア</value>
</data> </data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>フォントの不透明度(非電流再生エリア)</value> <value>フォントの不透明度(非電流再生エリア)</value>
@@ -854,7 +923,7 @@
<value>余分な光</value> <value>余分な光</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>フォントカラー(現在の再生エリア</value> <value>現在の再生エリア</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>歌詞の背景に適応する(色付き)</value> <value>歌詞の背景に適応する(色付き)</value>
@@ -892,6 +961,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve"> <data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>グロー効果</value> <value>グロー効果</value>
</data> </data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>ハイライト</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve"> <data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>オリジナルのハイライト範囲</value> <value>オリジナルのハイライト範囲</value>
</data> </data>
@@ -940,9 +1012,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve"> <data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>影だ</value> <value>影だ</value>
</data> </data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌詞ストロークカラー</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve"> <data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌詞スタイル</value> <value>歌詞スタイル</value>
</data> </data>
@@ -1021,6 +1090,9 @@
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve"> <data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>ファイルエクスプローラーで開きます</value> <value>ファイルエクスプローラーで開きます</value>
</data> </data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve"> <data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>カラーピックスタイル</value> <value>カラーピックスタイル</value>
</data> </data>
@@ -1036,6 +1108,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve"> <data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>パスはコンピューターでは見つかりません</value> <value>パスはコンピューターでは見つかりません</value>
</data> </data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>リリックアノテーション</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>発音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve"> <data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>マンダリンのピンイン</value> <value>マンダリンのピンイン</value>
</data> </data>
@@ -1111,6 +1189,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve"> <data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>最初の行の期間</value> <value>最初の行の期間</value>
</data> </data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>サーバーアドレス</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve"> <data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>テストサーバー</value> <value>テストサーバー</value>
</data> </data>
@@ -1150,6 +1231,9 @@
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve"> <data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>現在の値: </value> <value>現在の値: </value>
</data> </data>
<data name="SettingsPageSnowFlakeLayer.Header" xml:space="preserve">
<value>スノーフレークレイヤー</value>
</data>
<data name="SettingsPageSongInfo.Text" xml:space="preserve"> <data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>曲のタイトル&アーティスト</value> <value>曲のタイトル&アーティスト</value>
</data> </data>
@@ -1174,7 +1258,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve"> <data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>標準モード</value> <value>標準モード</value>
</data> </data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve"> <data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>ストロークカラー</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>デフォルト</value> <value>デフォルト</value>
</data> </data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve"> <data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1207,6 +1294,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve"> <data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>ショートカットキーを切り込んで切り取ります</value> <value>ショートカットキーを切り込んで切り取ります</value>
</data> </data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve"> <data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌詞翻訳</value> <value>歌詞翻訳</value>
</data> </data>
@@ -1222,6 +1312,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve"> <data name="SettingsPageVersion.Text" xml:space="preserve">
<value>バージョン</value> <value>バージョン</value>
</data> </data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>英字</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve"> <data name="SettingsPageWidth.Header" xml:space="preserve">
<value>幅</value> <value>幅</value>
</data> </data>
@@ -1258,12 +1351,21 @@
<data name="SystemTrayRestart.Text" xml:space="preserve"> <data name="SystemTrayRestart.Text" xml:space="preserve">
<value>再起動</value> <value>再起動</value>
</data> </data>
<data name="SystemTraySearch.Text" xml:space="preserve">
<value>歌詞検索ウィンドウ</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve"> <data name="SystemTraySettings.Text" xml:space="preserve">
<value>設定を開く</value> <value>設定を開く</value>
</data> </data>
<data name="SystemTraySwitch.Text" xml:space="preserve"> <data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌詞ウィンドウスイッチャー</value> <value>歌詞ウィンドウスイッチャー</value>
</data> </data>
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
<value>パスが存在しないため、トラックを追加できません</value>
</data>
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
<value>選択したトラックがこのプレイリストに追加されました</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve"> <data name="TranslateServerNotSet" xml:space="preserve">
<value>翻訳サーバーは設定されていません。最初に設定で構成してください</value> <value>翻訳サーバーは設定されていません。最初に設定で構成してください</value>
</data> </data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>작전 완료</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve"> <data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>로컬 음악 파일</value> <value>로컬 음악 파일</value>
</data> </data>
@@ -138,6 +141,9 @@
<data name="Cancel" xml:space="preserve"> <data name="Cancel" xml:space="preserve">
<value>취소</value> <value>취소</value>
</data> </data>
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
<value>재생 목록이 성공적으로 생성되었습니다</value>
</data>
<data name="DemoWindowControlDefault.Text" xml:space="preserve"> <data name="DemoWindowControlDefault.Text" xml:space="preserve">
<value>기본</value> <value>기본</value>
</data> </data>
@@ -171,12 +177,18 @@
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve"> <data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
<value>음악 갤러리</value> <value>음악 갤러리</value>
</data> </data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve"> <data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
<value>설정</value> <value>설정</value>
</data> </data>
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
<value>재생 목록을 성공적으로 가져왔습니다</value>
</data>
<data name="ImportSettingsFailed" xml:space="preserve"> <data name="ImportSettingsFailed" xml:space="preserve">
<value>설정 파일 가져 오기 실패, 응용 프로그램 설정은 변경되지 않았습니다</value> <value>설정 파일 가져 오기 실패, 응용 프로그램 설정은 변경되지 않았습니다</value>
</data> </data>
<data name="Jyutping" xml:space="preserve">
<value>광둥어 병음</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve"> <data name="LastFMAuthFailed" xml:space="preserve">
<value>승인이 실패했습니다. 다시 시도하십시오</value> <value>승인이 실패했습니다. 다시 시도하십시오</value>
</data> </data>
@@ -243,7 +255,10 @@
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve"> <data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
<value>번역 제공자</value> <value>번역 제공자</value>
</data> </data>
<data name="LyricsSearchControlArtist.Header" xml:space="preserve"> <data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
<value>앨범</value>
</data>
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
<value>아티스트</value> <value>아티스트</value>
</data> </data>
<data name="LyricsSearchControlHelp.Text" xml:space="preserve"> <data name="LyricsSearchControlHelp.Text" xml:space="preserve">
@@ -267,13 +282,13 @@
<data name="LyricsSearchControlSearch.Content" xml:space="preserve"> <data name="LyricsSearchControlSearch.Content" xml:space="preserve">
<value>검색</value> <value>검색</value>
</data> </data>
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve"> <data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
<value>노래 정보 매핑</value> <value>노래 정보 매핑</value>
</data> </data>
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve"> <data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
<value>가사 검색 공급자를 타겟팅하십시오</value> <value>가사 검색 공급자를 타겟팅하십시오</value>
</data> </data>
<data name="LyricsSearchControlTitle.Header" xml:space="preserve"> <data name="LyricsSearchControlTitle.Text" xml:space="preserve">
<value>제목</value> <value>제목</value>
</data> </data>
<data name="LyricsSearchPageTitle" xml:space="preserve"> <data name="LyricsSearchPageTitle" xml:space="preserve">
@@ -337,8 +352,8 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve"> <data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>Betterlyrics에 오신 것을 환영합니다</value> <value>Betterlyrics에 오신 것을 환영합니다</value>
</data> </data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>재생 목록에 추가하십시오</value> <value>재생 목록에 추가</value>
</data> </data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>목록의 끝</value> <value>목록의 끝</value>
@@ -346,13 +361,13 @@
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
<value>다음 항목</value> <value>다음 항목</value>
</data> </data>
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
<value>재생 큐에 추가하십시오</value> <value>재생 큐에 추가하십시오</value>
</data> </data>
<data name="MusicGalleryPageAllSongs" xml:space="preserve"> <data name="MusicGalleryPageAllSongs" xml:space="preserve">
<value>모든 노래</value> <value>모든 노래</value>
</data> </data>
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
<value>플레이 대기열을 클리어합니다</value> <value>플레이 대기열을 클리어합니다</value>
</data> </data>
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve"> <data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
@@ -379,6 +394,9 @@
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
<value>체재</value> <value>체재</value>
</data> </data>
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
<value>가사</value>
</data>
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
<value>길</value> <value>길</value>
</data> </data>
@@ -394,8 +412,11 @@
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve"> <data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
<value>미디어 라이브러리에는 노래가 없습니다</value> <value>미디어 라이브러리에는 노래가 없습니다</value>
</data> </data>
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
<value>파일에서 가져오기</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve"> <data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>재생 목록을 만듭니다</value> <value>재생목록을 만드세요</value>
</data> </data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve"> <data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>모두 재생하십시오</value> <value>모두 재생하십시오</value>
@@ -406,26 +427,32 @@
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve"> <data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
<value>플레이 대기열이 비어 있습니다</value> <value>플레이 대기열이 비어 있습니다</value>
</data> </data>
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve"> <data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
<value>재생 목록</value>
</data>
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
<value>목록 루프</value> <value>목록 루프</value>
</data> </data>
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve"> <data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
<value>무작위의</value> <value>무작위의</value>
</data> </data>
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
<value>재생 목록에서 제거</value>
</data>
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve"> <data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
<value>재생 목록에서 제거하십시오</value> <value>재생 목록에서 제거하십시오</value>
</data> </data>
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve"> <data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
<value>아이템을 재생하기위한 포지셔닝</value> <value>아이템을 재생하기위한 포지셔닝</value>
</data> </data>
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve"> <data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
<value>모두를 선택하십시오</value> <value>모두를 선택하십시오</value>
</data> </data>
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve"> <data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
<value>단일 루프</value> <value>단일 루프</value>
</data> </data>
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve"> <data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
<value>노래 검색</value> <value>노래 제목, 아티스트, 앨범 또는 폴더 경로를 검색하세요</value>
</data> </data>
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
<value>앨범</value> <value>앨범</value>
@@ -433,12 +460,21 @@
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
<value>아티스트</value> <value>아티스트</value>
</data> </data>
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
<value>폴더</value>
</data>
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
<value>제목</value> <value>제목</value>
</data> </data>
<data name="MusicGalleryPageSortType.Text" xml:space="preserve"> <data name="MusicGalleryPageSortType.Text" xml:space="preserve">
<value>정렬 유형</value> <value>정렬 유형</value>
</data> </data>
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
<value>별표 표시된 재생 목록</value>
</data>
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
<value>멈추기</value>
</data>
<data name="MusicGalleryPageTitle" xml:space="preserve"> <data name="MusicGalleryPageTitle" xml:space="preserve">
<value>음악 갤러리 - BetterLyrics</value> <value>음악 갤러리 - BetterLyrics</value>
</data> </data>
@@ -448,6 +484,15 @@
<data name="PictureInPictureMode" xml:space="preserve"> <data name="PictureInPictureMode" xml:space="preserve">
<value>사진 인당 모드</value> <value>사진 인당 모드</value>
</data> </data>
<data name="Pinyin" xml:space="preserve">
<value>만다린의 피니 인</value>
</data>
<data name="PlaylistViewFailed" xml:space="preserve">
<value>경로가 존재하지 않으므로 트랙을 볼 수 없습니다</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>로만</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve"> <data name="SetingsPageContributors.Text" xml:space="preserve">
<value>기여자</value> <value>기여자</value>
</data> </data>
@@ -457,9 +502,18 @@
<data name="SetingsPageFeedback.Text" xml:space="preserve"> <data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>피드백</value> <value>피드백</value>
</data> </data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>지침</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve"> <data name="SetingsPageThanks.Text" xml:space="preserve">
<value>이 프로젝트가 마음에 들면 기부하여 지원을 고려하십시오. 귀하의 지원은 프로젝트를 계속 유지하고 추가 개발을 장려하는 데 도움이 될 것입니다.</value> <value>이 프로젝트가 마음에 들면 기부하여 지원을 고려하십시오. 귀하의 지원은 프로젝트를 계속 유지하고 추가 개발을 장려하는 데 도움이 될 것입니다.</value>
</data> </data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 가사</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>심도</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve"> <data name="SettingsPageAbout.Content" xml:space="preserve">
<value>에 대한</value> <value>에 대한</value>
</data> </data>
@@ -529,6 +583,12 @@
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve"> <data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>자동 조정</value> <value>자동 조정</value>
</data> </data>
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>앱이 시작되면 음악 라이브러리 창을 여세요</value>
</data>
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>음악 라이브러리 창이 열리면 자동으로 계속 재생됩니다</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve"> <data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>자동 시작</value> <value>자동 시작</value>
</data> </data>
@@ -562,9 +622,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve"> <data name="SettingsPageChinese.Header" xml:space="preserve">
<value>화음</value> <value>화음</value>
</data> </data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>중국어 가사</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve"> <data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>중국어를 전통적인 중국어로 전환합니다</value> <value>중국어를 전통적인 중국어로 전환합니다</value>
</data> </data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>한중일 통합 이데오그래프</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>캐시 파일을 지웁니다</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve"> <data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>클릭률</value> <value>클릭률</value>
</data> </data>
@@ -712,6 +781,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve"> <data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>시스템을 따르십시오</value> <value>시스템을 따르십시오</value>
</data> </data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>폰트 색상</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve"> <data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>투표를 통해 가사 창을 맨 위에 두세요</value> <value>투표를 통해 가사 창을 맨 위에 두세요</value>
</data> </data>
@@ -808,9 +880,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve"> <data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 음악 서버</value> <value>LX 음악 서버</value>
</data> </data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>가사 스타일과 효과</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve"> <data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>조정</value> <value>조정</value>
</data> </data>
@@ -818,7 +887,7 @@
<value>가사 배경</value> <value>가사 배경</value>
</data> </data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>글꼴 색상 (비 전류 재생 영역)</value> <value>비 전류 재생 영역</value>
</data> </data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>글꼴 불투명 (비 전류 재생 영역)</value> <value>글꼴 불투명 (비 전류 재생 영역)</value>
@@ -854,7 +923,7 @@
<value>여분의 빛</value> <value>여분의 빛</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>글꼴 색상 (현재 재생 영역)</value> <value>현재 재생 영역</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>가사 배경 (색상)에 적응</value> <value>가사 배경 (색상)에 적응</value>
@@ -892,6 +961,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve"> <data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>글로우 효과</value> <value>글로우 효과</value>
</data> </data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>하이라이트</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve"> <data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>원래 하이라이트 범위</value> <value>원래 하이라이트 범위</value>
</data> </data>
@@ -940,9 +1012,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve"> <data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>그림자</value> <value>그림자</value>
</data> </data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>가사 스트로크 컬러</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve"> <data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>가사 스타일</value> <value>가사 스타일</value>
</data> </data>
@@ -1021,6 +1090,9 @@
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve"> <data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>파일 탐색기에서 열립니다</value> <value>파일 탐색기에서 열립니다</value>
</data> </data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>원본</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve"> <data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>색상 선택 스타일</value> <value>색상 선택 스타일</value>
</data> </data>
@@ -1036,6 +1108,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve"> <data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>경로는 컴퓨터에서 찾을 수 없습니다</value> <value>경로는 컴퓨터에서 찾을 수 없습니다</value>
</data> </data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>가사 주석</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>발성</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve"> <data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>만다린의 피니 인</value> <value>만다린의 피니 인</value>
</data> </data>
@@ -1111,6 +1189,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve"> <data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>첫 번째 줄의 기간</value> <value>첫 번째 줄의 기간</value>
</data> </data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>서버 주소</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve"> <data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>테스트 서버</value> <value>테스트 서버</value>
</data> </data>
@@ -1150,6 +1231,9 @@
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve"> <data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>현재 가치 : </value> <value>현재 가치 : </value>
</data> </data>
<data name="SettingsPageSnowFlakeLayer.Header" xml:space="preserve">
<value>스노우 플레이크 레이어</value>
</data>
<data name="SettingsPageSongInfo.Text" xml:space="preserve"> <data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>노래 제목 및 아티스트</value> <value>노래 제목 및 아티스트</value>
</data> </data>
@@ -1174,7 +1258,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve"> <data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>표준 모드</value> <value>표준 모드</value>
</data> </data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve"> <data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>윤곽선 색상</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>기본</value> <value>기본</value>
</data> </data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve"> <data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1207,6 +1294,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve"> <data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>바로 가기 키를 자르고 잘라냅니다</value> <value>바로 가기 키를 자르고 잘라냅니다</value>
</data> </data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>번역</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve"> <data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>가사 번역</value> <value>가사 번역</value>
</data> </data>
@@ -1222,6 +1312,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve"> <data name="SettingsPageVersion.Text" xml:space="preserve">
<value>버전</value> <value>버전</value>
</data> </data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>라틴 알파벳</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve"> <data name="SettingsPageWidth.Header" xml:space="preserve">
<value>너비</value> <value>너비</value>
</data> </data>
@@ -1258,12 +1351,21 @@
<data name="SystemTrayRestart.Text" xml:space="preserve"> <data name="SystemTrayRestart.Text" xml:space="preserve">
<value>다시 시작</value> <value>다시 시작</value>
</data> </data>
<data name="SystemTraySearch.Text" xml:space="preserve">
<value>가사 검색 창</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve"> <data name="SystemTraySettings.Text" xml:space="preserve">
<value>열기 설정</value> <value>열기 설정</value>
</data> </data>
<data name="SystemTraySwitch.Text" xml:space="preserve"> <data name="SystemTraySwitch.Text" xml:space="preserve">
<value>가사 창 전환기</value> <value>가사 창 전환기</value>
</data> </data>
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
<value>경로가 존재하지 않으므로 트랙을 추가할 수 없습니다</value>
</data>
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
<value>선택한 트랙이 이 재생 목록에 추가되었습니다</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve"> <data name="TranslateServerNotSet" xml:space="preserve">
<value>번역 서버가 설정되지 않았습니다. 먼저 설정으로 구성하십시오.</value> <value>번역 서버가 설정되지 않았습니다. 먼저 설정으로 구성하십시오.</value>
</data> </data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作完成</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve"> <data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>本地音乐文件</value> <value>本地音乐文件</value>
</data> </data>
@@ -138,6 +141,9 @@
<data name="Cancel" xml:space="preserve"> <data name="Cancel" xml:space="preserve">
<value>取消</value> <value>取消</value>
</data> </data>
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
<value>播放列表创建成功</value>
</data>
<data name="DemoWindowControlDefault.Text" xml:space="preserve"> <data name="DemoWindowControlDefault.Text" xml:space="preserve">
<value>默认</value> <value>默认</value>
</data> </data>
@@ -171,12 +177,18 @@
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve"> <data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
<value>音乐库</value> <value>音乐库</value>
</data> </data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve"> <data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
<value>设置</value> <value>设置</value>
</data> </data>
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
<value>播放列表已成功导入</value>
</data>
<data name="ImportSettingsFailed" xml:space="preserve"> <data name="ImportSettingsFailed" xml:space="preserve">
<value>设置文件导入失败,应用程序设置保持不变</value> <value>设置文件导入失败,应用程序设置保持不变</value>
</data> </data>
<data name="Jyutping" xml:space="preserve">
<value>粤语拼音</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve"> <data name="LastFMAuthFailed" xml:space="preserve">
<value>授权失败,请重试</value> <value>授权失败,请重试</value>
</data> </data>
@@ -243,7 +255,10 @@
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve"> <data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
<value>翻译来源</value> <value>翻译来源</value>
</data> </data>
<data name="LyricsSearchControlArtist.Header" xml:space="preserve"> <data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
<value>专辑</value>
</data>
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
<value>艺术家</value> <value>艺术家</value>
</data> </data>
<data name="LyricsSearchControlHelp.Text" xml:space="preserve"> <data name="LyricsSearchControlHelp.Text" xml:space="preserve">
@@ -267,13 +282,13 @@
<data name="LyricsSearchControlSearch.Content" xml:space="preserve"> <data name="LyricsSearchControlSearch.Content" xml:space="preserve">
<value>搜索</value> <value>搜索</value>
</data> </data>
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve"> <data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
<value>歌曲信息映射</value> <value>歌曲信息映射</value>
</data> </data>
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve"> <data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
<value>目标歌词搜索提供商</value> <value>目标歌词搜索提供商</value>
</data> </data>
<data name="LyricsSearchControlTitle.Header" xml:space="preserve"> <data name="LyricsSearchControlTitle.Text" xml:space="preserve">
<value>标题</value> <value>标题</value>
</data> </data>
<data name="LyricsSearchPageTitle" xml:space="preserve"> <data name="LyricsSearchPageTitle" xml:space="preserve">
@@ -337,8 +352,8 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve"> <data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>欢迎使用 BetterLyrics</value> <value>欢迎使用 BetterLyrics</value>
</data> </data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>添加到歌单</value> <value>添加到播放列表</value>
</data> </data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>列表的结尾</value> <value>列表的结尾</value>
@@ -346,13 +361,13 @@
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
<value>下一个项目</value> <value>下一个项目</value>
</data> </data>
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
<value>添加到播放队列</value> <value>添加到播放队列</value>
</data> </data>
<data name="MusicGalleryPageAllSongs" xml:space="preserve"> <data name="MusicGalleryPageAllSongs" xml:space="preserve">
<value>所有歌曲</value> <value>所有歌曲</value>
</data> </data>
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
<value>清除播放队列</value> <value>清除播放队列</value>
</data> </data>
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve"> <data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
@@ -379,6 +394,9 @@
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
<value>格式</value> <value>格式</value>
</data> </data>
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
<value>歌词</value>
</data>
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
<value>路径</value> <value>路径</value>
</data> </data>
@@ -394,8 +412,11 @@
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve"> <data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
<value>未在媒体库内找到任何歌曲</value> <value>未在媒体库内找到任何歌曲</value>
</data> </data>
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
<value>从文件导入</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve"> <data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>创建歌单</value> <value>创建播放列表</value>
</data> </data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve"> <data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>播放全部</value> <value>播放全部</value>
@@ -406,26 +427,32 @@
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve"> <data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
<value>播放队列是空的</value> <value>播放队列是空的</value>
</data> </data>
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve"> <data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
<value>播放列表</value>
</data>
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
<value>列表循环</value> <value>列表循环</value>
</data> </data>
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve"> <data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
<value>随机</value> <value>随机</value>
</data> </data>
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
<value>从播放列表中删除</value>
</data>
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve"> <data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
<value>从播放列表移除</value> <value>从播放列表移除</value>
</data> </data>
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve"> <data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
<value>定位到播放项</value> <value>定位到播放项</value>
</data> </data>
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve"> <data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
<value>选择全部</value> <value>选择全部</value>
</data> </data>
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve"> <data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
<value>单曲循环</value> <value>单曲循环</value>
</data> </data>
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve"> <data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
<value>搜索歌曲</value> <value>搜索歌曲名、艺术家、专辑或所在文件夹路径</value>
</data> </data>
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
<value>专辑</value> <value>专辑</value>
@@ -433,12 +460,21 @@
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
<value>艺术家</value> <value>艺术家</value>
</data> </data>
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
<value>文件夹</value>
</data>
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
<value>标题</value> <value>标题</value>
</data> </data>
<data name="MusicGalleryPageSortType.Text" xml:space="preserve"> <data name="MusicGalleryPageSortType.Text" xml:space="preserve">
<value>排序类型</value> <value>排序类型</value>
</data> </data>
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
<value>已加星标的歌单</value>
</data>
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
<value>停止</value>
</data>
<data name="MusicGalleryPageTitle" xml:space="preserve"> <data name="MusicGalleryPageTitle" xml:space="preserve">
<value>音乐库 - BetterLyrics</value> <value>音乐库 - BetterLyrics</value>
</data> </data>
@@ -448,6 +484,15 @@
<data name="PictureInPictureMode" xml:space="preserve"> <data name="PictureInPictureMode" xml:space="preserve">
<value>画中画模式</value> <value>画中画模式</value>
</data> </data>
<data name="Pinyin" xml:space="preserve">
<value>普通话拼音</value>
</data>
<data name="PlaylistViewFailed" xml:space="preserve">
<value>无法查看曲目,因为路径不存在</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>罗马音</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve"> <data name="SetingsPageContributors.Text" xml:space="preserve">
<value>贡献者</value> <value>贡献者</value>
</data> </data>
@@ -457,9 +502,18 @@
<data name="SetingsPageFeedback.Text" xml:space="preserve"> <data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>反馈</value> <value>反馈</value>
</data> </data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>操作指南</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve"> <data name="SetingsPageThanks.Text" xml:space="preserve">
<value>如果您喜欢这个项目,请考虑通过捐赠来支持它。您的支持将有助于保持项目的生命并鼓励进一步的发展。</value> <value>如果您喜欢这个项目,请考虑通过捐赠来支持它。您的支持将有助于保持项目的生命并鼓励进一步的发展。</value>
</data> </data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 歌词</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve"> <data name="SettingsPageAbout.Content" xml:space="preserve">
<value>关于</value> <value>关于</value>
</data> </data>
@@ -529,6 +583,12 @@
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve"> <data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自动调整</value> <value>自动调整</value>
</data> </data>
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>应用程序启动时打开音乐库窗口</value>
</data>
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>打开音乐库窗口时自动继续播放</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve"> <data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自动启动</value> <value>自动启动</value>
</data> </data>
@@ -562,9 +622,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve"> <data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value> <value>中文注音</value>
</data> </data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中文歌词</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve"> <data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中文转换为繁体</value> <value>中文转换为繁体</value>
</data> </data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>中日韩统一表意文字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>清除缓存文件</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve"> <data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>点击穿透</value> <value>点击穿透</value>
</data> </data>
@@ -712,6 +781,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve"> <data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>跟随系统</value> <value>跟随系统</value>
</data> </data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>字体颜色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve"> <data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>通过轮询方式使歌词窗口保持置于顶层状态</value> <value>通过轮询方式使歌词窗口保持置于顶层状态</value>
</data> </data>
@@ -808,9 +880,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve"> <data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 音乐服务器</value> <value>LX 音乐服务器</value>
</data> </data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌词样式与动效</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve"> <data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>对齐方式</value> <value>对齐方式</value>
</data> </data>
@@ -818,7 +887,7 @@
<value>歌词背景</value> <value>歌词背景</value>
</data> </data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>字体颜色(非当前播放区域</value> <value>非当前播放区域</value>
</data> </data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>字体不透明度(非当前播放区域)</value> <value>字体不透明度(非当前播放区域)</value>
@@ -854,7 +923,7 @@
<value>超细</value> <value>超细</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>字体颜色(当前播放区域</value> <value>当前播放区域</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>适应歌词背景(彩色)</value> <value>适应歌词背景(彩色)</value>
@@ -892,6 +961,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve"> <data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>辉光效果</value> <value>辉光效果</value>
</data> </data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>高亮</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve"> <data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮显示范围</value> <value>原文高亮显示范围</value>
</data> </data>
@@ -940,9 +1012,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve"> <data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>阴影</value> <value>阴影</value>
</data> </data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌词描边颜色</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve"> <data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌词样式</value> <value>歌词样式</value>
</data> </data>
@@ -1021,6 +1090,9 @@
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve"> <data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>在文件资源管理器中打开</value> <value>在文件资源管理器中打开</value>
</data> </data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve"> <data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>取色风格</value> <value>取色风格</value>
</data> </data>
@@ -1036,6 +1108,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve"> <data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>无法在您的计算机中找到该路径</value> <value>无法在您的计算机中找到该路径</value>
</data> </data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>歌词注音</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>注音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve"> <data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>普通话拼音</value> <value>普通话拼音</value>
</data> </data>
@@ -1111,6 +1189,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve"> <data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>首行持续时间</value> <value>首行持续时间</value>
</data> </data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>服务器地址</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve"> <data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>测试服务器</value> <value>测试服务器</value>
</data> </data>
@@ -1150,6 +1231,9 @@
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve"> <data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>当前值: </value> <value>当前值: </value>
</data> </data>
<data name="SettingsPageSnowFlakeLayer.Header" xml:space="preserve">
<value>雪花层</value>
</data>
<data name="SettingsPageSongInfo.Text" xml:space="preserve"> <data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲标题和艺术家</value> <value>歌曲标题和艺术家</value>
</data> </data>
@@ -1174,7 +1258,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve"> <data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>标准模式</value> <value>标准模式</value>
</data> </data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve"> <data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>描边颜色</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>默认</value> <value>默认</value>
</data> </data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve"> <data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1207,6 +1294,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve"> <data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入与切出快捷键</value> <value>切入与切出快捷键</value>
</data> </data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve"> <data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌词翻译</value> <value>歌词翻译</value>
</data> </data>
@@ -1222,6 +1312,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve"> <data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本号</value> <value>版本号</value>
</data> </data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve"> <data name="SettingsPageWidth.Header" xml:space="preserve">
<value>宽度</value> <value>宽度</value>
</data> </data>
@@ -1258,12 +1351,21 @@
<data name="SystemTrayRestart.Text" xml:space="preserve"> <data name="SystemTrayRestart.Text" xml:space="preserve">
<value>重新启动</value> <value>重新启动</value>
</data> </data>
<data name="SystemTraySearch.Text" xml:space="preserve">
<value>歌词搜索窗口</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve"> <data name="SystemTraySettings.Text" xml:space="preserve">
<value>打开设置</value> <value>打开设置</value>
</data> </data>
<data name="SystemTraySwitch.Text" xml:space="preserve"> <data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌词窗口切换器</value> <value>歌词窗口切换器</value>
</data> </data>
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
<value>由于路径不存在,无法添加曲目</value>
</data>
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
<value>所选曲目已添加到此播放列表</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve"> <data name="TranslateServerNotSet" xml:space="preserve">
<value>未设置Translate服务器请先在设置中进行配置</value> <value>未设置Translate服务器请先在设置中进行配置</value>
</data> </data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作完成</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve"> <data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>本地音樂文件</value> <value>本地音樂文件</value>
</data> </data>
@@ -138,6 +141,9 @@
<data name="Cancel" xml:space="preserve"> <data name="Cancel" xml:space="preserve">
<value>取消</value> <value>取消</value>
</data> </data>
<data name="CreatePlaylistSuccessfully" xml:space="preserve">
<value>已成功建立播放清單</value>
</data>
<data name="DemoWindowControlDefault.Text" xml:space="preserve"> <data name="DemoWindowControlDefault.Text" xml:space="preserve">
<value>預設</value> <value>預設</value>
</data> </data>
@@ -171,12 +177,18 @@
<data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve"> <data name="HostWindowMusicGalleryButtonToolTip.Content" xml:space="preserve">
<value>音樂庫</value> <value>音樂庫</value>
</data> </data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve"> <data name="HostWindowSettingsButtonToolTip.Text" xml:space="preserve">
<value>設定</value> <value>設定</value>
</data> </data>
<data name="ImportPlaylistSuccessfully" xml:space="preserve">
<value>已成功匯入播放清單</value>
</data>
<data name="ImportSettingsFailed" xml:space="preserve"> <data name="ImportSettingsFailed" xml:space="preserve">
<value>設置文件導入失敗,應用程序設置保持不變</value> <value>設置文件導入失敗,應用程序設置保持不變</value>
</data> </data>
<data name="Jyutping" xml:space="preserve">
<value>粵語拼音</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve"> <data name="LastFMAuthFailed" xml:space="preserve">
<value>授權失敗,請重試</value> <value>授權失敗,請重試</value>
</data> </data>
@@ -243,7 +255,10 @@
<data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve"> <data name="LyricsPageTranslationProviderPrefix.Header" xml:space="preserve">
<value>翻譯來源</value> <value>翻譯來源</value>
</data> </data>
<data name="LyricsSearchControlArtist.Header" xml:space="preserve"> <data name="LyricsSearchControlAlbum.Text" xml:space="preserve">
<value>專輯</value>
</data>
<data name="LyricsSearchControlArtist.Text" xml:space="preserve">
<value>藝術家</value> <value>藝術家</value>
</data> </data>
<data name="LyricsSearchControlHelp.Text" xml:space="preserve"> <data name="LyricsSearchControlHelp.Text" xml:space="preserve">
@@ -267,13 +282,13 @@
<data name="LyricsSearchControlSearch.Content" xml:space="preserve"> <data name="LyricsSearchControlSearch.Content" xml:space="preserve">
<value>搜索</value> <value>搜索</value>
</data> </data>
<data name="LyricsSearchControlSongInfoMapping.Header" xml:space="preserve"> <data name="LyricsSearchControlSongInfoMapping.Text" xml:space="preserve">
<value>歌曲信息映射</value> <value>歌曲信息映射</value>
</data> </data>
<data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve"> <data name="LyricsSearchControlTargetSearchProvider.Header" xml:space="preserve">
<value>目標歌詞搜尋提供者</value> <value>目標歌詞搜尋提供者</value>
</data> </data>
<data name="LyricsSearchControlTitle.Header" xml:space="preserve"> <data name="LyricsSearchControlTitle.Text" xml:space="preserve">
<value>標題</value> <value>標題</value>
</data> </data>
<data name="LyricsSearchPageTitle" xml:space="preserve"> <data name="LyricsSearchPageTitle" xml:space="preserve">
@@ -337,8 +352,8 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve"> <data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>歡迎使用 BetterLyrics</value> <value>歡迎使用 BetterLyrics</value>
</data> </data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToCustomList.Text" xml:space="preserve">
<value>添加到歌單</value> <value>新增到播放清單</value>
</data> </data>
<data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToEnd.Text" xml:space="preserve">
<value>列表的結尾</value> <value>列表的結尾</value>
@@ -346,13 +361,13 @@
<data name="MusicGalleryPageAddToNext.Text" xml:space="preserve"> <data name="MusicGalleryPageAddToNext.Text" xml:space="preserve">
<value>下一個項目</value> <value>下一個項目</value>
</data> </data>
<data name="MusicGalleryPageAddToPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageAddToPlayingQueue.Text" xml:space="preserve">
<value>新增到播放隊列</value> <value>新增到播放隊列</value>
</data> </data>
<data name="MusicGalleryPageAllSongs" xml:space="preserve"> <data name="MusicGalleryPageAllSongs" xml:space="preserve">
<value>所有歌曲</value> <value>所有歌曲</value>
</data> </data>
<data name="MusicGalleryPageEmptyPlayingQueue.Content" xml:space="preserve"> <data name="MusicGalleryPageEmptyPlayingQueue.Text" xml:space="preserve">
<value>清除播放隊列</value> <value>清除播放隊列</value>
</data> </data>
<data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve"> <data name="MusicGalleryPageFileAlbum.Text" xml:space="preserve">
@@ -379,6 +394,9 @@
<data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoFormat.Text" xml:space="preserve">
<value>格式</value> <value>格式</value>
</data> </data>
<data name="MusicGalleryPageFileInfoLyrics.Text" xml:space="preserve">
<value>歌词</value>
</data>
<data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve"> <data name="MusicGalleryPageFileInfoPath.Text" xml:space="preserve">
<value>路徑</value> <value>路徑</value>
</data> </data>
@@ -394,8 +412,11 @@
<data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve"> <data name="MusicGalleryPageFileNotFound.Text" xml:space="preserve">
<value>未在媒體庫內找到任何歌曲</value> <value>未在媒體庫內找到任何歌曲</value>
</data> </data>
<data name="MusicGalleryPageImportFromFile.Text" xml:space="preserve">
<value>從檔案匯入</value>
</data>
<data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve"> <data name="MusicGalleryPageNewPlaylist.Text" xml:space="preserve">
<value>建立單</value> <value>建立播放清單</value>
</data> </data>
<data name="MusicGalleryPagePlayAll.Content" xml:space="preserve"> <data name="MusicGalleryPagePlayAll.Content" xml:space="preserve">
<value>播放全部</value> <value>播放全部</value>
@@ -406,26 +427,32 @@
<data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve"> <data name="MusicGalleryPagePlayingQueueEmpty.Text" xml:space="preserve">
<value>播放隊列是空的</value> <value>播放隊列是空的</value>
</data> </data>
<data name="MusicGalleryPageQueueLoop.Content" xml:space="preserve"> <data name="MusicGalleryPagePlaylist.Text" xml:space="preserve">
<value>播放清單</value>
</data>
<data name="MusicGalleryPageQueueLoop.Text" xml:space="preserve">
<value>列表循環</value> <value>列表循環</value>
</data> </data>
<data name="MusicGalleryPageQueueRandom.Content" xml:space="preserve"> <data name="MusicGalleryPageQueueRandom.Text" xml:space="preserve">
<value>隨機</value> <value>隨機</value>
</data> </data>
<data name="MusicGalleryPageRemoveFromCustomList.Text" xml:space="preserve">
<value>從播放列表中刪除</value>
</data>
<data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve"> <data name="MusicGalleryPageRemoveFromPlayingQueue.Text" xml:space="preserve">
<value>從播放列表移除</value> <value>從播放列表移除</value>
</data> </data>
<data name="MusicGalleryPageScrollToPlayingItem.Content" xml:space="preserve"> <data name="MusicGalleryPageScrollToPlayingItem.Text" xml:space="preserve">
<value>定位到播放項</value> <value>定位到播放項</value>
</data> </data>
<data name="MusicGalleryPageSelectAll.Content" xml:space="preserve"> <data name="MusicGalleryPageSelectAll.Content" xml:space="preserve">
<value>選擇全部</value> <value>選擇全部</value>
</data> </data>
<data name="MusicGalleryPageSingleLoop.Content" xml:space="preserve"> <data name="MusicGalleryPageSingleLoop.Text" xml:space="preserve">
<value>單曲循環</value> <value>單曲循環</value>
</data> </data>
<data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve"> <data name="MusicGalleryPageSongSearchBox.PlaceholderText" xml:space="preserve">
<value>搜歌曲</value> <value>搜歌曲名稱、藝人、專輯或所在資料夾路徑</value>
</data> </data>
<data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByAlbum.Content" xml:space="preserve">
<value>專輯</value> <value>專輯</value>
@@ -433,12 +460,21 @@
<data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByArtist.Content" xml:space="preserve">
<value>藝術家</value> <value>藝術家</value>
</data> </data>
<data name="MusicGalleryPageSortByFolder.Content" xml:space="preserve">
<value>文件夹</value>
</data>
<data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve"> <data name="MusicGalleryPageSortByTitle.Content" xml:space="preserve">
<value>標題</value> <value>標題</value>
</data> </data>
<data name="MusicGalleryPageSortType.Text" xml:space="preserve"> <data name="MusicGalleryPageSortType.Text" xml:space="preserve">
<value>排序類型</value> <value>排序類型</value>
</data> </data>
<data name="MusicGalleryPageStarredPlaylist.Content" xml:space="preserve">
<value>已加星號的歌单</value>
</data>
<data name="MusicGalleryPageStopTrack.Text" xml:space="preserve">
<value>停止</value>
</data>
<data name="MusicGalleryPageTitle" xml:space="preserve"> <data name="MusicGalleryPageTitle" xml:space="preserve">
<value>音樂庫 - BetterLyrics</value> <value>音樂庫 - BetterLyrics</value>
</data> </data>
@@ -448,6 +484,15 @@
<data name="PictureInPictureMode" xml:space="preserve"> <data name="PictureInPictureMode" xml:space="preserve">
<value>畫中畫模式</value> <value>畫中畫模式</value>
</data> </data>
<data name="Pinyin" xml:space="preserve">
<value>普通話拼音</value>
</data>
<data name="PlaylistViewFailed" xml:space="preserve">
<value>由於路徑不存在,因此無法檢視曲目</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>羅馬音</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve"> <data name="SetingsPageContributors.Text" xml:space="preserve">
<value>貢獻者</value> <value>貢獻者</value>
</data> </data>
@@ -457,9 +502,18 @@
<data name="SetingsPageFeedback.Text" xml:space="preserve"> <data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>回饋</value> <value>回饋</value>
</data> </data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>說明</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve"> <data name="SetingsPageThanks.Text" xml:space="preserve">
<value>如果您喜歡這個項目,請考慮通過捐贈來支持它。您的支持將有助於保持項目的生命並鼓勵進一步的發展。</value> <value>如果您喜歡這個項目,請考慮通過捐贈來支持它。您的支持將有助於保持項目的生命並鼓勵進一步的發展。</value>
</data> </data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 歌詞</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve"> <data name="SettingsPageAbout.Content" xml:space="preserve">
<value>關於</value> <value>關於</value>
</data> </data>
@@ -529,6 +583,12 @@
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve"> <data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自動調整</value> <value>自動調整</value>
</data> </data>
<data name="SettingsPageAutoOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>應用程式啟動時開啟音樂庫視窗</value>
</data>
<data name="SettingsPageAutoPlayWhenOpenMusicGalleryWindow.Header" xml:space="preserve">
<value>打開音樂庫視窗時自動繼續播放</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve"> <data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自動啟動</value> <value>自動啟動</value>
</data> </data>
@@ -562,9 +622,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve"> <data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value> <value>中文注音</value>
</data> </data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中文歌詞</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve"> <data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中文轉換為繁體</value> <value>中文轉換為繁體</value>
</data> </data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>中日韓統一表意文字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>清除快取檔案</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve"> <data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>點擊穿透</value> <value>點擊穿透</value>
</data> </data>
@@ -712,6 +781,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve"> <data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>跟隨系統</value> <value>跟隨系統</value>
</data> </data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>字體顏色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve"> <data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>透過輪詢方式使歌詞視窗保持置於頂層狀態</value> <value>透過輪詢方式使歌詞視窗保持置於頂層狀態</value>
</data> </data>
@@ -808,9 +880,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve"> <data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 音樂服務器</value> <value>LX 音樂服務器</value>
</data> </data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌詞樣式與動效</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve"> <data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>對齊方式</value> <value>對齊方式</value>
</data> </data>
@@ -818,7 +887,7 @@
<value>歌詞背景</value> <value>歌詞背景</value>
</data> </data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>字體顏色(非當前播放區域</value> <value>非當前播放區域</value>
</data> </data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve"> <data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>字體不透明度(非目前播放區域)</value> <value>字體不透明度(非目前播放區域)</value>
@@ -854,7 +923,7 @@
<value>超細</value> <value>超細</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>字體顏色(當前播放區域</value> <value>當前播放區域</value>
</data> </data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve"> <data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>適應歌詞背景(彩色)</value> <value>適應歌詞背景(彩色)</value>
@@ -892,6 +961,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve"> <data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>輝光效果</value> <value>輝光效果</value>
</data> </data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>高亮</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve"> <data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮顯示範圍</value> <value>原文高亮顯示範圍</value>
</data> </data>
@@ -940,9 +1012,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve"> <data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>陰影</value> <value>陰影</value>
</data> </data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌詞描邊顏色</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve"> <data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌詞樣式</value> <value>歌詞樣式</value>
</data> </data>
@@ -1021,6 +1090,9 @@
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve"> <data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>在檔案總管中開啟</value> <value>在檔案總管中開啟</value>
</data> </data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve"> <data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>取色風格</value> <value>取色風格</value>
</data> </data>
@@ -1036,6 +1108,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve"> <data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>無法在您的電腦中找到該路徑</value> <value>無法在您的電腦中找到該路徑</value>
</data> </data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>歌詞注音</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>注音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve"> <data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>普通話拼音</value> <value>普通話拼音</value>
</data> </data>
@@ -1111,6 +1189,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve"> <data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>首行持續時間</value> <value>首行持續時間</value>
</data> </data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>服務器地址</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve"> <data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>測試服務器</value> <value>測試服務器</value>
</data> </data>
@@ -1150,6 +1231,9 @@
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve"> <data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>目前值: </value> <value>目前值: </value>
</data> </data>
<data name="SettingsPageSnowFlakeLayer.Header" xml:space="preserve">
<value>雪花層</value>
</data>
<data name="SettingsPageSongInfo.Text" xml:space="preserve"> <data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲標題和藝術家</value> <value>歌曲標題和藝術家</value>
</data> </data>
@@ -1174,7 +1258,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve"> <data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>標準模式</value> <value>標準模式</value>
</data> </data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve"> <data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>描邊顏色</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>預設</value> <value>預設</value>
</data> </data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve"> <data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1207,6 +1294,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve"> <data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入與切出快捷鍵</value> <value>切入與切出快捷鍵</value>
</data> </data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>譯文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve"> <data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌詞翻譯</value> <value>歌詞翻譯</value>
</data> </data>
@@ -1222,6 +1312,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve"> <data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本號</value> <value>版本號</value>
</data> </data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve"> <data name="SettingsPageWidth.Header" xml:space="preserve">
<value>寬度</value> <value>寬度</value>
</data> </data>
@@ -1258,12 +1351,21 @@
<data name="SystemTrayRestart.Text" xml:space="preserve"> <data name="SystemTrayRestart.Text" xml:space="preserve">
<value>重新啟動</value> <value>重新啟動</value>
</data> </data>
<data name="SystemTraySearch.Text" xml:space="preserve">
<value>歌詞搜尋視窗</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve"> <data name="SystemTraySettings.Text" xml:space="preserve">
<value>打開設置</value> <value>打開設置</value>
</data> </data>
<data name="SystemTraySwitch.Text" xml:space="preserve"> <data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌詞視窗切換器</value> <value>歌詞視窗切換器</value>
</data> </data>
<data name="TracksAddToPlaylistFailed" xml:space="preserve">
<value>路徑不存在,無法新增曲目</value>
</data>
<data name="TracksAddToPlaylistSuccessfully" xml:space="preserve">
<value>所選曲目已新增到此播放列表</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve"> <data name="TranslateServerNotSet" xml:space="preserve">
<value>未設定翻譯伺服器,請先在設定中進行配置</value> <value>未設定翻譯伺服器,請先在設定中進行配置</value>
</data> </data>

View File

@@ -1,25 +0,0 @@
using BetterLyrics.WinUI3.Enums;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace BetterLyrics.WinUI3.TemplateSelector;
public class SongOrderTemplateSelector : DataTemplateSelector
{
public DataTemplate ByTitleTemplate { get; set; }
public DataTemplate ByAlbumTemplate { get; set; }
public DataTemplate ByArtistTemplate { get; set; }
public CommonSongProperty SongOrderType { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
return SongOrderType switch
{
CommonSongProperty.Title => ByTitleTemplate,
CommonSongProperty.Album => ByAlbumTemplate,
CommonSongProperty.Artist => ByArtistTemplate,
_ => ByTitleTemplate
};
}
}

Some files were not shown because too many files have changed in this diff Show More