Compare commits

...

69 Commits

Author SHA1 Message Date
Zhe Fang
e15699bb11 fix: language display 2025-10-30 17:33:13 -04:00
Zhe Fang
780cd302f0 fix: pivot issue 2025-10-30 15:52:43 -04:00
Zhe Fang
345949f536 fix: windows status switching issues 2025-10-30 15:29:31 -04:00
Zhe Fang
8dd178991a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-29 20:05:52 -04:00
Zhe Fang
834d0bf5cc fix: search page language name display 2025-10-29 20:05:50 -04:00
Zhe Fang
6d6ecb39b6 Update README.md 2025-10-29 12:07:49 -04:00
Zhe Fang
7db7c68acc Update README.md 2025-10-29 12:06:04 -04:00
Zhe Fang
7fea4ac900 Update README.md 2025-10-29 09:24:50 -04:00
Zhe Fang
3783227f43 Update README.md 2025-10-29 09:06:44 -04:00
Zhe Fang
222c1d9aa1 chores: replace romaji convert package with a lightweight one; fix search control result lacking languages 2025-10-28 15:28:45 -04:00
Zhe Fang
4e668c9890 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-27 17:31:39 -04:00
Zhe Fang
a823901b13 fix: use x:Bind to prevent properties get function got lost after compiling 2025-10-27 17:31:38 -04:00
Zhe Fang
2f9b3df92c Update README.md 2025-10-27 15:01:36 -04:00
Zhe Fang
5f65021400 chores: support volume adjustment; add more lyrics language preview in search panel; fix audio graph not shown in release mode. 2025-10-27 14:52:32 -04:00
Zhe Fang
c28866fdbe fix: sc and tc convert issue 2025-10-26 22:46:34 -04:00
Zhe Fang
fc606f9d30 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-26 22:11:46 -04:00
Zhe Fang
e5d33177d4 feat: phonetic, original and translated text can be displayed at the same time; support set cjk and western font family individually; phonetic and translated font size can be adjusted 2025-10-26 22:11:44 -04:00
Zhe Fang
ab029c9da3 Update index.md 2025-10-26 10:13:29 -04:00
Zhe Fang
a28eef85a5 Update index.md 2025-10-26 10:12:55 -04:00
Zhe Fang
9905d7642c feature: 3d lyrics (x, y, z and depth) 2025-10-25 18:57:34 -04:00
Zhe Fang
02341ecc4a feature: add angle config for fan lyrics effect 2025-10-25 16:59:03 -04:00
Zhe Fang
13802e7d16 chores: update faq 2025-10-25 16:13:39 -04:00
Zhe Fang
d25920c697 chores: update banner.png 2025-10-25 10:59:20 -04:00
Zhe Fang
639c4171dd chores: add items in faq 2025-10-25 09:55:37 -04:00
Zhe Fang
95a1d65c50 chores: add faq hyperlink btn in no music playing placeholder 2025-10-25 09:43:47 -04:00
Zhe Fang
feb4f47db9 chores: add item in faq; hide horizontal scroll bar 2025-10-25 09:14:47 -04:00
Zhe Fang
81f2c4e34a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-25 08:24:30 -04:00
Zhe Fang
48176cce0f fix: misspelling of restart 2025-10-25 08:24:28 -04:00
Zhe Fang
77d41c4813 Update README.md 2025-10-24 22:49:49 -04:00
Zhe Fang
8d1be745ac chores: update version code 2025-10-24 20:54:12 -04:00
Zhe Fang
978702b6ae fix: remove border indicator on DemoWindowGrid to prevent crash 2025-10-24 20:46:30 -04:00
Zhe Fang
0e1f487ac1 chores: add .gif in readme.md 2025-10-24 18:21:19 -04:00
Zhe Fang
3c8775d2cd chores: reduce .gif fps to 24 2025-10-24 18:09:04 -04:00
Zhe Fang
7c39214f2d chores: replace .mp4 with .gif in docs 2025-10-24 18:03:27 -04:00
Zhe Fang
b7952f5eef chores: edit .csproj content to make it possible for publishing to ms store, update version code 2025-10-24 16:45:26 -04:00
Zhe Fang
8c0d3667e4 chores: add contributors section in settings page 2025-10-24 16:21:09 -04:00
Zhe Fang
e1f900a9e6 chores: add help text in switcher 2025-10-24 15:57:33 -04:00
Zhe Fang
212c1fbcdd chores: add lyrics window switcher entry for top command area ands system tray, add animation when open and close switcher 2025-10-24 15:43:36 -04:00
Zhe Fang
2cb04fa1b7 feature: add support for song title and artist font size automatic adjustment 2025-10-24 14:08:28 -04:00
Zhe Fang
8ab3a53a38 chores: add video width in docs 2025-10-24 13:15:09 -04:00
Zhe Fang
3b4d5b9668 chores: update docs 2025-10-24 13:12:29 -04:00
Zhe Fang
2409165b91 chores: update docs 2025-10-24 12:31:55 -04:00
Zhe Fang
fe1eb2882e chores: update docs 2025-10-24 12:31:15 -04:00
Zhe Fang
51dd58fc74 docs: update Google Drive link 2025-10-24 07:53:18 -04:00
Zhe Fang
0f5f663b32 chores: round value to 1 decimal place in ExtendedSlider control. 2025-10-24 07:48:53 -04:00
Zhe Fang
4815c32dba chores: default to hide in system env in docked mode, desktop mode and fullscreen mode templates 2025-10-24 07:17:49 -04:00
Zhe Fang
3f5a0a0d73 Merge pull request #120 from Storyteller-Studios/dev
chores: Force Dpi to 96
2025-10-24 07:10:48 -04:00
Raspberry-Monster
1b34b28fbe chores: Force Dpi to 96 2025-10-24 16:17:08 +08:00
Zhe Fang
fe4d67c1f1 chores: adjust SongInfoFontSize for fullscreen template mode 2025-10-23 22:42:51 -04:00
Zhe Fang
1ae00257a1 chores: update template mode config (to match with fluid layer enabled by defualt) 2025-10-23 22:26:58 -04:00
Zhe Fang
814de1a4a5 chore: enable fluid layer by default 2025-10-23 22:23:47 -04:00
Zhe Fang
28b568e7a4 chore: add accelerator Escape for close button in LyricsWindowSwitchControl 2025-10-23 22:19:51 -04:00
Zhe Fang
786d23b320 chores: add animation when switching color picker type, enable line fade by default, default to MedianCut, edit displayed text for color picker type for better direct understanding for users. 2025-10-23 21:47:37 -04:00
Zhe Fang
a394527f80 Merge pull request #119 from Storyteller-Studios/dev
Support Multiple Palette Generation Algorithm and Remove ImageSharp
2025-10-23 21:09:12 -04:00
Raspberry-Monster
80422376c3 chores: Use Bitmap's Dpi First 2025-10-24 00:31:24 +08:00
Raspberry-Monster
5114c83843 chores: Reduce Unnecessary Buffer Copies 2025-10-23 23:16:26 +08:00
Raspberry-Monster
835e0d34fc chores: Bump Dependencies, Remove ImageSharp 2025-10-23 22:38:31 +08:00
Raspberry-Monster
7ab833a53a chores: Support Multiple Palette Generation Method 2025-10-23 18:16:23 +08:00
Raspberry-Monster
d348a30237 Merge branch 'dev-upstream' into dev 2025-10-22 23:06:08 +08:00
Zhe Fang
d0b626c508 fix: issue related with docked mode 2025-10-22 10:52:57 -04:00
Raspberry-Monster
9debdc76f9 chores: Change ColorThief to Impressionist 2025-10-22 22:48:10 +08:00
Zhe Fang
67a45e90fa chore: update version code 2025-10-22 10:31:14 -04:00
Zhe Fang
b4c7655043 chores: move window color sampling settings item to general tab, remove useless debug writeline 2025-10-22 10:23:50 -04:00
Zhe Fang
2adc2aced2 fix: window color sampling incorrect behavior 2025-10-22 10:18:49 -04:00
Zhe Fang
e638739638 fix: improve docked mode window sizeing behaviors 2025-10-22 09:24:16 -04:00
Zhe Fang
c24213358e Merge pull request #118 from Storyteller-Studios/dev
Improve identification of NeteaseFamily and fix Lrc Parser unexpected behavior when parsing [Min:Sec:MillSec]
2025-10-22 07:58:28 -04:00
Raspberry-Monster
6e78f849c4 chores: Improve LrcParser 2025-10-22 14:10:23 +08:00
Raspberry-Monster
80444b69e0 chores: Improve identification of NeteaseFamily and fix Lrc Parser unexpected behavior when parsing [Min:Sec:MillSec] 2025-10-22 13:06:33 +08:00
Zhe Fang
78775e9bb3 Update README.md 2025-10-21 22:51:53 -04:00
151 changed files with 5895 additions and 2107 deletions

View File

@@ -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)' &lt; '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)' &lt; '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>

View File

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

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: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>
@@ -59,6 +60,9 @@
<converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" />
<converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" />
<converter:RectToMarginConverter x:Key="RectToMarginConverter" />
<converter:LanguageCodeToDisplayedNameConverter x:Key="LanguageCodeToDisplayedNameConverter" />
<converter:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter" />
<converter:DisplayLanguageCodeToIndexConverter x:Key="DisplayLanguageCodeToIndexConverter" />
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
@@ -335,6 +339,7 @@
<!-- Fonts -->
<FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
</ResourceDictionary>
</Application.Resources>

View File

@@ -118,6 +118,7 @@ namespace BetterLyrics.WinUI3
.AddSingleton<LyricsSearchControlViewModel>()
.AddSingleton<LyricsWindowSettingsControlViewModel>()
.AddSingleton<LyricsWindowSwitchControlViewModel>()
.AddSingleton<LyricsWindowSwitchWindowViewModel>()
.AddSingleton<LyricsWindowViewModel>()
.AddSingleton<SettingsWindowViewModel>()
.AddSingleton<SystemTrayViewModel>()

View File

@@ -20,15 +20,15 @@
<PRIResource Remove="ViewModels\Lyrics\**" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\effect.bin" />
<None Remove="Assets\Segoe Fluent Icons.ttf" />
<None Remove="Assets\Wiki82.profile.xml" />
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
<None Remove="Controls\AppSettingsControl.xaml" />
<None Remove="Controls\DemoWindowGrid.xaml" />
<None Remove="Controls\ExtendedSlider.xaml" />
<None Remove="Controls\FontFamilyAutoSuggestBox.xaml" />
<None Remove="Controls\LyricsSearchControl.xaml" />
<None Remove="Controls\LyricsSettingsControl.xaml" />
<None Remove="Controls\LyricsStyleSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSwitchControl.xaml" />
<None Remove="Controls\MediaSettingsControl.xaml" />
@@ -49,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" />
@@ -64,36 +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="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="RomajiConverter.Core" Version="1.0.9" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.3-dev-02320" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
<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="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.CoreAudio" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.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>
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
<ProjectReference Include="..\..\Impressionist\Impressionist\Impressionist.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="Rendering\InAppLyricsRenderer.xaml">
@@ -108,6 +111,8 @@
<!--Disable Trimming for Specific Packages-->
<ItemGroup>
<TrimmerRootAssembly Include="TagLibSharp" />
<TrimmerRootAssembly Include="NAudio.Wasapi" />
<TrimmerRootAssembly Include="Vanara.PInvoke.CoreAudio" />
</ItemGroup>
<ItemGroup>
<Content Update="Assets\AIMP.png">
@@ -122,7 +127,7 @@
<Content Update="Assets\Edge.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\effect.bin">
<Content Update="Assets\FluidEffect.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Empty.png">
@@ -198,6 +203,16 @@
<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>
@@ -239,7 +254,7 @@
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsSettingsControl.xaml">
<Page Update="Controls\LyricsEffectSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>

View File

@@ -9,7 +9,9 @@ namespace BetterLyrics.WinUI3.Constants
public static class Link
{
public const string GitHubUrl = "https://github.com/jayfunc/BetterLyrics";
public const string FAQUrl = $"{GitHubUrl}/blob/dev/FAQ/FAQ.md";
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";

View File

@@ -23,7 +23,7 @@
Glyph=&#xE744;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAutoSize">
<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}">
@@ -67,14 +67,26 @@
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E9;}">
<local:ExtendedSlider
Default="18"
Frequency="2"
Maximum="72"
Minimum="8"
Value="{x:Bind AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageLyricsFontSize"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8E9;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAutoAdjust">
<ToggleSwitch IsOn="{x:Bind 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"

View File

@@ -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=&#xF2B7;}"
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>

View File

@@ -21,23 +21,7 @@
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{ThemeResource AccentAcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource AccentFillColorDefaultBrush}"
CornerRadius="4">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsWindowStatus.IsBorderless, Mode=OneWay}"
ComparisonCondition="Equal"
Value="True">
<interactivity:ChangePropertyAction PropertyName="BorderThickness" Value="0" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind LyricsWindowStatus.IsBorderless, Mode=OneWay}"
ComparisonCondition="Equal"
Value="False">
<interactivity:ChangePropertyAction PropertyName="BorderThickness" Value="1" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</Grid>
CornerRadius="4" />
<!-- Is default -->
<Grid
Margin="4"
@@ -82,10 +66,18 @@
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4"
Opacity="0.7">
<TextBlock
FontSize="12"
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}"
TextWrapping="Wrap" />
<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

View File

@@ -19,6 +19,7 @@
StepFrequency="{x:Bind Frequency, Mode=OneWay}"
TickFrequency="{x:Bind Frequency, Mode=OneWay}"
TickPlacement="None"
ValueChanged="Slider_ValueChanged"
Value="{x:Bind Value, Mode=TwoWay}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
@@ -43,7 +44,7 @@
Margin="3,-2,3,0"
Orientation="Horizontal"
Spacing="2">
<TextBlock VerticalAlignment="Center" Text="{x:Bind Value, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind RoundedValue, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind Unit, Mode=OneWay}" />
</StackPanel>

View File

@@ -21,11 +21,18 @@ namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class ExtendedSlider : UserControl
{
public event EventHandler<RangeBaseValueChangedEventArgs> ValueChanged;
public ExtendedSlider()
{
InitializeComponent();
}
private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
ValueChanged?.Invoke(sender, e);
}
private void Subtract()
{
if (Value - Frequency < Minimum)
@@ -68,6 +75,8 @@ namespace BetterLyrics.WinUI3.Controls
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 =
@@ -93,7 +102,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
{

View File

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

View File

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

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns: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"
@@ -113,6 +114,13 @@
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>

View File

@@ -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=&#xEB42;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
Default="0"
Frequency="1"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE727;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
Default="5"
Frequency="1"
Maximum="10"
Minimum="0"
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED3A;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- 高亮 -->
<controls:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E6;}">
<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=&#xF5EF;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Frequency="1"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 辉光效果 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsGlowEffect"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE9A9;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Frequency="1"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 浮动动画 -->
<controls:SettingsExpander
x:Uid="SettingsPageLyricsFloatAnimation"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8C5;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="1"
Frequency="1"
Maximum="4"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- 扇形歌词 -->
<controls:SettingsExpander
x:Uid="SettingsPageFan"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xEBC5;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard IsEnabled="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="30"
Frequency="1"
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=&#xE914;}"
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"
Frequency="1"
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"
Frequency="1"
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"
Frequency="1"
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=&#xECE7;}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
</ComboBox>
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDuration">
<local:ExtendedSlider
Default="500"
Frequency="50"
Maximum="1000"
Minimum="50"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDuration, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollTopDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollTopDelay, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageScrollBottomDelay">
<local:ExtendedSlider
Default="0"
Frequency="50"
Maximum="2000"
Minimum="0"
Unit="ms"
Value="{x:Bind LyricsEffectSettings.LyricsScrollBottomDelay, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -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
{

View File

@@ -145,35 +145,46 @@
Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Grid>
<Grid Grid.Column="2">
<ListView ItemsSource="{x:Bind ViewModel.LyricsData.LyricsLines, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsLine, Mode=TwoWay}">
<Pivot ItemsSource="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
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.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="NotEqual"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ListView.ItemTemplate>
<Pivot.HeaderTemplate>
<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>
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{Binding LanguageCode, Mode=OneWay, Converter={StaticResource LanguageCodeToDisplayedNameConverter}}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</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"
@@ -182,13 +193,13 @@
<Image MaxWidth="100" Source="/Assets/Page.png" />
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
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.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="Equal"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />

View File

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

View File

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

View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsStyleSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid>
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<!-- Lyrics style -->
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsExpander x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D2;}">
<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=&#xE8DD;}">
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB42;}">
<local:ExtendedSlider
Default="30"
Frequency="1"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEC12;}">
<local:ExtendedSlider
Default="0"
Frequency="1"
Maximum="5"
Minimum="0"
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- 字体颜色 -->
<controls:SettingsExpander x:Uid="SettingsPageFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D3;}">
<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=&#xE8E9;}">
<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="96"
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="96"
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="96"
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=&#xF579;}">
<local:ExtendedSlider
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
Default="0.5"
Frequency="0.1"
Maximum="2"
Minimum="0"
Unit="x"
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF464;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

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

View File

@@ -92,7 +92,73 @@
</Grid>
<Grid Grid.Column="1">
<controls:SwitchPresenter Margin="0,100,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Pivot SelectionChanged="Pivot_SelectionChanged">
<PivotItem Tag="General">
<PivotItem.Header>
<TextBlock
x:Uid="AppSettingsControlGeneral"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="AlbumArtStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAlbumStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsEffect">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsEffect"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsBackground">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageBackgroundOverlay"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="Advanced">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAdvanced"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
</Pivot>
</StackPanel>
</Grid>
<controls:SwitchPresenter Margin="0,110,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
<controls:SwitchPresenter.ContentTransitions>
<TransitionCollection>
<PopupThemeTransition />
@@ -137,76 +203,6 @@
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageWindowBounds"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF16B;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="X">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Right, Mode=OneWay}"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Left, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Header="Y">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom, Mode=OneWay}"
Minimum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Top, Mode=OneWay}"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageWidth">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageHeight">
<uc:ExtendedSlider
Frequency="1"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
Minimum="64"
ResetButtonVisibility="Collapsed"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsExpander
x:Uid="SettingsPageAOT"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE718;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsExpander
x:Uid="SettingsPageWorkArea"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
@@ -230,6 +226,86 @@
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
</ComboBox>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsExpander
x:Uid="SettingsPageAdaptEnvColor"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE88F;}"
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:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageWindowBounds"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF16B;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<controls:SettingsCard Header="X">
<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=&#xE718;}"
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>
@@ -247,9 +323,14 @@
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics style and effect -->
<controls:Case Value="Lyrics">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
<!-- 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 -->
@@ -275,24 +356,6 @@
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsExpander
x:Uid="SettingsPageAdaptEnvColor"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE88F;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageEnvColorSample" Header="Environment color sample mode">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.EnvironmentSampleMode, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleBelow" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleAbove" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" />
</ComboBox>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB41;}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" />
@@ -308,81 +371,6 @@
</controls:SwitchPresenter>
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<ListView
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollMode="Disabled"
SelectionChanged="ListView_SelectionChanged">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Items>
<ListViewItem Tag="General">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xECAA;" />
<TextBlock x:Uid="AppSettingsControlGeneral" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="AlbumArtStyle">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE93C;" />
<TextBlock x:Uid="SettingsPageAlbumStyle" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="Lyrics">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xEDC6;" />
<TextBlock x:Uid="SettingsPageLyrics" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="LyricsBackground">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xF5EF;" />
<TextBlock x:Uid="SettingsPageBackgroundOverlay" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
<ListViewItem Tag="Advanced">
<StackPanel Orientation="Horizontal" Spacing="6">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xEC7A;" />
<TextBlock x:Uid="SettingsPageAdvanced" VerticalAlignment="Center" />
</StackPanel>
</ListViewItem>
</ListView.Items>
</ListView>
</StackPanel>
</Grid>
</Grid>
</Grid>
</UserControl>

