Compare commits
156 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
041459e564 | ||
|
|
7de813b645 | ||
|
|
838d663834 | ||
|
|
9add190383 | ||
|
|
fa58360884 | ||
|
|
4dd032655c | ||
|
|
80984218ec | ||
|
|
df45026638 | ||
|
|
aafc5c9fb5 | ||
|
|
c5fccfbb63 | ||
|
|
42f03b4291 | ||
|
|
3339bb0d41 | ||
|
|
7d60f29845 | ||
|
|
bd7e93f3e6 | ||
|
|
c37c6ab489 | ||
|
|
125794c44f | ||
|
|
f5bdb3a431 | ||
|
|
e15699bb11 | ||
|
|
780cd302f0 | ||
|
|
345949f536 | ||
|
|
8dd178991a | ||
|
|
834d0bf5cc | ||
|
|
6d6ecb39b6 | ||
|
|
7db7c68acc | ||
|
|
7fea4ac900 | ||
|
|
3783227f43 | ||
|
|
222c1d9aa1 | ||
|
|
4e668c9890 | ||
|
|
a823901b13 | ||
|
|
2f9b3df92c | ||
|
|
5f65021400 | ||
|
|
c28866fdbe | ||
|
|
fc606f9d30 | ||
|
|
e5d33177d4 | ||
|
|
ab029c9da3 | ||
|
|
a28eef85a5 | ||
|
|
9905d7642c | ||
|
|
02341ecc4a | ||
|
|
13802e7d16 | ||
|
|
d25920c697 | ||
|
|
639c4171dd | ||
|
|
95a1d65c50 | ||
|
|
feb4f47db9 | ||
|
|
81f2c4e34a | ||
|
|
48176cce0f | ||
|
|
77d41c4813 | ||
|
|
8d1be745ac | ||
|
|
978702b6ae | ||
|
|
0e1f487ac1 | ||
|
|
3c8775d2cd | ||
|
|
7c39214f2d | ||
|
|
b7952f5eef | ||
|
|
8c0d3667e4 | ||
|
|
e1f900a9e6 | ||
|
|
212c1fbcdd | ||
|
|
2cb04fa1b7 | ||
|
|
8ab3a53a38 | ||
|
|
3b4d5b9668 | ||
|
|
2409165b91 | ||
|
|
fe1eb2882e | ||
|
|
51dd58fc74 | ||
|
|
0f5f663b32 | ||
|
|
4815c32dba | ||
|
|
3f5a0a0d73 | ||
|
|
1b34b28fbe | ||
|
|
fe4d67c1f1 | ||
|
|
1ae00257a1 | ||
|
|
814de1a4a5 | ||
|
|
28b568e7a4 | ||
|
|
786d23b320 | ||
|
|
a394527f80 | ||
|
|
80422376c3 | ||
|
|
5114c83843 | ||
|
|
835e0d34fc | ||
|
|
7ab833a53a | ||
|
|
d348a30237 | ||
|
|
d0b626c508 | ||
|
|
9debdc76f9 | ||
|
|
67a45e90fa | ||
|
|
b4c7655043 | ||
|
|
2adc2aced2 | ||
|
|
e638739638 | ||
|
|
c24213358e | ||
|
|
6e78f849c4 | ||
|
|
80444b69e0 | ||
|
|
78775e9bb3 | ||
|
|
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 |
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']
|
||||
|
||||
@@ -1,150 +1,150 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0'">
|
||||
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
|
||||
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
|
||||
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<AssetTargetFallback>net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
|
||||
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
|
||||
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
|
||||
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
|
||||
<Content Include="Images\LargeTile.scale-100.png" />
|
||||
<Content Include="Images\LargeTile.scale-125.png" />
|
||||
<Content Include="Images\LargeTile.scale-150.png" />
|
||||
<Content Include="Images\LargeTile.scale-200.png" />
|
||||
<Content Include="Images\LargeTile.scale-400.png" />
|
||||
<Content Include="Images\SmallTile.scale-100.png" />
|
||||
<Content Include="Images\SmallTile.scale-125.png" />
|
||||
<Content Include="Images\SmallTile.scale-150.png" />
|
||||
<Content Include="Images\SmallTile.scale-200.png" />
|
||||
<Content Include="Images\SmallTile.scale-400.png" />
|
||||
<Content Include="Images\SplashScreen.scale-100.png" />
|
||||
<Content Include="Images\SplashScreen.scale-125.png" />
|
||||
<Content Include="Images\SplashScreen.scale-150.png" />
|
||||
<Content Include="Images\SplashScreen.scale-200.png" />
|
||||
<Content Include="Images\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Images\SplashScreen.scale-400.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-100.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-125.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-150.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-400.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-100.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-125.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-150.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-400.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
|
||||
<Content Include="Images\StoreLogo.scale-100.png" />
|
||||
<Content Include="Images\StoreLogo.scale-125.png" />
|
||||
<Content Include="Images\StoreLogo.scale-150.png" />
|
||||
<Content Include="Images\StoreLogo.scale-200.png" />
|
||||
<Content Include="Images\StoreLogo.scale-400.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-100.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-125.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-150.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-400.png" />
|
||||
<None Include="Package.StoreAssociation.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
|
||||
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0'">
|
||||
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x86">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x86">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x86</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
|
||||
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
|
||||
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<AssetTargetFallback>net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
|
||||
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
|
||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
|
||||
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
|
||||
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<AppxBundle>Always</AppxBundle>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
|
||||
<Content Include="Images\LargeTile.scale-100.png" />
|
||||
<Content Include="Images\LargeTile.scale-125.png" />
|
||||
<Content Include="Images\LargeTile.scale-150.png" />
|
||||
<Content Include="Images\LargeTile.scale-200.png" />
|
||||
<Content Include="Images\LargeTile.scale-400.png" />
|
||||
<Content Include="Images\SmallTile.scale-100.png" />
|
||||
<Content Include="Images\SmallTile.scale-125.png" />
|
||||
<Content Include="Images\SmallTile.scale-150.png" />
|
||||
<Content Include="Images\SmallTile.scale-200.png" />
|
||||
<Content Include="Images\SmallTile.scale-400.png" />
|
||||
<Content Include="Images\SplashScreen.scale-100.png" />
|
||||
<Content Include="Images\SplashScreen.scale-125.png" />
|
||||
<Content Include="Images\SplashScreen.scale-150.png" />
|
||||
<Content Include="Images\SplashScreen.scale-200.png" />
|
||||
<Content Include="Images\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Images\SplashScreen.scale-400.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-100.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-125.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-150.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Images\Square150x150Logo.scale-400.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-100.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-125.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-150.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Images\Square44x44Logo.scale-400.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
|
||||
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
|
||||
<Content Include="Images\StoreLogo.scale-100.png" />
|
||||
<Content Include="Images\StoreLogo.scale-125.png" />
|
||||
<Content Include="Images\StoreLogo.scale-150.png" />
|
||||
<Content Include="Images\StoreLogo.scale-200.png" />
|
||||
<Content Include="Images\StoreLogo.scale-400.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-100.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-125.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-150.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Images\Wide310x150Logo.scale-400.png" />
|
||||
<None Include="Package.StoreAssociation.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
|
||||
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6584" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251003001" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||
</Project>
|
||||
@@ -12,13 +12,13 @@
|
||||
<Identity
|
||||
Name="37412.BetterLyrics"
|
||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||
Version="1.0.54.0" />
|
||||
Version="1.0.92.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>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converter="using:BetterLyrics.WinUI3.Converter"
|
||||
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
|
||||
xmlns:globalization="using:Windows.Globalization"
|
||||
xmlns:local="using:BetterLyrics.WinUI3"
|
||||
xmlns:media="using:CommunityToolkit.WinUI.Media">
|
||||
<Application.Resources>
|
||||
@@ -51,10 +52,19 @@
|
||||
<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:BoolNegationToOpacityConverter x:Key="BoolNegationToOpacityConverter" />
|
||||
<converter:RectToMarginConverter x:Key="RectToMarginConverter" />
|
||||
<converter:LanguageCodeToDisplayedNameConverter x:Key="LanguageCodeToDisplayedNameConverter" />
|
||||
<converter:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
|
||||
<converter:DisplayLanguageCodeToIndexConverter x:Key="DisplayLanguageCodeToIndexConverter" />
|
||||
<converter:PathToParentFolderConverter x:Key="PathToParentFolderConverter" />
|
||||
|
||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||
@@ -323,6 +333,16 @@
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="FlyoutGhostStyle"
|
||||
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||
TargetType="FlyoutPresenter">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||
</Style>
|
||||
|
||||
<StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" />
|
||||
@@ -331,6 +351,7 @@
|
||||
|
||||
<!-- Fonts -->
|
||||
<FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
|
||||
@@ -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,12 @@ 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<LyricsWindowSwitchWindowViewModel>()
|
||||
.AddSingleton<LyricsWindowViewModel>()
|
||||
.AddSingleton<SettingsWindowViewModel>()
|
||||
.AddSingleton<SystemTrayViewModel>()
|
||||
|
||||
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/AMLLPlayer.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
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/FluidEffect.bin
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/HyPlayer.png
Normal file
|
After Width: | Height: | Size: 830 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 |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/PlanetMusic.png
Normal file
|
After Width: | Height: | Size: 49 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 |
@@ -23,15 +23,20 @@
|
||||
<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\LyricsSettingsControl.xaml" />
|
||||
<None Remove="Controls\FontFamilyAutoSuggestBox.xaml" />
|
||||
<None Remove="Controls\LyricsSearchControl.xaml" />
|
||||
<None Remove="Controls\LyricsStyleSettingsControl.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" />
|
||||
@@ -44,7 +49,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="3v.EvtSource" Version="2.0.0" />
|
||||
<PackageReference Include="ColorThief.ImageSharp" Version="1.0.0" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Controls.OpacityMaskView" Version="0.1.251021-build.2365" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.MarqueeText" Version="0.1.230830" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.OpacityMaskView" Version="0.1.250703-build.2173" />
|
||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
|
||||
@@ -59,38 +64,39 @@
|
||||
<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-kana" Version="1.0.2" />
|
||||
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
|
||||
<PackageReference Include="DevWinUI.Controls" Version="9.4.2" />
|
||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
|
||||
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.0" />
|
||||
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.2" />
|
||||
<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.Extensions.DependencyInjection" Version="9.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.6584" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251003001" />
|
||||
<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="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" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="9.0.10" />
|
||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.10" />
|
||||
<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" />
|
||||
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.1.6" />
|
||||
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.1.6" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="4.1.6" />
|
||||
<PackageReference Include="WinUIEx" Version="2.6.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.2.0" />
|
||||
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.2.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.2.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.2.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" />
|
||||
<PackageReference Include="WinUIEx" Version="2.9.0" />
|
||||
<PackageReference Include="z440.atl.core" Version="7.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Hqub.Lastfm">
|
||||
<HintPath>..\..\..\Last.fm\src\Hqub.Lastfm\bin\Release\netstandard2.0\Hqub.Lastfm.dll</HintPath>
|
||||
</Reference>
|
||||
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
|
||||
<ProjectReference Include="..\..\Impressionist\Impressionist\Impressionist.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Rendering\InAppLyricsRenderer.xaml">
|
||||
@@ -105,21 +111,28 @@
|
||||
<!--Disable Trimming for Specific Packages-->
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="TagLibSharp" />
|
||||
<TrimmerRootAssembly Include="NAudio.Wasapi" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="Assets\AIMP.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AMLLPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\AppleMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<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\FluidEffect.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\Empty.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\EmptyBox.png">
|
||||
@@ -131,6 +144,9 @@
|
||||
<Content Update="Assets\foobar2000.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\HyPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\iTunes.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -143,6 +159,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 +174,22 @@
|
||||
<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\PlanetMusic.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\PotPlayer.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\QQMusic.png">
|
||||
@@ -173,19 +198,59 @@
|
||||
<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="Controls\FontFamilyAutoSuggestBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsStyleSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</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>
|
||||
@@ -197,12 +262,7 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\AllLyricsSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsSettingsControl.xaml">
|
||||
<Page Update="Controls\LyricsEffectSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
@@ -222,7 +282,7 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Controls\LyricsBavkgroundSettingsControl.xaml">
|
||||
<Page Update="Controls\LyricsBackgroundSettingsControl.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
@@ -251,6 +311,14 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PRIResource Update="Strings\en-US\Resources.resw">
|
||||
<Generator></Generator>
|
||||
</PRIResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="TemplateSelector\" />
|
||||
</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,10 @@ 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 WikiUrl = "https://github.com/jayfunc/BetterLyrics/wiki";
|
||||
public const string AppleMusicCfgUrl = $"{WikiUrl}/Lyrics-provider-configuration#apple-music";
|
||||
public const string FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/index.md";
|
||||
public const string QQGroupUrl = "https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info";
|
||||
public const string 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,38 +17,92 @@
|
||||
|
||||
<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="SettingsPageAutoAdjust">
|
||||
<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"
|
||||
Frequency="1"
|
||||
|
||||
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=}">
|
||||
<local:ExtendedSlider
|
||||
Default="12"
|
||||
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:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFontSize"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<ToggleSwitch IsOn="{x:Bind AlbumArtLayoutSettings.IsAutoSongInfoFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard>
|
||||
<local:ExtendedSlider
|
||||
Default="18"
|
||||
Frequency="2"
|
||||
IsEnabled="{x:Bind AlbumArtLayoutSettings.IsAutoSongInfoFontSize, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
|
||||
Maximum="72"
|
||||
Minimum="8"
|
||||
Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<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>
|
||||
@@ -5,8 +5,11 @@
|
||||
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:globalization="using:Windows.Globalization"
|
||||
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="using:BetterLyrics.WinUI3.Models"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
@@ -24,13 +27,14 @@
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.Language, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageSystemLanguage" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEN" />
|
||||
<ComboBoxItem x:Uid="SettingsPageSC" />
|
||||
<ComboBoxItem x:Uid="SettingsPageTC" />
|
||||
<ComboBoxItem x:Uid="SettingsPageJA" />
|
||||
<ComboBoxItem x:Uid="SettingsPageKO" />
|
||||
<ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedDisplayLanguages}" SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.LanguageCode, Mode=TwoWay, Converter={StaticResource DisplayLanguageCodeToIndexConverter}}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:ExtendedLanguage">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock Text="{x:Bind Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard>
|
||||
@@ -50,125 +54,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,96 @@
|
||||
<?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}"
|
||||
CornerRadius="4" />
|
||||
<!-- 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">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Margin="0,0,3,0"
|
||||
FontSize="12"
|
||||
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock FontSize="12" Text="[" />
|
||||
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}" />
|
||||
<TextBlock FontSize="12" Text="×" />
|
||||
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}" />
|
||||
<TextBlock FontSize="12" Text="]" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<!-- 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,60 @@
|
||||
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
|
||||
IsEnabled="{x:Bind IsSliderEnabled, Mode=OneWay}"
|
||||
Maximum="{x:Bind Maximum, Mode=OneWay}"
|
||||
Minimum="{x:Bind Minimum, Mode=OneWay}"
|
||||
SnapsTo="Ticks"
|
||||
StepFrequency="{x:Bind Frequency, Mode=OneWay}"
|
||||
Tapped="Slider_Tapped"
|
||||
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 RoundedValue, 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>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using BetterLyrics.WinUI3.Events;
|
||||
using Microsoft.UI.Input;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -21,6 +22,8 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class ExtendedSlider : UserControl
|
||||
{
|
||||
public event EventHandler<ExtendedSliderValueChangedByUserEventArgs>? ValueChangedByUser;
|
||||
|
||||
public ExtendedSlider()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -61,19 +64,23 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty FrequencyProperty =
|
||||
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(1.0));
|
||||
public static readonly DependencyProperty MinimumProperty =
|
||||
DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
public static readonly DependencyProperty MaximumProperty =
|
||||
DependencyProperty.Register(nameof(Maximum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
public static readonly DependencyProperty ValueProperty =
|
||||
DependencyProperty.Register(nameof(Value), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
private static readonly DependencyProperty RoundedValueProperty =
|
||||
DependencyProperty.Register(nameof(Value), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
public static readonly DependencyProperty DefaultProperty =
|
||||
DependencyProperty.Register(nameof(Default), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||
public static readonly DependencyProperty ResetButtonVisibilityProperty =
|
||||
DependencyProperty.Register(nameof(ResetButtonVisibility), typeof(Visibility), typeof(ExtendedSlider), new PropertyMetadata(Visibility.Visible));
|
||||
public static readonly DependencyProperty UnitProperty =
|
||||
DependencyProperty.Register(nameof(Unit), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(""));
|
||||
public static readonly DependencyProperty IsSliderEnabledProperty =
|
||||
DependencyProperty.Register(nameof(IsSliderEnabled), typeof(bool), typeof(ExtendedSlider), new PropertyMetadata(true));
|
||||
|
||||
public double Frequency
|
||||
{
|
||||
@@ -93,7 +100,16 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
public double Value
|
||||
{
|
||||
get => (double)GetValue(ValueProperty);
|
||||
set => SetValue(ValueProperty, value);
|
||||
set
|
||||
{
|
||||
SetValue(ValueProperty, value);
|
||||
SetValue(RoundedValueProperty, value.ToString("F1").Replace(".0", ""));
|
||||
}
|
||||
}
|
||||
private string RoundedValue
|
||||
{
|
||||
get => (string)GetValue(RoundedValueProperty);
|
||||
set => SetValue(RoundedValueProperty, value);
|
||||
}
|
||||
public double Default
|
||||
{
|
||||
@@ -110,20 +126,33 @@ namespace BetterLyrics.WinUI3.Controls
|
||||
get => (string)GetValue(UnitProperty);
|
||||
set => SetValue(UnitProperty, value);
|
||||
}
|
||||
public bool IsSliderEnabled
|
||||
{
|
||||
get => (bool)GetValue(IsSliderEnabledProperty);
|
||||
set => SetValue(IsSliderEnabledProperty, value);
|
||||
}
|
||||
|
||||
private void ResetButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Value = Default;
|
||||
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
|
||||
}
|
||||
|
||||
private void SubtractButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Subtract();
|
||||
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
|
||||
}
|
||||
|
||||
private void AddButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Add();
|
||||
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
|
||||
}
|
||||
|
||||
private void Slider_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.FontFamilyAutoSuggestBox"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<AutoSuggestBox
|
||||
x:Name="AutoSuggestBox"
|
||||
Width="150"
|
||||
GotFocus="AutoSuggestBox_GotFocus"
|
||||
LostFocus="AutoSuggestBox_LostFocus"
|
||||
SuggestionChosen="AutoSuggestBox_SuggestionChosen"
|
||||
Text="{x:Bind SelectedFontFamily, Mode=OneWay}"
|
||||
TextChanged="AutoSuggestBox_TextChanged" />
|
||||
<Button
|
||||
Click="Button_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,95 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class FontFamilyAutoSuggestBox : UserControl
|
||||
{
|
||||
private List<string> SystemFontNames { get; set; } = [.. FontHelper.SystemFontFamilies];
|
||||
|
||||
public FontFamilyAutoSuggestBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedFontFamilyProperty =
|
||||
DependencyProperty.Register(nameof(SelectedFontFamily), typeof(string), typeof(FontFamilyAutoSuggestBox), new PropertyMetadata(default));
|
||||
|
||||
public string SelectedFontFamily
|
||||
{
|
||||
get => (string)GetValue(SelectedFontFamilyProperty);
|
||||
set => SetValue(SelectedFontFamilyProperty, value);
|
||||
}
|
||||
|
||||
|
||||
private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
|
||||
{
|
||||
SelectedFontFamily = args.SelectedItem.ToString() ?? "";
|
||||
}
|
||||
|
||||
private void UpdateAutoSuggestBoxItemsSource()
|
||||
{
|
||||
var suitableItems = new List<string>();
|
||||
var splitText = AutoSuggestBox.Text.ToLower().Split(" ");
|
||||
foreach (var fontFamily in SystemFontNames)
|
||||
{
|
||||
var found = splitText.All((key) =>
|
||||
{
|
||||
return fontFamily.ToLower().Contains(key);
|
||||
});
|
||||
if (found)
|
||||
{
|
||||
suitableItems.Add(fontFamily);
|
||||
}
|
||||
}
|
||||
if (suitableItems.Count == 0)
|
||||
{
|
||||
suitableItems.Add("N/A");
|
||||
}
|
||||
AutoSuggestBox.ItemsSource = suitableItems.Order();
|
||||
}
|
||||
|
||||
private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
// Since selecting an item will also change the text,
|
||||
// only listen to changes caused by user entering text.
|
||||
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
|
||||
{
|
||||
UpdateAutoSuggestBoxItemsSource();
|
||||
}
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SystemFontNames = [.. FontHelper.SystemFontFamilies];
|
||||
}
|
||||
|
||||
private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
UpdateAutoSuggestBoxItemsSource();
|
||||
}
|
||||
|
||||
private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AutoSuggestBox.Text = SelectedFontFamily;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?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:enums="using:BetterLyrics.WinUI3.Enums"
|
||||
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">
|
||||
<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" 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"
|
||||
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageAlbumArtLayer" 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"
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageFluidLayer" 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"
|
||||
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsBackgroundSettings.FluidOverlayOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePaletteGeneratorType">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsBackgroundSettings.PaletteGeneratorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageMedianCut" />
|
||||
<ComboBoxItem x:Uid="SettingsPageOctTree" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageSnowFlakeLayer" IsExpanded="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSnowFlakeOverlayEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount">
|
||||
<uc:ExtendedSlider
|
||||
|
||||
Maximum="100"
|
||||
Minimum="10"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsBackgroundSettings.SnowFlakeOverlayAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageSpectrumLayer">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</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,13 +21,20 @@ using Windows.Foundation.Collections;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class AllLyricsSettingsControl : UserControl
|
||||
public sealed partial class LyricsBackgroundSettingsControl : UserControl
|
||||
{
|
||||
public AllLyricsSettingsControlViewModel ViewModel => (AllLyricsSettingsControlViewModel)DataContext;
|
||||
public AllLyricsSettingsControl()
|
||||
public static readonly DependencyProperty LyricsBackgroundSettingsProperty =
|
||||
DependencyProperty.Register(nameof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsBackgroundSettings LyricsBackgroundSettings
|
||||
{
|
||||
get => (LyricsBackgroundSettings)GetValue(LyricsBackgroundSettingsProperty);
|
||||
set => SetValue(LyricsBackgroundSettingsProperty, value);
|
||||
}
|
||||
|
||||
public LyricsBackgroundSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<AllLyricsSettingsControlViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,304 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsEffectSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<!-- Effect -->
|
||||
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageLyricsEffect"
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Effect" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
|
||||
Default="0"
|
||||
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
|
||||
Default="5"
|
||||
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 高亮 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPagePhoneticText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.PhoneticLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsHighlightScope">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageOriginalText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.OriginalLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslatedText">
|
||||
<local:ExtendedSlider
|
||||
Default="60"
|
||||
Frequency="5"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.TranslatedLyricsHighlightAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 阴影 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsShadow"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 辉光效果 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsGlowEffect"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 浮动动画 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFloatAnimation"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="1"
|
||||
|
||||
Maximum="4"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 扇形歌词 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageFan"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="30"
|
||||
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.FanLyricsAngle, Mode=TwoWay}" />
|
||||
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 3D 歌词 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPage3DLyrics"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard Header="X" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DXAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Y" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DYAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Z" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
|
||||
Maximum="90"
|
||||
Minimum="-90"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DZAngle, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPage3DLyricsDepth" IsEnabled="{x:Bind LyricsEffectSettings.Is3DLyricsEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="1000"
|
||||
Frequency="10"
|
||||
Maximum="1000"
|
||||
Minimum="100"
|
||||
Unit="°"
|
||||
Value="{x:Bind LyricsEffectSettings.Lyrics3DDepth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 滚动动画 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageScrollEasing" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
|
||||
<local:ExtendedSlider
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDelay">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="50"
|
||||
Maximum="2000"
|
||||
Minimum="0"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDelay, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="50"
|
||||
Maximum="2000"
|
||||
Minimum="0"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDelay, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -21,27 +21,15 @@ using Windows.Foundation.Collections;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class LyricsSettingsControl : UserControl
|
||||
public sealed partial class LyricsEffectSettingsControl : UserControl
|
||||
{
|
||||
public ObservableCollection<string> SystemFontNames { get; set; } = [.. FontHelper.SystemFontFamilies];
|
||||
|
||||
public LyricsSettingsControl()
|
||||
public LyricsEffectSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsStyleSettingsProperty =
|
||||
DependencyProperty.Register(nameof(LyricsStyleSettings), typeof(LyricsStyleSettings), typeof(LyricsSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsStyleSettings LyricsStyleSettings
|
||||
{
|
||||
get => (LyricsStyleSettings)GetValue(LyricsStyleSettingsProperty);
|
||||
set => SetValue(LyricsStyleSettingsProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public static readonly DependencyProperty LyricsEffectSettingsProperty =
|
||||
DependencyProperty.Register(nameof(LyricsEffectSettings), typeof(LyricsEffectSettings), typeof(LyricsSettingsControl), new PropertyMetadata(default));
|
||||
DependencyProperty.Register(nameof(LyricsEffectSettings), typeof(LyricsEffectSettings), typeof(LyricsEffectSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsEffectSettings LyricsEffectSettings
|
||||
{
|
||||
@@ -0,0 +1,261 @@
|
||||
<?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:models="using:BetterLyrics.WinUI3.Models"
|
||||
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 x:Uid="LyricsSearchControlAlbum" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalAlbum, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedAlbum, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||
<Button
|
||||
VerticalAlignment="Center"
|
||||
Command="{x:Bind ViewModel.ResetMappedAlbumCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
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 x:DataType="models:LyricsSearchResult">
|
||||
<ListViewItem IsEnabled="{x:Bind IsFound}">
|
||||
<Grid Opacity="{x:Bind IsFound, Converter={StaticResource BoolToOpacityConverter}}">
|
||||
<RelativePanel Padding="0,6">
|
||||
<TextBlock
|
||||
x:Name="SearchedTitle"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
Text="{x:Bind Title}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedArtists"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
RelativePanel.Below="SearchedTitle"
|
||||
Text="{x:Bind Artist}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedAlbum"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
RelativePanel.Below="SearchedArtists"
|
||||
Text="{x:Bind Album}"
|
||||
TextWrapping="Wrap"
|
||||
Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBlock
|
||||
x:Name="SearchedProvider"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
Text="{x:Bind Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||
</RelativePanel>
|
||||
<TextBlock
|
||||
x:Uid="LyricsSearchControlNotFound"
|
||||
VerticalAlignment="Center"
|
||||
Text="Not found"
|
||||
Visibility="{x:Bind 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">
|
||||
<Pivot ItemsSource="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<Pivot.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{Binding LanguageCode, Mode=OneWay, Converter={StaticResource LanguageCodeToDisplayedNameConverter}}" />
|
||||
</DataTemplate>
|
||||
</Pivot.HeaderTemplate>
|
||||
<Pivot.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<ListView ItemsSource="{Binding LyricsLines, Mode=OneWay}" SelectionChanged="ListView_SelectionChanged">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
|
||||
<TextBlock
|
||||
Margin="1,0"
|
||||
Foreground="{ThemeResource SystemFillColorNeutralBrush}"
|
||||
Text="-" />
|
||||
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding EndMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
|
||||
<TextBlock Margin="6,0" Text="{Binding OriginalText}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</DataTemplate>
|
||||
</Pivot.ItemTemplate>
|
||||
</Pivot>
|
||||
<StackPanel
|
||||
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.LyricsDataArr, Mode=OneWay}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="{x:Null}">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind ViewModel.LyricsDataArr, 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,14 +22,19 @@ using Windows.Foundation.Collections;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class LyricsBavkgroundSettingsControl : UserControl
|
||||
public sealed partial class LyricsSearchControl : UserControl
|
||||
{
|
||||
public LyricsBackgroundSettingsControlViewModel ViewModel => (LyricsBackgroundSettingsControlViewModel)DataContext;
|
||||
public LyricsSearchControlViewModel ViewModel => (LyricsSearchControlViewModel)DataContext;
|
||||
|
||||
public LyricsBavkgroundSettingsControl()
|
||||
public LyricsSearchControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsBackgroundSettingsControlViewModel>();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>();
|
||||
}
|
||||
|
||||
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
ViewModel.SelectedLyricsLine = e.OriginalSource as LyricsLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,379 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<!-- Lyrics style -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox ItemsSource="{x:Bind SystemFontNames, Mode=OneWay}" SelectedItem="{x:Bind LyricsStyleSettings.LyricsFontFamily, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="30"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="5"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsStrokeFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ColorPicker>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ColorPicker>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</ColorPicker>
|
||||
|
||||
<controls: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:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
|
||||
Default="0.5"
|
||||
Frequency="0.1"
|
||||
Maximum="2"
|
||||
Minimum="0"
|
||||
Unit="x"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
|
||||
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Effect -->
|
||||
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageLyricsEffect"
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="Effect" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
|
||||
Default="0"
|
||||
Frequency="1"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
|
||||
Default="5"
|
||||
Frequency="1"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 高亮 -->
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsHighlightScope" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<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
|
||||
x:Uid="SettingsPageLyricsShadow"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
Frequency="1"
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 辉光效果 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsGlowEffect"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="8"
|
||||
Frequency="1"
|
||||
Maximum="20"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 浮动动画 -->
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageLyricsFloatAnimation"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Default="1"
|
||||
Frequency="1"
|
||||
Maximum="4"
|
||||
Minimum="1"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 扇形歌词 -->
|
||||
<controls:SettingsCard x:Uid="SettingsPageFan" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageScrollEasing"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
|
||||
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
|
||||
</ComboBox>
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollTopDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsScrollBottomDurationExtendedSlider"
|
||||
Default="500"
|
||||
Frequency="50"
|
||||
Maximum="1000"
|
||||
Minimum="50"
|
||||
Unit="ms"
|
||||
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,240 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<UserControl
|
||||
x:Class="BetterLyrics.WinUI3.Controls.LyricsStyleSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<!-- Lyrics style -->
|
||||
|
||||
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageCJK">
|
||||
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsCJKFontFamily, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWesternChar">
|
||||
<local:FontFamilyAutoSuggestBox SelectedFontFamily="{x:Bind LyricsStyleSettings.LyricsWesternFontFamily, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="30"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Unit="%"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
Default="0"
|
||||
Maximum="10"
|
||||
Minimum="0"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 字体颜色 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageStrokeFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard HorizontalContentAlignment="Left">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsFgFontColor">
|
||||
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||
</ComboBox>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="Equal"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
<interactivity:DataTriggerBehavior
|
||||
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||
ComparisonCondition="NotEqual"
|
||||
Value="2">
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<ColorPicker
|
||||
ColorSpectrumShape="Box"
|
||||
IsAlphaEnabled="True"
|
||||
IsAlphaSliderVisible="True"
|
||||
IsAlphaTextInputVisible="True"
|
||||
IsColorChannelTextInputVisible="True"
|
||||
IsColorSliderVisible="True"
|
||||
IsHexInputVisible="True"
|
||||
IsMoreButtonVisible="True"
|
||||
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- 字体大小 -->
|
||||
<controls:SettingsExpander x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
|
||||
<ToggleSwitch IsOn="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPagePhoneticText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.PhoneticLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageOriginalText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.OriginalLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageTranslatedText" IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||
<local:ExtendedSlider
|
||||
Frequency="2"
|
||||
Maximum="256"
|
||||
Minimum="12"
|
||||
ResetButtonVisibility="Collapsed"
|
||||
Value="{x:Bind LyricsStyleSettings.TranslatedLyricsFontSize, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<local:ExtendedSlider
|
||||
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
|
||||
Default="0.5"
|
||||
Frequency="0.1"
|
||||
Maximum="2"
|
||||
Minimum="0"
|
||||
Unit="x"
|
||||
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
|
||||
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,40 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace BetterLyrics.WinUI3.Controls
|
||||
{
|
||||
public sealed partial class LyricsStyleSettingsControl : UserControl
|
||||
{
|
||||
public LyricsStyleSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty LyricsStyleSettingsProperty =
|
||||
DependencyProperty.Register(nameof(LyricsStyleSettings), typeof(LyricsStyleSettings), typeof(LyricsStyleSettingsControl), new PropertyMetadata(default));
|
||||
|
||||
public LyricsStyleSettings LyricsStyleSettings
|
||||
{
|
||||
get => (LyricsStyleSettings)GetValue(LyricsStyleSettingsProperty);
|
||||
set => SetValue(LyricsStyleSettingsProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
<?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">
|
||||
<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">
|
||||
|
||||
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<Pivot SelectionChanged="Pivot_SelectionChanged">
|
||||
|
||||
<PivotItem Tag="General">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="AppSettingsControlGeneral"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
<PivotItem Tag="AlbumArtStyle">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageAlbumStyle"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
<PivotItem Tag="LyricsStyle">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageLyricsStyle"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
<PivotItem Tag="LyricsEffect">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageLyricsEffect"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
<PivotItem Tag="LyricsBackground">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageBackgroundOverlay"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
<PivotItem Tag="Advanced">
|
||||
<PivotItem.Header>
|
||||
<TextBlock
|
||||
x:Uid="SettingsPageAdvanced"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource BodyTextBlockStyle}" />
|
||||
</PivotItem.Header>
|
||||
</PivotItem>
|
||||
|
||||
</Pivot>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<controls:SwitchPresenter Margin="0,110,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
|
||||
<controls:SwitchPresenter.ContentTransitions>
|
||||
<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: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"
|
||||
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:SettingsCard x:Uid="SettingsPageDockMonitor" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
|
||||
<Button
|
||||
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
FontSize=12,
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<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"
|
||||
IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
|
||||
<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:SettingsExpander
|
||||
x:Uid="SettingsPageWindowBounds"
|
||||
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsExpanded="True">
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard Header="X">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard Header="Y">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageWidth">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="SettingsPageHeight">
|
||||
<NumberBox
|
||||
SmallChange="10"
|
||||
SpinButtonPlacementMode="Inline"
|
||||
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: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 -->
|
||||
<controls:Case Value="LyricsStyle">
|
||||
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics effect -->
|
||||
<controls:Case Value="LyricsEffect">
|
||||
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics background -->
|
||||
<controls:Case Value="LyricsBackground">
|
||||
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
|
||||
</controls:Case>
|
||||
|
||||
<!-- Advanced -->
|
||||
<controls:Case Value="Advanced">
|
||||
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
<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: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>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,91 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||
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 readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
|
||||
|
||||
public LyricsWindowSettingsControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSettingsControlViewModel>();
|
||||
}
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is Pivot pivot)
|
||||
{
|
||||
if (pivot.SelectedItem is PivotItem pivotItem)
|
||||
{
|
||||
ViewModel?.ListViewSelectedItemTag = pivotItem.Tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?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">
|
||||
<FontIcon
|
||||
Margin="20"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
Glyph="" />
|
||||
<Button
|
||||
Margin="12"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Click="Button_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}">
|
||||
<Button.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="Escape" />
|
||||
</Button.KeyboardAccelerators>
|
||||
</Button>
|
||||
|
||||
<ListView
|
||||
Margin="48,56"
|
||||
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>
|
||||
|
||||
<StackPanel
|
||||
Margin="20"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Bottom"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<FontIcon
|
||||
Margin="0,1,0,0"
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||
Glyph="" />
|
||||
<TextBlock x:Uid="LyricsWindowSwitchWindowHelp" Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
@@ -0,0 +1,54 @@
|
||||
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 System.Threading.Tasks;
|
||||
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 async void Grid_Tapped(object sender, TappedRoutedEventArgs e)
|
||||
{
|
||||
await HideAsync();
|
||||
}
|
||||
|
||||
private async void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await HideAsync();
|
||||
}
|
||||
|
||||
private async Task HideAsync()
|
||||
{
|
||||
var lyricsWindowSwitchWindow = WindowHelper.GetWindowByWindowType<LyricsWindowSwitchWindow>();
|
||||
lyricsWindowSwitchWindow?.ViewModel.RootGridOpacity = 0;
|
||||
await Task.Delay(300);
|
||||
WindowHelper.HideWindow<LyricsWindowSwitchWindow>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,11 @@
|
||||
x:Class="BetterLyrics.WinUI3.Controls.PlaybackSettingsControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
|
||||
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:globalization="using:Windows.Globalization"
|
||||
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
@@ -31,16 +34,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,10 +125,17 @@
|
||||
</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.HorizontalScrollBarVisibility="Hidden"
|
||||
ScrollViewer.HorizontalScrollMode="Enabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollMode="Disabled"
|
||||
@@ -134,6 +148,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 +176,7 @@
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Center"
|
||||
@@ -187,6 +206,88 @@
|
||||
<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">
|
||||
<HyperlinkButton
|
||||
Content="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}"
|
||||
IsEnabled="False"
|
||||
NavigateUri="{x:Bind ViewModel.OriginalLyricsRef, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||
<HyperlinkButton
|
||||
Content="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}"
|
||||
IsEnabled="False"
|
||||
NavigateUri="{x:Bind ViewModel.TranslatedLyricsRef, Mode=OneWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Lyrics translation -->
|
||||
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander x:Uid="LyricsPageTranslationEnabled" 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 ItemsSource="{x:Bind helper:LanguageHelper.SupportedTranslationTargetLanguages}" SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="models:ExtendedLanguage">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBlock Text="{x:Bind Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</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:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<!-- Lyrics phonetic -->
|
||||
<TextBlock x:Uid="SettingsPagePhonetic" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<controls:SettingsExpander x:Uid="SettingsPageChinese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
|
||||
<controls:SettingsExpander.Items>
|
||||
<controls:SettingsCard IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
|
||||
<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">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- 中文简体繁体偏好 -->
|
||||
<TextBlock x:Uid="SettingsPageChineseLyrics" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<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,88 +319,10 @@
|
||||
</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>
|
||||
<controls:SettingsCard x:Uid="SettingsPageServerAddress">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox
|
||||
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||
@@ -311,6 +334,30 @@
|
||||
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<!-- Apple Music token -->
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="Apple Muisc media-user-token" />
|
||||
<controls:SettingsCard
|
||||
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
|
||||
Description="Use at your own risk"
|
||||
Foreground="{ThemeResource SystemFillColorCautionBrush}"
|
||||
Header="WARNING">
|
||||
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||
<TextBox
|
||||
MaxWidth="250"
|
||||
PlaceholderText="media-user-token"
|
||||
Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}"
|
||||
TextWrapping="Wrap" />
|
||||
<HyperlinkButton Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" NavigateUri="{x:Bind constants:Link.AppleMusicCfgUrl}" />
|
||||
<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
<Setter Property="MinWidth" Value="600" />
|
||||
</Style>
|
||||
</MenuFlyout.MenuFlyoutPresenterStyle>
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTraySwitch"
|
||||
Command="{x:Bind ViewModel.OpenLyricsWindowSwitchCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}" />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTrayLyrics"
|
||||
Command="{x:Bind ViewModel.OpenLyricsCommand}"
|
||||
@@ -44,19 +49,11 @@
|
||||
Command="{x:Bind ViewModel.OpenSettingsCommand}"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}" />
|
||||
<MenuFlyoutSeparator />
|
||||
<MenuFlyoutItem
|
||||
x:Uid="SystemTrayResetWindowPosition"
|
||||
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"
|
||||
Command="{x:Bind ViewModel.RestartAppCommand}"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class BoolNegationToOpacityConverter: IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 0.0 : 1.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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 partial class BoolToOpacityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is bool boolValue)
|
||||
{
|
||||
return boolValue ? 1.0 : 0.0;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class ByteArrayToImageConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is byte[] byteArray && byteArray.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var ms = new MemoryStream(byteArray))
|
||||
{
|
||||
var stream = ms.AsRandomAccessStream();
|
||||
var bitmapImage = new BitmapImage();
|
||||
|
||||
bitmapImage.SetSource(stream);
|
||||
|
||||
return bitmapImage;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Globalization;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class DisplayLanguageCodeToIndexConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string langCode)
|
||||
{
|
||||
return LanguageHelper.SupportedDisplayLanguages.FindIndex(x => x.LanguageCode == langCode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is int index)
|
||||
{
|
||||
return LanguageHelper.SupportedDisplayLanguages.ElementAt(index).LanguageCode;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Globalization;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class LanguageCodeToDisplayedNameConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string langCode)
|
||||
{
|
||||
if (PhoneticHelper.IsPhoneticCode(langCode))
|
||||
{
|
||||
return PhoneticHelper.GetDisplayName(langCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Language(langCode).DisplayName ?? langCode;
|
||||
}
|
||||
}
|
||||
return value?.ToString() ?? "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,27 @@
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Converter
|
||||
{
|
||||
public partial class PathToParentFolderConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string path)
|
||||
{
|
||||
return Directory.GetParent(path)?.Name ?? "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,28 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
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,
|
||||
}
|
||||
|
||||
public static class ChineseRomanizationExtensions
|
||||
{
|
||||
public static string ToPhoneticCode(this ChineseRomanization chineseRomanization)
|
||||
{
|
||||
return chineseRomanization switch
|
||||
{
|
||||
ChineseRomanization.Pinyin => PhoneticHelper.PinyinCode,
|
||||
ChineseRomanization.Jyutping => PhoneticHelper.JyutpingCode,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(chineseRomanization))
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
Title,
|
||||
Album,
|
||||
Artist
|
||||
Artist,
|
||||
Folder
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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 PaletteGeneratorType
|
||||
{
|
||||
MedianCut,
|
||||
OctTree
|
||||
}
|
||||
}
|
||||
@@ -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,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Events
|
||||
{
|
||||
public class ExtendedSliderValueChangedByUserEventArgs : EventArgs
|
||||
{
|
||||
public double Value { get; set; }
|
||||
|
||||
public ExtendedSliderValueChangedByUserEventArgs(double value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using BetterLyrics.WinUI3.Models;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Brushes;
|
||||
using Microsoft.Graphics.Canvas.Effects;
|
||||
using Microsoft.Graphics.Canvas.Geometry;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Microsoft.UI;
|
||||
@@ -72,11 +73,38 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
CanvasCommandList list = new(control);
|
||||
using var ds = list.CreateDrawingSession();
|
||||
|
||||
// 描边
|
||||
if (strokeWidth > 0)
|
||||
{
|
||||
ds.DrawGeometry(lyricsLine.TextGeometry, lyricsLine.Position, strokeColor, strokeWidth); // 描边
|
||||
if (lyricsLine.PhoneticCanvasGeometry != null)
|
||||
{
|
||||
ds.DrawGeometry(lyricsLine.PhoneticCanvasGeometry, lyricsLine.PhoneticPosition, strokeColor, strokeWidth);
|
||||
}
|
||||
if (lyricsLine.OriginalCanvasGeometry != null)
|
||||
{
|
||||
ds.DrawGeometry(lyricsLine.OriginalCanvasGeometry, lyricsLine.OriginalPosition, strokeColor, strokeWidth);
|
||||
}
|
||||
if (lyricsLine.TranslatedCanvasGeometry != null)
|
||||
{
|
||||
ds.DrawGeometry(lyricsLine.TranslatedCanvasGeometry, lyricsLine.TranslatedPosition, strokeColor, strokeWidth);
|
||||
}
|
||||
}
|
||||
ds.FillGeometry(lyricsLine.TextGeometry, lyricsLine.Position, fontColor); // 填充
|
||||
|
||||
// 绘制文本(填充)
|
||||
if (lyricsLine.PhoneticCanvasTextLayout != null)
|
||||
{
|
||||
ds.DrawTextLayout(lyricsLine.PhoneticCanvasTextLayout, lyricsLine.PhoneticPosition, fontColor);
|
||||
}
|
||||
if (lyricsLine.OriginalCanvasTextLayout != null)
|
||||
{
|
||||
ds.DrawTextLayout(lyricsLine.OriginalCanvasTextLayout, lyricsLine.OriginalPosition, fontColor);
|
||||
}
|
||||
if (lyricsLine.TranslatedCanvasTextLayout != null)
|
||||
{
|
||||
ds.DrawTextLayout(lyricsLine.TranslatedCanvasTextLayout, lyricsLine.TranslatedPosition, fontColor);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -105,12 +133,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var mask = new CanvasCommandList(control);
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
if (lyricsLine.CanvasTextLayout == null)
|
||||
if (lyricsLine.OriginalCanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
var highlightRegion = lyricsLine.CanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault();
|
||||
var highlightRegion = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault();
|
||||
|
||||
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
|
||||
// Draw the highlight for the current character
|
||||
@@ -121,20 +149,20 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
// Rects
|
||||
var highlightRect = new Rect(
|
||||
highlightRegion.LayoutBounds.X,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
highlightWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
|
||||
var fadeInRect = new Rect(
|
||||
highlightRect.Right - fadingWidth,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
fadingWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
var fadeOutRect = new Rect(
|
||||
highlightRect.Right,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
fadingWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
@@ -163,15 +191,15 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
var mask = new CanvasCommandList(control);
|
||||
|
||||
if (lyricsLine.CanvasTextLayout == null)
|
||||
if (lyricsLine.OriginalCanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, charStartIndex);
|
||||
var highlightRegion = lyricsLine.CanvasTextLayout
|
||||
var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, charStartIndex);
|
||||
var highlightRegion = lyricsLine.OriginalCanvasTextLayout
|
||||
.GetCharacterRegions(charStartIndex, charLength)
|
||||
.FirstOrDefault();
|
||||
if (regions.Length > 0)
|
||||
@@ -182,7 +210,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var region = regions[j];
|
||||
var rect = new Rect(
|
||||
region.LayoutBounds.X,
|
||||
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
region.LayoutBounds.Width,
|
||||
region.LayoutBounds.Height
|
||||
);
|
||||
@@ -199,14 +227,14 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
// Rects
|
||||
var highlightRect = new Rect(
|
||||
highlightRegion.LayoutBounds.X,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
highlightWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
|
||||
var fadeInRect = new Rect(
|
||||
highlightRect.Right - fadingWidth,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
fadingWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
@@ -217,7 +245,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
var fadeOutRect = new Rect(
|
||||
highlightRect.Right,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
highlightRegion.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
fadingWidth,
|
||||
highlightRegion.LayoutBounds.Height
|
||||
);
|
||||
@@ -238,12 +266,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var mask = new CanvasCommandList(control);
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
if (lyricsLine.CanvasTextLayout == null)
|
||||
if (lyricsLine.OriginalCanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length);
|
||||
var regions = lyricsLine.OriginalCanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length);
|
||||
if (regions.Length > 0)
|
||||
{
|
||||
for (int j = 0; j < regions.Length; j++)
|
||||
@@ -251,7 +279,65 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
var region = regions[j];
|
||||
var rect = new Rect(
|
||||
region.LayoutBounds.X,
|
||||
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||
region.LayoutBounds.Y + lyricsLine.OriginalPosition.Y,
|
||||
region.LayoutBounds.Width,
|
||||
region.LayoutBounds.Height
|
||||
);
|
||||
ds.FillRectangle(rect, Colors.White);
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
public static CanvasCommandList CreatePhoneticHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
|
||||
{
|
||||
var mask = new CanvasCommandList(control);
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
if (lyricsLine.PhoneticCanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
var regions = lyricsLine.PhoneticCanvasTextLayout.GetCharacterRegions(0, lyricsLine.PhoneticText.Length);
|
||||
if (regions.Length > 0)
|
||||
{
|
||||
for (int j = 0; j < regions.Length; j++)
|
||||
{
|
||||
var region = regions[j];
|
||||
var rect = new Rect(
|
||||
region.LayoutBounds.X,
|
||||
region.LayoutBounds.Y + lyricsLine.PhoneticPosition.Y,
|
||||
region.LayoutBounds.Width,
|
||||
region.LayoutBounds.Height
|
||||
);
|
||||
ds.FillRectangle(rect, Colors.White);
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
public static CanvasCommandList CreateTranslatedHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
|
||||
{
|
||||
var mask = new CanvasCommandList(control);
|
||||
using var ds = mask.CreateDrawingSession();
|
||||
|
||||
if (lyricsLine.TranslatedCanvasTextLayout == null)
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
var regions = lyricsLine.TranslatedCanvasTextLayout.GetCharacterRegions(0, lyricsLine.TranslatedText.Length);
|
||||
if (regions.Length > 0)
|
||||
{
|
||||
for (int j = 0; j < regions.Length; j++)
|
||||
{
|
||||
var region = regions[j];
|
||||
var rect = new Rect(
|
||||
region.LayoutBounds.X,
|
||||
region.LayoutBounds.Y + lyricsLine.TranslatedPosition.Y,
|
||||
region.LayoutBounds.Width,
|
||||
region.LayoutBounds.Height
|
||||
);
|
||||
@@ -267,12 +353,16 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
/// </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 +381,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,16 @@ 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 Color GetRandomColor()
|
||||
{
|
||||
return Color.FromArgb(255, (byte)Random.Shared.Next(0, 256), (byte)Random.Shared.Next(0, 256), (byte)Random.Shared.Next(0, 256));
|
||||
}
|
||||
|
||||
public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, string monitorDeviceName, WindowPixelSampleMode mode)
|
||||
{
|
||||
if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent;
|
||||
@@ -116,15 +132,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 - 2, screenWidth, 1);
|
||||
}
|
||||
case WindowPixelSampleMode.WindowArea:
|
||||
{
|
||||
@@ -142,49 +154,21 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
if (width <= 0 || height <= 0)
|
||||
return System.Drawing.Color.Transparent;
|
||||
|
||||
var edgeThickness = new Thickness(36, 0, 36, 0);
|
||||
var edgeThickness = new Thickness(36, 36, 36, 36);
|
||||
List<System.Drawing.Color> edgeColors = [];
|
||||
|
||||
// Top edge
|
||||
if (edgeThickness.Top > 0 && edgeThickness.Top < height)
|
||||
edgeColors.Add(
|
||||
GetAverageColorFromScreenRegion(
|
||||
myRect.Left,
|
||||
myRect.Top,
|
||||
width,
|
||||
(int)edgeThickness.Top
|
||||
)
|
||||
);
|
||||
if (edgeThickness.Top > 0)
|
||||
edgeColors.Add(GetAverageColorFromScreenRegion(myRect.Left, myRect.Top - (int)edgeThickness.Top, width, (int)edgeThickness.Top));
|
||||
// Bottom edge
|
||||
if (edgeThickness.Bottom > 0 && edgeThickness.Bottom < height)
|
||||
edgeColors.Add(
|
||||
GetAverageColorFromScreenRegion(
|
||||
myRect.Left,
|
||||
myRect.Bottom - (int)edgeThickness.Bottom,
|
||||
width,
|
||||
(int)edgeThickness.Bottom
|
||||
)
|
||||
);
|
||||
if (edgeThickness.Bottom > 0)
|
||||
edgeColors.Add(GetAverageColorFromScreenRegion(myRect.Left, myRect.Bottom, width, (int)edgeThickness.Bottom));
|
||||
// Left edge
|
||||
if (edgeThickness.Left > 0 && edgeThickness.Left < width)
|
||||
edgeColors.Add(
|
||||
GetAverageColorFromScreenRegion(
|
||||
myRect.Left,
|
||||
myRect.Top + (int)edgeThickness.Top,
|
||||
(int)edgeThickness.Left,
|
||||
height - (int)edgeThickness.Top - (int)edgeThickness.Bottom
|
||||
)
|
||||
);
|
||||
if (edgeThickness.Left > 0)
|
||||
edgeColors.Add(GetAverageColorFromScreenRegion(myRect.Left - (int)edgeThickness.Left, myRect.Top, (int)edgeThickness.Left, height));
|
||||
// Right edge
|
||||
if (edgeThickness.Right > 0 && edgeThickness.Right < width)
|
||||
edgeColors.Add(
|
||||
GetAverageColorFromScreenRegion(
|
||||
myRect.Right - (int)edgeThickness.Right,
|
||||
myRect.Top + (int)edgeThickness.Top,
|
||||
(int)edgeThickness.Right,
|
||||
height - (int)edgeThickness.Top - (int)edgeThickness.Bottom
|
||||
)
|
||||
);
|
||||
if (edgeThickness.Right > 0)
|
||||
edgeColors.Add(GetAverageColorFromScreenRegion(myRect.Right, myRect.Top, (int)edgeThickness.Right, height));
|
||||
|
||||
// 合并四边平均色
|
||||
if (edgeColors.Count == 0)
|
||||
@@ -246,6 +230,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -42,6 +43,29 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public static void DeleteAllFiles(string folderPath)
|
||||
{
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DirectoryInfo di = new DirectoryInfo(folderPath);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (FileInfo file in di.GetFiles())
|
||||
{
|
||||
try
|
||||
{
|
||||
file.Delete();
|
||||
}
|
||||
catch (Exception ex) { }
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string? ReadLyricsCache(string title, string artist, LyricsFormat format, string cacheFolderPath)
|
||||
public static string? ReadLyricsCache(string title, string artist, string album, LyricsFormat format, string cacheFolderPath)
|
||||
{
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}"));
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
|
||||
if (File.Exists(cacheFilePath))
|
||||
{
|
||||
return File.ReadAllText(cacheFilePath);
|
||||
@@ -57,9 +57,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void WriteLyricsCache(string title, string artist, string lyrics, LyricsFormat format, string cacheFolderPath)
|
||||
public static void WriteLyricsCache(string title, string artist, string album, string lyrics, LyricsFormat format, string cacheFolderPath)
|
||||
{
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title}{format.ToFileExtension()}"));
|
||||
var cacheFilePath = Path.Combine(cacheFolderPath, SanitizeFileName($"{artist} - {title} - {album}{format.ToFileExtension()}"));
|
||||
File.WriteAllText(cacheFilePath, lyrics);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models.Settings;
|
||||
using CommunityToolkit.WinUI.Helpers;
|
||||
using Impressionist.Abstractions;
|
||||
using Impressionist.Implementations;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using SixLabors.ImageSharp.Formats.Png;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
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;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.UI;
|
||||
using static Vanara.PInvoke.Ole32;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
@@ -45,7 +46,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return RandomAccessStreamReference.CreateFromStream(stream);
|
||||
}
|
||||
|
||||
public static async Task<byte[]> CreateTextPlaceholderBytesAsync(int width, int height)
|
||||
public static async Task<IRandomAccessStream> CreateTextPlaceholderBytesAsync(int width, int height)
|
||||
{
|
||||
using var device = CanvasDevice.GetSharedDevice();
|
||||
using var renderTarget = new CanvasRenderTarget(device, width, height, 96);
|
||||
@@ -75,31 +76,58 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
|
||||
// 保存为 PNG 并转为 byte[]
|
||||
using var stream = new InMemoryRandomAccessStream();
|
||||
var stream = new InMemoryRandomAccessStream();
|
||||
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
|
||||
var buffer = new byte[stream.Size];
|
||||
using (var reader = new DataReader(stream.GetInputStreamAt(0)))
|
||||
{
|
||||
await reader.LoadAsync((uint)stream.Size);
|
||||
reader.ReadBytes(buffer);
|
||||
}
|
||||
return buffer;
|
||||
stream.Seek(0);
|
||||
return stream;
|
||||
}
|
||||
|
||||
public static List<Windows.UI.Color> GetAccentColorsFromByte(byte[] bytes, int count, bool? isDark = null)
|
||||
|
||||
public static Task<ThemeColorResult> GetAccentColorAsync(BitmapDecoder decoder, PaletteGeneratorType generatorType)
|
||||
{
|
||||
using var image = Image.Load<Rgba32>(bytes);
|
||||
var colorThief = new ColorThief.ImageSharp.ColorThief();
|
||||
var mainColor = colorThief.GetColor(image, 10, false);
|
||||
var palette = colorThief.GetPalette(image, 255, 10, false);
|
||||
var topColors = palette
|
||||
.OrderByDescending(x => x.Population)
|
||||
.Where(x => x.IsDark == (isDark ?? mainColor.IsDark))
|
||||
.Select(x => Windows.UI.Color.FromArgb(x.Color.A, x.Color.R, x.Color.G, x.Color.B))
|
||||
.Take(count)
|
||||
.ToList();
|
||||
return generatorType switch
|
||||
{
|
||||
PaletteGeneratorType.OctTree => PaletteHelper.OctTreeGetAccentColorFromByteAsync(decoder),
|
||||
PaletteGeneratorType.MedianCut => PaletteHelper.MedianCutGetAccentColorFromByteAsync(decoder),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(generatorType)),
|
||||
};
|
||||
}
|
||||
|
||||
return topColors;
|
||||
public static Task<PaletteResult> GetAccentColorsAsync(BitmapDecoder decoder, int count, PaletteGeneratorType generatorType, bool? isDark = null)
|
||||
{
|
||||
return generatorType switch
|
||||
{
|
||||
PaletteGeneratorType.OctTree => PaletteHelper.OctTreeGetAccentColorsFromByteAsync(decoder, count, isDark),
|
||||
PaletteGeneratorType.MedianCut => PaletteHelper.MedianCutGetAccentColorsFromByteAsync(decoder, count, isDark),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(generatorType)),
|
||||
};
|
||||
}
|
||||
|
||||
public static async Task<Dictionary<Vector3, int>> GetPixelColor(BitmapDecoder bitmapDecoder)
|
||||
{
|
||||
var pixelDataProvider = await bitmapDecoder.GetPixelDataAsync();
|
||||
var pixels = pixelDataProvider.DetachPixelData();
|
||||
var count = bitmapDecoder.PixelWidth * bitmapDecoder.PixelHeight;
|
||||
var vector = new Dictionary<Vector3, int>();
|
||||
for (int i = 0; i < count; i += 10)
|
||||
{
|
||||
var offset = i * 4;
|
||||
var b = pixels[offset];
|
||||
var g = pixels[offset + 1];
|
||||
var r = pixels[offset + 2];
|
||||
var a = pixels[offset + 3];
|
||||
if (a == 0) continue;
|
||||
var color = new Vector3(r, g, b);
|
||||
if (vector.ContainsKey(color))
|
||||
{
|
||||
vector[color]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector[color] = 1;
|
||||
}
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
//public static async Task<BitmapImage> GetBitmapImageFromBytesAsync(byte[] imageBytes)
|
||||
@@ -128,13 +156,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
// return stream;
|
||||
//}
|
||||
|
||||
public static async Task<byte[]> ToByteArrayAsync(IRandomAccessStreamReference streamRef)
|
||||
public static async Task<IBuffer> ToBufferAsync(IRandomAccessStreamReference streamRef)
|
||||
{
|
||||
using IRandomAccessStream stream = await streamRef.OpenReadAsync();
|
||||
using var reader = new DataReader(stream);
|
||||
await reader.LoadAsync((uint)stream.Size);
|
||||
byte[] buffer = new byte[stream.Size];
|
||||
reader.ReadBytes(buffer);
|
||||
stream.Seek(0);
|
||||
var buffer = new Windows.Storage.Streams.Buffer((uint)stream.Size);
|
||||
await stream.ReadAsync(buffer, (uint)stream.Size, InputStreamOptions.None);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -155,53 +182,105 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return (double)(sum / (pixels.Length / 4));
|
||||
}
|
||||
|
||||
public static byte[] MakeSquareWithThemeColor(byte[] imageBytes)
|
||||
public static async Task<BitmapDecoder> MakeSquareWithThemeColor(IBuffer buffer, PaletteGeneratorType generatorType)
|
||||
{
|
||||
using var image = Image.Load<Rgba32>(imageBytes);
|
||||
|
||||
if (image.Width == image.Height)
|
||||
using var stream = new InMemoryRandomAccessStream();
|
||||
await stream.WriteAsync(buffer);
|
||||
var decoder = await BitmapDecoder.CreateAsync(stream);
|
||||
|
||||
if (decoder.PixelWidth == decoder.PixelHeight)
|
||||
{
|
||||
// 已经是正方形,直接返回
|
||||
return imageBytes;
|
||||
return decoder;
|
||||
}
|
||||
|
||||
int size = Math.Max(image.Width, image.Height);
|
||||
using var device = CanvasDevice.GetSharedDevice();
|
||||
using var canvasBitmap = await CanvasBitmap.LoadAsync(device, stream);
|
||||
var size = Math.Max(decoder.PixelWidth, decoder.PixelHeight);
|
||||
|
||||
var themeColor = Rgba32.ParseHex(GetAccentColorsFromByte(imageBytes, 1).FirstOrDefault().ToHex());
|
||||
var result = await GetAccentColorAsync(decoder, generatorType);
|
||||
var color = Windows.UI.Color.FromArgb(255, (byte)result.Color.X, (byte)result.Color.Y, (byte)result.Color.Z);
|
||||
using var renderTarget = new CanvasRenderTarget(device, size, size, 96);
|
||||
|
||||
using var square = new Image<Rgba32>(size, size, themeColor);
|
||||
int offsetX = (int)(size - decoder.PixelWidth) / 2;
|
||||
int offsetY = (int)(size - decoder.PixelHeight) / 2;
|
||||
using (var ds = renderTarget.CreateDrawingSession())
|
||||
{
|
||||
ds.FillRectangle(0, 0, size, size, color);
|
||||
ds.DrawImage(canvasBitmap, offsetX, offsetY);
|
||||
}
|
||||
|
||||
int offsetX = (size - image.Width) / 2;
|
||||
int offsetY = (size - image.Height) / 2;
|
||||
// 保存为 PNG 并转为 byte[]
|
||||
stream.Seek(0);
|
||||
stream.Size = 0;
|
||||
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
|
||||
stream.Seek(0);
|
||||
var newDecoder = await BitmapDecoder.CreateAsync(stream);
|
||||
return newDecoder;
|
||||
|
||||
square.Mutate(ctx => ctx.DrawImage(image, new Point(offsetX, offsetY), 1f));
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
square.Save(ms, new JpegEncoder());
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
public static byte[] Resize(byte[] imageBytes, int size)
|
||||
public static async Task<IBuffer> Resize(IBuffer buffer, int size)
|
||||
{
|
||||
using (Image image = Image.Load(imageBytes))
|
||||
using var stream = new InMemoryRandomAccessStream();
|
||||
await stream.WriteAsync(buffer);
|
||||
var decoder = await BitmapDecoder.CreateAsync(stream);
|
||||
|
||||
var factor = Math.Max((double)size / decoder.PixelWidth, (double)size / decoder.PixelHeight);
|
||||
|
||||
var width = (uint)(decoder.PixelWidth * factor);
|
||||
var height = (uint)(decoder.PixelHeight * factor);
|
||||
|
||||
if (factor > 1)
|
||||
{
|
||||
var factor = Math.Max((double)size / image.Width, (double)size / image.Height);
|
||||
|
||||
int width = (int)(image.Width * factor);
|
||||
int height = (int)(image.Height * factor);
|
||||
|
||||
if (factor > 1)
|
||||
var transform = new BitmapTransform()
|
||||
{
|
||||
image.Mutate(x => x.Resize(width, height, KnownResamplers.Welch));
|
||||
}
|
||||
else
|
||||
{
|
||||
image.Mutate(x => x.Resize(width, height, KnownResamplers.NearestNeighbor));
|
||||
}
|
||||
ScaledWidth = width,
|
||||
ScaledHeight = height,
|
||||
InterpolationMode = BitmapInterpolationMode.Fant
|
||||
};
|
||||
var pixelData = await decoder.GetPixelDataAsync(
|
||||
BitmapPixelFormat.Rgba8,
|
||||
BitmapAlphaMode.Straight,
|
||||
transform, ExifOrientationMode.RespectExifOrientation,
|
||||
ColorManagementMode.ColorManageToSRgb);
|
||||
var pixels = pixelData.DetachPixelData();
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
image.Save(ms, new JpegEncoder());
|
||||
return ms.ToArray();
|
||||
stream.Seek(0);
|
||||
stream.Size = 0;
|
||||
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
|
||||
encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, width, height, 96, 96, pixels);
|
||||
await encoder.FlushAsync();
|
||||
var output = new Windows.Storage.Streams.Buffer((uint)stream.Size);
|
||||
stream.Seek(0);
|
||||
await stream.ReadAsync(output, (uint)stream.Size, InputStreamOptions.None);
|
||||
return output;
|
||||
}
|
||||
else
|
||||
{
|
||||
var transform = new BitmapTransform()
|
||||
{
|
||||
ScaledWidth = (uint)width,
|
||||
ScaledHeight = (uint)height,
|
||||
InterpolationMode = BitmapInterpolationMode.NearestNeighbor
|
||||
};
|
||||
var pixelData = await decoder.GetPixelDataAsync(
|
||||
BitmapPixelFormat.Rgba8,
|
||||
BitmapAlphaMode.Straight,
|
||||
transform, ExifOrientationMode.RespectExifOrientation,
|
||||
ColorManagementMode.ColorManageToSRgb);
|
||||
var pixels = pixelData.DetachPixelData();
|
||||
|
||||
stream.Seek(0);
|
||||
stream.Size = 0;
|
||||
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
|
||||
encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, width, height, 96, 96, pixels);
|
||||
await encoder.FlushAsync();
|
||||
var output = new Windows.Storage.Streams.Buffer((uint)stream.Size);
|
||||
stream.Seek(0);
|
||||
await stream.ReadAsync(output, (uint)stream.Size, InputStreamOptions.None);
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,5 +298,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,56 +1,100 @@
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using NTextCat;
|
||||
using System;
|
||||
using NTextCat.Commons;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using TinyPinyin;
|
||||
using System.Text;
|
||||
using Windows.Globalization;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class LanguageHelper
|
||||
{
|
||||
private static readonly RankedLanguageIdentifierFactory _factory = new();
|
||||
private static readonly RankedLanguageIdentifier _identifier;
|
||||
|
||||
public static List<Models.LanguageInfo> SupportedTargetLanguages =>
|
||||
public static List<ExtendedLanguage> SupportedTranslationTargetLanguages { 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("cs", "Čeština"),
|
||||
new Models.LanguageInfo("da", "Dansk"),
|
||||
new Models.LanguageInfo("nl", "Nederlands"),
|
||||
new Models.LanguageInfo("en", "English"),
|
||||
new Models.LanguageInfo("eo", "Esperanto"),
|
||||
new Models.LanguageInfo("fi", "Suomi"),
|
||||
new Models.LanguageInfo("fr", "Français"),
|
||||
new Models.LanguageInfo("de", "Deutsch"),
|
||||
new Models.LanguageInfo("el", "Ελληνικά"),
|
||||
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("pl", "Polski"),
|
||||
new Models.LanguageInfo("pt", "Português"),
|
||||
new Models.LanguageInfo("ru", "Русский"),
|
||||
new Models.LanguageInfo("sk", "Slovenčina"),
|
||||
new Models.LanguageInfo("es", "Español"),
|
||||
new Models.LanguageInfo("sv", "Svenska"),
|
||||
new Models.LanguageInfo("tr", "Türkçe"),
|
||||
new Models.LanguageInfo("uk", "Українська"),
|
||||
new Models.LanguageInfo("vi", "Tiếng Việt"),
|
||||
new ExtendedLanguage("ar"),
|
||||
new ExtendedLanguage("az"),
|
||||
|
||||
new ExtendedLanguage("bg"),
|
||||
new ExtendedLanguage("bn"),
|
||||
|
||||
new ExtendedLanguage("ca"),
|
||||
new ExtendedLanguage("cs"),
|
||||
|
||||
new ExtendedLanguage("da"),
|
||||
new ExtendedLanguage("de"),
|
||||
|
||||
new ExtendedLanguage("el"),
|
||||
new ExtendedLanguage("en"),
|
||||
new ExtendedLanguage("eo"),
|
||||
new ExtendedLanguage("es"),
|
||||
new ExtendedLanguage("et"),
|
||||
new ExtendedLanguage("eu"),
|
||||
|
||||
new ExtendedLanguage("fa"),
|
||||
new ExtendedLanguage("fi"),
|
||||
new ExtendedLanguage("fr"),
|
||||
|
||||
new ExtendedLanguage("ga"),
|
||||
new ExtendedLanguage("gl"),
|
||||
|
||||
new ExtendedLanguage("he"),
|
||||
new ExtendedLanguage("hi"),
|
||||
new ExtendedLanguage("hu"),
|
||||
|
||||
new ExtendedLanguage("id"),
|
||||
new ExtendedLanguage("it"),
|
||||
|
||||
new ExtendedLanguage("ja"),
|
||||
|
||||
new ExtendedLanguage("ko"),
|
||||
new ExtendedLanguage("ky"),
|
||||
|
||||
new ExtendedLanguage("lt"),
|
||||
new ExtendedLanguage("lv"),
|
||||
|
||||
new ExtendedLanguage("ms"),
|
||||
|
||||
new ExtendedLanguage("nb"),
|
||||
new ExtendedLanguage("nl"),
|
||||
|
||||
new ExtendedLanguage("pt-BR"),
|
||||
new ExtendedLanguage("pl"),
|
||||
new ExtendedLanguage("pt"),
|
||||
|
||||
new ExtendedLanguage("ro"),
|
||||
new ExtendedLanguage("ru"),
|
||||
|
||||
new ExtendedLanguage("sk"),
|
||||
new ExtendedLanguage("sl"),
|
||||
new ExtendedLanguage("sq"),
|
||||
new ExtendedLanguage("sr"),
|
||||
new ExtendedLanguage("sv"),
|
||||
|
||||
new ExtendedLanguage("th"),
|
||||
new ExtendedLanguage("tl"),
|
||||
new ExtendedLanguage("tr"),
|
||||
|
||||
new ExtendedLanguage("uk"),
|
||||
new ExtendedLanguage("ur"),
|
||||
|
||||
new ExtendedLanguage("vi"),
|
||||
|
||||
new ExtendedLanguage("zh"),
|
||||
];
|
||||
|
||||
public static List<ExtendedLanguage> SupportedDisplayLanguages { get; set; } =
|
||||
[
|
||||
new ExtendedLanguage("", App.ResourceLoader!.GetString("SettingsPageSystemLanguage")),
|
||||
new ExtendedLanguage("en-US", "English"),
|
||||
new ExtendedLanguage("ja-JP"),
|
||||
new ExtendedLanguage("ko-KR"),
|
||||
new ExtendedLanguage("zh-CN", "简体中文"),
|
||||
new ExtendedLanguage("zh-TW", "繁體中文"),
|
||||
];
|
||||
|
||||
static LanguageHelper()
|
||||
@@ -67,9 +111,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 +127,17 @@ namespace BetterLyrics.WinUI3.Services
|
||||
};
|
||||
}
|
||||
|
||||
public static string ConvertToCountryCode(string? languageCode)
|
||||
public static string GetDefaultTargetTranslationLanguageCode()
|
||||
{
|
||||
if (languageCode == null) return "us";
|
||||
|
||||
return languageCode switch
|
||||
var found = SupportedTranslationTargetLanguages.Find(x => ApplicationLanguages.Languages.FirstOrDefault()?.Contains(x.LanguageCode) == 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.LanguageCode;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetOrderChar(string text)
|
||||
@@ -113,12 +147,22 @@ namespace BetterLyrics.WinUI3.Services
|
||||
if (char.IsLetter(c) && c < 128)
|
||||
return char.ToUpper(c).ToString();
|
||||
|
||||
if (PinyinHelper.IsChinese(c))
|
||||
if (IsHanzi(c.ToString()))
|
||||
{
|
||||
return PinyinHelper.GetPinyinInitials($"{c}");
|
||||
return PhoneticHelper.ToPinyin(c.ToString(), Pinyin.ManTone.Style.NORMAL).ToUpper().FirstOrDefault().ToString();
|
||||
}
|
||||
|
||||
return "#";
|
||||
}
|
||||
|
||||
public static bool IsHanzi(char ch)
|
||||
{
|
||||
return IsHanzi(ch.ToString());
|
||||
}
|
||||
|
||||
public static bool IsHanzi(string text)
|
||||
{
|
||||
return Pinyin.Pinyin.Instance.IsHanzi(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,29 +3,45 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using Lyricify.Lyrics.Helpers.General;
|
||||
using Lyricify.Lyrics.Models;
|
||||
using Lyricify.Lyrics.Parsers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Windows.Globalization.Fonts;
|
||||
using Vanara.PInvoke;
|
||||
using LyricsData = BetterLyrics.WinUI3.Models.LyricsData;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public class LyricsParser
|
||||
public partial class LyricsParser
|
||||
{
|
||||
private List<LyricsData> _lyricsDataArr = [];
|
||||
public List<LyricsData> LyricsDataArr { get; private set; } = [];
|
||||
|
||||
public List<LyricsData> Parse(string? raw, int? durationMs)
|
||||
public void Parse(List<MappedSongSearchQuery> mappedSongSearchQueries, string title, string artist, string album, string? raw, int? durationMs, LyricsSearchProvider? lyricsSearchProvider)
|
||||
{
|
||||
var overridenTitle = title;
|
||||
var overridenArtist = artist;
|
||||
var overridenAlbum = album;
|
||||
|
||||
var found = mappedSongSearchQueries
|
||||
.Where(x => x.OriginalTitle == overridenTitle && x.OriginalArtist == overridenArtist && x.OriginalAlbum == overridenAlbum)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (found != null)
|
||||
{
|
||||
overridenTitle = found.MappedTitle;
|
||||
overridenArtist = found.MappedArtist;
|
||||
overridenAlbum = found.MappedAlbum;
|
||||
}
|
||||
|
||||
LyricsDataArr = [];
|
||||
durationMs ??= (int)TimeSpan.FromMinutes(99).TotalMilliseconds;
|
||||
_lyricsDataArr = [];
|
||||
if (raw == null)
|
||||
{
|
||||
_lyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value));
|
||||
LyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -36,10 +52,10 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
ParseLrc(raw);
|
||||
break;
|
||||
case LyricsFormat.Qrc:
|
||||
ParseQQNeteaseKugou(Lyricify.Lyrics.Parsers.QrcParser.Parse(raw).Lines);
|
||||
ParseQQNeteaseKugou(QrcParser.Parse(raw).Lines);
|
||||
break;
|
||||
case LyricsFormat.Krc:
|
||||
ParseQQNeteaseKugou(Lyricify.Lyrics.Parsers.KrcParser.Parse(raw).Lines);
|
||||
ParseQQNeteaseKugou(KrcParser.Parse(raw).Lines);
|
||||
break;
|
||||
case LyricsFormat.Ttml:
|
||||
ParseTtml(raw);
|
||||
@@ -48,50 +64,111 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
break;
|
||||
}
|
||||
}
|
||||
FillChineseLyricsData();
|
||||
_lyricsDataArr.Add(new LyricsData()); // 为机翻预留
|
||||
return _lyricsDataArr;
|
||||
FillRomanizationLyricsData();
|
||||
FillTranslationFromCache(overridenTitle, overridenArtist, overridenAlbum, lyricsSearchProvider);
|
||||
}
|
||||
|
||||
private void FillChineseLyricsData()
|
||||
private void FillTranslationFromCache(string title, string artist, string album, LyricsSearchProvider? provider)
|
||||
{
|
||||
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)
|
||||
string? translationRaw = null;
|
||||
switch (provider)
|
||||
{
|
||||
// 如果没有繁体中文歌词,则将简体中文歌词转换为繁体中文
|
||||
_lyricsDataArr.Add(new LyricsData
|
||||
case LyricsSearchProvider.QQ:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.Kugou:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.Netease:
|
||||
translationRaw = FileHelper.ReadLyricsCache(title, artist, album, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
|
||||
break;
|
||||
case LyricsSearchProvider.LrcLib:
|
||||
break;
|
||||
case LyricsSearchProvider.AmllTtmlDb:
|
||||
break;
|
||||
case LyricsSearchProvider.LocalMusicFile:
|
||||
break;
|
||||
case LyricsSearchProvider.LocalLrcFile:
|
||||
break;
|
||||
case LyricsSearchProvider.LocalEslrcFile:
|
||||
break;
|
||||
case LyricsSearchProvider.LocalTtmlFile:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (translationRaw != null)
|
||||
{
|
||||
switch (provider)
|
||||
{
|
||||
LyricsLines = simplifiedChinese.LyricsLines.Select(line => new LyricsLine
|
||||
case LyricsSearchProvider.QQ:
|
||||
case LyricsSearchProvider.Kugou:
|
||||
case LyricsSearchProvider.Netease:
|
||||
ParseLrc(translationRaw);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillRomanizationLyricsData()
|
||||
{
|
||||
var chinese = LyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
|
||||
if (chinese != null)
|
||||
{
|
||||
LyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LanguageCode = PhoneticHelper.PinyinCode,
|
||||
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = ChineseConverter.ConvertToTraditionalChinese(line.OriginalText),
|
||||
OriginalText = PhoneticHelper.ToPinyin(line.OriginalText),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = ChineseConverter.ConvertToTraditionalChinese(c.Text),
|
||||
Text = PhoneticHelper.ToPinyin(c.Text),
|
||||
StartIndex = c.StartIndex
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
});
|
||||
LyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LanguageCode = PhoneticHelper.JyutpingCode,
|
||||
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = PhoneticHelper.ToJyutping(line.OriginalText),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = PhoneticHelper.ToJyutping(c.Text),
|
||||
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
|
||||
LyricsDataArr.Add(new LyricsData
|
||||
{
|
||||
LyricsLines = traditionalChinese.LyricsLines.Select(line => new LyricsLine
|
||||
LanguageCode = PhoneticHelper.RomajiCode,
|
||||
LyricsLines = japanese.LyricsLines.Select(line => new LyricsLine
|
||||
{
|
||||
StartMs = line.StartMs,
|
||||
EndMs = line.EndMs,
|
||||
OriginalText = ChineseConverter.ConvertToSimplifiedChinese(line.OriginalText),
|
||||
OriginalText = PhoneticHelper.ToRomaji(line.OriginalText),
|
||||
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
|
||||
{
|
||||
StartMs = c.StartMs,
|
||||
EndMs = c.EndMs,
|
||||
Text = ChineseConverter.ConvertToSimplifiedChinese(c.Text),
|
||||
Text = PhoneticHelper.ToRomaji(c.Text),
|
||||
StartIndex = c.StartIndex
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
@@ -106,9 +183,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
new List<(int time, string text, List<(int time, string text)> syllables)>();
|
||||
|
||||
// 支持 [mm:ss.xx]字、<mm:ss.xx>字,毫秒两位或三位
|
||||
var syllableRegex = new Regex(
|
||||
@"(\[|\<)(\d{2}):(\d{2})\.(\d{2,3})(\]|\>)([^\[\]\<\>]*)"
|
||||
);
|
||||
var syllableRegex = SyllableRegex();
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
@@ -125,7 +200,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
|
||||
syllables.Add((totalMs, text));
|
||||
}
|
||||
if (syllables.Count > 0)
|
||||
if (syllables.Count > 1)
|
||||
{
|
||||
lrcLines.Add(
|
||||
(
|
||||
@@ -138,18 +213,20 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
else
|
||||
{
|
||||
// 普通LRC行
|
||||
var bracketRegex = new Regex(@"\[(\d{2}):(\d{2})\.(\d{2,3})\]");
|
||||
Regex? bracketRegex = LrcRegex();
|
||||
var bracketMatches = bracketRegex.Matches(line);
|
||||
|
||||
string content = line;
|
||||
int? lineStartTime = null;
|
||||
if (bracketMatches.Count > 0)
|
||||
{
|
||||
var m = bracketMatches[0];
|
||||
var m = bracketMatches![0];
|
||||
int min = int.Parse(m.Groups[1].Value);
|
||||
int sec = int.Parse(m.Groups[2].Value);
|
||||
int ms = int.Parse(m.Groups[3].Value.PadRight(3, '0'));
|
||||
int ms = int.Parse(m.Groups[4].Value.PadRight(3, '0'));
|
||||
lineStartTime = min * 60_000 + sec * 1000 + ms;
|
||||
content = bracketRegex.Replace(line, "");
|
||||
content = bracketRegex!.Replace(line, "");
|
||||
if (content == "//") content = "";
|
||||
lrcLines.Add((lineStartTime.Value, content, new List<(int, string)>()));
|
||||
}
|
||||
}
|
||||
@@ -165,8 +242,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
|
||||
// 初始化每种语言的歌词列表
|
||||
_lyricsDataArr.Clear();
|
||||
for (int i = 0; i < languageCount; i++) _lyricsDataArr.Add(new LyricsData());
|
||||
//LyricsDataArr.Clear();
|
||||
int langStartIndex = LyricsDataArr.Count;
|
||||
for (int i = 0; i < languageCount; i++) LyricsDataArr.Add(new LyricsData());
|
||||
|
||||
// 遍历每个时间分组
|
||||
if (grouped != null)
|
||||
@@ -204,7 +282,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
currentIndex += charText?.Length ?? 0;
|
||||
}
|
||||
}
|
||||
_lyricsDataArr[langIdx].LyricsLines.Add(line);
|
||||
LyricsDataArr[langStartIndex + langIdx].LyricsLines.Add(line);
|
||||
}
|
||||
// 没有翻译行则不补原文,直接跳过
|
||||
}
|
||||
@@ -230,10 +308,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();
|
||||
|
||||
// 原文和翻译分离
|
||||
@@ -315,9 +394,9 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
});
|
||||
}
|
||||
}
|
||||
_lyricsDataArr.Add(new LyricsData(originalLines));
|
||||
LyricsDataArr.Add(new LyricsData(originalLines));
|
||||
if (translationLines.Count > 0)
|
||||
_lyricsDataArr.Add(new LyricsData(translationLines));
|
||||
LyricsDataArr.Add(new LyricsData(translationLines));
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -432,7 +511,12 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
}
|
||||
|
||||
_lyricsDataArr.Add(new LyricsData(lyricsLines));
|
||||
LyricsDataArr.Add(new LyricsData(lyricsLines));
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"\[(\d*):(\d*)(\.|\:)(\d*)\]")]
|
||||
private static partial Regex LrcRegex();
|
||||
[GeneratedRegex(@"(\[|\<)(\d*):(\d*)\.(\d*)(\]|\>)([^\[\]\<\>]*)")]
|
||||
private static partial Regex SyllableRegex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
using ColorThiefDotNet;
|
||||
using Impressionist.Abstractions;
|
||||
using Impressionist.Implementations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Storage.Streams;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PaletteHelper
|
||||
{
|
||||
private static ColorThief colorThief = new();
|
||||
public static async Task<PaletteResult> OctTreeGetAccentColorsFromByteAsync(BitmapDecoder decoder, int count, bool? isDark = null)
|
||||
{
|
||||
var colors = await GetPixelColor(decoder);
|
||||
var palette = await PaletteGenerators.OctTreePaletteGenerator.CreatePalette(colors, count, false, isDark);
|
||||
return palette;
|
||||
}
|
||||
|
||||
public static async Task<ThemeColorResult> OctTreeGetAccentColorFromByteAsync(BitmapDecoder decoder)
|
||||
{
|
||||
var colors = await GetPixelColor(decoder);
|
||||
var theme = await PaletteGenerators.OctTreePaletteGenerator.CreateThemeColor(colors, false);
|
||||
return theme;
|
||||
}
|
||||
|
||||
public static async Task<ThemeColorResult> MedianCutGetAccentColorFromByteAsync(BitmapDecoder decoder)
|
||||
{
|
||||
var mainColor = await colorThief.GetColor(decoder, 10, false);
|
||||
var theme = new ThemeColorResult(new Vector3(mainColor.Color.R, mainColor.Color.G, mainColor.Color.B), mainColor.IsDark);
|
||||
return theme;
|
||||
}
|
||||
|
||||
public static async Task<PaletteResult> MedianCutGetAccentColorsFromByteAsync(BitmapDecoder decoder, int count, bool? isDark = null)
|
||||
{
|
||||
var mainColor = await colorThief.GetColor(decoder, 10, false);
|
||||
var theme = new ThemeColorResult(new Vector3(mainColor.Color.R, mainColor.Color.G, mainColor.Color.B), mainColor.IsDark);
|
||||
var palette = await colorThief.GetPalette(decoder, 255, 10, false);
|
||||
var topColors = palette
|
||||
.Where(x => x.IsDark == (isDark ?? mainColor.IsDark))
|
||||
.OrderByDescending(x => x.Population)
|
||||
.Select(x => new Vector3(x.Color.R, x.Color.G, x.Color.B))
|
||||
.Take(count)
|
||||
.ToList();
|
||||
var paletteResult = new PaletteResult(topColors, mainColor.IsDark, theme);
|
||||
|
||||
return paletteResult;
|
||||
}
|
||||
|
||||
public static async Task<Dictionary<Vector3, int>> GetPixelColor(BitmapDecoder bitmapDecoder)
|
||||
{
|
||||
var pixelDataProvider = await bitmapDecoder.GetPixelDataAsync();
|
||||
var pixels = pixelDataProvider.DetachPixelData();
|
||||
var count = bitmapDecoder.PixelWidth * bitmapDecoder.PixelHeight;
|
||||
var vector = new Dictionary<Vector3, int>();
|
||||
for (int i = 0; i < count; i += 10)
|
||||
{
|
||||
var offset = i * 4;
|
||||
var b = pixels[offset];
|
||||
var g = pixels[offset + 1];
|
||||
var r = pixels[offset + 2];
|
||||
var a = pixels[offset + 3];
|
||||
if (a == 0) continue;
|
||||
var color = new Vector3(r, g, b);
|
||||
if (vector.ContainsKey(color))
|
||||
{
|
||||
vector[color]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector[color] = 1;
|
||||
}
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PhoneticHelper
|
||||
{
|
||||
public const string PinyinCode = "zh-pinyin";
|
||||
public const string JyutpingCode = "zh-jyutping";
|
||||
public const string RomajiCode = "ja-romaji";
|
||||
|
||||
public static bool IsPhoneticCode(string code)
|
||||
{
|
||||
return code == PinyinCode || code == JyutpingCode || code == RomajiCode;
|
||||
}
|
||||
|
||||
public static string GetDisplayName(string code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case PinyinCode:
|
||||
return App.ResourceLoader!.GetString("Pinyin");
|
||||
case JyutpingCode:
|
||||
return App.ResourceLoader!.GetString("Jyutping");
|
||||
case RomajiCode:
|
||||
return App.ResourceLoader!.GetString("Romaji");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(code));
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToRomaji(string text)
|
||||
{
|
||||
return Kana.Kana.KanaToRomaji(text, Kana.Error.Ignore).ToStr();
|
||||
}
|
||||
|
||||
public static string ToPinyin(string text, Pinyin.ManTone.Style style = Pinyin.ManTone.Style.TONE)
|
||||
{
|
||||
return Pinyin.Pinyin.Instance.HanziToPinyin(text, style).ToStr();
|
||||
}
|
||||
|
||||
public static string ToJyutping(string text)
|
||||
{
|
||||
return Pinyin.Jyutping.Instance.HanziToPinyin(text).ToStr();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
public static class PlayerIdMatcher
|
||||
{
|
||||
private static readonly List<string> _neteaseFamilyRegex =
|
||||
[
|
||||
"cloudmusic.exe", //NetEaseCloudMusic
|
||||
"^17588BrandonWong\\.LyricEase_", //LyricEase
|
||||
"^48848aaaaaaccd\\.HyPlayer_" //HyPlayer
|
||||
];
|
||||
|
||||
public static bool IsNeteaseFamily(string player)
|
||||
{
|
||||
foreach (var regex in _neteaseFamilyRegex)
|
||||
{
|
||||
var isMatch = Regex.IsMatch(player, regex);
|
||||
if (isMatch) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||