Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78c81347c8 | ||
|
|
65941323eb | ||
|
|
aee79b9971 | ||
|
|
97df1c1891 | ||
|
|
8a831b17cc | ||
|
|
78076efe40 | ||
|
|
d0346bf422 | ||
|
|
7cb4172e84 | ||
|
|
1f2426f51b | ||
|
|
e122fdabe8 | ||
|
|
97078d966d | ||
|
|
c43b69b4cb | ||
|
|
94b22552e5 | ||
|
|
6deb16f6cb | ||
|
|
e467ab9c73 | ||
|
|
ea038c9c56 | ||
|
|
560250ad30 | ||
|
|
536acc69a5 | ||
|
|
0bbb379912 | ||
|
|
1f4d29e6f2 | ||
|
|
5d1d7476c9 | ||
|
|
e016baefe1 | ||
|
|
70b6194788 | ||
|
|
9f103b0ea3 | ||
|
|
2924140f95 | ||
|
|
3d3f168926 | ||
|
|
63b2285a36 | ||
|
|
780689fa05 | ||
|
|
01384717c4 | ||
|
|
e18d78170a | ||
|
|
023bf77afc | ||
|
|
2877ac2101 | ||
|
|
16d82109bb | ||
|
|
c703f04119 | ||
|
|
998853f9d2 | ||
|
|
f560735da0 | ||
|
|
ab9da73b49 | ||
|
|
dc364edf75 | ||
|
|
7fbc8fbfe7 | ||
|
|
4a00bb2ddf | ||
|
|
7472aa048f | ||
|
|
49b0f7a692 | ||
|
|
4d0602ebef | ||
|
|
626395d93a | ||
|
|
0ab5602569 | ||
|
|
37a7528762 | ||
|
|
3ca391a509 | ||
|
|
f5e542d2f3 | ||
|
|
107bdf8bee | ||
|
|
3e9e56f5cc | ||
|
|
b0fd43ead5 | ||
|
|
81c59495c0 | ||
|
|
7c5f1a804e | ||
|
|
13ee4227f7 | ||
|
|
c1360ac972 | ||
|
|
c72aa8a58f | ||
|
|
9545ed610b | ||
|
|
1c4515acb9 | ||
|
|
92a6fe46de | ||
|
|
2f9fa02214 | ||
|
|
c174363c07 | ||
|
|
8506062c9a | ||
|
|
52711cba1f | ||
|
|
7eda076920 | ||
|
|
282c2f5ac0 | ||
|
|
94e76a6ac9 | ||
|
|
516d388009 | ||
|
|
ad33eed57c | ||
|
|
64bf2dc3d9 | ||
|
|
b86e4a3d12 | ||
|
|
411506b9cd |
2
.github/FUNDING.yml
vendored
@@ -12,4 +12,4 @@ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cl
|
||||
polar: # Replace with a single Polar username
|
||||
buy_me_a_coffee: founchoo
|
||||
thanks_dev: # Replace with a single thanks.dev username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
custom: ['https://paypal.me/zhefangpay']
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
<Identity
|
||||
Name="37412.BetterLyrics"
|
||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||
Version="1.0.53.0" />
|
||||
Version="1.0.82.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>BetterLyrics</DisplayName>
|
||||
<PublisherDisplayName>founchoo</PublisherDisplayName>
|
||||
<PublisherDisplayName>Zhe Fang</PublisherDisplayName>
|
||||
<Logo>Images\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
|
||||
@@ -51,10 +51,14 @@
|
||||
<converter:TranslationSearchProviderToDisplayNameConverter x:Key="TranslationSearchProviderToDisplayNameConverter" />
|
||||
<converter:AlbumArtSearchProviderToDisplayNameConverter x:Key="AlbumArtSearchProviderToDisplayNameConverter" />
|
||||
<converter:SecondsToFormattedTimeConverter x:Key="SecondsToFormattedTimeConverter" />
|
||||
<converter:MillisecondsToFormattedTimeConverter x:Key="MillisecondsToFormattedTimeConverter" />
|
||||
<converter:MediaSourceProviderToLogoUriConverter x:Key="MediaSourceProviderToLogoUriConverter" />
|
||||
<converter:MediaSourceProviderToDisplayedNameConverter x:Key="MediaSourceProviderToDisplayedNameConverter" />
|
||||
<converter:FPSToTimeSpanConverter x:Key="FPSToTimeSpanConverter" />
|
||||
<converter:ShortcutToStringConverter x:Key="ShortcutToStringConverter" />
|
||||
<converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" />
|
||||
<converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" />
|
||||
<converter:RectToMarginConverter x:Key="RectToMarginConverter" />
|
||||
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace BetterLyrics.WinUI3
|
||||
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||
{
|
||||
WindowHelper.OpenWindow<LyricsWindow>();
|
||||
WindowHelper.OpenOrShowWindow<LyricsWindow>();
|
||||
}
|
||||
|
||||
private static void ConfigureServices()
|
||||
@@ -113,11 +113,11 @@ namespace BetterLyrics.WinUI3
|
||||
.AddSingleton<ILastFMService, LastFMService>()
|
||||
// ViewModels
|
||||
.AddSingleton<AppSettingsControlViewModel>()
|
||||
.AddSingleton<LyricsBackgroundSettingsControlViewModel>()
|
||||
.AddSingleton<AlbumArtLayoutSettingsControlViewModel>()
|
||||
.AddSingleton<PlaybackSettingsControlViewModel>()
|
||||
.AddSingleton<MediaSettingsControlViewModel>()
|
||||
.AddSingleton<AllLyricsSettingsControlViewModel>()
|
||||
.AddSingleton<LyricsSearchControlViewModel>()
|
||||
.AddSingleton<LyricsWindowSettingsControlViewModel>()
|
||||
.AddSingleton<LyricsWindowSwitchControlViewModel>()
|
||||
.AddSingleton<LyricsWindowViewModel>()
|
||||
.AddSingleton<SettingsWindowViewModel>()
|
||||
.AddSingleton<SystemTrayViewModel>()
|
||||
|
||||
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Alipay.jpg
Normal file
|
After Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 14 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Empty.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Listen1.png
Normal file
|
After Width: | Height: | Size: 879 B |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/MoeKoeMusic.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Page.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 192 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/WeChatReward.png
Normal file
|
After Width: | Height: | Size: 209 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/effect.bin
Normal file
@@ -20,18 +20,23 @@
|
||||
<PRIResource Remove="ViewModels\Lyrics\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\effect.bin" />
|
||||
<None Remove="Assets\Segoe Fluent Icons.ttf" />
|
||||
<None Remove="Assets\Wiki82.profile.xml" />
|
||||
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
|
||||
<None Remove="Controls\AllLyricsSettingsControl.xaml" />
|
||||
<None Remove="Controls\AppSettingsControl.xaml" />
|
||||
<None Remove="Controls\DemoWindowGrid.xaml" />
|
||||
<None Remove="Controls\ExtendedSlider.xaml" />
|
||||
<None Remove="Controls\LyricsBavkgroundSettingsControl.xaml" />
|
||||
<None Remove="Controls\LyricsSearchControl.xaml" />
|
||||
<None Remove="Controls\LyricsSettingsControl.xaml" />
|
||||
<None Remove="Controls\LyricsWindowSettingsControl.xaml" />
|
||||
<None Remove="Controls\LyricsWindowSwitchControl.xaml" />
|
||||
<None Remove="Controls\MediaSettingsControl.xaml" />
|
||||
<None Remove="Controls\PlaybackSettingsControl.xaml" />
|
||||
<None Remove="Controls\ShortcutTextBox.xaml" />
|
||||
<None Remove="Controls\SystemTray.xaml" />
|
||||
<None Remove="Views\LyricsSearchWindow.xaml" />
|
||||
<None Remove="Views\LyricsWindowSwitchWindow.xaml" />
|
||||
<None Remove="Views\MusicGalleryPage.xaml" />
|
||||
<None Remove="Views\MusicGalleryWindow.xaml" />
|
||||
<None Remove="Views\SettingsWindow.xaml" />
|
||||
@@ -59,17 +64,21 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
|
||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
|
||||
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.0" />
|
||||
<PackageReference Include="Hqub.Last.fm" Version="2.5.1" />
|
||||
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
|
||||
<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.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
|
||||
@@ -77,7 +86,6 @@
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" />
|
||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||
<PackageReference Include="TinyPinyin.Net" Version="1.0.2" />
|
||||
<PackageReference Include="Ude.NetStandard" Version="1.2.0" />
|
||||
<PackageReference Include="Vanara.PInvoke.CoreAudio" Version="4.1.6" />
|
||||
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.1.6" />
|
||||
@@ -87,11 +95,6 @@
|
||||
<PackageReference Include="WinUIEx" Version="2.6.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Hqub.Lastfm">
|
||||
<HintPath>..\..\..\Last.fm\src\Hqub.Lastfm\bin\Release\netstandard2.0\Hqub.Lastfm.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Rendering\InAppLyricsRenderer.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -116,10 +119,13 @@
|
||||
<Content Update="Assets\Chrome.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Discord.png">
|
||||
<Content Update="Assets\Edge.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Edge.png">
|
||||
<Content Update="Assets\effect.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Empty.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyBox.png">
|
||||
@@ -143,6 +149,9 @@
|
||||
<Content Update="Assets\Leaf.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Listen1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Logo.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -155,16 +164,19 @@
|
||||
<Content Update="Assets\MediaPlayerWindows11.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MoeKoeMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\MusicBee.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\NetEaseCloudMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PotPlayer.png">
|
||||
<Content Update="Assets\Page.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\QQ.png">
|
||||
<Content Update="Assets\PotPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\QQMusic.png">
|
||||
@@ -173,19 +185,49 @@
|
||||
<Content Update="Assets\Question.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\SaltPlayerForWindows.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Segoe Fluent Icons.ttf">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Spotify.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Telegram.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Wiki82.profile.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\LyricsWindowSwitchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsWindowSwitchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\DemoWindowGrid.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsWindowSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Views\LyricsSearchWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsSearchControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\ShortcutTextBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -196,11 +238,6 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AllLyricsSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -222,7 +259,7 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsBavkgroundSettingsControl.xaml">
|
||||
<Page Update="Controls\LyricsBackgroundSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
@@ -251,6 +288,11 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Update="Strings\en-US\Resources.resw">
|
||||
<Generator></Generator>
|
||||
</PRIResource>
|
||||
</ItemGroup>
|
||||
<!-- Publish Properties -->
|
||||
<PropertyGroup>
|
||||
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Constants
|
||||
{
|
||||
public static class AppleMusic
|
||||
{
|
||||
public const string MediaUserTokenKey = "AppleMusicMediaUserToken";
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,6 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
{
|
||||
public static class LXMusic
|
||||
{
|
||||
public const string QuerySuffix = "/subscribe-player-status?filter=progress,duration";
|
||||
public const string QuerySuffix = "/subscribe-player-status?filter=progress,duration,picUrl";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
{
|
||||
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 FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/FAQ.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 DiscordUrl = "https://discord.gg/5yAQPnyCKv";
|
||||
public const string TelegramUrl = "https://t.me/+svhSLZ7awPsxNGY1";
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public const string PotPlayer = "PotPlayerMini64.exe";
|
||||
public const string Spotify = "Spotify.exe";
|
||||
public const string AppleMusic = "AppleInc.AppleMusicWin_nzyj5cx40ttqa!App";
|
||||
public const string AppleMusicAlternative = "AppleMusic.exe";
|
||||
public const string NetEaseCloudMusic = "cloudmusic.exe";
|
||||
public const string KugouMusic = "kugou";
|
||||
public const string QQMusic = "QQMusic.exe";
|
||||
@@ -25,5 +26,9 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public const string Edge = "MSEdge";
|
||||
public const string BetterLyrics = "37412.BetterLyrics_rd1g0rsrrtxw8!App";
|
||||
public const string BetterLyricsDebug = "37412.BetterLyrics_c8mj3v9sysxb4!App";
|
||||
public const string SaltPlayerForWindows = "Sakawish.SaltPlayerforWindows_q65q631pyh094!SaltPlayerforWindows";
|
||||
public const string MoeKoeMusic = "cn.MoeKoe.Music";
|
||||
public const string MoeKoeMusicAlternative = "electron.app.MoeKoe Music";
|
||||
public const string Listen1 = "com.listen1.listen1";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public const string PotPlayer = "PotPlayer";
|
||||
public const string Spotify = "Spotify";
|
||||
public const string AppleMusic = "Apple Music";
|
||||
public const string AppleMusicAlternative = "Apple Music";
|
||||
public const string NetEaseCloudMusic = "网易云音乐";
|
||||
public const string KugouMusic = "酷狗音乐";
|
||||
public const string QQMusic = "QQ 音乐";
|
||||
@@ -24,5 +25,8 @@ namespace BetterLyrics.WinUI3.Constants
|
||||
public const string Edge = "Microsoft Edge";
|
||||
public const string BetterLyrics = "BetterLyrics";
|
||||
public const string BetterLyricsDebug = "BetterLyrics (Debug)";
|
||||
public const string SaltPlayerForWindows = "Salt Player for Windows";
|
||||
public const string MoeKoeMusic = "MoeKoe Music";
|
||||
public const string Listen1 = "Listen 1";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,27 @@
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageAlbumArtSize"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoSize">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind AlbumArtLayoutSettings.AutoAlbumArtSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="800"
|
||||
Minimum="10"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.AlbumArtSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="12"
|
||||
@@ -24,7 +45,7 @@
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" />
|
||||
Value="{x:Bind AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
@@ -33,22 +54,43 @@
|
||||
Frequency="1"
|
||||
Maximum="64"
|
||||
Minimum="0"
|
||||
Value="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" />
|
||||
Value="{x:Bind AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.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="SettingsPageSongInfoCenter" />
|
||||
<ComboBoxItem x:Uid="SettingsPageSongInfoRight" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="18"
|
||||
Frequency="2"
|
||||
Maximum="72"
|
||||
Minimum="8"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageShowTitle"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowArtists">
|
||||
<ToggleSwitch IsEnabled="{x:Bind AlbumArtLayoutSettings.ShowTitle, Mode=OneWay}" IsOn="{x:Bind AlbumArtLayoutSettings.ShowArtists, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -22,11 +23,18 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class AlbumArtLayoutSettingsControl : UserControl
|
||||
{
|
||||
public AlbumArtLayoutSettingsControlViewModel ViewModel => (AlbumArtLayoutSettingsControlViewModel)DataContext;
|
||||
public static readonly DependencyProperty AlbumArtLayoutSettingsProperty =
|
||||
DependencyProperty.Register(nameof(AlbumArtLayoutSettings), typeof(AlbumArtLayoutSettings), typeof(AlbumArtLayoutSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public AlbumArtLayoutSettings AlbumArtLayoutSettings
|
||||
{
|
||||
get => (AlbumArtLayoutSettings)GetValue(AlbumArtLayoutSettingsProperty);
|
||||
set => SetValue(AlbumArtLayoutSettingsProperty, value);
|
||||
}
|
||||
|
||||
public AlbumArtLayoutSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<AlbumArtLayoutSettingsControlViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.AllLyricsSettingsControl"
|
||||
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:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<controls:SwitchPresenter Margin="0,72,0,0" Value="{Binding SelectedItem.Tag, ElementName=LyricsSettingsSegmentedControl}">
|
||||
<controls:Case Value="Standard">
|
||||
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.StandardLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.StandardLyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
<controls:Case Value="Desktop">
|
||||
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
<controls:Case Value="Dock">
|
||||
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DockLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DockLyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
<controls:Case Value="PictureInPicture">
|
||||
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
</controls:SwitchPresenter>
|
||||
<controls:Segmented
|
||||
x:Name="LyricsSettingsSegmentedControl"
|
||||
Margin="36,36,36,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
SelectedIndex="{x:Bind ViewModel.SelectedTabIndex, Mode=OneWay}">
|
||||
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlStandard" Tag="Standard" />
|
||||
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDock" Tag="Dock" />
|
||||
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDesktop" Tag="Desktop" />
|
||||
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlPictureInPicture" Tag="PictureInPicture" />
|
||||
</controls:Segmented>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -50,125 +50,28 @@
|
||||
Unloaded="AutoStartupToggleSwitch_Unloaded" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoStartWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.AutoStartWindowType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageAutoStartInAppLyrics" />
|
||||
<ComboBoxItem x:Uid="SettingsPageAutoStartDockLyrics" />
|
||||
<ComboBoxItem x:Uid="SettingsPageAutoStartDesktopLyrics" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageIgnoreFullscreenWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IgnoreFullscreenWindow, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.HideWindowWhenNotPlaying, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageGlobalDrag" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IsDragEverywhereEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Standard mode -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppStandard" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.StandardModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<controls:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Desktop mode -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppDesktop" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DesktopModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<controls:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoLock" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.DesktopModeSettings.AutoLockOnDesktopMode, Mode=TwoWay}" />
|
||||
<controls:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLockHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.LockShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Dock mode -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppDock" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DockModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.AppSettings.DockModeSettings.DockMonitorDeviceName, Mode=TwoWay}" />
|
||||
<Button
|
||||
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockWindowHeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="64"
|
||||
Frequency="1"
|
||||
Maximum="200"
|
||||
Minimum="64"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.AppSettings.DockModeSettings.DockWindowHeight, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockPlacement" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
|
||||
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Picture in picture mode -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAppPictureInPicture" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.PictureInPictureModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.PictureInPictureModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Playback shortcut -->
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.DemoWindowGrid"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid
|
||||
Width="{x:Bind LyricsWindowStatus.DemoMonitorBounds.Width, Mode=OneWay}"
|
||||
Height="{x:Bind LyricsWindowStatus.DemoMonitorBounds.Height, Mode=OneWay}"
|
||||
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
|
||||
CornerRadius="4">
|
||||
<Grid
|
||||
Width="{x:Bind LyricsWindowStatus.DemoWindowBounds.Width, Mode=OneWay}"
|
||||
Height="{x:Bind LyricsWindowStatus.DemoWindowBounds.Height, Mode=OneWay}"
|
||||
Margin="{x:Bind LyricsWindowStatus.DemoWindowBounds, Converter={StaticResource RectToMarginConverter}, Mode=OneWay}"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Background="{ThemeResource AccentAcrylicBackgroundFillColorDefaultBrush}"
|
||||
BorderBrush="{ThemeResource AccentFillColorDefaultBrush}"
|
||||
CornerRadius="4">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsWindowStatus.IsBorderless, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="True">
|
||||
<interactivity:ChangePropertyAction PropertyName="BorderThickness" Value="0" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsWindowStatus.IsBorderless, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="False">
|
||||
<interactivity:ChangePropertyAction PropertyName="BorderThickness" Value="1" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</Grid>
|
||||
<!-- Is default -->
|
||||
<Grid
|
||||
Margin="4"
|
||||
Padding="6,3"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
|
||||
CornerRadius="4"
|
||||
Opacity="0.7"
|
||||
Visibility="{x:Bind LyricsWindowStatus.IsDefault, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
|
||||
<TextBlock
|
||||
x:Uid="DemoWindowControlDefault"
|
||||
FontSize="12"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<!-- Is always on top -->
|
||||
<Grid
|
||||
Margin="4"
|
||||
Padding="6,3"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
|
||||
CornerRadius="4"
|
||||
Opacity="0.7"
|
||||
Visibility="{x:Bind LyricsWindowStatus.IsAlwaysOnTop, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="12"
|
||||
Glyph="" />
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="12"
|
||||
Glyph=""
|
||||
Visibility="{x:Bind LyricsWindowStatus.IsAlwaysOnTopPolling, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
||||
</Grid>
|
||||
<!-- Moniter name -->
|
||||
<Grid
|
||||
Margin="4"
|
||||
Padding="6,3"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
|
||||
CornerRadius="4"
|
||||
Opacity="0.7">
|
||||
<TextBlock
|
||||
FontSize="12"
|
||||
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<!-- Config name -->
|
||||
<Grid
|
||||
Padding="6,3"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="4"
|
||||
Opacity="0.7">
|
||||
<TextBlock
|
||||
FontWeight="ExtraBlack"
|
||||
Text="{x:Bind LyricsWindowStatus.Name, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
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 BetterLyrics.WinUI3.Models;
|
||||
|
||||
// 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 DemoWindowGrid : UserControl
|
||||
{
|
||||
public DemoWindowGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsWindowStatusProperty =
|
||||
DependencyProperty.Register(nameof(LyricsWindowStatus), typeof(LyricsWindowStatus), typeof(DemoWindowGrid), new PropertyMetadata(default));
|
||||
|
||||
public LyricsWindowStatus LyricsWindowStatus
|
||||
{
|
||||
get => (LyricsWindowStatus)GetValue(LyricsWindowStatusProperty);
|
||||
set => SetValue(LyricsWindowStatusProperty, value);
|
||||
}
|
||||
}
|
||||
@@ -4,54 +4,58 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="6,0,2,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Value, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
Margin="0,0,14,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Unit, Mode=OneWay}" />
|
||||
<StackPanel>
|
||||
|
||||
<Slider
|
||||
Maximum="{x:Bind Maximum, Mode=OneWay}"
|
||||
Minimum="{x:Bind Minimum, Mode=OneWay}"
|
||||
SnapsTo="Ticks"
|
||||
StepFrequency="{x:Bind Frequency, Mode=OneWay}"
|
||||
TickFrequency="{x:Bind Frequency, Mode=OneWay}"
|
||||
TickPlacement="Outside"
|
||||
TickPlacement="None"
|
||||
Value="{x:Bind Value, Mode=TwoWay}" />
|
||||
<Button
|
||||
Margin="3,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Click="ResetButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}"
|
||||
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
|
||||
<Button
|
||||
x:Name="SubtractButton"
|
||||
Margin="3,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Click="SubtractButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
<Button
|
||||
x:Name="AddButton"
|
||||
Margin="3,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Click="AddButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Click="ResetButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}"
|
||||
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
|
||||
<Button
|
||||
x:Name="SubtractButton"
|
||||
VerticalAlignment="Center"
|
||||
Click="SubtractButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
<StackPanel
|
||||
Margin="3,-2,3,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="2">
|
||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind Value, Mode=OneWay}" />
|
||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind Unit, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
|
||||
<Button
|
||||
x:Name="AddButton"
|
||||
VerticalAlignment="Center"
|
||||
Click="AddButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsBackgroundSettingsControl"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageFollowSystem" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageDark" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPagePureLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsPureColorOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageAlbumArtLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSpeed" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="50"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBlurAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsCoverOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageFluidLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOpacity" IsEnabled="{x:Bind LyricsBackgroundSettings.IsFluidOverlayEnabled, Mode=OneWay}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.FluidOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageSpectrumLayer"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,3 +1,4 @@
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -20,14 +21,20 @@ using Windows.Foundation.Collections;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class LyricsBavkgroundSettingsControl : UserControl
|
||||
public sealed partial class LyricsBackgroundSettingsControl : UserControl
|
||||
{
|
||||
public LyricsBackgroundSettingsControlViewModel ViewModel => (LyricsBackgroundSettingsControlViewModel)DataContext;
|
||||
public static readonly DependencyProperty LyricsBackgroundSettingsProperty =
|
||||
DependencyProperty.Register(nameof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsBavkgroundSettingsControl()
|
||||
public LyricsBackgroundSettings LyricsBackgroundSettings
|
||||
{
|
||||
get => (LyricsBackgroundSettings)GetValue(LyricsBackgroundSettingsProperty);
|
||||
set => SetValue(LyricsBackgroundSettingsProperty, value);
|
||||
}
|
||||
|
||||
public LyricsBackgroundSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsBackgroundSettingsControlViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsBavkgroundSettingsControl"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageFollowSystem" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageDark" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsPureColorBgOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundSpeed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<uc:ExtendedSlider
|
||||
Default="50"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<uc:ExtendedSlider
|
||||
Default="100"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<uc:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,227 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsSearchControl"
|
||||
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 Padding="16" RowSpacing="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<controls:SettingsExpander x:Uid="LyricsSearchControlSongInfoMapping" IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<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=}"
|
||||
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=}"
|
||||
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">
|
||||
<Button
|
||||
x:Uid="LyricsSearchControlSearch"
|
||||
Command="{x:Bind ViewModel.SearchCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
<ListView ItemsSource="{x:Bind ViewModel.LyricsSearchResults, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsSearchResult, Mode=TwoWay}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ListViewItem IsEnabled="{Binding IsFound}">
|
||||
<Grid Opacity="{Binding IsFound, Converter={StaticResource BoolToOpacityConverter}}">
|
||||
<RelativePanel Padding="0,6">
|
||||
<TextBlock
|
||||
x:Name="SearchedTitle"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
Text="{Binding Title}"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedArtists"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
RelativePanel.Below="SearchedTitle"
|
||||
Text="{Binding Artist}"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedProvider"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
Text="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
</RelativePanel>
|
||||
<TextBlock
|
||||
x:Uid="LyricsSearchControlNotFound"
|
||||
VerticalAlignment="Center"
|
||||
Text="Not found"
|
||||
Visibility="{Binding IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</ListViewItem>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="0">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="0">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ListView>
|
||||
<StackPanel
|
||||
Padding="0,36"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="12">
|
||||
<Image MaxWidth="100" Source="/Assets/Empty.png" />
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="0">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="0">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</StackPanel>
|
||||
<ProgressBar
|
||||
VerticalAlignment="Top"
|
||||
IsIndeterminate="True"
|
||||
ShowError="False"
|
||||
ShowPaused="False"
|
||||
Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
||||
</Grid>
|
||||
<Grid Grid.Column="2">
|
||||
<ListView ItemsSource="{x:Bind ViewModel.LyricsData.LyricsLines, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsLine, Mode=TwoWay}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<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>
|
||||
<StackPanel
|
||||
Padding="0,36"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Spacing="12">
|
||||
<Image MaxWidth="100" Source="/Assets/Page.png" />
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1">
|
||||
<RelativePanel>
|
||||
<TextBlock
|
||||
x:Uid="LyricsSearchControlHelp"
|
||||
Margin="0,0,24,0"
|
||||
FontSize="12"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
RelativePanel.LeftOf="Reset"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
x:Name="Reset"
|
||||
x:Uid="LyricsSearchControlReset"
|
||||
Margin="0,0,6,0"
|
||||
Command="{x:Bind ViewModel.ResetCommand}"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
RelativePanel.LeftOf="SaveChanges" />
|
||||
<Button
|
||||
x:Name="SaveChanges"
|
||||
x:Uid="LyricsSearchControlSaveChanges"
|
||||
Command="{x:Bind ViewModel.SaveCommand}"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
</RelativePanel>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,3 +1,4 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -12,6 +13,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Ude.Core;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
@@ -20,13 +22,14 @@ using Windows.Foundation.Collections;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class AllLyricsSettingsControl : UserControl
|
||||
public sealed partial class LyricsSearchControl : UserControl
|
||||
{
|
||||
public AllLyricsSettingsControlViewModel ViewModel => (AllLyricsSettingsControlViewModel)DataContext;
|
||||
public AllLyricsSettingsControl()
|
||||
public LyricsSearchControlViewModel ViewModel => (LyricsSearchControlViewModel)DataContext;
|
||||
|
||||
public LyricsSearchControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<AllLyricsSettingsControlViewModel>();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,14 +175,25 @@
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ColorPicker>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="96"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFontSize"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageDynamicLyricsFontSize">
|
||||
<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=}">
|
||||
<local:ExtendedSlider
|
||||
@@ -234,14 +245,46 @@
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 高亮 -->
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsHighlightScope" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<!-- 译文高亮 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsTranslationHighlight"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
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=}"
|
||||
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:SettingsCard>
|
||||
<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
|
||||
@@ -319,6 +362,7 @@
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 滚动动画 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageScrollEasing"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
@@ -341,7 +385,6 @@
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollTopDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
@@ -351,7 +394,6 @@
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
@@ -361,7 +403,6 @@
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollBottomDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
@@ -369,6 +410,24 @@
|
||||
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>
|
||||
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsWindowSettingsControl"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid ColumnSpacing="6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0">
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageRecordedWindowStatus"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<Button x:Uid="SettingsPageCreateFromCurrent" Command="{x:Bind ViewModel.CopyLyricsWindowStatusCommand}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageCreateFromTemplates"
|
||||
VerticalAlignment="Center"
|
||||
RelativePanel.AlignRightWithPanel="True">
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDesktopMode" Command="{x:Bind ViewModel.CreateTransparentLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageDockedMode" Command="{x:Bind ViewModel.CreateDockedLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageFullscreenMode" Command="{x:Bind ViewModel.CreateFullLyricsWindowStatusCommand}" />
|
||||
<MenuFlyoutItem x:Uid="SettingsPageNarrowMode" Command="{x:Bind ViewModel.CreateNarrowLyricsWindowStatusCommand}" />
|
||||
</MenuFlyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<StackPanel
|
||||
Padding="24,0"
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
CornerRadius="4"
|
||||
Spacing="16"
|
||||
Visibility="{Binding ElementName=LyricsWindowManagerExpander, Path=IsExpanded, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
|
||||
<ListView
|
||||
x:Name="WindowStatusListView"
|
||||
Padding="0,12"
|
||||
CornerRadius="4"
|
||||
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel
|
||||
Padding="0,10"
|
||||
RightTapped="StackPanel_RightTapped"
|
||||
Spacing="6">
|
||||
<StackPanel.ContextFlyout>
|
||||
<MenuBarItemFlyout>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="LyricsWindowSettingsControlSetDefault"
|
||||
Click="SetDefaultMenuFlyoutItem_Click"
|
||||
IsEnabled="{Binding IsDefault, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SettingsPageDelete"
|
||||
Click="DeleteMenuFlyoutItem_Click"
|
||||
IsEnabled="{Binding IsDefault, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
|
||||
</MenuBarItemFlyout>
|
||||
</StackPanel.ContextFlyout>
|
||||
<uc:DemoWindowGrid LyricsWindowStatus="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
<Grid Grid.Column="1">
|
||||
|
||||
<controls:SwitchPresenter Margin="0,100,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
|
||||
<controls:SwitchPresenter.ContentTransitions>
|
||||
<TransitionCollection>
|
||||
<PopupThemeTransition />
|
||||
</TransitionCollection>
|
||||
</controls:SwitchPresenter.ContentTransitions>
|
||||
|
||||
<!-- General -->
|
||||
<controls:Case Value="General">
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel
|
||||
Margin="0,6,0,0"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<TextBox Text="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.Name, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageDisplayTypeSwitcher"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLayoutOrientation">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<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=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageWindowBounds"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard Header="X">
|
||||
<uc:ExtendedSlider
|
||||
Frequency="1"
|
||||
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Right, Mode=OneWay}"
|
||||
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Left, Mode=OneWay}"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Y">
|
||||
<uc:ExtendedSlider
|
||||
Frequency="1"
|
||||
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom, Mode=OneWay}"
|
||||
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Top, Mode=OneWay}"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWidth">
|
||||
<uc:ExtendedSlider
|
||||
Frequency="1"
|
||||
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}"
|
||||
Minimum="64"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageHeight">
|
||||
<uc:ExtendedSlider
|
||||
Frequency="1"
|
||||
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
|
||||
Minimum="64"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="px"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageAOT"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageWorkArea"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
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=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</controls:Case>
|
||||
|
||||
<!-- Album art area style -->
|
||||
<controls:Case Value="AlbumArtStyle">
|
||||
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics style and effect -->
|
||||
<controls:Case Value="Lyrics">
|
||||
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics background -->
|
||||
<controls:Case Value="LyricsBackground">
|
||||
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Advanced -->
|
||||
<controls:Case Value="Advanced">
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsClickThrough, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageAdaptEnvColor"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageEnvColorSample" Header="Environment color sample mode">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.EnvironmentSampleMode, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleBelow" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleAbove" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" />
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaTop" />
|
||||
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaWhole" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</controls:Case>
|
||||
|
||||
</controls:SwitchPresenter>
|
||||
|
||||
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<ListView
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
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="" />
|
||||
<TextBlock x:Uid="AppSettingsControlGeneral" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
|
||||
<ListViewItem Tag="AlbumArtStyle">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="16"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="SettingsPageAlbumStyle" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
|
||||
<ListViewItem Tag="Lyrics">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="16"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="SettingsPageLyrics" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
|
||||
<ListViewItem Tag="LyricsBackground">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="16"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="SettingsPageBackgroundOverlay" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
|
||||
<ListViewItem Tag="Advanced">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="16"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="SettingsPageAdvanced" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ListViewItem>
|
||||
|
||||
</ListView.Items>
|
||||
|
||||
</ListView>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,84 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
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 NTextCat.Commons;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using static Vanara.PInvoke.ComCtl32;
|
||||
|
||||
// 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 LyricsWindowSettingsControl : UserControl
|
||||
{
|
||||
public LyricsWindowSettingsControlViewModel ViewModel => (LyricsWindowSettingsControlViewModel)DataContext;
|
||||
|
||||
private ISettingsService _settingsService;
|
||||
|
||||
public LyricsWindowSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSettingsControlViewModel>();
|
||||
_settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
}
|
||||
|
||||
private void DeleteMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
var data = menuFlyoutItem.DataContext as LyricsWindowStatus;
|
||||
if (data != null)
|
||||
{
|
||||
ViewModel.AppSettings.WindowBoundsRecords.Remove(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (sender is MenuFlyoutItem menuFlyoutItem)
|
||||
{
|
||||
var data = menuFlyoutItem.DataContext as LyricsWindowStatus;
|
||||
if (data != null)
|
||||
{
|
||||
ViewModel.AppSettings.WindowBoundsRecords.ForEach(x => x.IsDefault = false);
|
||||
data.IsDefault = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StackPanel_RightTapped(object sender, RightTappedRoutedEventArgs e)
|
||||
{
|
||||
if (sender is StackPanel stackPanel)
|
||||
{
|
||||
if (stackPanel.DataContext is MenuBarItemFlyout menuBarItemFlyout)
|
||||
{
|
||||
menuBarItemFlyout.ShowAt(stackPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsWindowSwitchControl"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"
|
||||
CornerRadius="12">
|
||||
<Button
|
||||
Margin="12"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="Button_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
<ListView
|
||||
Margin="48"
|
||||
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
|
||||
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid
|
||||
Margin="0,10"
|
||||
Padding="5"
|
||||
AllowFocusOnInteraction="True"
|
||||
CornerRadius="4"
|
||||
Tapped="Grid_Tapped">
|
||||
<uc:DemoWindowGrid LyricsWindowStatus="{Binding}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,45 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
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.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 LyricsWindowSwitchControl : UserControl
|
||||
{
|
||||
public LyricsWindowSwitchControlViewModel ViewModel => (LyricsWindowSwitchControlViewModel)DataContext;
|
||||
|
||||
public LyricsWindowSwitchControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSwitchControlViewModel>();
|
||||
}
|
||||
|
||||
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.HideWindow<LyricsWindowSwitchWindow>();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.HideWindow<LyricsWindowSwitchWindow>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,16 +31,20 @@
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 时间轴相关配置 -->
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsTimelineThresholdReset"
|
||||
Frequency="100"
|
||||
Maximum="1000"
|
||||
Minimum="0"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="ms"
|
||||
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="100"
|
||||
Maximum="1000"
|
||||
Minimum="0"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Unit="ms"
|
||||
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPagePositionOffsetReset"
|
||||
@@ -118,8 +122,15 @@
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- 播放源列表 -->
|
||||
<ListView
|
||||
x:Name="MediaSourceProvidersListView"
|
||||
VerticalAlignment="Top"
|
||||
AllowDrop="True"
|
||||
CanDragItems="True"
|
||||
CanReorderItems="True"
|
||||
DragItemsCompleted="MediaSourceProvidersListView_DragItemsCompleted"
|
||||
ItemsSource="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo, Mode=OneWay}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.HorizontalScrollMode="Enabled"
|
||||
@@ -134,6 +145,10 @@
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:MediaSourceProviderInfo">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<FontIcon
|
||||
FontFamily="Segoe UI Symbol"
|
||||
FontSize="12"
|
||||
Glyph="⠿" />
|
||||
<ImageIcon Height="16" Source="{Binding Provider, Converter={StaticResource MediaSourceProviderToLogoUriConverter}, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
MaxWidth="200"
|
||||
@@ -158,6 +173,7 @@
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -187,6 +203,132 @@
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<!-- Provider info -->
|
||||
<TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Lyrics translation -->
|
||||
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander
|
||||
x:Uid="LyricsPageTranslationEnabled"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
|
||||
<ComboBoxItem Content="العربية" Tag="ar" />
|
||||
<ComboBoxItem Content="Azərbaycan dili" Tag="az" />
|
||||
<ComboBoxItem Content="Български" Tag="bg" />
|
||||
<ComboBoxItem Content="বাংলা" Tag="bn" />
|
||||
<ComboBoxItem Content="Català" Tag="ca" />
|
||||
<ComboBoxItem Content="Čeština" Tag="cs" />
|
||||
<ComboBoxItem Content="Dansk" Tag="da" />
|
||||
<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>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<controls:SettingsCard.Description>
|
||||
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageTranslationInfoLink"
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap" />
|
||||
</HyperlinkButton>
|
||||
</controls:SettingsCard.Description>
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="12">
|
||||
<TextBox
|
||||
x:Name="LibreTranslateServerTextBox"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
PlaceholderText="http://localhost:5000"
|
||||
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.LibreTranslateServer, Mode=TwoWay}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageServerTestButton"
|
||||
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- Lyrics phonetic -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageChinese"
|
||||
IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard>
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
|
||||
<ComboBoxItem x:Uid="SettingsPagePinyin" />
|
||||
<ComboBoxItem x:Uid="SettingsPageJyutping" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsCard x:Uid="SettingsPageJapanese" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 中文简体繁体偏好 -->
|
||||
<controls:SettingsCard x:Uid="SettingsPageChinesePreference">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Last.fm -->
|
||||
<TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander
|
||||
@@ -218,85 +360,7 @@
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<!-- Lyrics translation -->
|
||||
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander
|
||||
x:Uid="LyricsPageTranslationEnabled"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.SelectedTargetLanguageIndex, Mode=TwoWay}">
|
||||
<ComboBoxItem Content="العربية" Tag="ar" />
|
||||
<ComboBoxItem Content="Azərbaycan dili" Tag="az" />
|
||||
<ComboBoxItem Content="简体中文" Tag="zh-Hans" />
|
||||
<ComboBoxItem Content="繁體中文" Tag="zh-Hant" />
|
||||
<ComboBoxItem Content="Čeština" Tag="cs" />
|
||||
<ComboBoxItem Content="Dansk" Tag="da" />
|
||||
<ComboBoxItem Content="Nederlands" Tag="nl" />
|
||||
<ComboBoxItem Content="English" Tag="en" />
|
||||
<ComboBoxItem Content="Esperanto" Tag="eo" />
|
||||
<ComboBoxItem Content="Suomi" Tag="fi" />
|
||||
<ComboBoxItem Content="Français" Tag="fr" />
|
||||
<ComboBoxItem Content="Deutsch" Tag="de" />
|
||||
<ComboBoxItem Content="Ελληνικά" Tag="el" />
|
||||
<ComboBoxItem Content="עברית" Tag="he" />
|
||||
<ComboBoxItem Content="हिन्दी" Tag="hi" />
|
||||
<ComboBoxItem Content="Magyar" Tag="hu" />
|
||||
<ComboBoxItem Content="Bahasa Indonesia" Tag="id" />
|
||||
<ComboBoxItem Content="Gaeilge" Tag="ga" />
|
||||
<ComboBoxItem Content="Italiano" Tag="it" />
|
||||
<ComboBoxItem Content="日本語" Tag="ja" />
|
||||
<ComboBoxItem Content="한국어" Tag="ko" />
|
||||
<ComboBoxItem Content="فارسی" Tag="fa" />
|
||||
<ComboBoxItem Content="Polski" Tag="pl" />
|
||||
<ComboBoxItem Content="Português" Tag="pt" />
|
||||
<ComboBoxItem Content="Русский" Tag="ru" />
|
||||
<ComboBoxItem Content="Slovenčina" Tag="sk" />
|
||||
<ComboBoxItem Content="Español" Tag="es" />
|
||||
<ComboBoxItem Content="Svenska" Tag="sv" />
|
||||
<ComboBoxItem Content="Türkçe" Tag="tr" />
|
||||
<ComboBoxItem Content="Українська" Tag="uk" />
|
||||
<ComboBoxItem Content="Tiếng Việt" Tag="vi" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig">
|
||||
<controls:SettingsCard.Description>
|
||||
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageTranslationInfoLink"
|
||||
FontSize="14"
|
||||
TextWrapping="Wrap" />
|
||||
</HyperlinkButton>
|
||||
</controls:SettingsCard.Description>
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="12">
|
||||
<TextBox
|
||||
x:Name="LibreTranslateServerTextBox"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
PlaceholderText="http://localhost:5000"
|
||||
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.LibreTranslateServer, Mode=TwoWay}" />
|
||||
<Button
|
||||
x:Uid="SettingsPageServerTestButton"
|
||||
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
|
||||
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- LX music server -->
|
||||
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsCard>
|
||||
@@ -311,6 +375,28 @@
|
||||
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Apple Music token -->
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="media-user-token (for Apple Muisc)" />
|
||||
<controls:SettingsCard
|
||||
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
|
||||
Foreground="{ThemeResource SystemFillColorCautionBrush}"
|
||||
Header="Use at your own risk">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox
|
||||
MaxWidth="250"
|
||||
PlaceholderText="media-user-token"
|
||||
Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<Button
|
||||
Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -41,5 +41,11 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
// <20><> LyricsSearchProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
|
||||
ViewModel.SelectedMediaSourceProvider?.LyricsSearchProvidersInfo?.Refresh();
|
||||
}
|
||||
|
||||
private void MediaSourceProvidersListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
|
||||
{
|
||||
// <20><> MediaSourceProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
|
||||
ViewModel.AppSettings.MediaSourceProvidersInfo?.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,14 @@
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
<Button
|
||||
Margin="3,0,0,0"
|
||||
HorizontalAlignment="Right"
|
||||
Click="CheckButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -91,5 +92,22 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
Shortcut = [];
|
||||
UpdateTextBox();
|
||||
}
|
||||
|
||||
private void CheckButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut);
|
||||
if (registered)
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||
App.ResourceLoader!.GetString("SettingsPageShortcutRegSuccessInfo"),
|
||||
InfoBarSeverity.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||
App.ResourceLoader!.GetString("SettingsPageShortcutRegFailInfo"),
|
||||
InfoBarSeverity.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,12 +50,6 @@
|
||||
Command="{x:Bind ViewModel.ResetWindowPositionCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTrayUnlock"
|
||||
Command="{x:Bind ViewModel.UnlockWindowCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Visibility="{x:Bind ViewModel.IsLyricsWindowLocked, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<MenuFlyoutSeparator />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTrayRestart"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class BoolNegationToVisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
return Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 BoolToOpacityConverter : 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
LyricsSearchProvider.Netease => "网易云音乐",
|
||||
LyricsSearchProvider.Kugou => "酷狗音乐",
|
||||
LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||
LyricsSearchProvider.AppleMusic => "Apple Music",
|
||||
LyricsSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||
LyricsSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||
LyricsSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||
|
||||
@@ -33,6 +33,10 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
PlayerID.Edge => PlayerName.Edge,
|
||||
PlayerID.BetterLyrics => PlayerName.BetterLyrics,
|
||||
PlayerID.BetterLyricsDebug => PlayerName.BetterLyricsDebug,
|
||||
PlayerID.SaltPlayerForWindows => PlayerName.SaltPlayerForWindows,
|
||||
PlayerID.MoeKoeMusic => PlayerName.MoeKoeMusic,
|
||||
PlayerID.MoeKoeMusicAlternative => PlayerName.MoeKoeMusic,
|
||||
PlayerID.Listen1 => PlayerName.Listen1,
|
||||
_ => provider,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
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
|
||||
{
|
||||
@@ -19,6 +15,7 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
PlayerID.Spotify => PathHelper.SpotifyLogoPath,
|
||||
PlayerID.AppleMusic => PathHelper.AppleMusicLogoPath,
|
||||
PlayerID.AppleMusicAlternative => PathHelper.AppleMusicLogoPath,
|
||||
PlayerID.iTunes => PathHelper.iTunesLogoPath,
|
||||
PlayerID.KugouMusic => PathHelper.KugouMusicLogoPath,
|
||||
PlayerID.NetEaseCloudMusic => PathHelper.NetEaseCloudMusicLogoPath,
|
||||
@@ -33,6 +30,10 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
PlayerID.Edge => PathHelper.EdgeLogoPath,
|
||||
PlayerID.BetterLyrics => PathHelper.LogoPath,
|
||||
PlayerID.BetterLyricsDebug => PathHelper.LogoPath,
|
||||
PlayerID.SaltPlayerForWindows => PathHelper.SaltPlayerForWindowsLogoPath,
|
||||
PlayerID.MoeKoeMusic => PathHelper.MoeKoeMusicLogoPath,
|
||||
PlayerID.MoeKoeMusicAlternative => PathHelper.MoeKoeMusicLogoPath,
|
||||
PlayerID.Listen1 => PathHelper.Listen1LogoPath,
|
||||
_ => PathHelper.UnknownPlayerLogoPath,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
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 MillisecondsToFormattedTimeConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is int milliseconds)
|
||||
{
|
||||
return TimeSpan.FromMilliseconds(milliseconds).ToString(@"mm\:ss\.fff");
|
||||
}
|
||||
else if (value is double doubleMilliseconds)
|
||||
{
|
||||
return TimeSpan.FromMilliseconds(doubleMilliseconds).ToString(@"mm\:ss\.fff");
|
||||
}
|
||||
return value?.ToString() ?? "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 RectToMarginConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is Windows.Foundation.Rect rect)
|
||||
{
|
||||
return new Microsoft.UI.Xaml.Thickness(rect.X, rect.Y, 0, 0);
|
||||
}
|
||||
return new Microsoft.UI.Xaml.Thickness(0);
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ namespace BetterLyrics.WinUI3.Converter
|
||||
TranslationSearchProvider.Netease => "网易云音乐",
|
||||
TranslationSearchProvider.Kugou => "酷狗音乐",
|
||||
TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||
TranslationSearchProvider.AppleMusic => "Apple Music",
|
||||
TranslationSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||
TranslationSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||
TranslationSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum ChineseRomanization
|
||||
{
|
||||
Pinyin,
|
||||
Jyutping,
|
||||
}
|
||||
}
|
||||
@@ -67,5 +67,16 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
_ => ".*",
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsSearchProvider? ToLyricsSearchProvider(this LyricsFormat format)
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
LyricsFormat.Lrc => LyricsSearchProvider.LocalLrcFile,
|
||||
LyricsFormat.Eslrc => LyricsSearchProvider.LocalEslrcFile,
|
||||
LyricsFormat.Ttml => LyricsSearchProvider.LocalTtmlFile,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
LocalLrcFile,
|
||||
LocalEslrcFile,
|
||||
LocalTtmlFile,
|
||||
AppleMusic,
|
||||
}
|
||||
|
||||
public static class LyricsSearchProviderExtensions
|
||||
@@ -28,6 +29,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
LyricsSearchProvider.Netease => PathHelper.NeteaseLyricsCacheDirectory,
|
||||
LyricsSearchProvider.Kugou => PathHelper.KugouLyricsCacheDirectory,
|
||||
LyricsSearchProvider.AmllTtmlDb => PathHelper.AmllTtmlDbLyricsCacheDirectory,
|
||||
LyricsSearchProvider.AppleMusic => PathHelper.AppleMusicCacheDirectory,
|
||||
_ => throw new System.ArgumentOutOfRangeException(nameof(provider)),
|
||||
};
|
||||
}
|
||||
@@ -41,6 +43,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
LyricsSearchProvider.Kugou => LyricsFormat.Krc,
|
||||
LyricsSearchProvider.Netease => LyricsFormat.Lrc,
|
||||
LyricsSearchProvider.AmllTtmlDb => LyricsFormat.Ttml,
|
||||
LyricsSearchProvider.AppleMusic => LyricsFormat.Ttml,
|
||||
LyricsSearchProvider.LocalLrcFile => LyricsFormat.Lrc,
|
||||
LyricsSearchProvider.LocalEslrcFile => LyricsFormat.Eslrc,
|
||||
LyricsSearchProvider.LocalTtmlFile => LyricsFormat.Ttml,
|
||||
@@ -71,6 +74,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
LyricsSearchProvider.Kugou => TranslationSearchProvider.Kugou,
|
||||
LyricsSearchProvider.Netease => TranslationSearchProvider.Netease,
|
||||
LyricsSearchProvider.AmllTtmlDb => TranslationSearchProvider.AmllTtmlDb,
|
||||
LyricsSearchProvider.AppleMusic => TranslationSearchProvider.AppleMusic,
|
||||
LyricsSearchProvider.LocalMusicFile => TranslationSearchProvider.LocalMusicFile,
|
||||
LyricsSearchProvider.LocalLrcFile => TranslationSearchProvider.LocalLrcFile,
|
||||
LyricsSearchProvider.LocalEslrcFile => TranslationSearchProvider.LocalEslrcFile,
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum LyricsWindowMode
|
||||
{
|
||||
StandardMode,
|
||||
DockMode,
|
||||
DesktopMode,
|
||||
PictureInPictureMode,
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum ShortcutID
|
||||
{
|
||||
DesktopLock,
|
||||
DesktopToggle,
|
||||
DockToggle,
|
||||
PictureInPictureToggle,
|
||||
LyricsWindowShowOrHide,
|
||||
Borderless,
|
||||
ClickThrough,
|
||||
LyricsWindowSwitch,
|
||||
PlayOrPauseSong,
|
||||
NextSong,
|
||||
PreviousSong,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public enum TitleBarArea
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
Whole,
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
Netease,
|
||||
LrcLib,
|
||||
AmllTtmlDb,
|
||||
AppleMusic,
|
||||
LocalMusicFile,
|
||||
LocalLrcFile,
|
||||
LocalEslrcFile,
|
||||
|
||||
@@ -8,11 +8,11 @@ using Windows.UI;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Events
|
||||
{
|
||||
public class AlbumArtChangedEventArgs(byte[]? bytes, SoftwareBitmap? albumArtSwBitmap, Color? albumArtLightAccentColor, Color? albumArtDarkAccentColor) : EventArgs
|
||||
public class AlbumArtChangedEventArgs(byte[]? bytes, SoftwareBitmap? albumArtSwBitmap, List<Color> albumArtLightAccentColors, List<Color> albumArtDarkAccentColors) : EventArgs
|
||||
{
|
||||
public byte[]? Bytes { get; set; } = bytes;
|
||||
public SoftwareBitmap? AlbumArtSwBitmap { get; set; } = albumArtSwBitmap;
|
||||
public Color? AlbumArtLightAccentColor { get; set; } = albumArtLightAccentColor;
|
||||
public Color? AlbumArtDarkAccentColor { get; set; } = albumArtDarkAccentColor;
|
||||
public List<Color> AlbumArtLightAccentColors { get; set; } = albumArtLightAccentColors;
|
||||
public List<Color> AlbumArtDarkAccentColors { get; set; } = albumArtDarkAccentColors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Events
|
||||
{
|
||||
public class LyricsChangedEventArgs(LyricsData? lyricsData) : EventArgs
|
||||
{
|
||||
public LyricsData? LyricsData { get; } = lyricsData;
|
||||
}
|
||||
}
|
||||
126
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppleMusic.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using BetterLyrics.WinUI3.Constants;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class AppleMusic
|
||||
{
|
||||
private readonly HttpClient _client;
|
||||
private string _accessToken = "";
|
||||
private string _storefront = "";
|
||||
private string _language = "";
|
||||
|
||||
public AppleMusic()
|
||||
{
|
||||
_client = new HttpClient();
|
||||
_client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36");
|
||||
_client.DefaultRequestHeaders.Add("Accept", "application/json");
|
||||
_client.DefaultRequestHeaders.Add("Origin", "https://music.apple.com");
|
||||
_client.DefaultRequestHeaders.Add("Referer", "https://music.apple.com/");
|
||||
}
|
||||
|
||||
public async Task<bool> InitAsync()
|
||||
{
|
||||
await GetAccessTokenAsync();
|
||||
await SetMediaUserTokenAsync();
|
||||
return
|
||||
!string.IsNullOrEmpty(_accessToken) &&
|
||||
!string.IsNullOrEmpty(PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey));
|
||||
}
|
||||
|
||||
private async Task GetAccessTokenAsync()
|
||||
{
|
||||
var resp = await _client.GetStringAsync("https://music.apple.com/us/browse");
|
||||
var jsMatch = Regex.Match(resp, "(?<=index)(.*?)(?=\\.js\")");
|
||||
if (!jsMatch.Success) throw new Exception("Failed to find index.js");
|
||||
var jsUrl = $"https://music.apple.com/assets/index{jsMatch.Value}.js";
|
||||
var jsResp = await _client.GetStringAsync(jsUrl);
|
||||
var tokenMatch = Regex.Match(jsResp, "(?=eyJh)(.*?)(?=\")");
|
||||
if (!tokenMatch.Success) throw new Exception("Failed to find access token");
|
||||
_accessToken = tokenMatch.Value;
|
||||
_client.DefaultRequestHeaders.Remove("Authorization");
|
||||
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_accessToken}");
|
||||
}
|
||||
|
||||
private async Task SetMediaUserTokenAsync()
|
||||
{
|
||||
_client.DefaultRequestHeaders.Remove("media-user-token");
|
||||
_client.DefaultRequestHeaders.Add("media-user-token",
|
||||
PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey));
|
||||
var resp = await _client.GetStringAsync("https://amp-api.music.apple.com/v1/me/storefront");
|
||||
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||
_storefront = json.GetProperty("data")[0].GetProperty("id").ToString();
|
||||
_language = json.GetProperty("data")[0].GetProperty("attributes").GetProperty("defaultLanguageTag").ToString();
|
||||
_client.DefaultRequestHeaders.Remove("Accept-Language");
|
||||
_client.DefaultRequestHeaders.Add("Accept-Language", $"{_language},en;q=0.9");
|
||||
}
|
||||
|
||||
public async Task<string?> GetLyricsAsync(string title, string artist)
|
||||
{
|
||||
string id = await SearchSongInfoAsync(artist, title);
|
||||
|
||||
var apiUrl = $"https://amp-api.music.apple.com/v1/catalog/{_storefront}/songs/{id}";
|
||||
var url = apiUrl + $"?include[songs]=lyrics,syllable-lyrics&l={_language}";
|
||||
var resp = await _client.GetStringAsync(url);
|
||||
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||
var data = json.GetProperty("data");
|
||||
if (data.GetArrayLength() == 0) return string.Empty;
|
||||
var song = data[0];
|
||||
|
||||
if (!song.TryGetProperty("relationships", out var relationships))
|
||||
return string.Empty;
|
||||
|
||||
if (relationships.TryGetProperty("syllable-lyrics", out var syllableLyrics) &&
|
||||
syllableLyrics.GetProperty("data").GetArrayLength() > 0)
|
||||
{
|
||||
var syllableLyric = syllableLyrics.GetProperty("data")[0];
|
||||
if (syllableLyric.TryGetProperty("attributes", out var attributes) &&
|
||||
attributes.TryGetProperty("ttml", out var ttml))
|
||||
{
|
||||
string? raw = ttml.GetString();
|
||||
if (raw != null && raw.Contains("begin=") && raw.Contains("end="))
|
||||
{
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if (relationships.TryGetProperty("lyrics", out var lyrics) &&
|
||||
// lyrics.GetProperty("data").GetArrayLength() > 0)
|
||||
//{
|
||||
// var lyric = lyrics.GetProperty("data")[0];
|
||||
// if (lyric.TryGetProperty("attributes", out var attributes) &&
|
||||
// attributes.TryGetProperty("ttml", out var ttml))
|
||||
// {
|
||||
// return ttml.GetString();
|
||||
// }
|
||||
//}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task<string> SearchSongInfoAsync(string artist, string title)
|
||||
{
|
||||
var query = $"{artist} {title}";
|
||||
var apiUrl = $"https://amp-api.music.apple.com/v1/catalog/{_storefront}/search";
|
||||
var url = apiUrl + $"?term={WebUtility.UrlEncode(query)}&types=songs&limit=1&l={_language}";
|
||||
var resp = await _client.GetStringAsync(url);
|
||||
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||
var results = json.GetProperty("results");
|
||||
if (results.TryGetProperty("songs", out var songs) && songs.GetProperty("data").GetArrayLength() > 0)
|
||||
{
|
||||
var song = songs.GetProperty("data")[0];
|
||||
return song.GetProperty("id").ToString();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,9 +74,17 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
using var ds = list.CreateDrawingSession();
|
||||
if (strokeWidth > 0)
|
||||
{
|
||||
if (lyricsLine.TextGeometry == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
ds.DrawGeometry(lyricsLine.TextGeometry, lyricsLine.Position, strokeColor, strokeWidth); // 描边
|
||||
}
|
||||
ds.FillGeometry(lyricsLine.TextGeometry, lyricsLine.Position, fontColor); // 填充
|
||||
if (lyricsLine.CanvasTextLayout == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
ds.DrawTextLayout(lyricsLine.CanvasTextLayout, lyricsLine.Position, fontColor); // 绘制文本(填充)
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -262,17 +270,50 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return mask;
|
||||
}
|
||||
|
||||
public static CanvasCommandList CreateTranslationHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
|
||||
{
|
||||
var mask = new CanvasCommandList(control);
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
if (lyricsLine.CanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(lyricsLine.OriginalText.Length, lyricsLine.DisplayedText.Length - lyricsLine.OriginalText.Length);
|
||||
if (regions.Length > 0)
|
||||
{
|
||||
for (int j = 0; j < regions.Length; j++)
|
||||
{
|
||||
var region = regions[j];
|
||||
var rect = new Rect(
|
||||
region.LayoutBounds.X,
|
||||
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
region.LayoutBounds.Width,
|
||||
region.LayoutBounds.Height
|
||||
);
|
||||
ds.FillRectangle(rect, Colors.White);
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建高亮效果层
|
||||
/// </summary>
|
||||
/// <param name="control"></param>
|
||||
/// <param name="lineRenderingType"></param>
|
||||
public static AlphaMaskEffect CreateForegroundHighlightEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask)
|
||||
public static OpacityEffect CreateForegroundHighlightEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
|
||||
{
|
||||
return new AlphaMaskEffect
|
||||
return new OpacityEffect
|
||||
{
|
||||
Source = foregroundFontEffect,
|
||||
AlphaMask = mask,
|
||||
Source = new AlphaMaskEffect
|
||||
{
|
||||
Source = foregroundFontEffect,
|
||||
AlphaMask = mask,
|
||||
},
|
||||
Opacity = (float)opacity,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -291,6 +332,19 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
};
|
||||
}
|
||||
|
||||
public static OpacityEffect CreateForegroundTranslationEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
|
||||
{
|
||||
return new OpacityEffect
|
||||
{
|
||||
Source = new AlphaMaskEffect
|
||||
{
|
||||
Source = foregroundFontEffect,
|
||||
AlphaMask = mask,
|
||||
},
|
||||
Opacity = (float)opacity,
|
||||
};
|
||||
}
|
||||
|
||||
public static IGraphicsEffectSource GetAlphaMask(ICanvasAnimatedControl control, IGraphicsEffectSource charMask, IGraphicsEffectSource lineStartToCharMask, IGraphicsEffectSource lineMask, LineRenderingType lineRenderingType)
|
||||
{
|
||||
var result = lineRenderingType switch
|
||||
|
||||
@@ -7,6 +7,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Numerics;
|
||||
using Vanara.PInvoke;
|
||||
using Windows.UI;
|
||||
|
||||
@@ -94,6 +95,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return Color.FromArgb(alpha, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public static Color WithOpacity(this Color color, float opacity)
|
||||
{
|
||||
return Color.FromArgb((byte)(opacity * 255), color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public static Color WithBrightness(this Color color, double brightness)
|
||||
{
|
||||
// 确保亮度因子在合理范围内
|
||||
@@ -106,6 +112,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return CommunityToolkit.WinUI.Helpers.ColorHelper.FromHsl(h, s, brightness);
|
||||
}
|
||||
|
||||
public static Vector3 ToVector3RGB(this Color color)
|
||||
{
|
||||
return new Vector3((float)color.R / 0xff, (float)color.G / 0xff, (float)color.B / 0xff);
|
||||
}
|
||||
|
||||
public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, string monitorDeviceName, WindowPixelSampleMode mode)
|
||||
{
|
||||
if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent;
|
||||
@@ -116,15 +127,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
case WindowPixelSampleMode.BelowWindow:
|
||||
{
|
||||
int sampleHeight = 1;
|
||||
int sampleY = myRect.Bottom + 1;
|
||||
return GetAverageColorFromScreenRegion(myRect.Left, sampleY, screenWidth, sampleHeight);
|
||||
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Bottom + 2, screenWidth, 1);
|
||||
}
|
||||
case WindowPixelSampleMode.AboveWindow:
|
||||
{
|
||||
int sampleHeight = 1;
|
||||
int sampleY = myRect.Top - 1;
|
||||
return GetAverageColorFromScreenRegion(myRect.Left, sampleY, screenWidth, sampleHeight);
|
||||
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Top - 3, screenWidth, 1);
|
||||
}
|
||||
case WindowPixelSampleMode.WindowArea:
|
||||
{
|
||||
@@ -246,6 +253,5 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
if (count == 0) return System.Drawing.Color.Transparent;
|
||||
return System.Drawing.Color.FromArgb((int)(r / count), (int)(g / count), (int)(b / count));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vanara.PInvoke;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class DesktopModeHelper
|
||||
{
|
||||
private static readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
|
||||
private static readonly Dictionary<IntPtr, bool> _originalTopmostStates = [];
|
||||
private static readonly Dictionary<IntPtr, (double X, double Y, double Width, double Height)> _originalWindowBounds = [];
|
||||
private static readonly Dictionary<IntPtr, WindowStyle> _originalWindowStyles = [];
|
||||
|
||||
private delegate nint WndProcDelegate(nint hWnd, uint msg, nint wParam, nint lParam);
|
||||
|
||||
public static void Disable(Window window)
|
||||
{
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
// <20>ָ<EFBFBD>TopMost״̬
|
||||
if (_originalTopmostStates.TryGetValue(hwnd, out var wasTopMost))
|
||||
{
|
||||
window.SetIsAlwaysOnTop(wasTopMost);
|
||||
_originalTopmostStates.Remove(hwnd);
|
||||
}
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>úʹ<C3BA>С
|
||||
if (_originalWindowBounds.TryGetValue(hwnd, out var bounds))
|
||||
{
|
||||
window.AppWindow.MoveAndResize(
|
||||
new Windows.Graphics.RectInt32(
|
||||
(int)bounds.X,
|
||||
(int)bounds.Y,
|
||||
(int)bounds.Width,
|
||||
(int)bounds.Height
|
||||
)
|
||||
);
|
||||
_originalWindowBounds.Remove(hwnd);
|
||||
}
|
||||
|
||||
window.SetIsShownInSwitchers(true);
|
||||
}
|
||||
|
||||
public static void Enable(Window window)
|
||||
{
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
// <20><>¼ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>λ<EFBFBD>úʹ<C3BA>С
|
||||
if (!_originalWindowBounds.ContainsKey(hwnd))
|
||||
{
|
||||
_originalWindowBounds[hwnd] = (
|
||||
window.AppWindow.Position.X,
|
||||
window.AppWindow.Position.Y,
|
||||
window.AppWindow.Size.Width,
|
||||
window.AppWindow.Size.Height
|
||||
);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>ô<EFBFBD><C3B4>ڴ<EFBFBD>С<EFBFBD><D0A1>λ<EFBFBD><CEBB>
|
||||
window.AppWindow.MoveAndResize(_settingsService.AppSettings.DesktopModeSettings.WindowBounds.ToRectInt32());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ԭTopMost״̬
|
||||
if (!_originalTopmostStates.ContainsKey(hwnd))
|
||||
_originalTopmostStates[hwnd] = window.GetIsAlwaysOnTop();
|
||||
|
||||
// <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD>ö<EFBFBD>
|
||||
window.SetIsAlwaysOnTop(true);
|
||||
|
||||
window.SetIsShownInSwitchers(false);
|
||||
}
|
||||
|
||||
public static void SetClickThrough(Window window, bool enable)
|
||||
{
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
int exStyle = User32.GetWindowLong(hwnd, User32.WindowLongFlags.GWL_EXSTYLE);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD>ʽ
|
||||
if (!_originalWindowStyles.ContainsKey(hwnd))
|
||||
_originalWindowStyles[hwnd] = window.GetWindowStyle();
|
||||
|
||||
window.ToggleWindowStyle(true, WindowStyle.Popup | WindowStyle.Visible);
|
||||
User32.SetWindowLong(hwnd, User32.WindowLongFlags.GWL_EXSTYLE, exStyle | (int)User32.WindowStylesEx.WS_EX_TRANSPARENT | (int)User32.WindowStylesEx.WS_EX_LAYERED);
|
||||
}
|
||||
else
|
||||
{
|
||||
User32.SetWindowLong(hwnd, User32.WindowLongFlags.GWL_EXSTYLE, exStyle & ~(int)User32.WindowStylesEx.WS_EX_TRANSPARENT);
|
||||
// <20>ָ<EFBFBD><D6B8><EFBFBD>ʽ
|
||||
if (_originalWindowStyles.TryGetValue(hwnd, out var style))
|
||||
{
|
||||
window.SetWindowStyle(style);
|
||||
_originalWindowStyles.Remove(hwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Vanara.PInvoke;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class DockModeHelper
|
||||
{
|
||||
private static readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
|
||||
private static readonly HashSet<IntPtr> _registered = [];
|
||||
private static readonly Dictionary<IntPtr, RECT> _originalPositions = [];
|
||||
private static readonly Dictionary<IntPtr, WindowStyle> _originalWindowStyle = [];
|
||||
|
||||
public static bool IsEnabled(IntPtr hwnd)
|
||||
{
|
||||
return _registered.Contains(hwnd);
|
||||
}
|
||||
|
||||
public static void Disable(Window window)
|
||||
{
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (!_registered.Contains(hwnd)) return;
|
||||
|
||||
window.SetIsShownInSwitchers(true);
|
||||
window.ExtendsContentIntoTitleBar = true;
|
||||
window.SetIsAlwaysOnTop(false);
|
||||
|
||||
UnregisterAppBar(hwnd);
|
||||
|
||||
window.SetWindowStyle(_originalWindowStyle[hwnd]);
|
||||
_originalWindowStyle.Remove(hwnd);
|
||||
|
||||
window.ExtendsContentIntoTitleBar = true;
|
||||
|
||||
if (_originalPositions.TryGetValue(hwnd, out var rect))
|
||||
{
|
||||
User32.SetWindowPos(
|
||||
hwnd,
|
||||
IntPtr.Zero,
|
||||
rect.Left,
|
||||
rect.Top,
|
||||
rect.Right - rect.Left,
|
||||
rect.Bottom - rect.Top,
|
||||
User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
||||
);
|
||||
_originalPositions.Remove(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Enable(Window window, string monitorDeviceName, int appBarHeight, DockPlacement dockPlacement)
|
||||
{
|
||||
window.SetIsShownInSwitchers(false);
|
||||
window.SetIsAlwaysOnTop(true);
|
||||
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (!_originalWindowStyle.ContainsKey(hwnd))
|
||||
{
|
||||
_originalWindowStyle[hwnd] = window.GetWindowStyle();
|
||||
}
|
||||
|
||||
if (!_originalPositions.ContainsKey(hwnd))
|
||||
{
|
||||
if (User32.GetWindowRect(hwnd, out var rect))
|
||||
{
|
||||
_originalPositions[hwnd] = rect;
|
||||
}
|
||||
}
|
||||
|
||||
RegisterAppBar(hwnd, monitorDeviceName, appBarHeight, dockPlacement);
|
||||
|
||||
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(_settingsService.AppSettings.DockModeSettings.DockMonitorDeviceName);
|
||||
|
||||
int screenWidth = monitorInfo.rcMonitor.Width;
|
||||
int screenHeight = monitorInfo.rcMonitor.Bottom - monitorInfo.rcMonitor.Top;
|
||||
int y = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - appBarHeight;
|
||||
|
||||
User32.SetWindowPos(
|
||||
hwnd,
|
||||
IntPtr.Zero,
|
||||
monitorInfo.rcMonitor.Left,
|
||||
y,
|
||||
screenWidth,
|
||||
appBarHeight,
|
||||
User32.SetWindowPosFlags.SWP_HIDEWINDOW
|
||||
);
|
||||
window.ExtendsContentIntoTitleBar = false;
|
||||
window.ToggleWindowStyle(true, WindowStyle.Popup);
|
||||
window.Show();
|
||||
}
|
||||
|
||||
private static void RegisterAppBar(IntPtr hwnd, string monitorDeviceName, int height, DockPlacement dockPlacement)
|
||||
{
|
||||
if (_registered.Contains(hwnd)) return;
|
||||
|
||||
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(monitorDeviceName);
|
||||
|
||||
int top = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - height;
|
||||
int bottom = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top + height : monitorInfo.rcMonitor.Bottom;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd,
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = monitorInfo.rcMonitor.Left,
|
||||
Top = top,
|
||||
Right = monitorInfo.rcMonitor.Right,
|
||||
Bottom = bottom,
|
||||
},
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_NEW, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||
|
||||
_registered.Add(hwnd);
|
||||
}
|
||||
|
||||
private static void UnregisterAppBar(IntPtr hwnd)
|
||||
{
|
||||
if (!_registered.Contains(hwnd))
|
||||
return;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_REMOVE, ref abd);
|
||||
|
||||
_registered.Remove(hwnd);
|
||||
}
|
||||
|
||||
public static void UpdateAppBarHeight(IntPtr hwnd, string monitorDeviceName, int newHeight, DockPlacement dockPlacement)
|
||||
{
|
||||
App.DispatcherQueueTimer?.Debounce(() =>
|
||||
{
|
||||
if (!_registered.Contains(hwnd))
|
||||
return;
|
||||
|
||||
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(monitorDeviceName);
|
||||
|
||||
int screenWidth = monitorInfo.rcMonitor.Width;
|
||||
int top = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - newHeight;
|
||||
int bottom = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top + newHeight : monitorInfo.rcMonitor.Bottom;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd,
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = monitorInfo.rcMonitor.Left,
|
||||
Top = top,
|
||||
Right = monitorInfo.rcMonitor.Right,
|
||||
Bottom = bottom,
|
||||
},
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||
|
||||
// 同步窗口实际高度和位置
|
||||
int y = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - newHeight;
|
||||
int repeatCount = 2;
|
||||
while (repeatCount > 0)
|
||||
{
|
||||
repeatCount--;
|
||||
User32.SetWindowPos(
|
||||
hwnd,
|
||||
IntPtr.Zero,
|
||||
monitorInfo.rcMonitor.Left,
|
||||
y,
|
||||
screenWidth,
|
||||
newHeight,
|
||||
newHeight == 0 ? User32.SetWindowPosFlags.SWP_HIDEWINDOW : User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
||||
);
|
||||
}
|
||||
}, TimeSpan.FromMilliseconds(100));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,6 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class FontHelper
|
||||
{
|
||||
public static string[] SystemFontFamilies => CanvasTextFormat.GetSystemFontFamilies();
|
||||
public static string[] SystemFontFamilies => CanvasTextFormat.GetSystemFontFamilies().Order().ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
private readonly List<User32.HWINEVENTHOOK> _hooks = new();
|
||||
private HWND _currentForeground = HWND.NULL;
|
||||
private readonly IntPtr _selfHwnd;
|
||||
private readonly ThrottleHelper _winEventProcThrottle = new(TimeSpan.FromSeconds(1));
|
||||
|
||||
public delegate void WindowChangedHandler(HWND hwnd);
|
||||
private readonly WindowChangedHandler _onWindowChanged;
|
||||
@@ -73,7 +72,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
_hooks.Clear();
|
||||
|
||||
_timer.Stop();
|
||||
//_timer.Stop();
|
||||
}
|
||||
|
||||
private void Timer_Tick(object? sender, object e)
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class GlobalHotKeyHelper
|
||||
{
|
||||
private static Dictionary<int, Action> _hotKeyActions = [];
|
||||
private static Dictionary<int, Action> _actions = [];
|
||||
private static Dictionary<int, List<string>> _keys = [];
|
||||
|
||||
/// <summary>
|
||||
/// Register a global hotkey for a specific window type
|
||||
@@ -22,7 +23,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
/// <param name="id"></param>
|
||||
/// <param name="keys"></param>
|
||||
/// <param name="action"></param>
|
||||
public static void RegisterHotKey<T>(ShortcutID id, List<string> keys, Action action)
|
||||
private static void RegisterHotKey<T>(ShortcutID id, List<string> keys, Action action)
|
||||
{
|
||||
if (keys.Count == 0) return;
|
||||
|
||||
@@ -55,18 +56,23 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
key = (VirtualKey)Enum.Parse(typeof(VirtualKey), item, true);
|
||||
}
|
||||
}
|
||||
User32.RegisterHotKey(hwnd, (int)id, modifiers, (uint)key);
|
||||
_hotKeyActions[(int)id] = action;
|
||||
bool success = User32.RegisterHotKey(hwnd, (int)id, modifiers, (uint)key);
|
||||
if (success)
|
||||
{
|
||||
_actions[(int)id] = action;
|
||||
_keys[(int)id] = keys;
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnregisterHotKey<T>(ShortcutID id)
|
||||
private static void UnregisterHotKey<T>(ShortcutID id)
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<T>();
|
||||
if (window == null) return;
|
||||
|
||||
HWND hwnd = WindowNative.GetWindowHandle(window);
|
||||
User32.UnregisterHotKey(hwnd, (int)id);
|
||||
_hotKeyActions.Remove((int)id);
|
||||
_actions.Remove((int)id);
|
||||
_keys.Remove((int)id);
|
||||
}
|
||||
|
||||
public static void UpdateHotKey<T>(ShortcutID id, List<string> keys, Action action)
|
||||
@@ -75,6 +81,16 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
RegisterHotKey<T>(id, keys, action);
|
||||
}
|
||||
|
||||
public static bool IsHotKeyRegistered(ShortcutID id)
|
||||
{
|
||||
return _actions.ContainsKey((int)id);
|
||||
}
|
||||
|
||||
public static bool IsHotKeyRegistered(List<string> keys)
|
||||
{
|
||||
return _keys.ContainsValue(keys);
|
||||
}
|
||||
|
||||
public static bool TryInvokeAction(ShortcutID id)
|
||||
{
|
||||
return TryInvokeAction((int)id);
|
||||
@@ -82,7 +98,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
public static bool TryInvokeAction(int id)
|
||||
{
|
||||
if (_hotKeyActions.TryGetValue(id, out var action))
|
||||
if (_actions.TryGetValue(id, out var action))
|
||||
{
|
||||
action?.Invoke();
|
||||
return true;
|
||||
|
||||
@@ -14,6 +14,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
@@ -177,7 +178,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
square.Mutate(ctx => ctx.DrawImage(image, new Point(offsetX, offsetY), 1f));
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
square.Save(ms, new JpegEncoder());
|
||||
square.Save(ms, new PngEncoder());
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
@@ -219,5 +220,68 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
return pixelData;
|
||||
}
|
||||
|
||||
public static async Task<byte[]> DownloadImageAsByteArrayAsync(string url)
|
||||
{
|
||||
using var httpClient = new HttpClient();
|
||||
return await httpClient.GetByteArrayAsync(url);
|
||||
}
|
||||
|
||||
public static byte[]? DataUrlToByteArray(string dataUrl)
|
||||
{
|
||||
const string base64Marker = ";base64,";
|
||||
int base64Index = dataUrl.IndexOf(base64Marker, StringComparison.OrdinalIgnoreCase);
|
||||
if (base64Index >= 0)
|
||||
{
|
||||
string base64Data = dataUrl.Substring(base64Index + base64Marker.Length);
|
||||
return Convert.FromBase64String(base64Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非 base64,直接取逗号后内容并解码
|
||||
int commaIndex = dataUrl.IndexOf(',');
|
||||
if (commaIndex >= 0)
|
||||
{
|
||||
string rawData = dataUrl.Substring(commaIndex + 1);
|
||||
return System.Text.Encoding.UTF8.GetBytes(Uri.UnescapeDataString(rawData));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<byte[]?> GetImageBytesFromUrlAsync(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (url.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// data URL,直接解析
|
||||
return DataUrlToByteArray(url);
|
||||
}
|
||||
else if (Uri.TryCreate(url, UriKind.Absolute, out var uri) &&
|
||||
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
|
||||
{
|
||||
// 普通网络图片,下载
|
||||
return await DownloadImageAsByteArrayAsync(url);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 其他类型暂不支持
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using NTextCat;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using TinyPinyin;
|
||||
using Windows.Globalization;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services
|
||||
@@ -18,44 +11,83 @@ namespace BetterLyrics.WinUI3.Services
|
||||
private static readonly RankedLanguageIdentifierFactory _factory = new();
|
||||
private static readonly RankedLanguageIdentifier _identifier;
|
||||
|
||||
public static List<Models.LanguageInfo> SupportedTargetLanguages =>
|
||||
public static List<Models.LanguageInfo> SupportedTargetLanguages { get; set; } =
|
||||
[
|
||||
new Models.LanguageInfo("ar", "العربية"),
|
||||
new Models.LanguageInfo("az", "Azərbaycan dili"),
|
||||
new Models.LanguageInfo("zh-Hans", "简体中文"),
|
||||
new Models.LanguageInfo("zh-Hant", "繁體中文"),
|
||||
|
||||
new Models.LanguageInfo("bg", "Български"),
|
||||
new Models.LanguageInfo("bn", "বাংলা"),
|
||||
|
||||
new Models.LanguageInfo("ca", "Català"),
|
||||
new Models.LanguageInfo("cs", "Čeština"),
|
||||
|
||||
new Models.LanguageInfo("da", "Dansk"),
|
||||
new Models.LanguageInfo("nl", "Nederlands"),
|
||||
new Models.LanguageInfo("de", "Deutsch"),
|
||||
|
||||
new Models.LanguageInfo("el", "Ελληνικά"),
|
||||
new Models.LanguageInfo("en", "English"),
|
||||
new Models.LanguageInfo("eo", "Esperanto"),
|
||||
new Models.LanguageInfo("es", "Español"),
|
||||
new Models.LanguageInfo("et", "Eesti"),
|
||||
new Models.LanguageInfo("eu", "Euskara"),
|
||||
|
||||
new Models.LanguageInfo("fa", "فارسی"),
|
||||
new Models.LanguageInfo("fi", "Suomi"),
|
||||
new Models.LanguageInfo("fr", "Français"),
|
||||
new Models.LanguageInfo("de", "Deutsch"),
|
||||
new Models.LanguageInfo("el", "Ελληνικά"),
|
||||
|
||||
new Models.LanguageInfo("ga", "Gaeilge"),
|
||||
new Models.LanguageInfo("gl", "Galego"),
|
||||
|
||||
new Models.LanguageInfo("he", "עברית"),
|
||||
new Models.LanguageInfo("hi", "हिन्दी"),
|
||||
new Models.LanguageInfo("hu", "Magyar"),
|
||||
|
||||
new Models.LanguageInfo("id", "Bahasa Indonesia"),
|
||||
new Models.LanguageInfo("ga", "Gaeilge"),
|
||||
new Models.LanguageInfo("it", "Italiano"),
|
||||
|
||||
new Models.LanguageInfo("ja", "日本語"),
|
||||
|
||||
new Models.LanguageInfo("ko", "한국어"),
|
||||
new Models.LanguageInfo("fa", "فارسی"),
|
||||
new Models.LanguageInfo("ky", "Кыргызча"),
|
||||
|
||||
new Models.LanguageInfo("lt", "Lietuvių"),
|
||||
new Models.LanguageInfo("lv", "Latviešu"),
|
||||
|
||||
new Models.LanguageInfo("ms", "Bahasa Melayu"),
|
||||
|
||||
new Models.LanguageInfo("nb", "Norsk bokmål"),
|
||||
new Models.LanguageInfo("nl", "Nederlands"),
|
||||
|
||||
new Models.LanguageInfo("pt-BR", "Português (Brasil)"),
|
||||
new Models.LanguageInfo("pl", "Polski"),
|
||||
new Models.LanguageInfo("pt", "Português"),
|
||||
|
||||
new Models.LanguageInfo("ro", "Română"),
|
||||
new Models.LanguageInfo("ru", "Русский"),
|
||||
|
||||
new Models.LanguageInfo("sk", "Slovenčina"),
|
||||
new Models.LanguageInfo("es", "Español"),
|
||||
new Models.LanguageInfo("sl", "Slovenščina"),
|
||||
new Models.LanguageInfo("sq", "Shqip"),
|
||||
new Models.LanguageInfo("sr", "Српски"),
|
||||
new Models.LanguageInfo("sv", "Svenska"),
|
||||
|
||||
new Models.LanguageInfo("th", "ไทย"),
|
||||
new Models.LanguageInfo("tl", "Filipino"),
|
||||
new Models.LanguageInfo("tr", "Türkçe"),
|
||||
|
||||
new Models.LanguageInfo("uk", "Українська"),
|
||||
new Models.LanguageInfo("ur", "اردو"),
|
||||
|
||||
new Models.LanguageInfo("vi", "Tiếng Việt"),
|
||||
|
||||
new Models.LanguageInfo("zh", "中文"),
|
||||
];
|
||||
|
||||
static LanguageHelper()
|
||||
{
|
||||
_identifier = _factory.Load(PathHelper.LanguageProfilePath);
|
||||
RomajiConverter.Core.Helpers.RomajiHelper.Init();
|
||||
}
|
||||
|
||||
public static string? DetectLanguageCode(string? text)
|
||||
@@ -67,9 +99,8 @@ namespace BetterLyrics.WinUI3.Services
|
||||
code = code switch
|
||||
{
|
||||
"simple" => "en",
|
||||
"zh_classical" => "zh-Hant",
|
||||
"zh_yue" => "zh-Hant",
|
||||
"zh" => text == ChineseConverter.ConvertToSimplifiedChinese(text) ? "zh-Hans" : "zh-Hant",
|
||||
"zh_classical" => "zh",
|
||||
"zh_yue" => "zh",
|
||||
_ => code
|
||||
};
|
||||
return code;
|
||||
@@ -84,26 +115,17 @@ namespace BetterLyrics.WinUI3.Services
|
||||
};
|
||||
}
|
||||
|
||||
public static string ConvertToCountryCode(string? languageCode)
|
||||
public static string GetDefaultTargetLanguageCode()
|
||||
{
|
||||
if (languageCode == null) return "us";
|
||||
|
||||
return languageCode switch
|
||||
var found = SupportedTargetLanguages.Find(x => ApplicationLanguages.Languages.FirstOrDefault()?.Contains(x.Code) == true);
|
||||
if (found == null)
|
||||
{
|
||||
"zh" => "cn",
|
||||
"zh-Hans" => "cn",
|
||||
"zh-Hant" => "tw",
|
||||
"ja" => "jp",
|
||||
"ko" => "kr",
|
||||
_ => "us"
|
||||
};
|
||||
}
|
||||
|
||||
public static int GetDefaultTargetLanguageIndex()
|
||||
{
|
||||
int found = SupportedTargetLanguages.FindIndex(x => ApplicationLanguages.Languages.FirstOrDefault()?.Contains(x.Code) == true);
|
||||
if (found == -1) found = 7; // 默认使用英语
|
||||
return found;
|
||||
return "en";
|
||||
}
|
||||
else
|
||||
{
|
||||
return found.Code;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetOrderChar(string text)
|
||||
@@ -113,12 +135,17 @@ namespace BetterLyrics.WinUI3.Services
|
||||
if (char.IsLetter(c) && c < 128)
|
||||
return char.ToUpper(c).ToString();
|
||||
|
||||
if (PinyinHelper.IsChinese(c))
|
||||
if (Pinyin.Pinyin.Instance.IsHanzi(c.ToString()))
|
||||
{
|
||||
return PinyinHelper.GetPinyinInitials($"{c}");
|
||||
return Pinyin.Pinyin.Instance.HanziToPinyin(c.ToString(), Pinyin.ManTone.Style.NORMAL).ToStr().ToUpper().FirstOrDefault().ToString();
|
||||
}
|
||||
|
||||
return "#";
|
||||
}
|
||||
|
||||
public static string ToRomaji(string text)
|
||||
{
|
||||
return string.Join(" ", RomajiConverter.Core.Helpers.RomajiHelper.SentenceToRomaji(text).Select(x => x.Romaji));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class BackgroundTaskRunner
|
||||
public class LatestOnlyTaskRunner
|
||||
{
|
||||
private CancellationTokenSource? _cts;
|
||||
|
||||
public void Run(Func<CancellationToken, Task> taskFactory)
|
||||
public async Task RunAsync(Func<CancellationToken, Task> taskFactory)
|
||||
{
|
||||
_cts?.Cancel();
|
||||
_cts?.Dispose();
|
||||
@@ -19,19 +19,16 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
_cts = new CancellationTokenSource();
|
||||
var token = _cts.Token;
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
await taskFactory(token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}, token);
|
||||
await taskFactory(token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,12 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using Lyricify.Lyrics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using Windows.Globalization.Fonts;
|
||||
using LyricsData = BetterLyrics.WinUI3.Models.LyricsData;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
@@ -48,50 +46,67 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
break;
|
||||
}
|
||||
}
|
||||
FillChineseLyricsData();
|
||||
FillRomanizationLyricsData();
|
||||
_lyricsDataArr.Add(new LyricsData()); // 为机翻预留
|
||||
return _lyricsDataArr;
|
||||
}
|
||||
|
||||
private void FillChineseLyricsData()
|
||||
private void FillRomanizationLyricsData()
|
||||
{
|
||||
var simplifiedChinese = _lyricsDataArr.Where(x => x.LanguageCode == "zh-Hans").FirstOrDefault();
|
||||
var traditionalChinese = _lyricsDataArr.Where(x => x.LanguageCode == "zh-Hant").FirstOrDefault();
|
||||
if (simplifiedChinese != null && traditionalChinese == null)
|
||||
var chinese = _lyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
|
||||
if (chinese != null)
|
||||
{
|
||||
// 如果没有繁体中文歌词,则将简体中文歌词转换为繁体中文
|
||||
_lyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LyricsLines = simplifiedChinese.LyricsLines.Select(line => new LyricsLine
|
||||
LanguageCode = "pinyin",
|
||||
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = ChineseConverter.ConvertToTraditionalChinese(line.OriginalText),
|
||||
OriginalText = Pinyin.Pinyin.Instance.HanziToPinyin(line.OriginalText).ToStr(),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = ChineseConverter.ConvertToTraditionalChinese(c.Text),
|
||||
Text = Pinyin.Pinyin.Instance.HanziToPinyin(c.Text).ToStr(),
|
||||
StartIndex = c.StartIndex
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
});
|
||||
_lyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LanguageCode = "jyutping",
|
||||
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = Pinyin.Jyutping.Instance.HanziToPinyin(line.OriginalText).ToStr(),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = Pinyin.Jyutping.Instance.HanziToPinyin(c.Text).ToStr(),
|
||||
StartIndex = c.StartIndex
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
});
|
||||
}
|
||||
else if (traditionalChinese != null && simplifiedChinese == null)
|
||||
var japanese = _lyricsDataArr.Where(x => x.LanguageCode == "ja").FirstOrDefault();
|
||||
if (japanese != null)
|
||||
{
|
||||
// 如果没有简体中文歌词,则将繁体中文歌词转换为简体中文
|
||||
_lyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LyricsLines = traditionalChinese.LyricsLines.Select(line => new LyricsLine
|
||||
LanguageCode = "romaji",
|
||||
LyricsLines = japanese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = ChineseConverter.ConvertToSimplifiedChinese(line.OriginalText),
|
||||
OriginalText = LanguageHelper.ToRomaji(line.OriginalText),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = ChineseConverter.ConvertToSimplifiedChinese(c.Text),
|
||||
Text = LanguageHelper.ToRomaji(c.Text),
|
||||
StartIndex = c.StartIndex
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
@@ -230,10 +245,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
int pStartMs = ParseTtmlTime(pBegin);
|
||||
int pEndMs = ParseTtmlTime(pEnd);
|
||||
|
||||
// 只获取一级span,且排除ttm:role="x-bg"的span
|
||||
// 只获取一级span,且排除 ttm:role="x-bg" 的 span 和 ttm:role="x-roman"
|
||||
var spans = p.Elements()
|
||||
.Where(s => s.Name.LocalName == "span" &&
|
||||
s.Attribute(XName.Get("role", "http://www.w3.org/ns/ttml#metadata"))?.Value != "x-bg")
|
||||
s.Attribute(XName.Get("role", "http://www.w3.org/ns/ttml#metadata"))?.Value != "x-bg" &&
|
||||
s.Attribute(XName.Get("role", "http://www.w3.org/ns/ttml#metadata"))?.Value != "x-roman")
|
||||
.ToList();
|
||||
|
||||
// 原文和翻译分离
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -6,6 +7,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Vanara.PInvoke;
|
||||
using WinRT.Interop;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
@@ -60,5 +62,14 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var primaryMonitorInfo = GetPrimaryMonitorInfoEx();
|
||||
return primaryMonitorInfo.szDevice;
|
||||
}
|
||||
|
||||
public static User32.MONITORINFOEX GetMonitorInfoExFromWindow(Window window)
|
||||
{
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
var hMonitor = User32.MonitorFromWindow(hwnd, User32.MonitorFlags.MONITOR_DEFAULTTONEAREST);
|
||||
User32.MONITORINFOEX monitorInfoEx = new() { cbSize = (uint)Marshal.SizeOf<User32.MONITORINFOEX>() };
|
||||
User32.GetMonitorInfo(hMonitor, ref monitorInfoEx);
|
||||
return monitorInfoEx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static string PotPlayerLogoPath => Path.Combine(AssetsFolder, "PotPlayer.png");
|
||||
public static string ChromeLogoPath => Path.Combine(AssetsFolder, "Chrome.png");
|
||||
public static string EdgeLogoPath => Path.Combine(AssetsFolder, "Edge.png");
|
||||
public static string SaltPlayerForWindowsLogoPath => Path.Combine(AssetsFolder, "SaltPlayerForWindows.png");
|
||||
public static string MoeKoeMusicLogoPath => Path.Combine(AssetsFolder, "MoeKoeMusic.png");
|
||||
public static string Listen1LogoPath => Path.Combine(AssetsFolder, "Listen1.png");
|
||||
|
||||
public static string UnknownPlayerLogoPath => Path.Combine(AssetsFolder, "Question.png");
|
||||
|
||||
public static string LogDirectory => Path.Combine(CacheFolder, "logs");
|
||||
@@ -46,6 +50,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static string QQLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "qq");
|
||||
public static string KugouLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "kugou");
|
||||
public static string AmllTtmlDbLyricsCacheDirectory => Path.Combine(LyricsCacheDirectory, "amll-ttml-db");
|
||||
public static string AppleMusicCacheDirectory => Path.Combine(LyricsCacheDirectory, "apple-music");
|
||||
public static string AmllTtmlDbIndexPath => Path.Combine(LyricsCacheDirectory, "amll-ttml-db-index.json");
|
||||
public static string AmllTtmlDbLastUpdatedPath => Path.Combine(LyricsCacheDirectory, "amll-ttml-db-last-updated.txt");
|
||||
|
||||
@@ -53,6 +58,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
public static string QQTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "qq");
|
||||
public static string NeteaseTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "netease");
|
||||
public static string KugouTranslationCacheDirectory => Path.Combine(TranslationCacheDirectory, "kugou");
|
||||
|
||||
public static string AlbumArtCacheDirectory => Path.Combine(CacheFolder, "album-art");
|
||||
|
||||
@@ -69,9 +75,11 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
Directory.CreateDirectory(KugouLyricsCacheDirectory);
|
||||
Directory.CreateDirectory(NeteaseLyricsCacheDirectory);
|
||||
Directory.CreateDirectory(AmllTtmlDbLyricsCacheDirectory);
|
||||
Directory.CreateDirectory(AppleMusicCacheDirectory);
|
||||
|
||||
Directory.CreateDirectory(QQTranslationCacheDirectory);
|
||||
Directory.CreateDirectory(NeteaseTranslationCacheDirectory);
|
||||
Directory.CreateDirectory(KugouTranslationCacheDirectory);
|
||||
|
||||
Directory.CreateDirectory(iTunesAlbumArtCacheDirectory);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PointHelper
|
||||
{
|
||||
public static PointInt32 ToPointInt32(this Point point)
|
||||
{
|
||||
return new PointInt32((int)point.X, (int)point.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,5 +18,45 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
(int)rect.Height
|
||||
);
|
||||
}
|
||||
|
||||
public static Windows.Foundation.Rect WithHeight(this Windows.Foundation.Rect rect, double height)
|
||||
{
|
||||
return new Windows.Foundation.Rect(
|
||||
rect.X,
|
||||
rect.Y,
|
||||
rect.Width,
|
||||
height
|
||||
);
|
||||
}
|
||||
|
||||
public static Windows.Foundation.Rect WithWidth(this Windows.Foundation.Rect rect, double width)
|
||||
{
|
||||
return new Windows.Foundation.Rect(
|
||||
rect.X,
|
||||
rect.Y,
|
||||
width,
|
||||
rect.Height
|
||||
);
|
||||
}
|
||||
|
||||
public static Windows.Foundation.Rect WithX(this Windows.Foundation.Rect rect, double x)
|
||||
{
|
||||
return new Windows.Foundation.Rect(
|
||||
x,
|
||||
rect.Y,
|
||||
rect.Width,
|
||||
rect.Height
|
||||
);
|
||||
}
|
||||
|
||||
public static Windows.Foundation.Rect WithY(this Windows.Foundation.Rect rect, double y)
|
||||
{
|
||||
return new Windows.Foundation.Rect(
|
||||
rect.X,
|
||||
y,
|
||||
rect.Width,
|
||||
rect.Height
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using NAudio.Dsp;
|
||||
using NAudio.Wave;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class SpectrumAnalyzer : IDisposable
|
||||
{
|
||||
private WasapiLoopbackCapture _capture;
|
||||
|
||||
private int _sampleRate = 48000;
|
||||
private readonly int _fftLength = 2048;
|
||||
|
||||
private readonly float[] _fftLeftBuffer;
|
||||
private readonly float[] _fftRightBuffer;
|
||||
|
||||
private readonly Complex[] _fftLeftData;
|
||||
private readonly Complex[] _fftRightData;
|
||||
|
||||
private float[] _spectrumLeftData;
|
||||
private float[] _spectrumRightData;
|
||||
private float[] _spectrumData;
|
||||
|
||||
private bool _disposed = false;
|
||||
|
||||
private double[] _hammingWindow;
|
||||
|
||||
private float[] _currentSpectrum;
|
||||
public float[] SmoothSpectrum { get; private set; }
|
||||
|
||||
public int BarCount { get; set; } = 32;
|
||||
public int Sensitivity { get; set; } = 10;
|
||||
public float SmoothingFactor { get; set; } = 0.95f;
|
||||
public bool IsCapturing { get; private set; } = false;
|
||||
|
||||
public SpectrumAnalyzer()
|
||||
{
|
||||
_fftLeftBuffer = new float[_fftLength];
|
||||
_fftLeftData = new Complex[_fftLength];
|
||||
_fftRightBuffer = new float[_fftLength];
|
||||
_fftRightData = new Complex[_fftLength];
|
||||
_hammingWindow = new double[_fftLength];
|
||||
//汉明窗
|
||||
for (int i = 0; i < _fftLength; i++)
|
||||
{
|
||||
_hammingWindow[i] = 0.54 - 0.46 * Math.Cos((2 * Math.PI * i) / (_fftLength - 1));
|
||||
}
|
||||
}
|
||||
|
||||
public void StartCapture()
|
||||
{
|
||||
_currentSpectrum = new float[BarCount];
|
||||
SmoothSpectrum = new float[BarCount];
|
||||
|
||||
try
|
||||
{
|
||||
_capture = new WasapiLoopbackCapture();
|
||||
_sampleRate = _capture.WaveFormat.SampleRate;
|
||||
_spectrumLeftData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2];
|
||||
_spectrumRightData = new float[(int)(24000.0f / _sampleRate * _fftLength) / 2];
|
||||
_spectrumData = new float[(int)(24000.0f / _sampleRate * _fftLength)];
|
||||
_capture.DataAvailable += OnDataAvailable;
|
||||
_capture.RecordingStopped += OnRecordingStopped;
|
||||
_capture.StartRecording();
|
||||
|
||||
IsCapturing = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void StopCapture()
|
||||
{
|
||||
_capture?.DataAvailable -= OnDataAvailable;
|
||||
_capture?.RecordingStopped -= OnRecordingStopped;
|
||||
_capture?.StopRecording();
|
||||
|
||||
IsCapturing = false;
|
||||
}
|
||||
|
||||
private void OnDataAvailable(object? sender, WaveInEventArgs e)
|
||||
{
|
||||
if (_disposed || e.BytesRecorded == 0) return;
|
||||
// 将字节转换为浮点数
|
||||
int samples = e.BytesRecorded / 8;
|
||||
if (samples < _fftLength) return;
|
||||
for (int i = 0; i < _fftLength; i++)
|
||||
{
|
||||
_fftLeftBuffer[i] = BitConverter.ToSingle(e.Buffer, i * 8);
|
||||
_fftRightBuffer[i] = BitConverter.ToSingle(e.Buffer, i * 8 + 4);
|
||||
}
|
||||
for (int i = 0; i < _fftLength; i++)
|
||||
{
|
||||
_fftLeftData[i].X = _fftLeftBuffer[i] * (float)_hammingWindow[i]; // Real part
|
||||
_fftLeftData[i].Y = 0; // Imaginary part
|
||||
_fftRightData[i].X = _fftRightBuffer[i] * (float)_hammingWindow[i];
|
||||
_fftRightData[i].Y = 0;
|
||||
}
|
||||
|
||||
// FFT
|
||||
FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftLeftData);
|
||||
FastFourierTransform.FFT(true, (int)Math.Log(_fftLength, 2), _fftRightData);
|
||||
for (int i = 0; i < _spectrumLeftData.Length; i++)
|
||||
{
|
||||
float real = (float)_fftLeftData[i].X;
|
||||
float imaginary = (float)_fftLeftData[i].Y;
|
||||
float magnitude = (float)Math.Sqrt(real * real + imaginary * imaginary);
|
||||
float frequency = i * _sampleRate / _fftLength;
|
||||
float compensationFactor = GetCompensationFactor(frequency);
|
||||
_spectrumLeftData[i] = magnitude * compensationFactor;
|
||||
_spectrumRightData[i] = (float)Math.Sqrt((float)_fftRightData[i].X * (float)_fftRightData[i].X + (float)_fftRightData[i].Y * (float)_fftRightData[i].Y) * compensationFactor;
|
||||
for (int j = 0; j < _spectrumLeftData.Length; j++)
|
||||
{
|
||||
_spectrumData[j] = _spectrumLeftData[_spectrumLeftData.Length - 1 - j];
|
||||
}
|
||||
Array.Copy(_spectrumRightData, 0, _spectrumData, _spectrumLeftData.Length, _spectrumRightData.Length);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BarCount; i++)
|
||||
{
|
||||
int index = (int)((float)i / BarCount * _spectrumData.Length);
|
||||
if (index < _spectrumData.Length)
|
||||
{
|
||||
_currentSpectrum[i] = _spectrumData[index] * 250f * Sensitivity;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UpdateSmoothSpectrum()
|
||||
{
|
||||
for (int i = 0; i < BarCount; i++)
|
||||
{
|
||||
SmoothSpectrum[i] = SmoothSpectrum[i] * SmoothingFactor +
|
||||
_currentSpectrum[i] * (1 - SmoothingFactor);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetCompensationFactor(float freq)
|
||||
{
|
||||
// 补偿曲线
|
||||
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 };
|
||||
if (freq <= frequencies[0])
|
||||
{
|
||||
return gains[0];
|
||||
}
|
||||
if (freq >= frequencies[frequencies.Length - 1])
|
||||
{
|
||||
return gains[gains.Length - 1];
|
||||
}
|
||||
int i = 0;
|
||||
while (freq > frequencies[i + 1])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
// 线性插值
|
||||
float x1 = frequencies[i];
|
||||
float y1 = gains[i];
|
||||
float x2 = frequencies[i + 1];
|
||||
float y2 = gains[i + 1];
|
||||
return y1 + (freq - x1) * ((y2 - y1) / (x2 - x1));
|
||||
}
|
||||
|
||||
private void OnRecordingStopped(object? sender, StoppedEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_capture?.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
@@ -11,6 +10,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
private T _currentValue;
|
||||
private double _durationSeconds;
|
||||
private double _delaySeconds;
|
||||
private double _delayRemaining;
|
||||
private EasingType? _easingType;
|
||||
private Func<T, T, double, T> _interpolator;
|
||||
private bool _isTransitioning;
|
||||
@@ -19,18 +20,21 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
private T _targetValue;
|
||||
|
||||
public double DurationSeconds => _durationSeconds;
|
||||
public double DelaySeconds => _delaySeconds;
|
||||
|
||||
public bool IsTransitioning => _isTransitioning;
|
||||
public T Value => _currentValue;
|
||||
public T TargetValue => _targetValue;
|
||||
public EasingType? EasingType => _easingType;
|
||||
|
||||
public ValueTransition(T initialValue, double durationSeconds, Func<T, T, double, T>? interpolator = null, EasingType? easingType = null)
|
||||
public ValueTransition(T initialValue, double durationSeconds, Func<T, T, double, T>? interpolator = null, EasingType? easingType = null, double delaySeconds = 0)
|
||||
{
|
||||
_currentValue = initialValue;
|
||||
_startValue = initialValue;
|
||||
_targetValue = initialValue;
|
||||
_durationSeconds = durationSeconds;
|
||||
_delaySeconds = delaySeconds;
|
||||
_delayRemaining = 0;
|
||||
_progress = 1f;
|
||||
_isTransitioning = false;
|
||||
|
||||
@@ -58,12 +62,18 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
_durationSeconds = seconds;
|
||||
}
|
||||
|
||||
public void SetDelay(double seconds)
|
||||
{
|
||||
_delaySeconds = seconds;
|
||||
}
|
||||
|
||||
private void JumpTo(T value)
|
||||
{
|
||||
_currentValue = value;
|
||||
_startValue = value;
|
||||
_targetValue = value;
|
||||
_progress = 1f;
|
||||
_delayRemaining = 0;
|
||||
_isTransitioning = false;
|
||||
}
|
||||
|
||||
@@ -73,6 +83,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
_startValue = value;
|
||||
_targetValue = value;
|
||||
_progress = 0f;
|
||||
_delayRemaining = 0;
|
||||
_isTransitioning = false;
|
||||
}
|
||||
|
||||
@@ -89,6 +100,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
_startValue = _currentValue;
|
||||
_targetValue = targetValue;
|
||||
_progress = 0f;
|
||||
_delayRemaining = _delaySeconds;
|
||||
_isTransitioning = true;
|
||||
}
|
||||
}
|
||||
@@ -103,7 +115,24 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
if (!_isTransitioning) return;
|
||||
|
||||
_progress += (double)(elapsedTime / TimeSpan.FromSeconds(_durationSeconds));
|
||||
if (_delayRemaining > 0)
|
||||
{
|
||||
double consume = Math.Min(_delayRemaining, elapsedTime.TotalSeconds);
|
||||
_delayRemaining -= consume;
|
||||
if (_delayRemaining > 0)
|
||||
return;
|
||||
elapsedTime = TimeSpan.FromSeconds(elapsedTime.TotalSeconds - consume);
|
||||
}
|
||||
|
||||
if (_durationSeconds <= 0)
|
||||
{
|
||||
_progress = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
_progress += elapsedTime.TotalSeconds / _durationSeconds;
|
||||
}
|
||||
|
||||
if (_progress >= 1f)
|
||||
{
|
||||
_progress = 1f;
|
||||
@@ -178,4 +207,4 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
_interpolator = GetInterpolatorByEasingType(easingType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vanara.PInvoke;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Foundation;
|
||||
using WinRT.Interop;
|
||||
using WinUIEx;
|
||||
|
||||
@@ -15,6 +22,22 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
public static class WindowHelper
|
||||
{
|
||||
private static List<object> _activeWindows = [];
|
||||
private static List<object> _workAreas = [];
|
||||
|
||||
private static readonly Dictionary<HWND, WindowStyle> _defaultWindowStyle = [];
|
||||
private static readonly Dictionary<HWND, ExtendedWindowStyle> _defaultExtendedWindowStyle = [];
|
||||
|
||||
private static readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
private static readonly IMediaSessionsService _mediaSessionsService = Ioc.Default.GetRequiredService<IMediaSessionsService>();
|
||||
|
||||
public static void HideWindow<T>()
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
if (window is Window w)
|
||||
{
|
||||
w.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public static void CloseWindow<T>()
|
||||
{
|
||||
@@ -41,7 +64,8 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
return default;
|
||||
}
|
||||
public static void OpenWindow<T>()
|
||||
|
||||
public static void OpenOrShowWindow<T>()
|
||||
{
|
||||
var window = _activeWindows.Find(w => w is T);
|
||||
if (window == null)
|
||||
@@ -59,6 +83,14 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
window = new MusicGalleryWindow();
|
||||
}
|
||||
else if (typeof(T) == typeof(LyricsSearchWindow))
|
||||
{
|
||||
window = new LyricsSearchWindow();
|
||||
}
|
||||
else if (typeof(T) == typeof(LyricsWindowSwitchWindow))
|
||||
{
|
||||
window = new LyricsWindowSwitchWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Unsupported window type", nameof(T));
|
||||
@@ -70,9 +102,14 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
if (typeof(T) == typeof(LyricsWindow))
|
||||
{
|
||||
var hwnd = WindowNative.GetWindowHandle(castedWindow);
|
||||
_defaultWindowStyle.Add(hwnd, castedWindow.GetWindowStyle());
|
||||
_defaultExtendedWindowStyle.Add(hwnd, castedWindow.GetExtendedWindowStyle());
|
||||
|
||||
var lyricsWindow = (LyricsWindow)window;
|
||||
lyricsWindow.ViewModel.InitShortcuts();
|
||||
lyricsWindow.AutoSelectLyricsMode();
|
||||
lyricsWindow.ViewModel.InitFgWindowWatcher();
|
||||
lyricsWindow.ViewModel.RefreshLyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -119,11 +156,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
private static void EnsureDockModeReleased()
|
||||
{
|
||||
LyricsWindow? lyricsWindow = GetWindowByWindowType<LyricsWindow>();
|
||||
if (lyricsWindow != null)
|
||||
{
|
||||
DockModeHelper.Disable(lyricsWindow);
|
||||
}
|
||||
SetIsWorkArea<LyricsWindow>(false);
|
||||
}
|
||||
|
||||
private static void TrackWindow(object window)
|
||||
@@ -141,7 +174,255 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
if (_activeWindows.Contains(sender))
|
||||
{
|
||||
_activeWindows.Remove(sender);
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(sender);
|
||||
_defaultWindowStyle.Remove(hwnd);
|
||||
_defaultExtendedWindowStyle.Remove(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsClickThrough<T>(bool enable)
|
||||
{
|
||||
Window? window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
window.SetExtendedWindowStyle(_defaultExtendedWindowStyle[hwnd] | ExtendedWindowStyle.Transparent | ExtendedWindowStyle.Layered);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.SetExtendedWindowStyle(_defaultExtendedWindowStyle[hwnd]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsWorkArea<T>(bool enable)
|
||||
{
|
||||
Window? window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
EnableWorkArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableWorkArea(window);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsBorderless<T>(bool enable)
|
||||
{
|
||||
var window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
window.SetWindowStyle(WindowStyle.Popup | WindowStyle.Visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.SetWindowStyle(_defaultWindowStyle[hwnd]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIsShowInSwitchers<T>(bool enable)
|
||||
{
|
||||
var window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
window.AppWindow.IsShownInSwitchers = enable;
|
||||
}
|
||||
|
||||
public static void SetIsAlwaysOnTop<T>(bool enable)
|
||||
{
|
||||
var window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
if (window.AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.IsAlwaysOnTop = enable;
|
||||
}
|
||||
}
|
||||
|
||||
public static void MoveAndResize<T>(Rect rect)
|
||||
{
|
||||
var window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
window.AppWindow.MoveAndResize(rect.ToRectInt32());
|
||||
}
|
||||
|
||||
public static void SetTitleBarArea<T>(TitleBarArea titleBarArea)
|
||||
{
|
||||
if (typeof(T) == typeof(LyricsWindow))
|
||||
{
|
||||
LyricsWindow? lyricsWindow = GetWindowByWindowType<LyricsWindow>();
|
||||
lyricsWindow?.SetTitleBarArea(titleBarArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Unsupported window type: {typeof(T).FullName}");
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
double y = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
|
||||
y -= 1;
|
||||
|
||||
User32.SetWindowPos(
|
||||
hwnd,
|
||||
IntPtr.Zero,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
(int)y,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
|
||||
User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
||||
);
|
||||
}
|
||||
|
||||
private static void RegisterWorkArea(IntPtr hwnd)
|
||||
{
|
||||
if (_workAreas.Contains(hwnd)) return;
|
||||
|
||||
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top : _liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd,
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
Top = (int)top,
|
||||
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
|
||||
Bottom = (int)bottom,
|
||||
},
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_NEW, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||
|
||||
_workAreas.Add(hwnd);
|
||||
}
|
||||
|
||||
private static void UnregisterWorkArea(IntPtr hwnd)
|
||||
{
|
||||
if (!_workAreas.Contains(hwnd))
|
||||
return;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_REMOVE, ref abd);
|
||||
|
||||
_workAreas.Remove(hwnd);
|
||||
}
|
||||
|
||||
public static void UpdateWorkAreaHeight<T>()
|
||||
{
|
||||
var window = GetWindowByWindowType<T>() as Window;
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
|
||||
App.DispatcherQueueTimer?.Debounce(() =>
|
||||
{
|
||||
if (!_workAreas.Contains(hwnd))
|
||||
return;
|
||||
|
||||
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||
|
||||
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
|
||||
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
|
||||
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
|
||||
|
||||
Shell32.APPBARDATA abd = new()
|
||||
{
|
||||
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
|
||||
hWnd = hwnd,
|
||||
uEdge = uEdge,
|
||||
rc = new RECT
|
||||
{
|
||||
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
Top = (int)top,
|
||||
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
|
||||
Bottom = (int)bottom,
|
||||
},
|
||||
};
|
||||
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||
|
||||
// 同步窗口实际高度和位置
|
||||
User32.SetWindowPos(
|
||||
hwnd,
|
||||
IntPtr.Zero,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
|
||||
(int)top - 1,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
|
||||
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
|
||||
User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
||||
);
|
||||
|
||||
}, TimeSpan.FromMilliseconds(100));
|
||||
}
|
||||
|
||||
public static void SetLyricsWindowVisibilityByPlayingStatus()
|
||||
{
|
||||
var window = GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && !_mediaSessionsService.IsPlaying)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(false);
|
||||
}
|
||||
HideWindow<LyricsWindow>();
|
||||
}
|
||||
else if (_liveStatesService.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow && _mediaSessionsService.IsPlaying)
|
||||
{
|
||||
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsWorkArea)
|
||||
{
|
||||
SetIsWorkArea<LyricsWindow>(true);
|
||||
}
|
||||
OpenOrShowWindow<LyricsWindow>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,26 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Vanara.PInvoke;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public partial class LiveStates : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowMode CurrentLyricsWindowMode { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsDisplayType CurrentLyricsDisplayType { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsStyleSettings CurrentLyricsStyleSettings { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsEffectSettings CurrentLyricsEffectSettings { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowStatus LyricsWindowStatus { get; set; }
|
||||
|
||||
public LiveStates(AppSettings appSettings)
|
||||
public LiveStates()
|
||||
{
|
||||
CurrentLyricsWindowMode = LyricsWindowMode.StandardMode;
|
||||
CurrentLyricsDisplayType = appSettings.StandardModeSettings.LyricsDisplayType;
|
||||
CurrentLyricsStyleSettings = appSettings.StandardLyricsStyleSettings;
|
||||
CurrentLyricsEffectSettings = appSettings.StandardLyricsEffectSettings;
|
||||
}
|
||||
|
||||
public void ToggleLyricsWindowMode(LyricsWindowMode mode)
|
||||
{
|
||||
if (CurrentLyricsWindowMode == mode)
|
||||
{
|
||||
CurrentLyricsWindowMode = LyricsWindowMode.StandardMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLyricsWindowMode = mode;
|
||||
}
|
||||
LyricsWindowStatus = new LyricsWindowStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using System;
|
||||
@@ -13,7 +14,12 @@ namespace BetterLyrics.WinUI3.Models
|
||||
public class LyricsData
|
||||
{
|
||||
public List<LyricsLine> LyricsLines { get; set; }
|
||||
public string? LanguageCode => LanguageHelper.DetectLanguageCode(WrappedOriginalText);
|
||||
private string? _languageCode;
|
||||
public string? LanguageCode
|
||||
{
|
||||
get => _languageCode ?? LanguageHelper.DetectLanguageCode(WrappedOriginalText);
|
||||
set => _languageCode = value;
|
||||
}
|
||||
public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.OriginalText));
|
||||
|
||||
public LyricsData()
|
||||
@@ -120,5 +126,18 @@ namespace BetterLyrics.WinUI3.Models
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
public LyricsLine? GetLyricsLine(double sec)
|
||||
{
|
||||
for (int i = 0; i < LyricsLines.Count; i++)
|
||||
{
|
||||
var line = LyricsLines[i];
|
||||
if (line.StartMs > sec * 1000)
|
||||
{
|
||||
return LyricsLines.ElementAtOrDefault(i - 1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public class LyricsSearchResult
|
||||
{
|
||||
public bool IsFound => !string.IsNullOrEmpty(Raw);
|
||||
public LyricsSearchProvider? Provider { get; set; }
|
||||
|
||||
public string? Raw { get; set; }
|
||||
|
||||
public string? Title { get; set; }
|
||||
public string? Artist { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Views;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI.Windowing;
|
||||
using System;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public partial class LyricsWindowStatus : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string Name { get; set; } = string.Empty;
|
||||
[ObservableProperty] public partial bool IsDefault { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MonitorDeviceName { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsWorkArea { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsBorderless { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsAlwaysOnTop { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsAlwaysOnTopPolling { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsShownInSwitchers { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsClickThrough { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsLayoutOrientation LyricsLayoutOrientation { get; set; } = LyricsLayoutOrientation.Horizontal;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsDisplayType LyricsDisplayType { get; set; } = LyricsDisplayType.SplitView;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Rect WindowBounds { get; set; } = new Rect(100, 100, 800, 500);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double DockHeight { get; set; } = 64;
|
||||
[ObservableProperty] public partial Rect DemoWindowBounds { get; set; }
|
||||
[ObservableProperty] public partial Rect MonitorBounds { get; set; }
|
||||
[ObservableProperty] public partial Rect DemoMonitorBounds { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial DockPlacement DockPlacement { get; set; } = DockPlacement.Top;
|
||||
[ObservableProperty] public partial LyricsStyleSettings LyricsStyleSettings { get; set; } = new();
|
||||
[ObservableProperty] public partial LyricsEffectSettings LyricsEffectSettings { get; set; } = new(500, 500, 500, EasingType.EaseInOutQuad);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsBackgroundSettings LyricsBackgroundSettings { get; set; } = new();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial AlbumArtLayoutSettings AlbumArtLayoutSettings { get; set; } = new();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsAdaptToEnvironment { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial WindowPixelSampleMode EnvironmentSampleMode { get; set; } = WindowPixelSampleMode.WindowEdge;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoShowOrHideWindow { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TitleBarArea TitleBarArea { get; set; } = TitleBarArea.Top;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowX { get; set; } = 100;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowY { get; set; } = 100;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowWidth { get; set; } = 800;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowHeight { get; set; } = 500;
|
||||
|
||||
public LyricsWindowStatus()
|
||||
{
|
||||
UpdateMonitorNameAndBounds();
|
||||
UpdateDemoWindowAndMonitorBounds();
|
||||
}
|
||||
|
||||
partial void OnWindowXChanged(double value)
|
||||
{
|
||||
WindowBounds = WindowBounds.WithX(value);
|
||||
}
|
||||
|
||||
partial void OnWindowYChanged(double value)
|
||||
{
|
||||
WindowBounds = WindowBounds.WithY(value);
|
||||
}
|
||||
|
||||
partial void OnWindowWidthChanged(double value)
|
||||
{
|
||||
WindowBounds = WindowBounds.WithWidth(value);
|
||||
}
|
||||
|
||||
partial void OnWindowHeightChanged(double value)
|
||||
{
|
||||
WindowBounds = WindowBounds.WithHeight(value);
|
||||
}
|
||||
|
||||
partial void OnLyricsStyleSettingsChanged(LyricsStyleSettings oldValue, LyricsStyleSettings newValue)
|
||||
{
|
||||
oldValue.PropertyChanged -= OldLyricsStyleSettings_PropertyChanged;
|
||||
newValue.PropertyChanged += OldLyricsStyleSettings_PropertyChanged;
|
||||
}
|
||||
|
||||
partial void OnLyricsEffectSettingsChanged(LyricsEffectSettings oldValue, LyricsEffectSettings newValue)
|
||||
{
|
||||
oldValue.PropertyChanged -= OldLyricsEffectSettings_PropertyChanged;
|
||||
newValue.PropertyChanged += OldLyricsEffectSettings_PropertyChanged;
|
||||
}
|
||||
|
||||
partial void OnLyricsBackgroundSettingsChanged(LyricsBackgroundSettings oldValue, LyricsBackgroundSettings newValue)
|
||||
{
|
||||
oldValue.PropertyChanged -= OldLyricsBackgroundSettings_PropertyChanged;
|
||||
newValue.PropertyChanged += OldLyricsBackgroundSettings_PropertyChanged;
|
||||
}
|
||||
|
||||
partial void OnAlbumArtLayoutSettingsChanged(AlbumArtLayoutSettings oldValue, AlbumArtLayoutSettings newValue)
|
||||
{
|
||||
oldValue.PropertyChanged -= OldAlbumArtLayoutSettings_PropertyChanged;
|
||||
newValue.PropertyChanged += OldAlbumArtLayoutSettings_PropertyChanged;
|
||||
}
|
||||
|
||||
private void OldLyricsStyleSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
this.OnPropertyChanged(nameof(LyricsStyleSettings));
|
||||
}
|
||||
|
||||
private void OldLyricsEffectSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
this.OnPropertyChanged(nameof(LyricsEffectSettings));
|
||||
}
|
||||
|
||||
private void OldLyricsBackgroundSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
this.OnPropertyChanged(nameof(LyricsBackgroundSettings));
|
||||
}
|
||||
|
||||
private void OldAlbumArtLayoutSettings_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
this.OnPropertyChanged(nameof(AlbumArtLayoutSettings));
|
||||
}
|
||||
|
||||
partial void OnWindowBoundsChanged(Rect value)
|
||||
{
|
||||
UpdateMonitorNameAndBounds();
|
||||
UpdateDemoWindowAndMonitorBounds();
|
||||
}
|
||||
|
||||
partial void OnAutoShowOrHideWindowChanged(bool value)
|
||||
{
|
||||
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
|
||||
}
|
||||
|
||||
public void UpdateMonitorNameAndBounds()
|
||||
{
|
||||
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (lyricsWindow == null) return;
|
||||
|
||||
var mointor = MonitorHelper.GetMonitorInfoExFromWindow(lyricsWindow);
|
||||
MonitorDeviceName = mointor.szDevice;
|
||||
MonitorBounds = new Rect(
|
||||
mointor.rcMonitor.Left,
|
||||
mointor.rcMonitor.Top,
|
||||
mointor.rcMonitor.Width,
|
||||
mointor.rcMonitor.Height
|
||||
);
|
||||
}
|
||||
|
||||
public void UpdateDemoWindowAndMonitorBounds(double factor = 0.1)
|
||||
{
|
||||
DemoWindowBounds = new Rect(
|
||||
(WindowBounds.X - MonitorBounds.Left) * factor,
|
||||
(WindowBounds.Y - MonitorBounds.Top) * factor,
|
||||
WindowBounds.Width * factor,
|
||||
WindowBounds.Height * factor
|
||||
);
|
||||
DemoMonitorBounds = new Rect(
|
||||
MonitorBounds.Left * factor,
|
||||
MonitorBounds.Top * factor,
|
||||
MonitorBounds.Width * factor,
|
||||
MonitorBounds.Height * factor
|
||||
);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = this.Name,
|
||||
IsDefault = this.IsDefault,
|
||||
MonitorDeviceName = this.MonitorDeviceName,
|
||||
IsWorkArea = this.IsWorkArea,
|
||||
IsBorderless = this.IsBorderless,
|
||||
IsAlwaysOnTop = this.IsAlwaysOnTop,
|
||||
IsAlwaysOnTopPolling = this.IsAlwaysOnTopPolling,
|
||||
IsShownInSwitchers = this.IsShownInSwitchers,
|
||||
IsClickThrough = this.IsClickThrough,
|
||||
LyricsLayoutOrientation = this.LyricsLayoutOrientation,
|
||||
LyricsDisplayType = this.LyricsDisplayType,
|
||||
WindowBounds = this.WindowBounds,
|
||||
DockHeight = this.DockHeight,
|
||||
DemoWindowBounds = this.DemoWindowBounds,
|
||||
MonitorBounds = this.MonitorBounds,
|
||||
DemoMonitorBounds = this.DemoMonitorBounds,
|
||||
LyricsStyleSettings = (LyricsStyleSettings)this.LyricsStyleSettings.Clone(),
|
||||
LyricsEffectSettings = (LyricsEffectSettings)this.LyricsEffectSettings.Clone(),
|
||||
LyricsBackgroundSettings = (LyricsBackgroundSettings)this.LyricsBackgroundSettings.Clone(),
|
||||
AlbumArtLayoutSettings = (AlbumArtLayoutSettings)this.AlbumArtLayoutSettings.Clone(),
|
||||
IsAdaptToEnvironment = this.IsAdaptToEnvironment,
|
||||
EnvironmentSampleMode = this.EnvironmentSampleMode,
|
||||
AutoShowOrHideWindow = this.AutoShowOrHideWindow,
|
||||
TitleBarArea = this.TitleBarArea,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class LyricsWindowStatusExtensions
|
||||
{
|
||||
public static LyricsWindowStatus DesktopMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("DesktopMode"),
|
||||
LyricsDisplayType = LyricsDisplayType.LyricsOnly,
|
||||
WindowBounds = new Rect(100, 100, 600, 250),
|
||||
IsAlwaysOnTop = true,
|
||||
IsAlwaysOnTopPolling = true,
|
||||
IsBorderless = true,
|
||||
IsClickThrough = true,
|
||||
IsAdaptToEnvironment = true,
|
||||
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
|
||||
LyricsStyleSettings = new()
|
||||
{
|
||||
LyricsFontSize = 20,
|
||||
LyricsAlignmentType = TextAlignmentType.Center,
|
||||
},
|
||||
LyricsBackgroundSettings = new LyricsBackgroundSettings
|
||||
{
|
||||
IsPureColorOverlayEnabled = false,
|
||||
IsCoverOverlayEnabled = false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus DockedMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("DockedMode"),
|
||||
IsWorkArea = true,
|
||||
IsAlwaysOnTop = true,
|
||||
IsAlwaysOnTopPolling = true,
|
||||
IsBorderless = true,
|
||||
IsAdaptToEnvironment = true,
|
||||
LyricsDisplayType = LyricsDisplayType.LyricsOnly,
|
||||
EnvironmentSampleMode = WindowPixelSampleMode.BelowWindow,
|
||||
TitleBarArea = TitleBarArea.None,
|
||||
LyricsStyleSettings = new LyricsStyleSettings
|
||||
{
|
||||
LyricsAlignmentType = TextAlignmentType.Center,
|
||||
LyricsFontSize = 18,
|
||||
},
|
||||
LyricsBackgroundSettings = new LyricsBackgroundSettings
|
||||
{
|
||||
IsCoverOverlayEnabled = false,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus FullscreenMode(Rect monitorBounds)
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("FullscreenMode"),
|
||||
WindowBounds = monitorBounds,
|
||||
IsAlwaysOnTop = true,
|
||||
IsBorderless = true,
|
||||
TitleBarArea = Enums.TitleBarArea.None,
|
||||
LyricsLayoutOrientation = Enums.LyricsLayoutOrientation.Vertical,
|
||||
LyricsStyleSettings = new LyricsStyleSettings
|
||||
{
|
||||
LyricsFontSize = 96,
|
||||
LyricsAlignmentType = Enums.TextAlignmentType.Center,
|
||||
},
|
||||
AlbumArtLayoutSettings = new AlbumArtLayoutSettings
|
||||
{
|
||||
AutoAlbumArtSize = false,
|
||||
AlbumArtSize = 148,
|
||||
SongInfoFontSize = 48,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus StandardMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("StandardMode"),
|
||||
};
|
||||
}
|
||||
|
||||
public static LyricsWindowStatus NarrowMode()
|
||||
{
|
||||
return new LyricsWindowStatus
|
||||
{
|
||||
Name = App.ResourceLoader!.GetString("NarrowMode"),
|
||||
WindowBounds = new Rect(100, 100, 400, 800),
|
||||
LyricsLayoutOrientation = LyricsLayoutOrientation.Vertical,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
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 MappedSongSearchQuery : ObservableRecipient
|
||||
{
|
||||
[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 MappedTitle { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string MappedArtist { get; set; } = string.Empty;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsMarkedAsPureMusic { get; set; } = false;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsSearchProvider? LyricsSearchProvider { get; set; }
|
||||
|
||||
public MappedSongSearchQuery Clone()
|
||||
{
|
||||
return new MappedSongSearchQuery
|
||||
{
|
||||
OriginalTitle = this.OriginalTitle,
|
||||
OriginalArtist = this.OriginalArtist,
|
||||
MappedTitle = this.MappedTitle,
|
||||
MappedArtist = this.MappedArtist,
|
||||
IsMarkedAsPureMusic = this.IsMarkedAsPureMusic,
|
||||
LyricsSearchProvider = this.LyricsSearchProvider
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,26 +12,33 @@ namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public partial class MediaSourceProviderInfo : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsEnabled { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsEnabled { get; set; } = true;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string Provider { get; set; }
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLastFMTrackEnabled { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLastFMTrackEnabled { get; set; } = false;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTimelineSyncEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int TimelineSyncThreshold { get; set; }
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PositionOffset { get; set; }
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ResetPositionOffsetOnSongChanged { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ResetPositionOffsetOnSongChanged { get; set; } = false;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsSearchProviderInfo> LyricsSearchProvidersInfo { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LyricsSearchProviderInfo> LyricsSearchProvidersInfo { get; set; } = [.. Enum.GetValues<LyricsSearchProvider>().Select(p => new LyricsSearchProviderInfo(p, true))];
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<AlbumArtSearchProviderInfo> AlbumArtSearchProvidersInfo { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<AlbumArtSearchProviderInfo> AlbumArtSearchProvidersInfo { get; set; } = [.. Enum.GetValues<AlbumArtSearchProvider>().Select(p => new AlbumArtSearchProviderInfo(p, true))];
|
||||
|
||||
public MediaSourceProviderInfo() { }
|
||||
|
||||
public MediaSourceProviderInfo(string provider) : base()
|
||||
public MediaSourceProviderInfo()
|
||||
{
|
||||
Provider = string.Empty;
|
||||
TimelineSyncThreshold = 0;
|
||||
PositionOffset = 0;
|
||||
}
|
||||
|
||||
public MediaSourceProviderInfo(string provider, bool isEnable = true)
|
||||
{
|
||||
IsEnabled = isEnable;
|
||||
switch (provider)
|
||||
{
|
||||
case Constants.PlayerID.AppleMusic:
|
||||
@@ -40,18 +47,19 @@ namespace BetterLyrics.WinUI3.Models
|
||||
PositionOffset = 1000;
|
||||
break;
|
||||
default:
|
||||
// 设置 100 以防不必要的重复同步
|
||||
TimelineSyncThreshold = 100;
|
||||
// 设置 300 以防不必要的重复同步
|
||||
TimelineSyncThreshold = 300;
|
||||
PositionOffset = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Provider = provider;
|
||||
IsEnabled = true;
|
||||
IsLastFMTrackEnabled = false;
|
||||
ResetPositionOffsetOnSongChanged = false;
|
||||
LyricsSearchProvidersInfo = [.. Enum.GetValues<LyricsSearchProvider>().Select(p => new LyricsSearchProviderInfo(p, true))];
|
||||
AlbumArtSearchProvidersInfo = [.. Enum.GetValues<AlbumArtSearchProvider>().Select(p => new AlbumArtSearchProviderInfo(p, true))];
|
||||
|
||||
AlbumArtSearchProvidersInfo.ItemPropertyChanged += AlbumArtSearchProvidersInfo_ItemPropertyChanged;
|
||||
AlbumArtSearchProvidersInfo.CollectionChanged += AlbumArtSearchProvidersInfo_CollectionChanged;
|
||||
|
||||
LyricsSearchProvidersInfo.ItemPropertyChanged += LyricsSearchProvidersInfo_ItemPropertyChanged;
|
||||
LyricsSearchProvidersInfo.CollectionChanged += LyricsSearchProvidersInfo_CollectionChanged;
|
||||
}
|
||||
|
||||
partial void OnAlbumArtSearchProvidersInfoChanged(FullyObservableCollection<AlbumArtSearchProviderInfo> oldValue, FullyObservableCollection<AlbumArtSearchProviderInfo> newValue)
|
||||
|
||||
@@ -8,12 +8,32 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class AlbumArtLayoutSettings : ObservableRecipient
|
||||
public partial class AlbumArtLayoutSettings : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType SongInfoAlignmentType { get; set; } = TextAlignmentType.Left;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageRadius { get; set; } = 12; // 12 % of the cover image size
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageShadowAmount { get; set; } = 12;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SongInfoFontSize { get; set; } = 18;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowTitle { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowArtists { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int AlbumArtSize { get; set; } = 64;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoAlbumArtSize { get; set; } = true;
|
||||
|
||||
public AlbumArtLayoutSettings() { }
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new AlbumArtLayoutSettings
|
||||
{
|
||||
SongInfoAlignmentType = this.SongInfoAlignmentType,
|
||||
CoverImageRadius = this.CoverImageRadius,
|
||||
CoverImageShadowAmount = this.CoverImageShadowAmount,
|
||||
SongInfoFontSize = this.SongInfoFontSize,
|
||||
ShowTitle = this.ShowTitle,
|
||||
ShowArtists = this.ShowArtists,
|
||||
AlbumArtSize = this.AlbumArtSize,
|
||||
AutoAlbumArtSize = this.AutoAlbumArtSize,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,23 +10,6 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public string Version { get; set; } = Helper.MetadataHelper.AppVersion;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsStyleSettings StandardLyricsStyleSettings { get; set; } = new LyricsStyleSettings(32, TextAlignmentType.Left, 0);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsStyleSettings DesktopLyricsStyleSettings { get; set; } = new LyricsStyleSettings(28, TextAlignmentType.Center, 2);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsStyleSettings DockLyricsStyleSettings { get; set; } = new LyricsStyleSettings(16, TextAlignmentType.Center, 0);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsStyleSettings PictureInPictureLyricsStyleSettings { get; set; } = new LyricsStyleSettings(28, TextAlignmentType.Left, 0);
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsEffectSettings StandardLyricsEffectSettings { get; set; } = new LyricsEffectSettings(100, 500, 1000, EasingType.EaseInOutQuad);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsEffectSettings DesktopLyricsEffectSettings { get; set; } = new LyricsEffectSettings(500, 500, 500, EasingType.EaseInOutQuad);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsEffectSettings DockLyricsEffectSettings { get; set; } = new LyricsEffectSettings(500, 500, 500, EasingType.EaseInOutQuad);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsEffectSettings PictureInPictureLyricsEffectSettings { get; set; } = new LyricsEffectSettings(500, 500, 500, EasingType.EaseInOutQuad);
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial StandardModeSettings StandardModeSettings { get; set; } = new StandardModeSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial DesktopModeSettings DesktopModeSettings { get; set; } = new DesktopModeSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial DockModeSettings DockModeSettings { get; set; } = new DockModeSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial PictureInPictureModeSettings PictureInPictureModeSettings { get; set; } = new PictureInPictureModeSettings();
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsBackgroundSettings LyricsBackgroundSettings { get; set; } = new LyricsBackgroundSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial AlbumArtLayoutSettings AlbumArtLayoutSettings { get; set; } = new AlbumArtLayoutSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TranslationSettings TranslationSettings { get; set; } = new TranslationSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial GeneralSettings GeneralSettings { get; set; } = new GeneralSettings();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial MusicGallerySettings MusicGallerySettings { get; set; } = new MusicGallerySettings();
|
||||
@@ -34,6 +17,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial FullyObservableCollection<LocalMediaFolder> LocalMediaFolders { 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<LyricsWindowStatus> WindowBoundsRecords { get; set; } = [];
|
||||
|
||||
public AppSettings() { }
|
||||
}
|
||||
|
||||
@@ -10,6 +10,5 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class BaseModeSettings : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsDisplayType LyricsDisplayType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class DesktopModeSettings : BaseModeSettings
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Rect WindowBounds { get; set; } = new Rect(100, 100, 400, 200);
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool AutoLockOnDesktopMode { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> LockShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "U" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ToggleShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "D" };
|
||||
|
||||
public DesktopModeSettings()
|
||||
{
|
||||
LyricsDisplayType = Enums.LyricsDisplayType.LyricsOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class DockModeSettings : BaseModeSettings
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial DockPlacement DockPlacement { get; set; } = DockPlacement.Top;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int DockWindowHeight { get; set; } = 64;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string DockMonitorDeviceName { get; set; } = MonitorHelper.GetPrimaryMonitorDeviceName();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ToggleShortcut { get; set; } = new List<string> { "Ctrl", "Shift", "D" };
|
||||
|
||||
public DockModeSettings()
|
||||
{
|
||||
LyricsDisplayType = LyricsDisplayType.LyricsOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,14 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class GeneralSettings : ObservableRecipient
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LyricsWindowMode AutoStartWindowType { get; set; } = LyricsWindowMode.StandardMode;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Language Language { get; set; } = Language.FollowSystem;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IgnoreFullscreenWindow { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LXMusicServer { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool HideWindowWhenNotPlaying { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsDragEverywhereEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsImmersiveMode { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ExitOnLyricsWindowClosed { get; set; } = true;
|
||||
[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 ListenOnNewPlaybackSource { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> BorderlessShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "B" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ClickThroughShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "C" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> LyricsWindowSwitchShortcut { get; set; } = new List<string>() { "Ctrl", "Alt", "S" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> PlayOrPauseShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "P" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> NextSongShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "Right" };
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> PreviousSongShortcut { get; set; } = new List<string> { "Ctrl", "Alt", "Left" };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -8,15 +9,37 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class LyricsBackgroundSettings : ObservableRecipient
|
||||
public partial class LyricsBackgroundSettings : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ElementTheme LyricsBackgroundTheme { get; set; } = ElementTheme.Dark;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsPureColorOverlayEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PureColorOverlayOpacity { get; set; } = 100; // 100 % = 1.0
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsCoverOverlayEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlayBlurAmount { get; set; } = 100; // 100 % of the cover image size
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlayOpacity { get; set; } = 100; // 100 % = 1.0
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PureColorOverlayOpacity { get; set; } = 100; // 100 % = 1.0
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlaySpeed { get; set; } = 50; // 50 % of the base rotate speed
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverAcrylicEffectAmount { get; set; } = 0;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsFluidOverlayEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int FluidOverlayOpacity { get; set; } = 100;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSpectrumOverlayEnabled { get; set; } = false;
|
||||
|
||||
public LyricsBackgroundSettings() { }
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new LyricsBackgroundSettings
|
||||
{
|
||||
LyricsBackgroundTheme = this.LyricsBackgroundTheme,
|
||||
CoverOverlayBlurAmount = this.CoverOverlayBlurAmount,
|
||||
CoverOverlayOpacity = this.CoverOverlayOpacity,
|
||||
PureColorOverlayOpacity = this.PureColorOverlayOpacity,
|
||||
CoverOverlaySpeed = this.CoverOverlaySpeed,
|
||||
CoverAcrylicEffectAmount = this.CoverAcrylicEffectAmount,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class LyricsEffectSettings : ObservableRecipient
|
||||
public partial class LyricsEffectSettings : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsBlurAmount { get; set; } = 5;
|
||||
|
||||
@@ -23,7 +23,10 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsShadowAmount { get; set; } = 8;
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsHighlightScope { get; set; } = LineRenderingType.LineStartToCurrentChar;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsHighlightAmount { get; set; } = 100; // 100% 是上界
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsTranslationHighlightAmount { get; set; } = 60; // 100% 是上界
|
||||
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFloatAmount { get; set; } = 1;
|
||||
|
||||
@@ -31,6 +34,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollDuration { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollTopDuration { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollBottomDuration { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsScrollTopDelay { 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 bool IsFanLyricsEnabled { get; set; } = false;
|
||||
@@ -42,5 +47,29 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
LyricsScrollBottomDuration = lyricsScrollBottomDuration;
|
||||
LyricsScrollEasingType = lyricsScrollEasingType;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new LyricsEffectSettings(this.LyricsScrollTopDuration, this.LyricsScrollDuration, this.LyricsScrollBottomDuration, this.LyricsScrollEasingType)
|
||||
{
|
||||
LyricsBlurAmount = this.LyricsBlurAmount,
|
||||
IsLyricsLineFadeEnabled = this.IsLyricsLineFadeEnabled,
|
||||
IsLyricsGlowEffectEnabled = this.IsLyricsGlowEffectEnabled,
|
||||
LyricsGlowEffectScope = this.LyricsGlowEffectScope,
|
||||
LyricsGlowEffectAmount = this.LyricsGlowEffectAmount,
|
||||
IsLyricsShadowEnabled = this.IsLyricsShadowEnabled,
|
||||
LyricsShadowScope = this.LyricsShadowScope,
|
||||
LyricsShadowAmount = this.LyricsShadowAmount,
|
||||
LyricsHighlightScope = this.LyricsHighlightScope,
|
||||
LyricsHighlightAmount = this.LyricsHighlightAmount,
|
||||
LyricsTranslationHighlightAmount = this.LyricsTranslationHighlightAmount,
|
||||
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
|
||||
LyricsFloatAmount = this.LyricsFloatAmount,
|
||||
LyricsScrollTopDelay = this.LyricsScrollTopDelay,
|
||||
LyricsScrollBottomDelay = this.LyricsScrollBottomDelay,
|
||||
LyricsVerticalEdgeOpacity = this.LyricsVerticalEdgeOpacity,
|
||||
IsFanLyricsEnabled = this.IsFanLyricsEnabled
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@ using Windows.UI;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class LyricsStyleSettings : ObservableRecipient
|
||||
public partial class LyricsStyleSettings : ObservableRecipient, ICloneable
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontSize { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType LyricsAlignmentType { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsDynamicLyricsFontSize { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontSize { get; set; } = 24;
|
||||
[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 LyricsFontStrokeWidth { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsFontStrokeWidth { get; set; } = 0;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Color LyricsCustomBgFontColor { get; set; } = Colors.White;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Color LyricsCustomFgFontColor { get; set; } = Colors.White;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Color LyricsCustomStrokeFontColor { get; set; } = Colors.White;
|
||||
@@ -36,5 +37,27 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
LyricsAlignmentType = lyricsAlignmentType;
|
||||
LyricsFontStrokeWidth = lyricsFontStrokeWidth;
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return new LyricsStyleSettings
|
||||
{
|
||||
IsDynamicLyricsFontSize = this.IsDynamicLyricsFontSize,
|
||||
LyricsFontSize = this.LyricsFontSize,
|
||||
LyricsAlignmentType = this.LyricsAlignmentType,
|
||||
LyricsBgFontOpacity = this.LyricsBgFontOpacity,
|
||||
LyricsFontStrokeWidth = this.LyricsFontStrokeWidth,
|
||||
LyricsCustomBgFontColor = this.LyricsCustomBgFontColor,
|
||||
LyricsCustomFgFontColor = this.LyricsCustomFgFontColor,
|
||||
LyricsCustomStrokeFontColor = this.LyricsCustomStrokeFontColor,
|
||||
LyricsBgFontColorType = this.LyricsBgFontColorType,
|
||||
LyricsFgFontColorType = this.LyricsFgFontColorType,
|
||||
LyricsStrokeFontColorType = this.LyricsStrokeFontColorType,
|
||||
LyricsFontWeight = this.LyricsFontWeight,
|
||||
LyricsLineSpacingFactor = this.LyricsLineSpacingFactor,
|
||||
LyricsTranslationSeparator = this.LyricsTranslationSeparator,
|
||||
LyricsFontFamily = this.LyricsFontFamily
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +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.Settings
|
||||
{
|
||||
public partial class PictureInPictureModeSettings : BaseModeSettings
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial List<string> ToggleShortcut { get; set; } = new List<string>() { "Ctrl", "Shift", "P" };
|
||||
|
||||
public PictureInPictureModeSettings()
|
||||
{
|
||||
LyricsDisplayType = Enums.LyricsDisplayType.SplitView;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models.Settings
|
||||
{
|
||||
public partial class StandardModeSettings : BaseModeSettings
|
||||
{
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial Rect WindowBounds { get; set; } = new Rect(100, 100, 1000, 600);
|
||||
|
||||
public StandardModeSettings()
|
||||
{
|
||||
LyricsDisplayType = LyricsDisplayType.SplitView;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +15,12 @@ namespace BetterLyrics.WinUI3.Models.Settings
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string LibreTranslateServer { get; set; } = string.Empty;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTranslationEnabled { get; set; } = true;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowTranslationOnly { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SelectedTargetLanguageIndex { get; set; } = LanguageHelper.GetDefaultTargetLanguageIndex();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial string SelectedTargetLanguageCode { get; set; } = LanguageHelper.GetDefaultTargetLanguageCode();
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsJyutpingEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ChineseRomanization ChineseRomanization { get; set; }
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsChineseRomanizationEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsJapaneseRomanizationEnabled { get; set; } = false;
|
||||
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsTraditionalChineseEnabled { get; set; } = false;
|
||||
|
||||
public TranslationSettings() { }
|
||||
}
|
||||
|
||||
@@ -21,11 +21,14 @@ namespace BetterLyrics.WinUI3.Models
|
||||
public partial double? DurationMs { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string? SourceAppUserModelId { get; set; } = null;
|
||||
public partial string? PlayerId { get; set; } = null;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string? SongId { get; set; } = null;
|
||||
|
||||
public SongInfo() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,17 +14,8 @@
|
||||
<Grid>
|
||||
<canvas:CanvasAnimatedControl
|
||||
x:Name="LyricsCanvas"
|
||||
CreateResources="LyricsCanvas_CreateResources"
|
||||
Draw="LyricsCanvas_Draw"
|
||||
Update="LyricsCanvas_Update" />
|
||||
<Grid
|
||||
Margin="36"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Visibility="{x:Bind ViewModel.IsTranslating, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<FontIcon
|
||||
x:Name="RotatingIcon"
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
Glyph="" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||