View File

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

View File

@@ -16,16 +16,27 @@
VerticalAlignment="Center"
Background="{ThemeResource AcrylicInAppFillColorDefaultBrush}"
CornerRadius="12">
<FontIcon
Margin="20"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE8AB;" />
<Button
Margin="12"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="Button_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE653;}"
Style="{StaticResource GhostButtonStyle}" />
Glyph=&#xE73C;}"
Style="{StaticResource GhostButtonStyle}">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Escape" />
</Button.KeyboardAccelerators>
</Button>
<ListView
Margin="48"
Margin="48,56"
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
@@ -46,5 +57,20 @@
</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="&#xE946;" />
<TextBlock x:Uid="LyricsWindowSwitchWindowHelp" Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</Grid>
</UserControl>

View File

@@ -14,6 +14,7 @@ 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;
@@ -32,13 +33,21 @@ namespace BetterLyrics.WinUI3.Controls
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSwitchControlViewModel>();
}
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
private async void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
WindowHelper.HideWindow<LyricsWindowSwitchWindow>();
await HideAsync();
}
private void Button_Click(object sender, RoutedEventArgs e)
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>();
}
}

View File

@@ -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"
@@ -132,7 +135,7 @@
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"
@@ -207,72 +210,32 @@
<!-- Provider info -->
<TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
<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">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
<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"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE774;}"
IsExpanded="True">
<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 SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
<ComboBoxItem Content="العربية" Tag="ar" />
<ComboBoxItem Content="Azərbaycan dili" Tag="az" />
<ComboBoxItem Content="Български" Tag="bg" />
<ComboBoxItem Content="বাংলা" Tag="bn" />
<ComboBoxItem Content="Català" Tag="ca" />
<ComboBoxItem Content="Čeština" Tag="cs" />
<ComboBoxItem Content="Dansk" Tag="da" />
<ComboBoxItem Content="Deutsch" Tag="de" />
<ComboBoxItem Content="Ελληνικά" Tag="el" />
<ComboBoxItem Content="English" Tag="en" />
<ComboBoxItem Content="Esperanto" Tag="eo" />
<ComboBoxItem Content="Español" Tag="es" />
<ComboBoxItem Content="Eesti" Tag="et" />
<ComboBoxItem Content="Euskara" Tag="eu" />
<ComboBoxItem Content="فارسی" Tag="fa" />
<ComboBoxItem Content="Suomi" Tag="fi" />
<ComboBoxItem Content="Français" Tag="fr" />
<ComboBoxItem Content="Gaeilge" Tag="ga" />
<ComboBoxItem Content="Galego" Tag="gl" />
<ComboBoxItem Content="עברית" Tag="he" />
<ComboBoxItem Content="हिन्दी" Tag="hi" />
<ComboBoxItem Content="Magyar" Tag="hu" />
<ComboBoxItem Content="Bahasa Indonesia" Tag="id" />
<ComboBoxItem Content="Italiano" Tag="it" />
<ComboBoxItem Content="日本語" Tag="ja" />
<ComboBoxItem Content="한국어" Tag="ko" />
<ComboBoxItem Content="Кыргызча" Tag="ky" />
<ComboBoxItem Content="Lietuvių" Tag="lt" />
<ComboBoxItem Content="Latviešu" Tag="lv" />
<ComboBoxItem Content="Bahasa Melayu" Tag="ms" />
<ComboBoxItem Content="Norsk bokmål" Tag="nb" />
<ComboBoxItem Content="Nederlands" Tag="nl" />
<ComboBoxItem Content="Português (Brasil)" Tag="pt-BR" />
<ComboBoxItem Content="Polski" Tag="pl" />
<ComboBoxItem Content="Português" Tag="pt" />
<ComboBoxItem Content="Română" Tag="ro" />
<ComboBoxItem Content="Русский" Tag="ru" />
<ComboBoxItem Content="Slovenčina" Tag="sk" />
<ComboBoxItem Content="Slovenščina" Tag="sl" />
<ComboBoxItem Content="Shqip" Tag="sq" />
<ComboBoxItem Content="Српски" Tag="sr" />
<ComboBoxItem Content="Svenska" Tag="sv" />
<ComboBoxItem Content="ไทย" Tag="th" />
<ComboBoxItem Content="Filipino" Tag="tl" />
<ComboBoxItem Content="Türkçe" Tag="tr" />
<ComboBoxItem Content="Українська" Tag="uk" />
<ComboBoxItem Content="اردو" Tag="ur" />
<ComboBoxItem Content="Tiếng Việt" Tag="vi" />
<ComboBoxItem Content="中文" Tag="zh" />
<ComboBox 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}">
@@ -299,20 +262,15 @@
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<!-- Lyrics phonetic -->
<controls:SettingsExpander
x:Uid="SettingsPageChinese"
IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"
IsExpanded="True">
<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>
<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" />
@@ -320,11 +278,12 @@
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageJapanese" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<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>
@@ -363,7 +322,7 @@
<!-- LX music server -->
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard>
<controls:SettingsCard Header="SettingsPageServerAddress">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBox
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
@@ -377,17 +336,19 @@
</controls:SettingsCard>
<!-- Apple Music token -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="media-user-token (for Apple Muisc)" />
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="Apple Muisc media-user-token" />
<controls:SettingsCard
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
Description="Use at your own risk"
Foreground="{ThemeResource SystemFillColorCautionBrush}"
Header="Use at your own risk">
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=&#xE897;}" NavigateUri="{x:Bind constants:Link.AppleMusicCfgUrl}" />
<Button
Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},

View File

@@ -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=&#xE8AB;}" />
<MenuFlyoutItem
x:Uid="SystemTrayLyrics"
Command="{x:Bind ViewModel.OpenLyricsCommand}"
@@ -44,13 +49,11 @@
Command="{x:Bind ViewModel.OpenSettingsCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE713;}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem
x:Uid="SystemTrayResetWindowPosition"
Command="{x:Bind ViewModel.ResetWindowPositionCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE923;}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem
x:Uid="SystemTrayRestart"
Command="{x:Bind ViewModel.RestartAppCommand}"

View File

@@ -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();
}
}
}

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
using System;
using BetterLyrics.WinUI3.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -11,4 +12,17 @@ namespace BetterLyrics.WinUI3.Enums
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))
};
}
}
}

View File

@@ -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
}
}

View File

@@ -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,19 +73,38 @@ namespace BetterLyrics.WinUI3.Helper
{
CanvasCommandList list = new(control);
using var ds = list.CreateDrawingSession();
// 描边
if (strokeWidth > 0)
{
if (lyricsLine.TextGeometry == null)
if (lyricsLine.PhoneticCanvasGeometry != null)
{
return list;
ds.DrawGeometry(lyricsLine.PhoneticCanvasGeometry, lyricsLine.PhoneticPosition, strokeColor, strokeWidth);
}
if (lyricsLine.OriginalCanvasGeometry != null)
{
ds.DrawGeometry(lyricsLine.OriginalCanvasGeometry, lyricsLine.OriginalPosition, strokeColor, strokeWidth);
}
if (lyricsLine.TranslatedCanvasGeometry != null)
{
ds.DrawGeometry(lyricsLine.TranslatedCanvasGeometry, lyricsLine.TranslatedPosition, strokeColor, strokeWidth);
}
ds.DrawGeometry(lyricsLine.TextGeometry, lyricsLine.Position, strokeColor, strokeWidth); // 描边
}
if (lyricsLine.CanvasTextLayout == null)
// 绘制文本(填充)
if (lyricsLine.PhoneticCanvasTextLayout != null)
{
return list;
ds.DrawTextLayout(lyricsLine.PhoneticCanvasTextLayout, lyricsLine.PhoneticPosition, fontColor);
}
ds.DrawTextLayout(lyricsLine.CanvasTextLayout, lyricsLine.Position, fontColor); // 绘制文本(填充)
if (lyricsLine.OriginalCanvasTextLayout != null)
{
ds.DrawTextLayout(lyricsLine.OriginalCanvasTextLayout, lyricsLine.OriginalPosition, fontColor);
}
if (lyricsLine.TranslatedCanvasTextLayout != null)
{
ds.DrawTextLayout(lyricsLine.TranslatedCanvasTextLayout, lyricsLine.TranslatedPosition, fontColor);
}
return list;
}
@@ -113,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
@@ -129,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
);
@@ -171,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)
@@ -190,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
);
@@ -207,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
);
@@ -225,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
);
@@ -246,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++)
@@ -259,7 +279,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
);
@@ -270,17 +290,17 @@ namespace BetterLyrics.WinUI3.Helper
return mask;
}
public static CanvasCommandList CreateTranslationHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
public static CanvasCommandList CreatePhoneticHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
{
var mask = new CanvasCommandList(control);
using var ds = mask.CreateDrawingSession();
if (lyricsLine.CanvasTextLayout == null)
if (lyricsLine.PhoneticCanvasTextLayout == null)
{
return mask;
}
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(lyricsLine.OriginalText.Length, lyricsLine.DisplayedText.Length - lyricsLine.OriginalText.Length);
var regions = lyricsLine.PhoneticCanvasTextLayout.GetCharacterRegions(0, lyricsLine.PhoneticText.Length);
if (regions.Length > 0)
{
for (int j = 0; j < regions.Length; j++)
@@ -288,7 +308,36 @@ 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.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
);

View File

@@ -131,7 +131,7 @@ namespace BetterLyrics.WinUI3.Helper
}
case WindowPixelSampleMode.AboveWindow:
{
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Top - 3, screenWidth, 1);
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Top - 2, screenWidth, 1);
}
case WindowPixelSampleMode.WindowArea:
{
@@ -149,49 +149,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)

View File

@@ -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) { }
}
}
}
}

View File

@@ -1,15 +1,14 @@
// 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;
@@ -21,6 +20,7 @@ using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage.Streams;
using Windows.UI;
using static Vanara.PInvoke.Ole32;
namespace BetterLyrics.WinUI3.Helper
{
@@ -46,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);
@@ -76,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)
@@ -129,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;
}
@@ -156,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 PngEncoder());
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;
}
}

View File

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

View File

@@ -4,6 +4,7 @@ using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services;
using Lyricify.Lyrics.Models;
using Lyricify.Lyrics.Parsers;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -13,17 +14,19 @@ 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 LyricsData? LibreTranslationLyricsData => LyricsDataArr.LastOrDefault();
public void Parse(string title, string artist, string? raw, int? durationMs, LyricsSearchProvider? lyricsSearchProvider)
{
LyricsDataArr = [];
durationMs ??= (int)TimeSpan.FromMinutes(99).TotalMilliseconds;
_lyricsDataArr = [];
if (raw == null)
{
_lyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value));
LyricsDataArr.Add(LyricsData.GetNotfoundPlaceholder(durationMs.Value));
}
else
{
@@ -34,10 +37,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);
@@ -47,66 +50,110 @@ namespace BetterLyrics.WinUI3.Helper
}
}
FillRomanizationLyricsData();
_lyricsDataArr.Add(new LyricsData()); // 为机翻预留
return _lyricsDataArr;
FillTranslationFromCache(title, artist, lyricsSearchProvider);
}
private void FillTranslationFromCache(string title, string artist, LyricsSearchProvider? provider)
{
string? translationRaw = null;
switch (provider)
{
case LyricsSearchProvider.QQ:
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.QQTranslationCacheDirectory);
break;
case LyricsSearchProvider.Kugou:
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.KugouTranslationCacheDirectory);
break;
case LyricsSearchProvider.Netease:
translationRaw = FileHelper.ReadLyricsCache(title, artist, LyricsFormat.Lrc, PathHelper.NeteaseTranslationCacheDirectory);
break;
case LyricsSearchProvider.LrcLib:
break;
case LyricsSearchProvider.AmllTtmlDb:
break;
case LyricsSearchProvider.LocalMusicFile:
break;
case LyricsSearchProvider.LocalLrcFile:
break;
case LyricsSearchProvider.LocalEslrcFile:
break;
case LyricsSearchProvider.LocalTtmlFile:
break;
default:
break;
}
if (translationRaw != null)
{
switch (provider)
{
case LyricsSearchProvider.QQ:
case LyricsSearchProvider.Kugou:
case LyricsSearchProvider.Netease:
ParseLrc(translationRaw);
break;
default:
break;
}
}
}
private void FillRomanizationLyricsData()
{
var chinese = _lyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
var chinese = LyricsDataArr.Where(x => x.LanguageCode == "zh").FirstOrDefault();
if (chinese != null)
{
_lyricsDataArr.Add(new LyricsData
LyricsDataArr.Add(new LyricsData
{
LanguageCode = "pinyin",
LanguageCode = PhoneticHelper.PinyinCode,
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
{
StartMs = line.StartMs,
EndMs = line.EndMs,
OriginalText = Pinyin.Pinyin.Instance.HanziToPinyin(line.OriginalText).ToStr(),
OriginalText = PhoneticHelper.ToPinyin(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{
StartMs = c.StartMs,
EndMs = c.EndMs,
Text = Pinyin.Pinyin.Instance.HanziToPinyin(c.Text).ToStr(),
Text = PhoneticHelper.ToPinyin(c.Text),
StartIndex = c.StartIndex
}).ToList()
}).ToList()
});
_lyricsDataArr.Add(new LyricsData
LyricsDataArr.Add(new LyricsData
{
LanguageCode = "jyutping",
LanguageCode = PhoneticHelper.JyutpingCode,
LyricsLines = chinese.LyricsLines.Select(line => new LyricsLine
{
StartMs = line.StartMs,
EndMs = line.EndMs,
OriginalText = Pinyin.Jyutping.Instance.HanziToPinyin(line.OriginalText).ToStr(),
OriginalText = PhoneticHelper.ToJyutping(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{
StartMs = c.StartMs,
EndMs = c.EndMs,
Text = Pinyin.Jyutping.Instance.HanziToPinyin(c.Text).ToStr(),
Text = PhoneticHelper.ToJyutping(c.Text),
StartIndex = c.StartIndex
}).ToList()
}).ToList()
});
}
var japanese = _lyricsDataArr.Where(x => x.LanguageCode == "ja").FirstOrDefault();
var japanese = LyricsDataArr.Where(x => x.LanguageCode == "ja").FirstOrDefault();
if (japanese != null)
{
_lyricsDataArr.Add(new LyricsData
LyricsDataArr.Add(new LyricsData
{
LanguageCode = "romaji",
LanguageCode = PhoneticHelper.RomajiCode,
LyricsLines = japanese.LyricsLines.Select(line => new LyricsLine
{
StartMs = line.StartMs,
EndMs = line.EndMs,
OriginalText = LanguageHelper.ToRomaji(line.OriginalText),
OriginalText = PhoneticHelper.ToRomaji(line.OriginalText),
LyricsChars = line.LyricsChars.Select(c => new LyricsChar
{
StartMs = c.StartMs,
EndMs = c.EndMs,
Text = LanguageHelper.ToRomaji(c.Text),
Text = PhoneticHelper.ToRomaji(c.Text),
StartIndex = c.StartIndex
}).ToList()
}).ToList()
@@ -121,9 +168,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)
{
@@ -140,7 +185,7 @@ namespace BetterLyrics.WinUI3.Helper
syllables.Add((totalMs, text));
}
if (syllables.Count > 0)
if (syllables.Count > 1)
{
lrcLines.Add(
(
@@ -153,18 +198,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)>()));
}
}
@@ -180,8 +227,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)
@@ -219,7 +267,7 @@ namespace BetterLyrics.WinUI3.Helper
currentIndex += charText?.Length ?? 0;
}
}
_lyricsDataArr[langIdx].LyricsLines.Add(line);
LyricsDataArr[langStartIndex + langIdx].LyricsLines.Add(line);
}
// 没有翻译行则不补原文,直接跳过
}
@@ -331,9 +379,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
{
@@ -448,7 +496,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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 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).ToStr();
}
public static string ToPinyin(string text, Pinyin.ManTone.Style style = Pinyin.ManTone.Style.TONE)
{
return Pinyin.Pinyin.Instance.HanziToPinyin(text, style).ToStr();
}
public static string ToJyutping(string text)
{
return Pinyin.Jyutping.Instance.HanziToPinyin(text).ToStr();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -67,7 +67,7 @@ namespace BetterLyrics.WinUI3.Helper
IsCapturing = true;
}
catch (Exception)
catch (Exception ex)
{
}
}

View File

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

View File

@@ -11,6 +11,7 @@ using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Vanara.PInvoke;
using Windows.ApplicationModel.Core;
using Windows.Foundation;
@@ -33,10 +34,8 @@ namespace BetterLyrics.WinUI3.Helper
public static void HideWindow<T>()
{
var window = _activeWindows.Find(w => w is T);
if (window is Window w)
{
w.Hide();
}
var castedWindow = window as Window;
castedWindow?.Hide();
}
public static void CloseWindow<T>()
@@ -115,16 +114,8 @@ namespace BetterLyrics.WinUI3.Helper
else
{
var castedWindow = (Window)window;
if (typeof(T) == typeof(LyricsWindow))
{
var lyricsWindow = (LyricsWindow)window;
lyricsWindow.Show();
}
else
{
castedWindow.Restore();
castedWindow.Activate();
}
castedWindow.Activate();
castedWindow.AppWindow.MoveInZOrderAtTop();
}
}
@@ -203,13 +194,15 @@ namespace BetterLyrics.WinUI3.Helper
Window? window = GetWindowByWindowType<T>() as Window;
if (window == null) return;
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (enable)
{
EnableWorkArea(window);
RegisterWorkArea(hwnd);
}
else
{
DisableWorkArea(window);
UnregisterWorkArea(hwnd);
}
}
@@ -254,7 +247,8 @@ namespace BetterLyrics.WinUI3.Helper
var window = GetWindowByWindowType<T>() as Window;
if (window == null) return;
window.AppWindow.MoveAndResize(rect.ToRectInt32());
window.AppWindow.Move(new Windows.Graphics.PointInt32((int)rect.X, (int)rect.Y));
window.AppWindow.Resize(new Windows.Graphics.SizeInt32((int)rect.Width, (int)rect.Height));
}
public static void SetTitleBarArea<T>(TitleBarArea titleBarArea)
@@ -270,40 +264,6 @@ namespace BetterLyrics.WinUI3.Helper
}
}
private static void DisableWorkArea(Window window)
{
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (!_workAreas.Contains(hwnd)) return;
UnregisterWorkArea(hwnd);
}
private static void EnableWorkArea(Window window)
{
IntPtr hwnd = WindowNative.GetWindowHandle(window);
if (_workAreas.Contains(hwnd)) return;
RegisterWorkArea(hwnd);
double y = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
y -= 1;
User32.SetWindowPos(
hwnd,
IntPtr.Zero,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
(int)y,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
User32.SetWindowPosFlags.SWP_SHOWWINDOW
);
}
private static void RegisterWorkArea(IntPtr hwnd)
{
if (_workAreas.Contains(hwnd)) return;
@@ -350,55 +310,40 @@ namespace BetterLyrics.WinUI3.Helper
_workAreas.Remove(hwnd);
}
public static void UpdateWorkAreaHeight<T>()
public static void UpdateWorkArea<T>()
{
var window = GetWindowByWindowType<T>() as Window;
if (window == null) return;
var hwnd = WindowNative.GetWindowHandle(window);
App.DispatcherQueueTimer?.Debounce(() =>
if (!_workAreas.Contains(hwnd))
return;
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
Shell32.APPBARDATA abd = new()
{
if (!_workAreas.Contains(hwnd))
return;
var uEdge = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
double top = _liveStatesService.LiveStates.LyricsWindowStatus.DockPlacement == DockPlacement.Top ?
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Top :
_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
double bottom = top + _liveStatesService.LiveStates.LyricsWindowStatus.DockHeight;
Shell32.APPBARDATA abd = new()
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
hWnd = hwnd,
uEdge = uEdge,
rc = new RECT
{
cbSize = (uint)Marshal.SizeOf<Shell32.APPBARDATA>(),
hWnd = hwnd,
uEdge = uEdge,
rc = new RECT
{
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
Top = (int)top,
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
Bottom = (int)bottom,
},
};
Left = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
Top = (int)top,
Right = (int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Right,
Bottom = (int)bottom,
},
};
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
// 同步窗口实际高度和位置
User32.SetWindowPos(
hwnd,
IntPtr.Zero,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Left,
(int)top - 1,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.MonitorBounds.Width,
(int)_liveStatesService.LiveStates.LyricsWindowStatus.DockHeight + 1,
User32.SetWindowPosFlags.SWP_SHOWWINDOW
);
}, TimeSpan.FromMilliseconds(100));
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
}
public static void SetLyricsWindowVisibilityByPlayingStatus()

View File

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

View File

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

View File

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

View File

@@ -32,7 +32,23 @@ namespace BetterLyrics.WinUI3.Models
LyricsLines = lyricsLines;
}
public void SetDisplayedTextAlongWith(LyricsData translationData, string separator, int toleranceMs = 0)
public void ClearTranslatedText()
{
foreach (var line in LyricsLines)
{
line.TranslatedText = "";
}
}
public void ClearPhoneticText()
{
foreach (var line in LyricsLines)
{
line.PhoneticText = "";
}
}
public void SetTranslatedText(LyricsData translationData, string separator, int toleranceMs = 0)
{
foreach (var line in LyricsLines)
{
@@ -42,17 +58,39 @@ namespace BetterLyrics.WinUI3.Models
if (transLine != null)
{
line.DisplayedText = $"{line.OriginalText}{separator}{transLine.OriginalText}";
// 此处 transLine.OriginalText 指翻译中的“原文”属性
line.TranslatedText = transLine.OriginalText;
}
else
{
// 没有匹配的翻译,翻译部分留空
line.DisplayedText = $"{line.OriginalText}";
// 没有匹配的翻译
line.TranslatedText = "";
}
}
}
public void SetDisplayedTextAlongWith(string translation, string separator)
public void SetPhoneticText(LyricsData phoneticData, string separator, int toleranceMs = 0)
{
foreach (var line in LyricsLines)
{
// 在音译歌词中查找与当前行开始时间最接近且在容忍范围内的行
var transLine = phoneticData.LyricsLines
.FirstOrDefault(t => Math.Abs(t.StartMs - line.StartMs) <= toleranceMs);
if (transLine != null)
{
// 此处 transLine.OriginalText 指音译中的“原文”属性
line.PhoneticText = transLine.OriginalText;
}
else
{
// 没有匹配的音译
line.PhoneticText = "";
}
}
}
public void SetTranslation(string translation, string separator)
{
List<string> translationArr = translation.Split(StringHelper.NewLine).ToList();
int i = 0;
@@ -60,24 +98,16 @@ namespace BetterLyrics.WinUI3.Models
{
if (i >= translationArr.Count)
{
line.DisplayedText = line.OriginalText; // No translation available, keep original text
line.TranslatedText = ""; // No translation available, keep empty
}
else
{
line.DisplayedText = $"{line.OriginalText}{separator}{translationArr[i]}";
line.TranslatedText = translationArr[i];
}
i++;
}
}
public void SetDisplayedTextInOriginalText()
{
foreach (var line in LyricsLines)
{
line.DisplayedText = line.OriginalText;
}
}
public LyricsData CreateLyricsDataFrom(string translation)
{
var result = new LyricsData(LyricsLines.Select(line => new LyricsLine
@@ -120,8 +150,9 @@ namespace BetterLyrics.WinUI3.Models
{
StartMs = 0,
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
PhoneticText = "",
OriginalText = "● ● ●",
DisplayedText = "● ● ●",
TranslatedText = "",
LyricsChars = [],
},
]);

View File

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

View File

@@ -47,26 +47,6 @@ namespace BetterLyrics.WinUI3.Models
UpdateDemoWindowAndMonitorBounds();
}
partial void OnWindowXChanged(double value)
{
WindowBounds = WindowBounds.WithX(value);
}
partial void OnWindowYChanged(double value)
{
WindowBounds = WindowBounds.WithY(value);
}
partial void OnWindowWidthChanged(double value)
{
WindowBounds = WindowBounds.WithWidth(value);
}
partial void OnWindowHeightChanged(double value)
{
WindowBounds = WindowBounds.WithHeight(value);
}
partial void OnLyricsStyleSettingsChanged(LyricsStyleSettings oldValue, LyricsStyleSettings newValue)
{
oldValue.PropertyChanged -= OldLyricsStyleSettings_PropertyChanged;
@@ -111,12 +91,6 @@ namespace BetterLyrics.WinUI3.Models
this.OnPropertyChanged(nameof(AlbumArtLayoutSettings));
}
partial void OnWindowBoundsChanged(Rect value)
{
UpdateMonitorNameAndBounds();
UpdateDemoWindowAndMonitorBounds();
}
partial void OnAutoShowOrHideWindowChanged(bool value)
{
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
@@ -137,6 +111,17 @@ namespace BetterLyrics.WinUI3.Models
);
}
public void UpdateMonitorBounds()
{
var mointor = MonitorHelper.GetMonitorInfoExFromDeviceName(MonitorDeviceName);
MonitorBounds = new Rect(
mointor.rcMonitor.Left,
mointor.rcMonitor.Top,
mointor.rcMonitor.Width,
mointor.rcMonitor.Height
);
}
public void UpdateDemoWindowAndMonitorBounds(double factor = 0.1)
{
DemoWindowBounds = new Rect(
@@ -181,6 +166,10 @@ namespace BetterLyrics.WinUI3.Models
EnvironmentSampleMode = this.EnvironmentSampleMode,
AutoShowOrHideWindow = this.AutoShowOrHideWindow,
TitleBarArea = this.TitleBarArea,
WindowX = this.WindowX,
WindowY = this.WindowY,
WindowWidth = this.WindowWidth,
WindowHeight = this.WindowHeight,
};
}
}
@@ -199,16 +188,16 @@ namespace BetterLyrics.WinUI3.Models
IsBorderless = true,
IsClickThrough = true,
IsAdaptToEnvironment = true,
IsShownInSwitchers = false,
EnvironmentSampleMode = WindowPixelSampleMode.WindowEdge,
LyricsStyleSettings = new()
{
LyricsFontSize = 20,
OriginalLyricsFontSize = 20,
LyricsAlignmentType = TextAlignmentType.Center,
},
LyricsBackgroundSettings = new LyricsBackgroundSettings
{
IsPureColorOverlayEnabled = false,
IsCoverOverlayEnabled = false,
IsFluidOverlayEnabled = false,
}
};
}
@@ -223,17 +212,19 @@ namespace BetterLyrics.WinUI3.Models
IsAlwaysOnTopPolling = true,
IsBorderless = true,
IsAdaptToEnvironment = true,
IsShownInSwitchers = false,
LyricsDisplayType = LyricsDisplayType.LyricsOnly,
EnvironmentSampleMode = WindowPixelSampleMode.BelowWindow,
TitleBarArea = TitleBarArea.None,
LyricsStyleSettings = new LyricsStyleSettings
{
LyricsAlignmentType = TextAlignmentType.Center,
LyricsFontSize = 18,
OriginalLyricsFontSize = 18,
},
LyricsBackgroundSettings = new LyricsBackgroundSettings
{
IsCoverOverlayEnabled = false,
IsFluidOverlayEnabled = false,
IsPureColorOverlayEnabled = true,
}
};
}
@@ -246,18 +237,19 @@ namespace BetterLyrics.WinUI3.Models
WindowBounds = monitorBounds,
IsAlwaysOnTop = true,
IsBorderless = true,
IsShownInSwitchers = false,
TitleBarArea = Enums.TitleBarArea.None,
LyricsLayoutOrientation = Enums.LyricsLayoutOrientation.Vertical,
LyricsStyleSettings = new LyricsStyleSettings
{
LyricsFontSize = 96,
OriginalLyricsFontSize = 72,
LyricsAlignmentType = Enums.TextAlignmentType.Center,
},
AlbumArtLayoutSettings = new AlbumArtLayoutSettings
{
AutoAlbumArtSize = false,
AlbumArtSize = 148,
SongInfoFontSize = 48,
AlbumArtSize = 128,
SongInfoFontSize = 36,
}
};
}

View File

@@ -13,6 +13,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial TextAlignmentType SongInfoAlignmentType { get; set; } = TextAlignmentType.Left;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageRadius { get; set; } = 12; // 12 % of the cover image size
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverImageShadowAmount { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsAutoSongInfoFontSize { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SongInfoFontSize { get; set; } = 18;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowTitle { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowArtists { get; set; } = true;
@@ -28,6 +29,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
SongInfoAlignmentType = this.SongInfoAlignmentType,
CoverImageRadius = this.CoverImageRadius,
CoverImageShadowAmount = this.CoverImageShadowAmount,
IsAutoSongInfoFontSize = this.IsAutoSongInfoFontSize,
SongInfoFontSize = this.SongInfoFontSize,
ShowTitle = this.ShowTitle,
ShowArtists = this.ShowArtists,

View File

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

View File

@@ -1,6 +1,7 @@
using BetterLyrics.WinUI3.Enums;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using BetterLyrics.WinUI3.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -13,20 +14,22 @@ namespace BetterLyrics.WinUI3.Models.Settings
{
[ObservableProperty][NotifyPropertyChangedRecipients] public partial ElementTheme LyricsBackgroundTheme { get; set; } = ElementTheme.Dark;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsPureColorOverlayEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsPureColorOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int PureColorOverlayOpacity { get; set; } = 100; // 100 % = 1.0
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsCoverOverlayEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsCoverOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlayBlurAmount { get; set; } = 100; // 100 % of the cover image size
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlayOpacity { get; set; } = 100; // 100 % = 1.0
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverOverlaySpeed { get; set; } = 50; // 50 % of the base rotate speed
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int CoverAcrylicEffectAmount { get; set; } = 0;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsFluidOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsFluidOverlayEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int FluidOverlayOpacity { get; set; } = 100;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial PaletteGeneratorType PaletteGeneratorType { get; set; } = PaletteGeneratorType.MedianCut;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSpectrumOverlayEnabled { get; set; } = false;
public LyricsBackgroundSettings() { }
public object Clone()
@@ -39,6 +42,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
PureColorOverlayOpacity = this.PureColorOverlayOpacity,
CoverOverlaySpeed = this.CoverOverlaySpeed,
CoverAcrylicEffectAmount = this.CoverAcrylicEffectAmount,
PaletteGeneratorType = this.PaletteGeneratorType
};
}
}

View File

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

View File

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

View File

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

View File

@@ -32,4 +32,4 @@ namespace BetterLyrics.WinUI3.Models
FilterValue = filterValue;
}
}
}
}

View File

@@ -14,7 +14,6 @@
<Grid>
<canvas:CanvasAnimatedControl
x:Name="LyricsCanvas"
CreateResources="LyricsCanvas_CreateResources"
Draw="LyricsCanvas_Draw"
Update="LyricsCanvas_Update" />
</Grid>

View File

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

View File

@@ -11,9 +11,11 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Streams;
namespace BetterLyrics.WinUI3.Services.AlbumArtSearchService
{
@@ -31,9 +33,9 @@ namespace BetterLyrics.WinUI3.Services.AlbumArtSearchService
_iTunesHttpClinet = new();
}
public async Task<byte[]?> SearchAsync(string mediaSessionId, string title, string artist, string album, byte[]? bytesFromSMTC, CancellationToken token)
public async Task<IBuffer?> SearchAsync(string mediaSessionId, string title, string artist, string album, IBuffer? bufferFromSMTC, CancellationToken token)
{
byte[]? result = null;
IBuffer? result = null;
try
{
@@ -47,15 +49,16 @@ namespace BetterLyrics.WinUI3.Services.AlbumArtSearchService
switch (provider.Provider)
{
case AlbumArtSearchProvider.Local:
result = SearchFile(artist, title);
result = SearchFile(artist, title)?.AsBuffer();
break;
case AlbumArtSearchProvider.SMTC:
result = bytesFromSMTC;
result = bufferFromSMTC;
break;
case AlbumArtSearchProvider.iTunes:
foreach (string countryCode in new List<string>() { "us", "cn", "jp", "kr" })
{
result = await SearchiTunesAsync(artist, album, title, countryCode);
var byteArray = await SearchiTunesAsync(artist, album, title, countryCode);
result = byteArray?.AsBuffer();
if (token.IsCancellationRequested) return result;
if (result != null) break;
}

View File

@@ -4,11 +4,12 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Streams;
namespace BetterLyrics.WinUI3.Services.AlbumArtSearchService
{
public interface IAlbumArtSearchService
{
Task<byte[]?> SearchAsync(string mediaSessionId, string title, string artist, string album, byte[]? bytesFromSMTC, CancellationToken token);
Task<IBuffer?> SearchAsync(string mediaSessionId, string title, string artist, string album, IBuffer? bufferFromSMTC, CancellationToken token);
}
}

View File

@@ -3,7 +3,11 @@ using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.WinUI.Controls;
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
namespace BetterLyrics.WinUI3.Services.LiveStatesService
{
@@ -29,15 +33,55 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
}
}
private void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
private async void LyricsWindowStatus_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
LiveStates.IsLyricsWindowStatusRefreshing = true;
switch (e.PropertyName)
{
case nameof(LyricsWindowStatus.DockHeight):
case nameof(LyricsWindowStatus.IsWorkArea):
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
await Task.Delay(300);
WindowHelper.MoveAndResize<LyricsWindow>(GetWindowBoundsWhenWorkArea());
}
break;
case nameof(LyricsWindowStatus.DockHeight):
case nameof(LyricsWindowStatus.DockPlacement):
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
WindowHelper.UpdateWorkArea<LyricsWindow>();
await Task.Delay(300);
WindowHelper.MoveAndResize<LyricsWindow>(GetWindowBoundsWhenWorkArea());
}
break;
case nameof(LyricsWindowStatus.MonitorDeviceName):
WindowHelper.UpdateWorkAreaHeight<LyricsWindow>();
// 记录切换前的窗口状态是否沾满屏幕
bool isStretchedToMonitor = LiveStates.LyricsWindowStatus.WindowBounds == LiveStates.LyricsWindowStatus.MonitorBounds;
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
WindowHelper.UpdateWorkArea<LyricsWindow>();
await Task.Delay(300);
WindowHelper.MoveAndResize<LyricsWindow>(GetWindowBoundsWhenWorkArea());
}
else
{
if (isStretchedToMonitor)
{
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.MonitorBounds);
}
else
{
WindowHelper.MoveAndResize<LyricsWindow>(new Rect(
LiveStates.LyricsWindowStatus.MonitorBounds.X,
LiveStates.LyricsWindowStatus.MonitorBounds.Y,
Math.Min(LiveStates.LyricsWindowStatus.MonitorBounds.Width, LiveStates.LyricsWindowStatus.WindowBounds.Width),
Math.Min(LiveStates.LyricsWindowStatus.MonitorBounds.Height, LiveStates.LyricsWindowStatus.WindowBounds.Height)
));
}
}
break;
case nameof(LyricsWindowStatus.IsShownInSwitchers):
WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
@@ -51,8 +95,25 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
case nameof(LyricsWindowStatus.IsBorderless):
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
break;
case nameof(LyricsWindowStatus.WindowX):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithX(LiveStates.LyricsWindowStatus.WindowX));
break;
case nameof(LyricsWindowStatus.WindowY):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithY(LiveStates.LyricsWindowStatus.WindowY));
break;
case nameof(LyricsWindowStatus.WindowWidth):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithWidth(LiveStates.LyricsWindowStatus.WindowWidth));
break;
case nameof(LyricsWindowStatus.WindowHeight):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds.WithHeight(LiveStates.LyricsWindowStatus.WindowHeight));
break;
case nameof(LyricsWindowStatus.WindowBounds):
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
LiveStates.LyricsWindowStatus.UpdateMonitorNameAndBounds();
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
LiveStates.LyricsWindowStatus.WindowX = LiveStates.LyricsWindowStatus.WindowBounds.X;
LiveStates.LyricsWindowStatus.WindowY = LiveStates.LyricsWindowStatus.WindowBounds.Y;
LiveStates.LyricsWindowStatus.WindowWidth = LiveStates.LyricsWindowStatus.WindowBounds.Width;
LiveStates.LyricsWindowStatus.WindowHeight = LiveStates.LyricsWindowStatus.WindowBounds.Height;
break;
case nameof(LyricsWindowStatus.TitleBarArea):
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
@@ -60,6 +121,8 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
default:
break;
}
LiveStates.IsLyricsWindowStatusRefreshing = true;
}
private void LiveStates_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
@@ -83,19 +146,52 @@ namespace BetterLyrics.WinUI3.Services.LiveStatesService
LiveStates.LyricsWindowStatus = defaultLyricsWindowStatus;
}
public void RefreshLyricsWindowStatus()
public async void RefreshLyricsWindowStatus()
{
// Order matters!!!
LiveStates.IsLyricsWindowStatusRefreshing = true;
LiveStates.LyricsWindowStatus.UpdateMonitorBounds();
WindowHelper.SetIsWorkArea<LyricsWindow>(LiveStates.LyricsWindowStatus.IsWorkArea);
await Task.Delay(300);
WindowHelper.SetIsShowInSwitchers<LyricsWindow>(LiveStates.LyricsWindowStatus.IsShownInSwitchers);
WindowHelper.SetIsAlwaysOnTop<LyricsWindow>(LiveStates.LyricsWindowStatus.IsAlwaysOnTop);
WindowHelper.SetIsClickThrough<LyricsWindow>(LiveStates.LyricsWindowStatus.IsClickThrough);
WindowHelper.SetIsBorderless<LyricsWindow>(LiveStates.LyricsWindowStatus.IsBorderless);
WindowHelper.SetLyricsWindowVisibilityByPlayingStatus();
WindowHelper.SetTitleBarArea<LyricsWindow>(LiveStates.LyricsWindowStatus.TitleBarArea);
if (LiveStates.LyricsWindowStatus.IsWorkArea)
{
LiveStates.LyricsWindowStatus.WindowBounds = GetWindowBoundsWhenWorkArea();
}
WindowHelper.MoveAndResize<LyricsWindow>(LiveStates.LyricsWindowStatus.WindowBounds);
LiveStates.LyricsWindowStatus.UpdateMonitorNameAndBounds();
LiveStates.LyricsWindowStatus.UpdateDemoWindowAndMonitorBounds();
LiveStates.IsLyricsWindowStatusRefreshing = false;
}
private Rect GetWindowBoundsWhenWorkArea()
{
return new Rect(
LiveStates.LyricsWindowStatus.MonitorBounds.X,
LiveStates.LyricsWindowStatus.DockPlacement switch
{
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.MonitorBounds.Bottom - LiveStates.LyricsWindowStatus.DockHeight - 1,
_ => LiveStates.LyricsWindowStatus.MonitorBounds.Top,
},
LiveStates.LyricsWindowStatus.MonitorBounds.Width,
LiveStates.LyricsWindowStatus.DockPlacement switch
{
Enums.DockPlacement.Top => LiveStates.LyricsWindowStatus.DockHeight,
Enums.DockPlacement.Bottom => LiveStates.LyricsWindowStatus.DockHeight + 1,
_ => LiveStates.LyricsWindowStatus.DockHeight,
}
);
}
}
}

View File

@@ -7,6 +7,7 @@ using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.SettingsService;
using CommunityToolkit.Mvvm.DependencyInjection;
using Lyricify.Lyrics.Helpers;
using Lyricify.Lyrics.Providers.Web.Kugou;
using Lyricify.Lyrics.Searchers;
using Microsoft.Extensions.Logging;
@@ -436,11 +437,11 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
return lyricsSearchResult;
}
private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, string? songId, Searchers searchers)
private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, string? songId, Searchers searcher)
{
var lyricsSearchResult = new LyricsSearchResult();
switch (searchers)
switch (searcher)
{
case Searchers.QQMusic:
lyricsSearchResult.Provider = LyricsSearchProvider.QQ;
@@ -458,21 +459,20 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
}
ISearchResult? result;
if (searchers == Searchers.Netease && songId != null)
if (searcher == Searchers.Netease && songId != null)
{
result = new NeteaseSearchResult(title, [artist], album, null, durationMs, songId);
}
else
{
result = await SearchersHelper.GetSearcher(searchers).SearchForResult(
new Lyricify.Lyrics.Models.TrackMultiArtistMetadata()
{
DurationMs = durationMs,
Album = album,
Artists = [artist],
Title = title,
}
);
result = await SearchHelper.Search(new Lyricify.Lyrics.Models.TrackMultiArtistMetadata()
{
DurationMs = durationMs,
Album = album,
AlbumArtists = [artist],
Artists = [artist],
Title = title,
}, searcher);
}
if (result is QQMusicSearchResult qqResult)
@@ -519,7 +519,17 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
{
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
string? original = null;
if (response?.Candidates.FirstOrDefault() is SearchLyricsResponse.Candidate candidate)
var candidateWithTranslation = response?.Candidates.Where(x => x.TransId != null).FirstOrDefault();
SearchLyricsResponse.Candidate? candidate;
if (candidateWithTranslation != null)
{
candidate = candidateWithTranslation;
}
else
{
candidate = response?.Candidates.FirstOrDefault();
}
if (candidate != null)
{
original = await Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyricsAsync(candidate.Id, candidate.AccessKey);
if (candidate.TransId != null)

View File

@@ -33,39 +33,38 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
return;
}
byte[]? bytes = await Task.Run(async () => await _albumArtSearchService.SearchAsync(
IBuffer? buffer = await Task.Run(async () => await _albumArtSearchService.SearchAsync(
SongInfo?.PlayerId ?? "",
_cachedSongInfo.Title,
_cachedSongInfo.Artist,
_cachedSongInfo?.Album ?? string.Empty,
_SMTCAlbumArtBytes,
_SMTCAlbumArtBuffer,
token
), token);
if (token.IsCancellationRequested) return;
BitmapDecoder? decoder = null;
if (bytes == null)
if (buffer == null)
{
bytes = await ImageHelper.CreateTextPlaceholderBytesAsync(500, 500);
using var placeHolderStream = await ImageHelper.CreateTextPlaceholderBytesAsync(500, 500);
var tempBuffer = new Windows.Storage.Streams.Buffer((uint)placeHolderStream.Size);
await placeHolderStream.ReadAsync(tempBuffer, (uint)placeHolderStream.Size, InputStreamOptions.None);
buffer = tempBuffer;
token.ThrowIfCancellationRequested();
}
bytes = ImageHelper.MakeSquareWithThemeColor(bytes);
using var stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(bytes.AsBuffer());
token.ThrowIfCancellationRequested();
var decoder = await BitmapDecoder.CreateAsync(stream);
decoder = await ImageHelper.MakeSquareWithThemeColor(buffer, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType);
token.ThrowIfCancellationRequested();
var albumArtSwBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Premultiplied);
albumArtSwBitmap = SoftwareBitmap.Copy(albumArtSwBitmap);
albumArtSwBitmap.DpiX = 96;
albumArtSwBitmap.DpiY = 96;
token.ThrowIfCancellationRequested();
var albumArtLightAccentColors = ImageHelper.GetAccentColorsFromByte(bytes, 4, false);
var albumArtDarkAccentColors = ImageHelper.GetAccentColorsFromByte(bytes, 4, true);
AlbumArtChanged?.Invoke(this, new AlbumArtChangedEventArgs(null, albumArtSwBitmap, albumArtLightAccentColors, albumArtDarkAccentColors));
var albumArtLightAccentColors = await ImageHelper.GetAccentColorsAsync(decoder, 4, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType, false);
var lightColorBytes = albumArtLightAccentColors.Palette.Select(t => Windows.UI.Color.FromArgb(255, (byte)t.X, (byte)t.Y, (byte)t.Z)).ToList();
var albumArtDarkAccentColors = await ImageHelper.GetAccentColorsAsync(decoder, 4, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.PaletteGeneratorType, true);
var darkColorBytes = albumArtDarkAccentColors.Palette.Select(t => Windows.UI.Color.FromArgb(255, (byte)t.X, (byte)t.Y, (byte)t.Z)).ToList();
AlbumArtChanged?.Invoke(this, new AlbumArtChangedEventArgs(null, albumArtSwBitmap, lightColorBytes, darkColorBytes));
}
}
}

View File

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

View File

@@ -23,6 +23,7 @@ using Microsoft.UI.Dispatching;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text.Json;
using System.Threading.Tasks;
using Windows.Media.Control;
@@ -35,6 +36,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
IRecipient<PropertyChangedMessage<bool>>,
IRecipient<PropertyChangedMessage<string>>,
IRecipient<PropertyChangedMessage<LyricsWindowStatus>>,
IRecipient<PropertyChangedMessage<PaletteGeneratorType>>,
IRecipient<PropertyChangedMessage<ChineseRomanization>>,
IRecipient<PropertyChangedMessage<List<string>>>
{
@@ -58,7 +60,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
private readonly MediaManager _mediaManager = new();
private SongInfo? _cachedSongInfo;
private byte[]? _SMTCAlbumArtBytes = null;
private IBuffer? _SMTCAlbumArtBuffer = null;
public event EventHandler<IsPlayingChangedEventArgs>? IsPlayingChanged;
public event EventHandler<TimelineChangedEventArgs>? TimelineChanged;
@@ -303,7 +305,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
StopSSE();
}
_SMTCAlbumArtBytes = null;
_SMTCAlbumArtBuffer = null;
}
else
{
@@ -322,13 +324,9 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
fixedArtist = mediaProperties.Artist.Split(" — ").FirstOrDefault() ?? mediaProperties.Artist;
fixedAlbum = mediaProperties.Artist.Split(" — ").LastOrDefault() ?? mediaProperties.AlbumTitle;
}
else if (sessionId == Constants.PlayerID.NetEaseCloudMusic)
else if (PlayerIdMatcher.IsNeteaseFamily(sessionId))
{
songId = mediaProperties.Genres.FirstOrDefault()?.Replace("NCM-", "");
if (songId != null && songId.Length != 10)
{
songId = null;
}
}
_cachedSongInfo = new SongInfo
@@ -356,15 +354,15 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
if (sessionId == Constants.PlayerID.LXMusic && _lxMusicAlbumArtBytes != null)
{
_SMTCAlbumArtBytes = _lxMusicAlbumArtBytes;
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
}
else if (mediaProperties.Thumbnail is IRandomAccessStreamReference streamReference)
{
_SMTCAlbumArtBytes = await ImageHelper.ToByteArrayAsync(streamReference);
_SMTCAlbumArtBuffer = await ImageHelper.ToBufferAsync(streamReference);
}
else
{
_SMTCAlbumArtBytes = null;
_SMTCAlbumArtBuffer = null;
}
}
@@ -536,7 +534,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{
_logger.LogInformation("LX Music Album Art URL: {url}", picUrl);
_lxMusicAlbumArtBytes = await ImageHelper.GetImageBytesFromUrlAsync(picUrl);
_SMTCAlbumArtBytes = _lxMusicAlbumArtBytes;
_SMTCAlbumArtBuffer = _lxMusicAlbumArtBytes.AsBuffer();
UpdateAlbumArt();
}
}
@@ -609,10 +607,6 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
{
UpdateTranslations();
}
else if (message.PropertyName == nameof(TranslationSettings.ShowTranslationOnly))
{
UpdateTranslations();
}
else if (message.PropertyName == nameof(TranslationSettings.IsChineseRomanizationEnabled))
{
UpdateTranslations();
@@ -688,5 +682,16 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
}
}
}
public void Receive(PropertyChangedMessage<PaletteGeneratorType> message)
{
if (message.Sender is LyricsBackgroundSettings)
{
if (message.PropertyName == nameof(LyricsBackgroundSettings.PaletteGeneratorType))
{
UpdateAlbumArt();
}
}
}
}
}

View File

@@ -105,30 +105,8 @@ namespace BetterLyrics.WinUI3.Services.SettingsService
{
switch (e.PropertyName)
{
case nameof(GeneralSettings.Language):
switch (AppSettings.GeneralSettings.Language)
{
case Enums.Language.FollowSystem:
ApplicationLanguages.PrimaryLanguageOverride = "";
break;
case Enums.Language.English:
ApplicationLanguages.PrimaryLanguageOverride = "en-US";
break;
case Enums.Language.SimplifiedChinese:
ApplicationLanguages.PrimaryLanguageOverride = "zh-CN";
break;
case Enums.Language.TraditionalChinese:
ApplicationLanguages.PrimaryLanguageOverride = "zh-TW";
break;
case Enums.Language.Japanese:
ApplicationLanguages.PrimaryLanguageOverride = "ja-JP";
break;
case Enums.Language.Korean:
ApplicationLanguages.PrimaryLanguageOverride = "ko-KR";
break;
default:
break;
}
case nameof(GeneralSettings.LanguageCode):
ApplicationLanguages.PrimaryLanguageOverride = AppSettings.GeneralSettings.LanguageCode;
break;
default:
break;

View File

@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>Operation completed</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>Local music files</value>
</data>
@@ -177,6 +180,9 @@
<data name="ImportSettingsFailed" xml:space="preserve">
<value>Settings file import failed, application settings remain unchanged</value>
</data>
<data name="Jyutping" xml:space="preserve">
<value>Cantonese pinyin</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve">
<value>Authorization failed, please try again</value>
</data>
@@ -303,6 +309,12 @@
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
<value>Set as default</value>
</data>
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
<value>Lyrics window switcher</value>
</data>
<data name="LyricsWindowSwitchWindowHelp.Text" xml:space="preserve">
<value>Go to Settings to add more modes</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>Album art area only</value>
</data>
@@ -331,9 +343,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>Welcome to BetterLyrics</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>Immersive mode</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
<value>Add to playlist</value>
</data>
@@ -445,15 +454,33 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="PictureInPictureMode" xml:space="preserve">
<value>Picture-in-picture mode</value>
</data>
<data name="Pinyin" xml:space="preserve">
<value>Mandarin pinyin</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>Romaji</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve">
<value>Contributors</value>
</data>
<data name="SetingsPageDonation.Text" xml:space="preserve">
<value>Donation</value>
</data>
<data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>Feedback</value>
</data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>Instructions</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve">
<value>If you like this project, please consider supporting it by donating. Your support will help keep the project alive and encourage further development.</value>
</data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D lyrics</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>Depth</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>About</value>
</data>
@@ -520,8 +547,8 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageApply.Content" xml:space="preserve">
<value>Apply</value>
</data>
<data name="SettingsPageAutoSize.Header" xml:space="preserve">
<value>Automatic resizing</value>
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>Automatic adjustment</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>Automatic startup</value>
@@ -556,9 +583,18 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>Chinese pronunciation</value>
</data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>Chinese lyrics</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>Convert Chinese to Traditional Chinese</value>
</data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>CJK Unified Ideograph</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>Clear cache files</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>Click-through</value>
</data>
@@ -625,9 +661,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageDragArea.Header" xml:space="preserve">
<value>Draggable area</value>
</data>
<data name="SettingsPageDynamicLyricsFontSize.Header" xml:space="preserve">
<value>Automatic adjustment</value>
</data>
<data name="SettingsPageEasingFuncType.Header" xml:space="preserve">
<value>Easing animation type</value>
</data>
@@ -709,6 +742,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>Follow system</value>
</data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>Font color</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>Keep the lyrics window on top by polling</value>
</data>
@@ -805,9 +841,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX Music Server</value>
</data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>Lyrics style and effect</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>Alignment</value>
</data>
@@ -815,7 +848,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<value>Lyrics background</value>
</data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>Font color (Non-current playback area)</value>
<value>Non-current playback area</value>
</data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>Font opacity (Non-current playback area)</value>
@@ -851,7 +884,7 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<value>Extra Light</value>
</data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>Font color (Current playback area)</value>
<value>Current playback area</value>
</data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>Adaptive to lyrics background (Colored)</value>
@@ -889,6 +922,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>Glow effect</value>
</data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>Highlight</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>Original highlight range</value>
</data>
@@ -937,9 +973,6 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>Shadows</value>
</data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>Lyrics stroke color</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>Lyrics style</value>
</data>
@@ -976,6 +1009,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageMediaLib.Content" xml:space="preserve">
<value>Media library</value>
</data>
<data name="SettingsPageMedianCut.Content" xml:space="preserve">
<value>Conservative</value>
</data>
<data name="SettingsPageMediaSourceProvidersConfig.Header" xml:space="preserve">
<value>Monitor this playback source</value>
</data>
@@ -1006,12 +1042,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>None</value>
</data>
<data name="SettingsPageOctTree.Content" xml:space="preserve">
<value>Aggressive</value>
</data>
<data name="SettingsPageOpacity.Header" xml:space="preserve">
<value>Opacity</value>
</data>
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>Open in file explorer</value>
</data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>Original text</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>Color picker style</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>This folder is already included in the existing folder and does not need to be added again</value>
</data>
@@ -1024,6 +1069,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>The path cannot be found on your computer</value>
</data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>Lyric annotation</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>Phonetic symbols</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>Pinyin of Mandarin</value>
</data>
@@ -1099,6 +1150,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>The duration of the first line</value>
</data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>Server address</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>Test server</value>
</data>
@@ -1162,7 +1216,10 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>Standard mode</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>Stroke color</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>Default</value>
</data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1195,6 +1252,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>Switch in and cut out shortcut keys</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>Translated text</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>Lyrics translation</value>
</data>
@@ -1210,6 +1270,9 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>Version</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>Latin alphabet</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>Width</value>
</data>
@@ -1244,11 +1307,14 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<value>Reset window position</value>
</data>
<data name="SystemTrayRestart.Text" xml:space="preserve">
<value>Resart</value>
<value>Restart</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve">
<value>Settings</value>
</data>
<data name="SystemTraySwitch.Text" xml:space="preserve">
<value>Lyrics window switcher</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve">
<value>Translate server is not set, please configure it in settings first</value>
</data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作が完了しました</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>ローカル音楽ファイル</value>
</data>
@@ -177,6 +180,9 @@
<data name="ImportSettingsFailed" xml:space="preserve">
<value>設定ファイルのインポートに失敗し、アプリケーション設定は変更されません</value>
</data>
<data name="Jyutping" xml:space="preserve">
<value>広東語のピンイン</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve">
<value>承認が失敗しました、もう一度やり直してください</value>
</data>
@@ -303,6 +309,12 @@
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
<value>既定のブラウザーに設定する</value>
</data>
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
<value>歌詞ウィンドウスイッチャー</value>
</data>
<data name="LyricsWindowSwitchWindowHelp.Text" xml:space="preserve">
<value>設定に移動して、さらにモードを追加してください</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>アルバムアートエリアのみ</value>
</data>
@@ -331,9 +343,6 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>BetterLyrics へようこそ</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>没入モード</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
<value>プレイリストに追加します</value>
</data>
@@ -445,15 +454,33 @@
<data name="PictureInPictureMode" xml:space="preserve">
<value>ピクチャーインピクチャーモード</value>
</data>
<data name="Pinyin" xml:space="preserve">
<value>マンダリンのピンイン</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>ローマン</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve">
<value>投稿者</value>
</data>
<data name="SetingsPageDonation.Text" xml:space="preserve">
<value>寄付</value>
</data>
<data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>フィードバック</value>
</data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>手順</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve">
<value>このプロジェクトが気に入っている場合は、寄付してサポートすることを検討してください。あなたのサポートは、プロジェクトを生かし続け、さらなる開発を促進するのに役立ちます。</value>
</data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3 D 歌詞</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>について</value>
</data>
@@ -520,8 +547,8 @@
<data name="SettingsPageApply.Content" xml:space="preserve">
<value>適用する</value>
</data>
<data name="SettingsPageAutoSize.Header" xml:space="preserve">
<value>自動サイズ変更</value>
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自動調整</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自動起動</value>
@@ -556,9 +583,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中国の発音</value>
</data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中国語の歌詞</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中国人を伝統的な中国人に変換します</value>
</data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>CJK統一漢字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>キャッシュファイルをクリア</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>クリックスルー</value>
</data>
@@ -625,9 +661,6 @@
<data name="SettingsPageDragArea.Header" xml:space="preserve">
<value>ドラッグ可能</value>
</data>
<data name="SettingsPageDynamicLyricsFontSize.Header" xml:space="preserve">
<value>自動調整</value>
</data>
<data name="SettingsPageEasingFuncType.Header" xml:space="preserve">
<value>アニメーションタイプを緩和します</value>
</data>
@@ -709,6 +742,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>システムをフォローします</value>
</data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>フォントの色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>ポーリングで歌詞ウィンドウを一番上に保ちましょう</value>
</data>
@@ -805,9 +841,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX Music Server</value>
</data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌詞のスタイルと効果</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>アライメント</value>
</data>
@@ -815,7 +848,7 @@
<value>歌詞の背景</value>
</data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>フォントカラー(非電流再生エリア</value>
<value>非電流再生エリア</value>
</data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>フォントの不透明度(非電流再生エリア)</value>
@@ -851,7 +884,7 @@
<value>余分な光</value>
</data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>フォントカラー(現在の再生エリア</value>
<value>現在の再生エリア</value>
</data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>歌詞の背景に適応する(色付き)</value>
@@ -889,6 +922,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>グロー効果</value>
</data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>ハイライト</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>オリジナルのハイライト範囲</value>
</data>
@@ -937,9 +973,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>影だ</value>
</data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌詞ストロークカラー</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌詞スタイル</value>
</data>
@@ -976,6 +1009,9 @@
<data name="SettingsPageMediaLib.Content" xml:space="preserve">
<value>メディアライブラリ</value>
</data>
<data name="SettingsPageMedianCut.Content" xml:space="preserve">
<value>保守的</value>
</data>
<data name="SettingsPageMediaSourceProvidersConfig.Header" xml:space="preserve">
<value>この再生ソースを監視します</value>
</data>
@@ -1006,12 +1042,21 @@
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>なし</value>
</data>
<data name="SettingsPageOctTree.Content" xml:space="preserve">
<value>急進的だ</value>
</data>
<data name="SettingsPageOpacity.Header" xml:space="preserve">
<value>不透明度</value>
</data>
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>ファイルエクスプローラーで開きます</value>
</data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>カラーピックスタイル</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>このフォルダーは既存のフォルダーに既に含まれており、再度追加する必要はありません</value>
</data>
@@ -1024,6 +1069,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>パスはコンピューターでは見つかりません</value>
</data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>リリックアノテーション</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>発音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>マンダリンのピンイン</value>
</data>
@@ -1099,6 +1150,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>最初の行の期間</value>
</data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>サーバーアドレス</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>テストサーバー</value>
</data>
@@ -1162,7 +1216,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>標準モード</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>ストロークカラー</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>デフォルト</value>
</data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1195,6 +1252,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>ショートカットキーを切り込んで切り取ります</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌詞翻訳</value>
</data>
@@ -1210,6 +1270,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>バージョン</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>英字</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>幅</value>
</data>
@@ -1244,11 +1307,14 @@
<value>ウィンドウの位置をリセットします</value>
</data>
<data name="SystemTrayRestart.Text" xml:space="preserve">
<value>再アート</value>
<value>再起動</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve">
<value>設定を開く</value>
</data>
<data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌詞ウィンドウスイッチャー</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve">
<value>翻訳サーバーは設定されていません。最初に設定で構成してください</value>
</data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>작전 완료</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>로컬 음악 파일</value>
</data>
@@ -177,6 +180,9 @@
<data name="ImportSettingsFailed" xml:space="preserve">
<value>설정 파일 가져 오기 실패, 응용 프로그램 설정은 변경되지 않았습니다</value>
</data>
<data name="Jyutping" xml:space="preserve">
<value>광둥어 병음</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve">
<value>승인이 실패했습니다. 다시 시도하십시오</value>
</data>
@@ -303,6 +309,12 @@
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
<value>기본 값으로 설정</value>
</data>
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
<value>가사 창 전환기</value>
</data>
<data name="LyricsWindowSwitchWindowHelp.Text" xml:space="preserve">
<value>설정으로 이동하여 모드를 더 추가하세요</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>앨범 아트 영역만</value>
</data>
@@ -331,9 +343,6 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>Betterlyrics에 오신 것을 환영합니다</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>몰입 형 모드</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
<value>재생 목록에 추가하십시오</value>
</data>
@@ -445,15 +454,33 @@
<data name="PictureInPictureMode" xml:space="preserve">
<value>사진 인당 모드</value>
</data>
<data name="Pinyin" xml:space="preserve">
<value>만다린의 피니 인</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>로만</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve">
<value>기여자</value>
</data>
<data name="SetingsPageDonation.Text" xml:space="preserve">
<value>기부</value>
</data>
<data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>피드백</value>
</data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>지침</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve">
<value>이 프로젝트가 마음에 들면 기부하여 지원을 고려하십시오. 귀하의 지원은 프로젝트를 계속 유지하고 추가 개발을 장려하는 데 도움이 될 것입니다.</value>
</data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 가사</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>심도</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>에 대한</value>
</data>
@@ -488,7 +515,7 @@
<value>앨범 표지 소스를 구성합니다</value>
</data>
<data name="SettingsPageAlbumArtSize.Header" xml:space="preserve">
<value>앨범아트</value>
<value>앨범 아트 크기</value>
</data>
<data name="SettingsPageAlbumLib.Content" xml:space="preserve">
<value>앨범 아트 소스</value>
@@ -520,8 +547,8 @@
<data name="SettingsPageApply.Content" xml:space="preserve">
<value>적용하다</value>
</data>
<data name="SettingsPageAutoSize.Header" xml:space="preserve">
<value>자동 크기 조정</value>
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>자동 조정</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>자동 시작</value>
@@ -556,9 +583,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>화음</value>
</data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>중국어 가사</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>중국어를 전통적인 중국어로 전환합니다</value>
</data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>한중일 통합 이데오그래프</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>캐시 파일을 지웁니다</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>클릭률</value>
</data>
@@ -625,9 +661,6 @@
<data name="SettingsPageDragArea.Header" xml:space="preserve">
<value>드래그 가능</value>
</data>
<data name="SettingsPageDynamicLyricsFontSize.Header" xml:space="preserve">
<value>자동 조정</value>
</data>
<data name="SettingsPageEasingFuncType.Header" xml:space="preserve">
<value>애니메이션 유형 완화</value>
</data>
@@ -709,6 +742,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>시스템을 따르십시오</value>
</data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>폰트 색상</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>투표를 통해 가사 창을 맨 위에 두세요</value>
</data>
@@ -805,9 +841,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 음악 서버</value>
</data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>가사 스타일과 효과</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>조정</value>
</data>
@@ -815,7 +848,7 @@
<value>가사 배경</value>
</data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>글꼴 색상 (비 전류 재생 영역)</value>
<value>비 전류 재생 영역</value>
</data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>글꼴 불투명 (비 전류 재생 영역)</value>
@@ -851,7 +884,7 @@
<value>여분의 빛</value>
</data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>글꼴 색상 (현재 재생 영역)</value>
<value>현재 재생 영역</value>
</data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>가사 배경 (색상)에 적응</value>
@@ -889,6 +922,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>글로우 효과</value>
</data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>하이라이트</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>원래 하이라이트 범위</value>
</data>
@@ -937,9 +973,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>그림자</value>
</data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>가사 스트로크 컬러</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>가사 스타일</value>
</data>
@@ -976,6 +1009,9 @@
<data name="SettingsPageMediaLib.Content" xml:space="preserve">
<value>미디어 라이브러리</value>
</data>
<data name="SettingsPageMedianCut.Content" xml:space="preserve">
<value>안전하게</value>
</data>
<data name="SettingsPageMediaSourceProvidersConfig.Header" xml:space="preserve">
<value>이 재생 소스를 모니터링하십시오</value>
</data>
@@ -1006,12 +1042,21 @@
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>없음</value>
</data>
<data name="SettingsPageOctTree.Content" xml:space="preserve">
<value>공격적인</value>
</data>
<data name="SettingsPageOpacity.Header" xml:space="preserve">
<value>투명도</value>
</data>
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>파일 탐색기에서 열립니다</value>
</data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>원본</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>색상 선택 스타일</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>이 폴더는 이미 기존 폴더에 포함되어 있으며 다시 추가 할 필요가 없습니다.</value>
</data>
@@ -1024,6 +1069,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>경로는 컴퓨터에서 찾을 수 없습니다</value>
</data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>가사 주석</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>발성</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>만다린의 피니 인</value>
</data>
@@ -1099,6 +1150,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>첫 번째 줄의 기간</value>
</data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>서버 주소</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>테스트 서버</value>
</data>
@@ -1162,7 +1216,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>표준 모드</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>윤곽선 색상</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>기본</value>
</data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1195,6 +1252,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>바로 가기 키를 자르고 잘라냅니다</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>번역</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>가사 번역</value>
</data>
@@ -1210,6 +1270,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>버전</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>라틴 알파벳</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>너비</value>
</data>
@@ -1244,11 +1307,14 @@
<value>창 위치를 재설정합니다</value>
</data>
<data name="SystemTrayRestart.Text" xml:space="preserve">
<value>resart</value>
<value>다시 시작</value>
</data>
<data name="SystemTraySettings.Text" xml:space="preserve">
<value>열기 설정</value>
</data>
<data name="SystemTraySwitch.Text" xml:space="preserve">
<value>가사 창 전환기</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve">
<value>번역 서버가 설정되지 않았습니다. 먼저 설정으로 구성하십시오.</value>
</data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作完成</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>本地音乐文件</value>
</data>
@@ -177,6 +180,9 @@
<data name="ImportSettingsFailed" xml:space="preserve">
<value>设置文件导入失败,应用程序设置保持不变</value>
</data>
<data name="Jyutping" xml:space="preserve">
<value>粤语拼音</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve">
<value>授权失败,请重试</value>
</data>
@@ -303,6 +309,12 @@
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
<value>设为默认</value>
</data>
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
<value>歌词窗口切换器</value>
</data>
<data name="LyricsWindowSwitchWindowHelp.Text" xml:space="preserve">
<value>转到“设置”以添加更多模式</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>仅显示专辑区域</value>
</data>
@@ -331,9 +343,6 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>欢迎使用 BetterLyrics</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>沉浸模式</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
<value>添加到歌单</value>
</data>
@@ -445,15 +454,33 @@
<data name="PictureInPictureMode" xml:space="preserve">
<value>画中画模式</value>
</data>
<data name="Pinyin" xml:space="preserve">
<value>普通话拼音</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>罗马音</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve">
<value>贡献者</value>
</data>
<data name="SetingsPageDonation.Text" xml:space="preserve">
<value>捐贈</value>
</data>
<data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>反馈</value>
</data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>操作指南</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve">
<value>如果您喜欢这个项目,请考虑通过捐赠来支持它。您的支持将有助于保持项目的生命并鼓励进一步的发展。</value>
</data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 歌词</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>关于</value>
</data>
@@ -488,7 +515,7 @@
<value>配置专辑封面源</value>
</data>
<data name="SettingsPageAlbumArtSize.Header" xml:space="preserve">
<value>专辑封面</value>
<value>专辑封面尺寸</value>
</data>
<data name="SettingsPageAlbumLib.Content" xml:space="preserve">
<value>专辑封面源</value>
@@ -520,8 +547,8 @@
<data name="SettingsPageApply.Content" xml:space="preserve">
<value>应用</value>
</data>
<data name="SettingsPageAutoSize.Header" xml:space="preserve">
<value>自动调整尺寸</value>
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自动调整</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自动启动</value>
@@ -556,9 +583,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value>
</data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中文歌词</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中文转换为繁体</value>
</data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>中日韩统一表意文字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>清除缓存文件</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>点击穿透</value>
</data>
@@ -625,9 +661,6 @@
<data name="SettingsPageDragArea.Header" xml:space="preserve">
<value>可拖拽区域</value>
</data>
<data name="SettingsPageDynamicLyricsFontSize.Header" xml:space="preserve">
<value>自动调整</value>
</data>
<data name="SettingsPageEasingFuncType.Header" xml:space="preserve">
<value>缓动动画类型</value>
</data>
@@ -709,6 +742,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>跟随系统</value>
</data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>字体颜色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>通过轮询方式使歌词窗口保持置于顶层状态</value>
</data>
@@ -805,9 +841,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 音乐服务器</value>
</data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌词样式与动效</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>对齐方式</value>
</data>
@@ -815,7 +848,7 @@
<value>歌词背景</value>
</data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>字体颜色(非当前播放区域</value>
<value>非当前播放区域</value>
</data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>字体不透明度(非当前播放区域)</value>
@@ -851,7 +884,7 @@
<value>超细</value>
</data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>字体颜色(当前播放区域</value>
<value>当前播放区域</value>
</data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>适应歌词背景(彩色)</value>
@@ -889,6 +922,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>辉光效果</value>
</data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>高亮</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮显示范围</value>
</data>
@@ -937,9 +973,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>阴影</value>
</data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌词描边颜色</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌词样式</value>
</data>
@@ -976,6 +1009,9 @@
<data name="SettingsPageMediaLib.Content" xml:space="preserve">
<value>媒体库</value>
</data>
<data name="SettingsPageMedianCut.Content" xml:space="preserve">
<value>保守</value>
</data>
<data name="SettingsPageMediaSourceProvidersConfig.Header" xml:space="preserve">
<value>监听此播放源</value>
</data>
@@ -1006,12 +1042,21 @@
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>无</value>
</data>
<data name="SettingsPageOctTree.Content" xml:space="preserve">
<value>激进</value>
</data>
<data name="SettingsPageOpacity.Header" xml:space="preserve">
<value>不透明度</value>
</data>
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>在文件资源管理器中打开</value>
</data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>取色风格</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>该文件夹已包含在已有文件夹中,无需再次添加</value>
</data>
@@ -1024,6 +1069,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>无法在您的计算机中找到该路径</value>
</data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>歌词注音</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>注音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>普通话拼音</value>
</data>
@@ -1099,6 +1150,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>首行持续时间</value>
</data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>服务器地址</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>测试服务器</value>
</data>
@@ -1162,7 +1216,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>标准模式</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>描边颜色</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>默认</value>
</data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1195,6 +1252,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入与切出快捷键</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>译文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌词翻译</value>
</data>
@@ -1210,6 +1270,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本号</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>宽度</value>
</data>
@@ -1249,6 +1312,9 @@
<data name="SystemTraySettings.Text" xml:space="preserve">
<value>打开设置</value>
</data>
<data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌词窗口切换器</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve">
<value>未设置Translate服务器请先在设置中进行配置</value>
</data>

View File

@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="ActionCompleted" xml:space="preserve">
<value>操作完成</value>
</data>
<data name="AlbumArtSearchLocalProvider" xml:space="preserve">
<value>本地音樂文件</value>
</data>
@@ -177,6 +180,9 @@
<data name="ImportSettingsFailed" xml:space="preserve">
<value>設置文件導入失敗,應用程序設置保持不變</value>
</data>
<data name="Jyutping" xml:space="preserve">
<value>粵語拼音</value>
</data>
<data name="LastFMAuthFailed" xml:space="preserve">
<value>授權失敗,請重試</value>
</data>
@@ -303,6 +309,12 @@
<data name="LyricsWindowSettingsControlSetDefault.Text" xml:space="preserve">
<value>設為預設</value>
</data>
<data name="LyricsWindowSwitchButtonToolTip.Content" xml:space="preserve">
<value>歌詞視窗切換器</value>
</data>
<data name="LyricsWindowSwitchWindowHelp.Text" xml:space="preserve">
<value>前往設定以新增更多模式</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>僅限相簿藝術區域</value>
</data>
@@ -331,9 +343,6 @@
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>歡迎使用 BetterLyrics</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>沉浸模式</value>
</data>
<data name="MusicGalleryPageAddToCustomList.Content" xml:space="preserve">
<value>添加到歌單</value>
</data>
@@ -445,15 +454,33 @@
<data name="PictureInPictureMode" xml:space="preserve">
<value>畫中畫模式</value>
</data>
<data name="Pinyin" xml:space="preserve">
<value>普通話拼音</value>
</data>
<data name="Romaji" xml:space="preserve">
<value>羅馬音</value>
</data>
<data name="SetingsPageContributors.Text" xml:space="preserve">
<value>貢獻者</value>
</data>
<data name="SetingsPageDonation.Text" xml:space="preserve">
<value>捐贈</value>
</data>
<data name="SetingsPageFeedback.Text" xml:space="preserve">
<value>回饋</value>
</data>
<data name="SetingsPageInstructions.Text" xml:space="preserve">
<value>說明</value>
</data>
<data name="SetingsPageThanks.Text" xml:space="preserve">
<value>如果您喜歡這個項目,請考慮通過捐贈來支持它。您的支持將有助於保持項目的生命並鼓勵進一步的發展。</value>
</data>
<data name="SettingsPage3DLyrics.Header" xml:space="preserve">
<value>3D 歌詞</value>
</data>
<data name="SettingsPage3DLyricsDepth.Header" xml:space="preserve">
<value>深度</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>關於</value>
</data>
@@ -488,7 +515,7 @@
<value>配置專輯封面源</value>
</data>
<data name="SettingsPageAlbumArtSize.Header" xml:space="preserve">
<value>專輯封面</value>
<value>相簿藝術尺寸</value>
</data>
<data name="SettingsPageAlbumLib.Content" xml:space="preserve">
<value>專輯封面來源</value>
@@ -520,8 +547,8 @@
<data name="SettingsPageApply.Content" xml:space="preserve">
<value>應用</value>
</data>
<data name="SettingsPageAutoSize.Header" xml:space="preserve">
<value>自動調整大小</value>
<data name="SettingsPageAutoAdjust.Header" xml:space="preserve">
<value>自動調整</value>
</data>
<data name="SettingsPageAutoStart.Header" xml:space="preserve">
<value>自動啟動</value>
@@ -556,9 +583,18 @@
<data name="SettingsPageChinese.Header" xml:space="preserve">
<value>中文注音</value>
</data>
<data name="SettingsPageChineseLyrics.Text" xml:space="preserve">
<value>中文歌詞</value>
</data>
<data name="SettingsPageChinesePreference.Header" xml:space="preserve">
<value>中文轉換為繁體</value>
</data>
<data name="SettingsPageCJK.Header" xml:space="preserve">
<value>中日韓統一表意文字</value>
</data>
<data name="SettingsPageClearCache.Content" xml:space="preserve">
<value>清除快取檔案</value>
</data>
<data name="SettingsPageClickThrough.Header" xml:space="preserve">
<value>點擊穿透</value>
</data>
@@ -625,9 +661,6 @@
<data name="SettingsPageDragArea.Header" xml:space="preserve">
<value>拖動</value>
</data>
<data name="SettingsPageDynamicLyricsFontSize.Header" xml:space="preserve">
<value>自動調整</value>
</data>
<data name="SettingsPageEasingFuncType.Header" xml:space="preserve">
<value>緩動動畫類型</value>
</data>
@@ -709,6 +742,9 @@
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>跟隨系統</value>
</data>
<data name="SettingsPageFontColor.Header" xml:space="preserve">
<value>字體顏色</value>
</data>
<data name="SettingsPageForceAlwaysOnTop.Description" xml:space="preserve">
<value>透過輪詢方式使歌詞視窗保持置於頂層狀態</value>
</data>
@@ -805,9 +841,6 @@
<data name="SettingsPageLXMusicServer.Text" xml:space="preserve">
<value>LX 音樂服務器</value>
</data>
<data name="SettingsPageLyrics.Text" xml:space="preserve">
<value>歌詞樣式與動效</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>對齊方式</value>
</data>
@@ -815,7 +848,7 @@
<value>歌詞背景</value>
</data>
<data name="SettingsPageLyricsBgFontColor.Header" xml:space="preserve">
<value>字體顏色(非當前播放區域</value>
<value>非當前播放區域</value>
</data>
<data name="SettingsPageLyricsBgFontOpacity.Header" xml:space="preserve">
<value>字體不透明度(非目前播放區域)</value>
@@ -851,7 +884,7 @@
<value>超細</value>
</data>
<data name="SettingsPageLyricsFgFontColor.Header" xml:space="preserve">
<value>字體顏色(當前播放區域</value>
<value>當前播放區域</value>
</data>
<data name="SettingsPageLyricsFgFontColorAdaptiveColored.Content" xml:space="preserve">
<value>適應歌詞背景(彩色)</value>
@@ -889,6 +922,9 @@
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>輝光效果</value>
</data>
<data name="SettingsPageLyricsHighlight.Header" xml:space="preserve">
<value>高亮</value>
</data>
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮顯示範圍</value>
</data>
@@ -937,9 +973,6 @@
<data name="SettingsPageLyricsShadow.Header" xml:space="preserve">
<value>陰影</value>
</data>
<data name="SettingsPageLyricsStrokeFontColor.Header" xml:space="preserve">
<value>歌詞描邊顏色</value>
</data>
<data name="SettingsPageLyricsStyle.Text" xml:space="preserve">
<value>歌詞樣式</value>
</data>
@@ -976,6 +1009,9 @@
<data name="SettingsPageMediaLib.Content" xml:space="preserve">
<value>媒體庫</value>
</data>
<data name="SettingsPageMedianCut.Content" xml:space="preserve">
<value>保守</value>
</data>
<data name="SettingsPageMediaSourceProvidersConfig.Header" xml:space="preserve">
<value>監聽此播放來源</value>
</data>
@@ -1006,12 +1042,21 @@
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>無</value>
</data>
<data name="SettingsPageOctTree.Content" xml:space="preserve">
<value>激進</value>
</data>
<data name="SettingsPageOpacity.Header" xml:space="preserve">
<value>專輯背景層不透明度</value>
</data>
<data name="SettingsPageOpenFolderButton.Content" xml:space="preserve">
<value>在檔案總管中開啟</value>
</data>
<data name="SettingsPageOriginalText.Header" xml:space="preserve">
<value>原文</value>
</data>
<data name="SettingsPagePaletteGeneratorType.Header" xml:space="preserve">
<value>取色風格</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>該資料夾已包含在已有資料夾中,無需再次添加</value>
</data>
@@ -1024,6 +1069,12 @@
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>無法在您的電腦中找到該路徑</value>
</data>
<data name="SettingsPagePhonetic.Text" xml:space="preserve">
<value>歌詞注音</value>
</data>
<data name="SettingsPagePhoneticText.Header" xml:space="preserve">
<value>注音</value>
</data>
<data name="SettingsPagePinyin.Content" xml:space="preserve">
<value>普通話拼音</value>
</data>
@@ -1099,6 +1150,9 @@
<data name="SettingsPageScrollTopDuration.Header" xml:space="preserve">
<value>首行持續時間</value>
</data>
<data name="SettingsPageServerAddress.Header" xml:space="preserve">
<value>服務器地址</value>
</data>
<data name="SettingsPageServerTestButton.Content" xml:space="preserve">
<value>測試服務器</value>
</data>
@@ -1162,7 +1216,10 @@
<data name="SettingsPageStandardMode.Text" xml:space="preserve">
<value>標準模式</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<data name="SettingsPageStrokeFontColor.Header" xml:space="preserve">
<value>描邊顏色</value>
</data>
<data name="SettingsPageSystemLanguage" xml:space="preserve">
<value>預設</value>
</data>
<data name="SettingsPageTargetLanguage.Header" xml:space="preserve">
@@ -1195,6 +1252,9 @@
<data name="SettingsPageToggleHotKey.Header" xml:space="preserve">
<value>切入與切出快捷鍵</value>
</data>
<data name="SettingsPageTranslatedText.Header" xml:space="preserve">
<value>譯文</value>
</data>
<data name="SettingsPageTranslation.Text" xml:space="preserve">
<value>歌詞翻譯</value>
</data>
@@ -1210,6 +1270,9 @@
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>版本號</value>
</data>
<data name="SettingsPageWesternChar.Header" xml:space="preserve">
<value>拉丁字母</value>
</data>
<data name="SettingsPageWidth.Header" xml:space="preserve">
<value>寬度</value>
</data>
@@ -1249,6 +1312,9 @@
<data name="SystemTraySettings.Text" xml:space="preserve">
<value>打開設置</value>
</data>
<data name="SystemTraySwitch.Text" xml:space="preserve">
<value>歌詞視窗切換器</value>
</data>
<data name="TranslateServerNotSet" xml:space="preserve">
<value>未設定翻譯伺服器,請先在設定中進行配置</value>
</data>

View File

@@ -1,11 +1,13 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services;
using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.SettingsService;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.ApplicationModel;

View File

@@ -38,8 +38,8 @@ namespace BetterLyrics.WinUI3.ViewModels
LiveStates = _liveStatesService.LiveStates;
//Volume = SystemVolumeHelper.GetMasterVolume();
//SystemVolumeHelper.VolumeChanged += SystemVolumeHelper_VolumeChanged;
Volume = SystemVolumeHelper.GetMasterVolume();
SystemVolumeHelper.VolumeChanged += SystemVolumeHelper_VolumeChanged;
_mediaSessionsService = mediaSessionsService;
_mediaSessionsService.SongInfoChanged += PlaybackService_SongInfoChanged;
@@ -54,10 +54,10 @@ namespace BetterLyrics.WinUI3.ViewModels
SongDurationSeconds = (int)e.End.TotalSeconds;
}
//private void SystemVolumeHelper_VolumeChanged(int volume)
//{
// Volume = volume;
//}
private void SystemVolumeHelper_VolumeChanged(int volume)
{
Volume = volume;
}
private void PlaybackService_IsPlayingChanged(object? sender, Events.IsPlayingChangedEventArgs e)
{
@@ -139,10 +139,10 @@ namespace BetterLyrics.WinUI3.ViewModels
TimelineSliderThumbLyricsLine = _mediaSessionsService.CurrentLyricsData?.GetLyricsLine(value);
}
//partial void OnVolumeChanged(int value)
//{
// SystemVolumeHelper.SetMasterVolume(value);
//}
partial void OnVolumeChanged(int value)
{
SystemVolumeHelper.SetMasterVolume(value);
}
public void Receive(PropertyChangedMessage<TimeSpan> message)
{

View File

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

View File

@@ -52,7 +52,18 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
DrawFluidBackground(control, combinedDs);
DrawSpectrum(control, combinedDs);
combinedDs.DrawImage(blurredLyrics);
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Is3DLyricsEnabled)
{
combinedDs.DrawImage(new Transform3DEffect
{
Source = blurredLyrics,
TransformMatrix = _lyrics3DMatrix
});
}
else
{
combinedDs.DrawImage(blurredLyrics);
}
ds.DrawImage(combined);
@@ -174,11 +185,11 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private void DrawFluidBackground(ICanvasAnimatedControl control, CanvasDrawingSession ds)
{
if (_effect != null && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsFluidOverlayEnabled)
if (_fluidEffect != null && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.IsFluidOverlayEnabled)
{
ds.DrawImage(new OpacityEffect
{
Source = _effect,
Source = _fluidEffect,
Opacity = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings.FluidOverlayOpacity / 100f
});
}
@@ -308,7 +319,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
var line = _currentLyricsData?.LyricsLines.ElementAtOrDefault(i);
if (line == null) continue;
var textLayout = line.CanvasTextLayout;
var textLayout = line.OriginalCanvasTextLayout;
if (textLayout == null) continue;
double layoutWidth = (double)textLayout.LayoutBounds.Width;
@@ -318,18 +329,20 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
double yOffset = line.YOffsetTransition.Value + _canvasHeight / 2 + _lyricsYTransition.Value;
// 组合变换:缩放 -> 旋转 -> 平移
//// 组合变换:缩放 -> 旋转 -> 平移
ds.Transform =
Matrix3x2.CreateScale((float)line.ScaleTransition.Value, line.CenterPosition)
* Matrix3x2.CreateRotation((float)line.AngleTransition.Value, currentPlayingLine.Position)
* Matrix3x2.CreateRotation((float)line.AngleTransition.Value,
currentPlayingLine.OriginalPosition.WithX(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.FanLyricsAngle < 0 ? (float)_maxLyricsWidth : 0))
* Matrix3x2.CreateTranslation((float)_lyricsXTransition.Value, (float)yOffset);
using var combined = new CanvasCommandList(control);
using var combinedDs = combined.CreateDrawingSession();
// 先铺一层带默认透明度的已经加了模糊效果的歌词作为最底层(背景歌词层次)
using var backgroundFontEffect = CanvasHelper.CreateFontEffect(line, control, _strokeFontColor,
using var backgroundFontEffect = CanvasHelper.CreateFontEffect(line, control, _strokeFontColor,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontStrokeWidth, _bgFontColor);
using var backgroundEffect = CanvasHelper.CreateBackgroundEffect(line, backgroundFontEffect, _lyricsOpacityTransition.Value);
combinedDs.DrawImage(backgroundEffect);
@@ -343,17 +356,24 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.IsLyricsLineFadeEnabled);
using var lineMask = CanvasHelper.CreateLineMask(control, line);
using var foregroundFontEffect = CanvasHelper.CreateFontEffect(line, control, _strokeFontColor,
using var foregroundFontEffect = CanvasHelper.CreateFontEffect(line, control, _strokeFontColor,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontStrokeWidth, _fgFontColor);
using var effectLayer = new CanvasCommandList(control);
using var effectLayerDs = effectLayer.CreateDrawingSession();
if (line.OriginalText != line.DisplayedText && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsTranslationHighlightAmount != 0)
if (line.PhoneticText != "" && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.PhoneticLyricsHighlightAmount != 0)
{
using var translationHighlightMask = CanvasHelper.CreateTranslationHighlightMask(control, line);
using var foregroundTranslationHighlightEffect = CanvasHelper.CreateForegroundHighlightEffect(foregroundFontEffect, translationHighlightMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsTranslationHighlightAmount / 100.0);
effectLayerDs.DrawImage(foregroundTranslationHighlightEffect);
using var phoneticHighlightMask = CanvasHelper.CreatePhoneticHighlightMask(control, line);
using var foregroundPhoneticHighlightEffect = CanvasHelper.CreateForegroundHighlightEffect(foregroundFontEffect, phoneticHighlightMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.PhoneticLyricsHighlightAmount / 100.0);
effectLayerDs.DrawImage(foregroundPhoneticHighlightEffect);
}
if (line.TranslatedText != "" && _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.TranslatedLyricsHighlightAmount != 0)
{
using var translatedHighlightMask = CanvasHelper.CreateTranslatedHighlightMask(control, line);
using var foregroundTranslatedHighlightEffect = CanvasHelper.CreateForegroundHighlightEffect(foregroundFontEffect, translatedHighlightMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.TranslatedLyricsHighlightAmount / 100.0);
effectLayerDs.DrawImage(foregroundTranslatedHighlightEffect);
}
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.IsLyricsShadowEnabled)
{
@@ -371,12 +391,12 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsGlowEffectAmount);
effectLayerDs.DrawImage(foregroundBlurEffect);
}
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsHighlightAmount != 0)
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.OriginalLyricsHighlightAmount != 0)
{
var highlightEffectMask = CanvasHelper.GetAlphaMask(control, charMask, lineStartToCharMask, lineMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsHighlightScope);
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.OriginalLyricsHighlightScope);
using var foregroundHighlightEffect = CanvasHelper.CreateForegroundHighlightEffect(foregroundFontEffect, highlightEffectMask,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsHighlightAmount / 100.0);
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.OriginalLyricsHighlightAmount / 100.0);
effectLayerDs.DrawImage(foregroundHighlightEffect);
}

View File

@@ -5,7 +5,10 @@ using Microsoft.Graphics.Canvas.UI.Xaml;
using Microsoft.UI;
using System;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
@@ -13,6 +16,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
private OpacityEffect? _albumArtBgEffect;
private CanvasCommandList? _albumArtEffect;
private PixelShaderEffect? _fluidEffect;
private OpacityEffect CreateBgImageEffect(CanvasBitmap canvasBitmap, double opacity)
{
@@ -246,5 +250,26 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
// 给一个偏移,是为了避免绘制时从原点开始,这样会造成阴影被裁切
ds.DrawImage(_albumArtEffect, control.Size.ToVector2() / 2 - new Vector2((float)_albumArtSize, (float)_albumArtSize) / 2);
}
private void DisposeFluidEffect()
{
_fluidEffect?.Dispose();
_fluidEffect = null;
}
private async void UpdateFluidEffect(ICanvasAnimatedControl control)
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/FluidEffect.bin"));
IBuffer buffer = await FileIO.ReadBufferAsync(file);
var bytes = buffer.ToArray();
_fluidEffect = new PixelShaderEffect(bytes);
_fluidEffect.Properties["Width"] = (float)control.ConvertDipsToPixels((float)control.Size.Width, CanvasDpiRounding.Round);
_fluidEffect.Properties["Height"] = (float)control.ConvertDipsToPixels((float)control.Size.Height, CanvasDpiRounding.Round);
_fluidEffect.Properties["color1"] = _albumArtAccentColor1Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color2"] = _albumArtAccentColor2Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color3"] = _albumArtAccentColor3Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color4"] = _albumArtAccentColor4Transition.Value.ToVector3RGB();
_fluidEffect.Properties["EnableLightWave"] = false;
}
}
}

View File

@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.UI.Xaml;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI;
@@ -55,6 +56,10 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
else if (message.PropertyName == nameof(LyricsEffectSettings.IsLyricsFloatAnimationEnabled))
{
}
else if (message.PropertyName == nameof(LyricsEffectSettings.Is3DLyricsEnabled))
{
_isLyrics3DMatrixChanged = true;
}
}
else if (message.Sender is MediaSourceProviderInfo)
{
@@ -84,6 +89,10 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
_isAlbumArtSizeChanged = true;
}
else if (message.PropertyName == nameof(AlbumArtLayoutSettings.IsAutoSongInfoFontSize))
{
UpdateSongInfoFontSize();
}
}
else if (message.Sender is LyricsBackgroundSettings)
{
@@ -202,10 +211,38 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
_isLayoutChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.FanLyricsAngle))
{
_isLayoutChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.Lyrics3DXAngle))
{
_isLyrics3DMatrixChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.Lyrics3DYAngle))
{
_isLyrics3DMatrixChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.Lyrics3DZAngle))
{
_isLyrics3DMatrixChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.Lyrics3DDepth))
{
_isLyrics3DMatrixChanged = true;
}
}
else if (message.Sender is LyricsStyleSettings)
{
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsFontSize))
if (message.PropertyName == nameof(LyricsStyleSettings.PhoneticLyricsFontSize))
{
_isLayoutChanged = true;
}
else if (message.PropertyName == nameof(LyricsStyleSettings.OriginalLyricsFontSize))
{
_isLayoutChanged = true;
}
else if (message.PropertyName == nameof(LyricsStyleSettings.TranslatedLyricsFontSize))
{
_isLayoutChanged = true;
}
@@ -239,7 +276,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
_isLayoutChanged = true;
}
else if (message.PropertyName == nameof(LyricsEffectSettings.LyricsHighlightScope))
else if (message.PropertyName == nameof(LyricsEffectSettings.OriginalLyricsHighlightScope))
{
_isLayoutChanged = true;
}
@@ -343,7 +380,14 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
if (message.Sender is LyricsStyleSettings)
{
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsFontFamily))
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsCJKFontFamily))
{
_isLayoutChanged = true;
}
}
if (message.Sender is LyricsStyleSettings)
{
if (message.PropertyName == nameof(LyricsStyleSettings.LyricsWesternFontFamily))
{
_isLayoutChanged = true;
}
@@ -358,7 +402,7 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
UpdateColorConfig();
UpdateSongInfoFontSize();
_isLayoutChanged = true;
}
}

View File

@@ -2,6 +2,7 @@
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services;
using CommunityToolkit.WinUI;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
@@ -56,6 +57,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private bool _isSpectrumOverlayEnabledChanged = true;
private bool _isLyrics3DMatrixChanged = true;
public void Update(ICanvasAnimatedControl control, CanvasAnimatedUpdateEventArgs args)
{
_elapsedTime = args.Timing.ElapsedTime;
@@ -73,27 +76,31 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
//_effect?.Properties["iTime"] = Convert.ToSingle(TotalTime.TotalSeconds);
if (_effect != null)
if (_fluidEffect == null)
{
var effectTime = Convert.ToSingle(_effect.Properties["iTime"]);
UpdateFluidEffect(control);
}
else
{
var effectTime = Convert.ToSingle(_fluidEffect.Properties["iTime"]);
effectTime += Convert.ToSingle(_elapsedTime.TotalSeconds);
_effect.Properties["iTime"] = effectTime;
_fluidEffect.Properties["iTime"] = effectTime;
if (_albumArtAccentColor1Transition.IsTransitioning)
{
_effect.Properties["color1"] = _albumArtAccentColor1Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color1"] = _albumArtAccentColor1Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor2Transition.IsTransitioning)
{
_effect.Properties["color2"] = _albumArtAccentColor2Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color2"] = _albumArtAccentColor2Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor3Transition.IsTransitioning)
{
_effect.Properties["color3"] = _albumArtAccentColor3Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color3"] = _albumArtAccentColor3Transition.Value.ToVector3RGB();
}
if (_albumArtAccentColor4Transition.IsTransitioning)
{
_effect.Properties["color4"] = _albumArtAccentColor4Transition.Value.ToVector3RGB();
_fluidEffect.Properties["color4"] = _albumArtAccentColor4Transition.Value.ToVector3RGB();
}
}
@@ -160,10 +167,13 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
if (_isCanvasWidthChanged || _isCanvasHeightChanged)
{
_isCoverAcrylicEffectAmountChanged = true;
UpdateSongInfoFontSize();
_effect?.Properties["Width"] = (float)control.ConvertDipsToPixels((float)_canvasWidth, CanvasDpiRounding.Round);
_effect?.Properties["Height"] = (float)control.ConvertDipsToPixels((float)_canvasHeight, CanvasDpiRounding.Round);
_isCoverAcrylicEffectAmountChanged = true;
_isLyrics3DMatrixChanged = true;
_fluidEffect?.Properties["Width"] = (float)control.ConvertDipsToPixels((float)_canvasWidth, CanvasDpiRounding.Round);
_fluidEffect?.Properties["Height"] = (float)control.ConvertDipsToPixels((float)_canvasHeight, CanvasDpiRounding.Round);
}
if (_isSongInfoFontSizeChanged || _isSongTitleVisibilityChanged || _isSongArtistsVisibilityChanged)
@@ -272,6 +282,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_isSongInfoFontSizeChanged = false;
_isSongTitleVisibilityChanged = false;
_isSongArtistsVisibilityChanged = false;
_isLyrics3DMatrixChanged = true;
}
// 先重置这两个的变化状态
@@ -385,6 +397,13 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_maxLyricsWidth = _canvasWidth - _lyricsXTransition.Value - _rightMargin;
_maxLyricsWidth = Math.Max(_maxLyricsWidth, 0);
_isLayoutChanged = true;
_isLyrics3DMatrixChanged = true;
}
if (_isLyrics3DMatrixChanged)
{
UpdateLyrics3DMatrix();
_isLyrics3DMatrixChanged = false;
}
if (_isLayoutChanged)
@@ -406,15 +425,19 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_titleXTransition.Update(_elapsedTime);
_titleYTransition.Update(_elapsedTime);
_lyricsXTransition.Update(_elapsedTime);
_lyricsYTransition.Update(_elapsedTime);
_albumArtXTransition.Update(_elapsedTime);
_albumArtYTransition.Update(_elapsedTime);
_lyricsOpacityTransition.Update(_elapsedTime);
_albumArtOpacityTransition.Update(_elapsedTime);
_immersiveBgOpacityTransition.Update(_elapsedTime);
_immersiveBgColorTransition.Update(_elapsedTime);
_albumArtAccentColor1Transition.Update(_elapsedTime);
_albumArtAccentColor2Transition.Update(_elapsedTime);
_albumArtAccentColor3Transition.Update(_elapsedTime);
@@ -426,6 +449,13 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
_canvasYScrollTransition.Update(_elapsedTime);
}
private string AutoSelectFontFamily(string text)
{
return LanguageHelper.IsCJK(text)
? _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsCJKFontFamily
: _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsWesternFontFamily;
}
private void ReLayout(ICanvasAnimatedControl control)
{
if (control == null)
@@ -433,14 +463,23 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.IsDynamicLyricsFontSize)
{
_lyricsTextFormat.FontSize = (float)Math.Clamp(Math.Min(_canvasHeight, _canvasWidth) / 10, 12, 72);
_originalLyricsFontSize = (int)Math.Clamp(Math.Min(_canvasHeight, _canvasWidth) / 15, 12, 96);
_translatedLyricsFontSize = _phoneticLyricsFontSize = (int)(_originalLyricsFontSize * 0.6);
}
else
{
_lyricsTextFormat.FontSize = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontSize;
_phoneticLyricsFontSize = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.PhoneticLyricsFontSize;
_originalLyricsFontSize = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.OriginalLyricsFontSize;
_translatedLyricsFontSize = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.TranslatedLyricsFontSize;
}
_originalLyricsFontWeight = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight;
if (SongInfo != null)
{
_titleTextFormat.FontFamily = AutoSelectFontFamily(SongInfo.Title);
_artistTextFormat.FontFamily = AutoSelectFontFamily(SongInfo.Artist);
}
_lyricsTextFormat.FontWeight = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontWeight.ToFontWeight();
_lyricsTextFormat.FontFamily = _artistTextFormat.FontFamily = _titleTextFormat.FontFamily = _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontFamily;
_canvasYScrollTransition.SetDuration(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsScrollDuration / 1000.0);
_canvasYScrollTransition.SetEasingType(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.LyricsScrollEasingType);
@@ -457,16 +496,70 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
continue;
}
line.Position = new Vector2(0, (float)y);
line.RecreateTextLayout(control, _lyricsTextFormat, _maxLyricsWidth, _canvasHeight, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsAlignmentType);
line.UpdateCenterPosition(_maxLyricsWidth, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsAlignmentType);
line.RecreateTextLayout(control,
_settingsService.AppSettings.TranslationSettings.IsChineseRomanizationEnabled || _settingsService.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled,
_settingsService.AppSettings.TranslationSettings.IsTranslationEnabled,
_phoneticLyricsFontSize, _originalLyricsFontSize, _translatedLyricsFontSize,
_originalLyricsFontWeight,
_liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsCJKFontFamily, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsWesternFontFamily,
_maxLyricsWidth, _canvasHeight, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsAlignmentType);
line.RecreateTextGeometry();
y +=
(double)line.CanvasTextLayout!.LayoutBounds.Height
/ line.CanvasTextLayout.LineCount
* (line.CanvasTextLayout.LineCount + _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsLineSpacingFactor);
// 设定注音文本布局坐标
line.PhoneticPosition = new Vector2(0, (float)y);
// Y += 注音文本布局高度
if (line.PhoneticCanvasTextLayout != null)
{
y += line.PhoneticCanvasTextLayout.LayoutBounds.Height;
}
// Y += 自定义 倍注音文本行高
if (line.PhoneticCanvasTextLayout != null)
{
y +=
(double)line.PhoneticCanvasTextLayout.LayoutBounds.Height
/ line.PhoneticCanvasTextLayout.LineCount
* 0.1;
}
// 设定原文文本布局坐标
line.OriginalPosition = new Vector2(0, (float)y);
// Y += 原文文本布局高度
if (line.OriginalCanvasTextLayout != null)
{
y += (double)line.OriginalCanvasTextLayout.LayoutBounds.Height;
}
if (line.TranslatedCanvasTextLayout != null)
{
// Y += 自定义 倍翻译文本行高
y +=
(double)line.TranslatedCanvasTextLayout.LayoutBounds.Height
/ line.TranslatedCanvasTextLayout.LineCount
* 0.1;
}
// 设定翻译文本布局坐标
line.TranslatedPosition = new Vector2(0, (float)y);
// Y += 翻译文本布局高度
if (line.TranslatedCanvasTextLayout != null)
{
y += line.TranslatedCanvasTextLayout.LayoutBounds.Height;
}
// Y += 用户自定义倍数原文文本布局高度
if (line.OriginalCanvasTextLayout != null)
{
y += (double)line.OriginalCanvasTextLayout.LayoutBounds.Height
/ line.OriginalCanvasTextLayout.LineCount
* _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsLineSpacingFactor;
}
line.UpdateCenterPosition(_maxLyricsWidth, _liveStatesService.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsAlignmentType);
}
}
@@ -482,11 +575,15 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
if (currentPlayingLine == null) return;
var playingTextLayout = currentPlayingLine?.CanvasTextLayout;
var playingTextLayout = currentPlayingLine?.OriginalCanvasTextLayout;
if (playingTextLayout == null) return;
double? targetYScrollOffset = -currentPlayingLine!.Position.Y + _currentLyricsData?.LyricsLines[0].Position.Y - playingTextLayout.LayoutBounds.Height / 2.0;
//double? targetYScrollOffset = -currentPlayingLine!.OriginalPosition.Y + _currentLyricsData?.LyricsLines[0].OriginalPosition.Y - playingTextLayout.LayoutBounds.Height / 2.0;
double? targetYScrollOffset =
-currentPlayingLine!.OriginalPosition.Y
+ _currentLyricsData?.LyricsLines[0].OriginalPosition.Y
- (currentPlayingLine.TranslatedPosition.Y + (currentPlayingLine.TranslatedCanvasTextLayout?.LayoutBounds.Height ?? 0) - currentPlayingLine.PhoneticPosition.Y) / 2.0;
if (!targetYScrollOffset.HasValue) return;
@@ -522,9 +619,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
int mid = (left + right) / 2;
var line = lines[mid];
var layout = line.CanvasTextLayout;
var layout = line.OriginalCanvasTextLayout;
if (layout == null) break;
double value = offset + line.Position.Y + (double)layout.LayoutBounds.Height;
double value = offset + line.OriginalPosition.Y + (double)layout.LayoutBounds.Height;
if (value >= 0)
{
result = mid;
@@ -545,9 +642,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
int mid = (left + right) / 2;
var line = lines[mid];
var layout = line.CanvasTextLayout;
var layout = line.OriginalCanvasTextLayout;
if (layout == null) break;
double value = offset + line.Position.Y + (double)layout.LayoutBounds.Height;
double value = offset + line.OriginalPosition.Y + (double)layout.LayoutBounds.Height;
if (value >= canvasHeight)
{
result = mid;
@@ -685,12 +782,12 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
{
int lineCountDelta = i - _playingLineIndex;
int absoluteLineCountDelta = Math.Abs(lineCountDelta);
double distanceFromPlayingLine = Math.Abs(line.Position.Y - currentPlayingLine.Position.Y);
double distanceFromPlayingLine = Math.Abs(line.OriginalPosition.Y - currentPlayingLine.OriginalPosition.Y);
double distanceFactor = Math.Clamp(distanceFromPlayingLine / (_canvasHeight / 2), 0, 1);
line.AngleTransition.StartTransition(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.IsFanLyricsEnabled
? Math.PI
* (30.0 / 180.0)
* (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.FanLyricsAngle / 180.0)
* distanceFactor
* (i > _playingLineIndex ? 1 : -1)
: 0
@@ -779,10 +876,50 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private void UpdateSongInfoFontSize()
{
_titleTextFormat.FontSize = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoFontSize;
_artistTextFormat.FontSize = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoFontSize - 2;
if (_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.IsAutoSongInfoFontSize)
{
_titleTextFormat.FontSize = (int)Math.Clamp(Math.Min(_canvasHeight, _canvasWidth) / 20, 8, 72);
}
else
{
_titleTextFormat.FontSize = _liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.SongInfoFontSize;
}
_artistTextFormat.FontSize = (int)(_titleTextFormat.FontSize * 0.8);
_isSongInfoFontSizeChanged = true;
}
private void UpdateLyrics3DMatrix()
{
if (!_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Is3DLyricsEnabled) return;
Vector3 center = new(
(float)(_lyricsXTransition.Value + _maxLyricsWidth / 2),
(float)(_lyricsYTransition.Value + _canvasHeight / 2),
0);
float rotationX = (float)(Math.PI * _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Lyrics3DXAngle / 180.0);
float rotationY = (float)(Math.PI * _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Lyrics3DYAngle / 180.0);
float rotationZ = (float)(Math.PI * _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Lyrics3DZAngle / 180.0);
Matrix4x4 rotation =
Matrix4x4.CreateRotationX(rotationX) *
Matrix4x4.CreateRotationY(rotationY) *
Matrix4x4.CreateRotationZ(rotationZ);
Matrix4x4 perspective = Matrix4x4.Identity;
perspective.M34 = 1.0f / _liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.Lyrics3DDepth;
// 组合变换:
// 1. 将中心移到原点
// 2. 旋转
// 3. 应用透视
// 4. 将中心移回原位
_lyrics3DMatrix =
Matrix4x4.CreateTranslation(-center) *
rotation *
perspective *
Matrix4x4.CreateTranslation(center);
}
}
}

View File

@@ -27,6 +27,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
@@ -133,12 +134,12 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private int _timelineSyncThreshold = 0;
private CanvasTextFormat _lyricsTextFormat = new()
{
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
FontSize = 12,
};
private int _phoneticLyricsFontSize = 18;
private int _originalLyricsFontSize = 36;
private int _translatedLyricsFontSize = 18;
private LyricsFontWeight _originalLyricsFontWeight = LyricsFontWeight.Bold;
private CanvasTextFormat _titleTextFormat = new()
{
FontSize = 18,
@@ -174,6 +175,8 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private SpectrumAnalyzer? _spectrumAnalyzer;
private Matrix4x4 _lyrics3DMatrix = Matrix4x4.Identity;
public LyricsRendererViewModel(
ISettingsService settingsService,
IMediaSessionsService mediaSessionsService,
@@ -394,6 +397,9 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
private void MediaSessionsService_AlbumArtChangedChanged(object? sender, AlbumArtChangedEventArgs e)
{
_lastAlbumArtCanvasBitmap?.Dispose();
_lastAlbumArtCanvasBitmap = null;
_lastAlbumArtSwBitmap = _albumArtSwBitmap;
_albumArtSwBitmap = e.AlbumArtSwBitmap;

View File

@@ -36,7 +36,7 @@ namespace BetterLyrics.WinUI3.ViewModels
public partial LyricsSearchResult? SelectedLyricsSearchResult { get; set; }
[ObservableProperty]
public partial LyricsData? LyricsData { get; set; }
public partial ObservableCollection<LyricsData>? LyricsDataArr { get; set; }
[ObservableProperty]
public partial LyricsLine? SelectedLyricsLine { get; set; }
@@ -68,7 +68,7 @@ namespace BetterLyrics.WinUI3.ViewModels
private void InitMappedSongSearchQuery()
{
LyricsSearchResults.Clear();
LyricsData = null;
LyricsDataArr = null;
if (_mediaSessionsService.SongInfo != null)
{
var found = GetMappedSongSearchQueryFromSettings();
@@ -172,12 +172,15 @@ namespace BetterLyrics.WinUI3.ViewModels
if (value?.Raw != null)
{
var lyricsParser = new LyricsParser();
var lyricsDataArr = lyricsParser.Parse(value?.Raw, (int?)_mediaSessionsService.SongInfo?.DurationMs);
LyricsData = lyricsDataArr.FirstOrDefault();
lyricsParser.Parse(
MappedSongSearchQuery?.MappedTitle ?? "",
MappedSongSearchQuery?.MappedArtist ?? "",
value?.Raw, (int?)_mediaSessionsService.SongInfo?.DurationMs, value?.Provider);
LyricsDataArr = [.. lyricsParser.LyricsDataArr];
}
else
{
LyricsData = null;
LyricsDataArr = null;
}
}

View File

@@ -56,7 +56,7 @@ namespace BetterLyrics.WinUI3.ViewModels
private void RefreshMonitorDeviceNames()
{
MonitorDeviceNames = [.. MonitorHelper.GetAllMonitorDeviceNames()];
LiveStates.LyricsWindowStatus.MonitorDeviceName = MonitorHelper.GetPrimaryMonitorDeviceName();
LiveStates.LyricsWindowStatus.MonitorDeviceName = MonitorDeviceNames.FirstOrDefault() ?? "";
}
[RelayCommand]

View File

@@ -0,0 +1,14 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class LyricsWindowSwitchWindowViewModel : BaseViewModel
{
[ObservableProperty] public partial float RootGridOpacity { get; set; } = 1;
}
}

View File

@@ -70,7 +70,7 @@ namespace BetterLyrics.WinUI3
[ObservableProperty] public partial ElementTheme ThemeType { get; set; } = ElementTheme.Default;
[ObservableProperty] public partial double TitleBarFontSize { get; set; } = 11;
[ObservableProperty] public partial double TitleBarFontSize { get; set; } = 12;
[ObservableProperty] public partial Visibility CloseButtonVisibility { get; set; } = Visibility.Visible;
@@ -154,7 +154,10 @@ namespace BetterLyrics.WinUI3
{
presenter.IsAlwaysOnTop = true;
}
UpdateBackdropAccentColor(hwnd);
if (_liveStatesService.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment)
{
UpdateBackdropAccentColor(hwnd);
}
}, Constants.Time.DebounceTimeout);
}
);

View File

@@ -17,9 +17,11 @@ using Hqub.Lastfm.Entities;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.Globalization;
namespace BetterLyrics.WinUI3.ViewModels
{
@@ -56,6 +58,12 @@ namespace BetterLyrics.WinUI3.ViewModels
[ObservableProperty]
public partial TranslationSearchProvider? TranslationSearchProvider { get; set; } = null;
[ObservableProperty]
public partial string OriginalLyricsRef { get; set; } = "about:blank";
[ObservableProperty]
public partial string TranslatedLyricsRef { get; set; } = "about:blank";
[ObservableProperty]
public partial int SelectedTargetLanguageIndex { get; set; }
@@ -83,7 +91,7 @@ namespace BetterLyrics.WinUI3.ViewModels
AppleMusicMediaUserToken = PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey) ?? "";
SelectedTargetLanguageIndex = LanguageHelper.SupportedTargetLanguages.ToList().FindIndex(x => x.Code == AppSettings.TranslationSettings.SelectedTargetLanguageCode);
SelectedTargetLanguageIndex = LanguageHelper.SupportedTranslationTargetLanguages.ToList().FindIndex(x => x.LanguageCode == AppSettings.TranslationSettings.SelectedTargetLanguageCode);
IsLastFMAuthenticated = _lastFMService.IsAuthenticated;
LastFMUser = _lastFMService.User;
@@ -223,7 +231,7 @@ namespace BetterLyrics.WinUI3.ViewModels
partial void OnSelectedTargetLanguageIndexChanged(int value)
{
AppSettings.TranslationSettings.SelectedTargetLanguageCode = LanguageHelper.SupportedTargetLanguages[value].Code;
AppSettings.TranslationSettings.SelectedTargetLanguageCode = LanguageHelper.SupportedTranslationTargetLanguages[value].LanguageCode;
}
}
}

View File

@@ -2,6 +2,7 @@
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Helper.BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services;
@@ -24,6 +25,7 @@ using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.Services.Store;
using Windows.Storage;
using WinRT.Interop;
namespace BetterLyrics.WinUI3.ViewModels
@@ -124,5 +126,27 @@ namespace BetterLyrics.WinUI3.ViewModels
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader?.GetString("ExportSettingsSuccess") ?? "", InfoBarSeverity.Success);
}
}
[RelayCommand]
private void ClearCacheFiles()
{
DirectoryHelper.DeleteAllFiles(PathHelper.LogDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.LyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.AmllTtmlDbLyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.KugouLyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.LrcLibLyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.NeteaseLyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.QQLyricsCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.TranslationCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.KugouTranslationCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.NeteaseTranslationCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.QQTranslationCacheDirectory);
DirectoryHelper.DeleteAllFiles(PathHelper.iTunesAlbumArtCacheDirectory);
App.Current.SettingsWindowNotificationPanel?.Notify(App.ResourceLoader!.GetString("ActionCompleted"), InfoBarSeverity.Success);
}
}
}

View File

@@ -52,5 +52,11 @@ namespace BetterLyrics.WinUI3.ViewModels
{
WindowHelper.OpenOrShowWindow<LyricsWindow>();
}
[RelayCommand]
private static void OpenLyricsWindowSwitch()
{
WindowHelper.OpenOrShowWindow<LyricsWindowSwitchWindow>();
}
}
}

View File

@@ -5,6 +5,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:animatedvisuals="using:Microsoft.UI.Xaml.Controls.AnimatedVisuals"
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
xmlns:const="using:BetterLyrics.WinUI3.Constants"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -18,19 +19,27 @@
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid x:Name="RootGrid" SizeChanged="RootGrid_SizeChanged">
<Grid
x:Name="RootGrid"
RightTapped="RootGrid_RightTapped"
SizeChanged="RootGrid_SizeChanged">
<!-- Lyrics area -->
<renderer:LyricsRenderer />
<!--<Image Source="/Assets/Cover.jpg" />-->
<!-- No music playing placeholder -->
<Grid x:Name="NoMusicPlayingGrid" Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}">
<TextBlock
x:Uid="MainPageNoMusicPlaying"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontFamily, Mode=OneWay}"
FontSize="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsFontSize, Mode=OneWay}" />
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock
x:Uid="MainPageNoMusicPlaying"
HorizontalAlignment="Center"
FontFamily="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.LyricsCJKFontFamily, Mode=OneWay}"
FontSize="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings.OriginalLyricsFontSize, Mode=OneWay}"
TextWrapping="Wrap" />
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<HyperlinkButton x:Uid="SettingsPageFAQ" NavigateUri="{x:Bind const:Link.FAQUrl}" />
</StackPanel>
</StackPanel>
<Grid.OpacityTransition>
<ScalarTransition />
</Grid.OpacityTransition>
@@ -80,6 +89,64 @@
<TextBlock Text="{Binding ElementName=TimelineSlider, Path=Maximum, Converter={StaticResource SecondsToFormattedTimeConverter}}" />
</StackPanel>
<!-- Volume -->
<Button Click="VolumeButton_Click" Style="{StaticResource GhostButtonStyle}">
<Grid>
<!-- Volumn: 0 -->
<FontIcon
x:Name="VolumeLevel0"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE74F;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<!-- Volumn: 1-32 -->
<FontIcon
x:Name="VolumeLevel1"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE993;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<!-- Volumn: 33-65 -->
<FontIcon
x:Name="VolumeLevel2"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE994;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<!-- Volumn: 66-100 -->
<FontIcon
x:Name="VolumeLevel3"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE995;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
</Grid>
<Button.ContextFlyout>
<Flyout x:Name="VolumeFlyout" ShouldConstrainToRootBounds="False">
<uc:ExtendedSlider
Frequency="1"
Maximum="100"
Minimum="0"
ResetButtonVisibility="Collapsed"
Unit="%"
Value="{x:Bind ViewModel.Volume, Mode=TwoWay}" />
</Flyout>
</Button.ContextFlyout>
</Button>
</StackPanel>
</Grid>
@@ -147,78 +214,6 @@
Orientation="Horizontal"
Spacing="3">
<!-- Volume -->
<!--<Button Click="VolumeButton_Click" Style="{StaticResource GhostButtonStyle}">
<Grid>
-->
<!-- Volumn: 0 -->
<!--
<FontIcon
x:Name="VolumeLevel0"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE74F;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
-->
<!-- Volumn: 1-32 -->
<!--
<FontIcon
x:Name="VolumeLevel1"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE993;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
-->
<!-- Volumn: 33-65 -->
<!--
<FontIcon
x:Name="VolumeLevel2"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE994;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
-->
<!-- Volumn: 66-100 -->
<!--
<FontIcon
x:Name="VolumeLevel3"
FontFamily="{StaticResource IconFontFamily}"
Glyph="&#xE995;">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
</Grid>
<Button.ContextFlyout>
<Flyout x:Name="VolumeFlyout" ShouldConstrainToRootBounds="False">
<StackPanel Orientation="Horizontal">
<TextBlock x:Uid="SettingsPageSliderPrefix" VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind ViewModel.Volume, Mode=OneWay}" />
<TextBlock Margin="0,0,14,0" VerticalAlignment="Center" />
<Slider
Width="150"
Maximum="100"
Minimum="0"
SnapsTo="Ticks"
StepFrequency="1"
TickFrequency="1"
TickPlacement="None"
Value="{x:Bind ViewModel.Volume, Mode=TwoWay}" />
</StackPanel>
</Flyout>
</Button.DataContext>
</Button>-->
<Button
Click="LyricsSearchShortcutButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
@@ -272,7 +267,7 @@
x:Name="SettingsButton"
Command="{x:Bind ViewModel.OpenSettingsWindowCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF8B0;}"
Glyph=&#xE713;}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip x:Name="SettingsToolTip" x:Uid="LyricsPageSettingsButtonToolTip" />
@@ -312,7 +307,8 @@
Margin="0,0,0,2"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}, Mode=OneWay}" />
<TextBlock Margin="0,0,0,2" Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.DisplayedText, Mode=OneWay}" />
<!-- TODO 原文翻译共同显示 -->
<TextBlock Margin="0,0,0,2" Text="{x:Bind ViewModel.TimelineSliderThumbLyricsLine.OriginalText, Mode=OneWay}" />
</StackPanel>
</Grid>
<Grid
@@ -370,7 +366,7 @@
<uc:SystemTray />
<VisualStateManager.VisualStateGroups>
<!--<VisualStateGroup x:Name="VolumeState">
<VisualStateGroup x:Name="VolumeState">
<VisualState x:Name="Volume0">
<VisualState.StateTriggers>
<ui:CompareStateTrigger
@@ -427,7 +423,7 @@
<Setter Target="VolumeLevel3.Opacity" Value="1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>-->
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</Page>

View File

@@ -83,10 +83,10 @@ namespace BetterLyrics.WinUI3.Views
}
}
//private void VolumeButton_Click(object sender, RoutedEventArgs e)
//{
// VolumeFlyout.ShowAt(BottomRightCommandStackPanel);
//}
private void VolumeButton_Click(object sender, RoutedEventArgs e)
{
VolumeFlyout.ShowAt(BottomLeftCommandStackPanel);
}
private void BottomCommandFlyoutTrigger_PointerEntered(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
@@ -172,5 +172,13 @@ namespace BetterLyrics.WinUI3.Views
{
ViewModel.TimelineSliderThumbOpacity = 0f;
}
private void RootGrid_RightTapped(object sender, Microsoft.UI.Xaml.Input.RightTappedRoutedEventArgs e)
{
if (BottomCommandFlyoutContainer.Children.Count != 0)
{
BottomCommandFlyout.ShowAt(BottomCommandFlyoutTrigger);
}
}
}
}

View File

@@ -33,6 +33,8 @@ namespace BetterLyrics.WinUI3.Views
AppWindow.TitleBar.PreferredTheme = TitleBarTheme.UseDefaultAppMode;
AppWindow.SetIcons();
ExtendsContentIntoTitleBar = true;
AppWindow.Closing += AppWindow_Closing;
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(Enums.BackdropType.Transparent);

View File

@@ -46,7 +46,7 @@
<ScalarTransition />
</StackPanel.OpacityTransition>
<!-- More -->
<!-- Music gallery -->
<Button Click="MusicGalleryButton_Click" Style="{StaticResource TitleBarButtonStyle}">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
@@ -57,6 +57,24 @@
</ToolTipService.ToolTip>
</Button>
<Button
x:Name="SettingsWindowButton"
Click="SettingsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE713;}"
Style="{StaticResource TitleBarButtonStyle}" />
<Button Click="LyricsWindowSwitchButton_Click" Style="{StaticResource TitleBarButtonStyle}">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
Glyph="&#xE8AB;" />
<ToolTipService.ToolTip>
<ToolTip x:Uid="LyricsWindowSwitchButtonToolTip" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</Grid>

View File

@@ -23,10 +23,11 @@ namespace BetterLyrics.WinUI3.Views
{
public sealed partial class LyricsWindow : Window
{
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
private readonly WindowMessageMonitor _wmm;
public LyricsWindowViewModel ViewModel { get; private set; } = Ioc.Default.GetRequiredService<LyricsWindowViewModel>();
public LyricsWindow()
{
this.InitializeComponent();
@@ -79,10 +80,13 @@ namespace BetterLyrics.WinUI3.Views
}
}
public LyricsWindowViewModel ViewModel { get; private set; } = Ioc.Default.GetRequiredService<LyricsWindowViewModel>();
private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
if (_liveStatesService.LiveStates.IsLyricsWindowStatusRefreshing)
{
//return;
}
if (args.DidPositionChange || args.DidSizeChange)
{
var size = AppWindow.Size;
@@ -95,10 +99,6 @@ namespace BetterLyrics.WinUI3.Views
else
{
_liveStatesService.LiveStates.LyricsWindowStatus.WindowBounds = new Windows.Foundation.Rect(rect.X, rect.Y, size.Width, size.Height);
_liveStatesService.LiveStates.LyricsWindowStatus.WindowX = rect.X;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowY = rect.Y;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowWidth = size.Width;
_liveStatesService.LiveStates.LyricsWindowStatus.WindowHeight = size.Height;
}
}
}
@@ -127,5 +127,15 @@ namespace BetterLyrics.WinUI3.Views
{
ViewModel.ExitOrClose();
}
private void LyricsWindowSwitchButton_Click(object sender, RoutedEventArgs e)
{
WindowHelper.OpenOrShowWindow<LyricsWindowSwitchWindow>();
}
private void SettingsWindowButton_Click(object sender, RoutedEventArgs e)
{
WindowHelper.OpenOrShowWindow<SettingsWindow>();
}
}
}

View File

@@ -10,7 +10,10 @@
Title="LyricsWindowSwitchWindow"
mc:Ignorable="d">
<Grid>
<Grid x:Name="RootGrid" Opacity="{x:Bind ViewModel.RootGridOpacity, Mode=OneWay}">
<Grid.OpacityTransition>
<ScalarTransition />
</Grid.OpacityTransition>
<Grid
x:Name="PlaceholderGrid"
Width="1"

View File

@@ -1,4 +1,6 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
@@ -25,6 +27,8 @@ namespace BetterLyrics.WinUI3.Views
/// </summary>
public sealed partial class LyricsWindowSwitchWindow : Window
{
public LyricsWindowSwitchWindowViewModel ViewModel { get; private set; } = Ioc.Default.GetRequiredService<LyricsWindowSwitchWindowViewModel>();
public LyricsWindowSwitchWindow()
{
InitializeComponent();
@@ -37,6 +41,19 @@ namespace BetterLyrics.WinUI3.Views
AppWindow.IsShownInSwitchers = false;
this.SetIsAlwaysOnTop(true);
SetTitleBar(PlaceholderGrid);
AppWindow.Changed += AppWindow_Changed;
}
private void AppWindow_Changed(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowChangedEventArgs args)
{
if (args.DidVisibilityChange)
{
if (sender.IsVisible)
{
ViewModel.RootGridOpacity = 1;
}
}
}
}
}

View File

@@ -12,6 +12,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:media="using:CommunityToolkit.WinUI.Media"
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:muxm="using:Microsoft.UI.Xaml.Media"
xmlns:templateselector="using:BetterLyrics.WinUI3.TemplateSelector"
xmlns:ui="using:CommunityToolkit.WinUI"
Unloaded="Page_Unloaded"
@@ -92,18 +93,11 @@
</Flyout>
</Grid.Tag>
<ListView
<Pivot
VerticalAlignment="Top"
ItemsSource="{x:Bind ViewModel.SongsTabInfoList, Mode=OneWay}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
SelectedIndex="{x:Bind ViewModel.SelectedSongsTabInfoIndex, Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="models:SongsTabInfo">
<Grid>
<Grid.ColumnDefinitions>
@@ -123,11 +117,12 @@
Grid.Column="0"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="{Binding Icon}" />
Glyph="{x:Bind Icon}" />
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{Binding Name}" />
Style="{StaticResource BodyTextBlockStyle}"
Text="{x:Bind Name}" />
</Grid>
<Button
Grid.Column="1"
@@ -137,13 +132,16 @@
Glyph=&#xE8BB;}"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource GhostButtonStyle}"
Visibility="{Binding IsClosable, Converter={StaticResource BoolToVisibilityConverter}}" />
Visibility="{x:Bind IsClosable, Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate />
</Pivot.ItemTemplate>
</Pivot>
<Grid Margin="0,48,0,0" VerticalAlignment="Top">
<Grid Margin="0,56,0,0" VerticalAlignment="Top">
<AutoSuggestBox
x:Name="SongSearchBox"
x:Uid="MusicGalleryPageSongSearchBox"
@@ -156,7 +154,7 @@
<StackPanel
HorizontalAlignment="Left"
Orientation="Horizontal"
Spacing="12">
Spacing="6">
<ToggleButton
x:Name="SelectAllToggleButton"
x:Uid="MusicGalleryPageSelectAll"
@@ -181,7 +179,7 @@
<StackPanel
HorizontalAlignment="Right"
Orientation="Horizontal"
Spacing="12">
Spacing="6">
<StackPanel Orientation="Horizontal" Spacing="12">
<TextBlock
x:Uid="MusicGalleryPageSortType"
@@ -208,56 +206,68 @@
SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate x:DataType="atl:Track">
<Grid Padding="12" RightTapped="SongListViewItemGrid_RightTapped">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1.5*" />
<ColumnDefinition Width="1.5*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid RightTapped="SongListViewItemGrid_RightTapped">
<!-- 歌曲名 -->
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
Text="{Binding Title}"
TextWrapping="Wrap" />
<Grid
x:Name="SongListViewItemContentGrid"
Padding="12"
ColumnSpacing="12">
<!-- 歌手名 -->
<HyperlinkButton
Grid.Column="1"
VerticalAlignment="Center"
Click="ArtistHyperlibkButton_Click"
Tag="{Binding Artist}">
<TextBlock Text="{Binding Artist}" TextWrapping="Wrap" />
</HyperlinkButton>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1.5*" />
<ColumnDefinition Width="1.5*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!-- 专辑名 -->
<HyperlinkButton
Grid.Column="2"
VerticalAlignment="Center"
Click="AlbumHyperlibkButton_Click"
Tag="{Binding Album}">
<TextBlock Text="{Binding Album}" TextWrapping="Wrap" />
</HyperlinkButton>
<Grid Grid.Column="0" CornerRadius="6">
<Image Source="{Binding EmbeddedPictures[0].PictureData, Mode=OneWay, Converter={StaticResource ByteArrayToImageConverter}}" Stretch="UniformToFill" />
</Grid>
<!-- 年份 -->
<TextBlock
Grid.Column="3"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding Year}"
TextWrapping="Wrap" />
<!-- 歌曲名 -->
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{Binding Title}"
TextWrapping="Wrap" />
<!-- 歌曲时长 -->
<TextBlock
Grid.Column="4"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
TextAlignment="Right"
TextWrapping="Wrap" />
<!-- 歌手名 -->
<HyperlinkButton
Grid.Column="2"
VerticalAlignment="Center"
Click="ArtistHyperlibkButton_Click"
Tag="{Binding Artist}">
<TextBlock Text="{Binding Artist}" TextWrapping="Wrap" />
</HyperlinkButton>
<!-- 专辑名 -->
<HyperlinkButton
Grid.Column="3"
VerticalAlignment="Center"
Click="AlbumHyperlibkButton_Click"
Tag="{Binding Album}">
<TextBlock Text="{Binding Album}" TextWrapping="Wrap" />
</HyperlinkButton>
<!-- 年份 -->
<TextBlock
Grid.Column="4"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding Year}"
TextWrapping="Wrap" />
<!-- 歌曲时长 -->
<TextBlock
Grid.Column="5"
VerticalAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{Binding Duration, Converter={StaticResource SecondsToFormattedTimeConverter}}"
TextAlignment="Right"
TextWrapping="Wrap" />
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
@@ -320,7 +330,7 @@
Grid.Column="1"
Margin="0,0,12,0">
<StackPanel Margin="0,10,0,0" Spacing="12">
<StackPanel Margin="0,10,0,0" Spacing="6">
<Grid Margin="0,6,0,0" VerticalAlignment="Top">
<TextBlock x:Uid="MusicGalleryPagePlayingQueue" Style="{StaticResource BodyStrongTextBlockStyle}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
@@ -329,7 +339,7 @@
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TrackPlayingQueue.Count, Mode=OneWay}" />
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal" Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="6">
<Button x:Uid="MusicGalleryPageEmptyPlayingQueue" Click="EmptyPlayingQueueButton_Click" />
<Button x:Uid="MusicGalleryPageScrollToPlayingItem" Click="ScrollToPlayingItemButton_Click" />
</StackPanel>

View File

@@ -6,13 +6,34 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:BetterLyrics.WinUI3.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MusicGalleryWindow"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Window.SystemBackdrop>
<MicaBackdrop />
<DesktopAcrylicBackdrop />
</Window.SystemBackdrop>
<local:MusicGalleryPage />
<Grid>
<local:MusicGalleryPage Margin="0,40,0,0" />
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<Button
x:Name="LyricsWindowButton"
Click="LyricsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE90B;}"
Style="{StaticResource TitleBarButtonStyle}" />
<Button
x:Name="SettingsWindowButton"
Click="SettingsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE713;}"
Style="{StaticResource TitleBarButtonStyle}" />
</StackPanel>
</Grid>
</Window>

View File

@@ -34,6 +34,8 @@ namespace BetterLyrics.WinUI3.Views
AppWindow.TitleBar.PreferredTheme = TitleBarTheme.UseDefaultAppMode;
AppWindow.SetIcons();
ExtendsContentIntoTitleBar = true;
AppWindow.Closing += AppWindow_Closing;
}
@@ -41,5 +43,15 @@ namespace BetterLyrics.WinUI3.Views
{
WindowHelper.CloseWindow<MusicGalleryWindow>();
}
private void LyricsWindowButton_Click(object sender, RoutedEventArgs e)
{
WindowHelper.OpenOrShowWindow<LyricsWindow>();
}
private void SettingsWindowButton_Click(object sender, RoutedEventArgs e)
{
WindowHelper.OpenOrShowWindow<SettingsWindow>();
}
}
}

View File

@@ -122,10 +122,14 @@
<controls:SettingsExpander.Items>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="GitHub" NavigateUri="{x:Bind const:Link.GitHubUrl}" />
<HyperlinkButton x:Uid="SettingsPageFAQ" NavigateUri="{x:Bind const:Link.FAQUrl}" />
<StackPanel Spacing="6">
<TextBlock x:Uid="SetingsPageInstructions" />
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="GitHub" NavigateUri="{x:Bind const:Link.GitHubUrl}" />
<HyperlinkButton Content="Wiki" NavigateUri="{x:Bind const:Link.WikiUrl}" />
</StackPanel>
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
@@ -188,8 +192,20 @@
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Spacing="6">
<TextBlock x:Uid="SetingsPageContributors" />
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="jayfunc" NavigateUri="https://github.com/jayfunc" />
<HyperlinkButton Content="Raspberry-Monster" NavigateUri="https://github.com/Raspberry-Monster" />
<HyperlinkButton Content="ZHider" NavigateUri="https://github.com/ZHider" />
<HyperlinkButton Content="kusutori" NavigateUri="https://github.com/kusutori" />
</StackPanel>
</StackPanel>
</controls:SettingsCard>
</controls:SettingsExpander.Items>
<controls:SettingsExpander.ItemsHeader>
<controls:SettingsExpander.ItemsFooter>
<InfoBar
x:Uid="SettingsPageDisclaimer"
BorderThickness="0"
@@ -197,16 +213,21 @@
IsClosable="False"
IsOpen="True"
Severity="Warning" />
</controls:SettingsExpander.ItemsHeader>
</controls:SettingsExpander.ItemsFooter>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageMockMusicPlaying">
<HyperlinkButton x:Uid="SettingsPagePlayingMockMusicButton" NavigateUri="https://soundcloud.com/carlyraejepsen/cut-to-the-feeling" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageCache">
<controls:SettingsExpander x:Uid="SettingsPageCache" IsExpanded="True">
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenCacheFolderCommand}" />
</controls:SettingsCard>
<controls:SettingsExpander.Items>
<controls:SettingsCard>
<Button x:Uid="SettingsPageClearCache" Command="{x:Bind ViewModel.ClearCacheFilesCommand}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="SettingsPageSettings">
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenSettingsFolderCommand}" />

View File

@@ -7,14 +7,35 @@
xmlns:local="using:BetterLyrics.WinUI3.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:scontrols="using:ShadowViewer.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Window.SystemBackdrop>
<MicaBackdrop />
<DesktopAcrylicBackdrop />
</Window.SystemBackdrop>
<Grid x:Name="RootGrid">
<Frame x:Name="RootFrame" />
<Frame x:Name="RootFrame" Margin="0,40,0,0" />
<StackPanel VerticalAlignment="Top" Orientation="Horizontal">
<Button
x:Name="LyricsWindowButton"
Click="LyricsWindowButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE90B;}"
Style="{StaticResource TitleBarButtonStyle}" />
<Button
Click="MusicGalleryButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE8F1;}"
Style="{StaticResource TitleBarButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip x:Uid="HostWindowMusicGalleryButtonToolTip" />
</ToolTipService.ToolTip>
</Button>
</StackPanel>
<scontrols:NotificationPanel
x:Name="TipContainerCenter"

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