Compare commits
165 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c43b69b4cb | ||
|
|
94b22552e5 | ||
|
|
6deb16f6cb | ||
|
|
e467ab9c73 | ||
|
|
ea038c9c56 | ||
|
|
560250ad30 | ||
|
|
536acc69a5 | ||
|
|
0bbb379912 | ||
|
|
1f4d29e6f2 | ||
|
|
5d1d7476c9 | ||
|
|
e016baefe1 | ||
|
|
70b6194788 | ||
|
|
9f103b0ea3 | ||
|
|
2924140f95 | ||
|
|
3d3f168926 | ||
|
|
63b2285a36 | ||
|
|
780689fa05 | ||
|
|
01384717c4 | ||
|
|
e18d78170a | ||
|
|
023bf77afc | ||
|
|
2877ac2101 | ||
|
|
16d82109bb | ||
|
|
c703f04119 | ||
|
|
998853f9d2 | ||
|
|
f560735da0 | ||
|
|
ab9da73b49 | ||
|
|
dc364edf75 | ||
|
|
7fbc8fbfe7 | ||
|
|
4a00bb2ddf | ||
|
|
7472aa048f | ||
|
|
49b0f7a692 | ||
|
|
4d0602ebef | ||
|
|
626395d93a | ||
|
|
0ab5602569 | ||
|
|
37a7528762 | ||
|
|
3ca391a509 | ||
|
|
f5e542d2f3 | ||
|
|
107bdf8bee | ||
|
|
3e9e56f5cc | ||
|
|
b0fd43ead5 | ||
|
|
81c59495c0 | ||
|
|
7c5f1a804e | ||
|
|
13ee4227f7 | ||
|
|
c1360ac972 | ||
|
|
c72aa8a58f | ||
|
|
9545ed610b | ||
|
|
1c4515acb9 | ||
|
|
92a6fe46de | ||
|
|
2f9fa02214 | ||
|
|
c174363c07 | ||
|
|
8506062c9a | ||
|
|
52711cba1f | ||
|
|
7eda076920 | ||
|
|
282c2f5ac0 | ||
|
|
94e76a6ac9 | ||
|
|
516d388009 | ||
|
|
ad33eed57c | ||
|
|
64bf2dc3d9 | ||
|
|
b86e4a3d12 | ||
|
|
411506b9cd | ||
|
|
f681b43e96 | ||
|
|
133acf5592 | ||
|
|
cbaa81b9bb | ||
|
|
b834be49ce | ||
|
|
8abe6d7f01 | ||
|
|
8a73ba9e6a | ||
|
|
49a090b0c7 | ||
|
|
a47dd67056 | ||
|
|
900ecc9776 | ||
|
|
464742d7c5 | ||
|
|
5f3aad4e99 | ||
|
|
7b6eca6ff6 | ||
|
|
9fcb1ac869 | ||
|
|
74ebda2b6d | ||
|
|
e194dfaa70 | ||
|
|
bfc877f924 | ||
|
|
af55446004 | ||
|
|
faf8acf669 | ||
|
|
5b79a54117 | ||
|
|
4ef55f6ece | ||
|
|
0593f9aa3f | ||
|
|
b09a6494ff | ||
|
|
b043f9acd0 | ||
|
|
7b2ff0cc8f | ||
|
|
7c9ab73a34 | ||
|
|
a08bf91784 | ||
|
|
61906670fd | ||
|
|
430b2f4d28 | ||
|
|
eb05c1ea13 | ||
|
|
9bebf36e6a | ||
|
|
d2b0b6afb1 | ||
|
|
9c2f4fbff9 | ||
|
|
1b69493afd | ||
|
|
c524dc013c | ||
|
|
9ca5939e57 | ||
|
|
860abd4037 | ||
|
|
618415016f | ||
|
|
bfcba1425d | ||
|
|
0dc9ebf18e | ||
|
|
366d396b93 | ||
|
|
35ca28ac7b | ||
|
|
1505933107 | ||
|
|
958227d0f2 | ||
|
|
b1978fec09 | ||
|
|
010040b376 | ||
|
|
35272d8324 | ||
|
|
29a714fe87 | ||
|
|
78edc2b3ce | ||
|
|
932f9d3a4f | ||
|
|
a56a7af08c | ||
|
|
5427c1992f | ||
|
|
64d69f44c3 | ||
|
|
d75fe4b27a | ||
|
|
eac9b3e28a | ||
|
|
d6975ba2d4 | ||
|
|
aae8e1322a | ||
|
|
88aac0eaf0 | ||
|
|
c463d9bc5c | ||
|
|
f305b469f2 | ||
|
|
ea276f3e2e | ||
|
|
15601e6ee4 | ||
|
|
44b14cab17 | ||
|
|
0a97c56c77 | ||
|
|
ac5dc5991f | ||
|
|
d22dc673e8 | ||
|
|
9eb2b83796 | ||
|
|
1cf6226a06 | ||
|
|
bce330a9e0 | ||
|
|
687e286c2e | ||
|
|
fc05035053 | ||
|
|
f45f5ead01 | ||
|
|
0eeea77896 | ||
|
|
78ca7d8435 | ||
|
|
98d2ac404d | ||
|
|
b4b1ffd58e | ||
|
|
2522bd00ab | ||
|
|
0601039fcf | ||
|
|
857b95e525 | ||
|
|
4be855f11a | ||
|
|
9e1018770d | ||
|
|
1235a09d19 | ||
|
|
1647c3a2f1 | ||
|
|
588838acaa | ||
|
|
25c772434c | ||
|
|
2c597a3b37 | ||
|
|
80a44977a6 | ||
|
|
0389fa6a56 | ||
|
|
30ca476d8d | ||
|
|
6439dee5ef | ||
|
|
f6e5a24fe4 | ||
|
|
77aad546bc | ||
|
|
7fdbe664ba | ||
|
|
df76074ce9 | ||
|
|
31939630a3 | ||
|
|
50500626f8 | ||
|
|
fb1f0c8fc7 | ||
|
|
9036b3be5f | ||
|
|
51f840c0ef | ||
|
|
b3a98cdaa2 | ||
|
|
7799a8dd94 | ||
|
|
e84d1faf71 | ||
|
|
66f0fd0f8f | ||
|
|
4f0dbe4836 | ||
|
|
d7a53e360a | ||
|
|
cb76341666 |
2
.github/FUNDING.yml
vendored
@@ -12,4 +12,4 @@ lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cl
|
|||||||
polar: # Replace with a single Polar username
|
polar: # Replace with a single Polar username
|
||||||
buy_me_a_coffee: founchoo
|
buy_me_a_coffee: founchoo
|
||||||
thanks_dev: # Replace with a single thanks.dev username
|
thanks_dev: # Replace with a single thanks.dev username
|
||||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
custom: ['https://paypal.me/zhefangpay']
|
||||||
|
|||||||
18
.github/workflows/issues-translator.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: 'issue-translator'
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: usthe/issues-translate-action@v2.7
|
||||||
|
with:
|
||||||
|
IS_MODIFY_TITLE: false
|
||||||
|
# not require, default false, . Decide whether to modify the issue title
|
||||||
|
# if true, the robot account @Issues-translate-bot must have modification permissions, invite @Issues-translate-bot to your project or use your custom bot.
|
||||||
|
CUSTOM_BOT_NOTE: Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
|
||||||
|
# not require. Customize the translation robot prefix message.
|
||||||
5
.github/workflows/release-to-telegram.yml
vendored
@@ -12,6 +12,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
|
||||||
CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
|
THREAD_ID: ${{ secrets.TELEGRAM_THREAD_ID }}
|
||||||
RELEASE_URL: ${{ github.event.release.html_url }}
|
RELEASE_URL: ${{ github.event.release.html_url }}
|
||||||
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
||||||
RELEASE_NAME: ${{ github.event.release.name }}
|
RELEASE_NAME: ${{ github.event.release.name }}
|
||||||
@@ -23,5 +24,5 @@ jobs:
|
|||||||
|
|
||||||
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
|
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
|
||||||
-d chat_id="${CHAT_ID}" \
|
-d chat_id="${CHAT_ID}" \
|
||||||
-d text="${TEXT}" \
|
-d message_thread_id="${THREAD_ID}" \
|
||||||
-d parse_mode=Markdown
|
-d text="${TEXT}"
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -406,3 +406,4 @@ FodyWeavers.xsd
|
|||||||
# JetBrains Rider
|
# JetBrains Rider
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package)_TemporaryKey.pfx
|
/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package)_TemporaryKey.pfx
|
||||||
|
/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/LastFM.cs
|
||||||
|
|||||||
@@ -1,149 +1,150 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0'">
|
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '15.0'">
|
||||||
<VisualStudioVersion>15.0</VisualStudioVersion>
|
<VisualStudioVersion>15.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|x86">
|
<ProjectConfiguration Include="Debug|x86">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>x86</Platform>
|
<Platform>x86</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|x86">
|
<ProjectConfiguration Include="Release|x86">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>x86</Platform>
|
<Platform>x86</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|x64">
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>x64</Platform>
|
<Platform>x64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|x64">
|
<ProjectConfiguration Include="Release|x64">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>x64</Platform>
|
<Platform>x64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|ARM64">
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>ARM64</Platform>
|
<Platform>ARM64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|ARM64">
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>ARM64</Platform>
|
<Platform>ARM64</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
|
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
|
||||||
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
|
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
|
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
|
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
|
||||||
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
|
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<AssetTargetFallback>net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
|
<AssetTargetFallback>net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
|
||||||
<DefaultLanguage>zh-CN</DefaultLanguage>
|
<DefaultLanguage>zh-CN</DefaultLanguage>
|
||||||
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
|
||||||
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
|
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
|
||||||
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
|
||||||
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
|
||||||
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
|
||||||
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
<GenerateTestArtifacts>True</GenerateTestArtifacts>
|
||||||
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
|
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
|
||||||
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
|
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
|
||||||
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
|
||||||
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
|
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
<AppxBundle>Always</AppxBundle>
|
<AppxBundle>Always</AppxBundle>
|
||||||
<DefaultLanguage>en-US</DefaultLanguage>
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AppxManifest Include="Package.appxmanifest">
|
<AppxManifest Include="Package.appxmanifest">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</AppxManifest>
|
</AppxManifest>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
|
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
|
||||||
<Content Include="Images\LargeTile.scale-100.png" />
|
<Content Include="Images\LargeTile.scale-100.png" />
|
||||||
<Content Include="Images\LargeTile.scale-125.png" />
|
<Content Include="Images\LargeTile.scale-125.png" />
|
||||||
<Content Include="Images\LargeTile.scale-150.png" />
|
<Content Include="Images\LargeTile.scale-150.png" />
|
||||||
<Content Include="Images\LargeTile.scale-200.png" />
|
<Content Include="Images\LargeTile.scale-200.png" />
|
||||||
<Content Include="Images\LargeTile.scale-400.png" />
|
<Content Include="Images\LargeTile.scale-400.png" />
|
||||||
<Content Include="Images\SmallTile.scale-100.png" />
|
<Content Include="Images\SmallTile.scale-100.png" />
|
||||||
<Content Include="Images\SmallTile.scale-125.png" />
|
<Content Include="Images\SmallTile.scale-125.png" />
|
||||||
<Content Include="Images\SmallTile.scale-150.png" />
|
<Content Include="Images\SmallTile.scale-150.png" />
|
||||||
<Content Include="Images\SmallTile.scale-200.png" />
|
<Content Include="Images\SmallTile.scale-200.png" />
|
||||||
<Content Include="Images\SmallTile.scale-400.png" />
|
<Content Include="Images\SmallTile.scale-400.png" />
|
||||||
<Content Include="Images\SplashScreen.scale-100.png" />
|
<Content Include="Images\SplashScreen.scale-100.png" />
|
||||||
<Content Include="Images\SplashScreen.scale-125.png" />
|
<Content Include="Images\SplashScreen.scale-125.png" />
|
||||||
<Content Include="Images\SplashScreen.scale-150.png" />
|
<Content Include="Images\SplashScreen.scale-150.png" />
|
||||||
<Content Include="Images\SplashScreen.scale-200.png" />
|
<Content Include="Images\SplashScreen.scale-200.png" />
|
||||||
<Content Include="Images\LockScreenLogo.scale-200.png" />
|
<Content Include="Images\LockScreenLogo.scale-200.png" />
|
||||||
<Content Include="Images\SplashScreen.scale-400.png" />
|
<Content Include="Images\SplashScreen.scale-400.png" />
|
||||||
<Content Include="Images\Square150x150Logo.scale-100.png" />
|
<Content Include="Images\Square150x150Logo.scale-100.png" />
|
||||||
<Content Include="Images\Square150x150Logo.scale-125.png" />
|
<Content Include="Images\Square150x150Logo.scale-125.png" />
|
||||||
<Content Include="Images\Square150x150Logo.scale-150.png" />
|
<Content Include="Images\Square150x150Logo.scale-150.png" />
|
||||||
<Content Include="Images\Square150x150Logo.scale-200.png" />
|
<Content Include="Images\Square150x150Logo.scale-200.png" />
|
||||||
<Content Include="Images\Square150x150Logo.scale-400.png" />
|
<Content Include="Images\Square150x150Logo.scale-400.png" />
|
||||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-16.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-24.png" />
|
||||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-256.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-32.png" />
|
||||||
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-48.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-16.png" />
|
||||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-256.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-32.png" />
|
||||||
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||||
<Content Include="Images\Square44x44Logo.scale-100.png" />
|
<Content Include="Images\Square44x44Logo.scale-100.png" />
|
||||||
<Content Include="Images\Square44x44Logo.scale-125.png" />
|
<Content Include="Images\Square44x44Logo.scale-125.png" />
|
||||||
<Content Include="Images\Square44x44Logo.scale-150.png" />
|
<Content Include="Images\Square44x44Logo.scale-150.png" />
|
||||||
<Content Include="Images\Square44x44Logo.scale-200.png" />
|
<Content Include="Images\Square44x44Logo.scale-200.png" />
|
||||||
<Content Include="Images\Square44x44Logo.scale-400.png" />
|
<Content Include="Images\Square44x44Logo.scale-400.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
|
||||||
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
|
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
|
||||||
<Content Include="Images\StoreLogo.scale-100.png" />
|
<Content Include="Images\StoreLogo.scale-100.png" />
|
||||||
<Content Include="Images\StoreLogo.scale-125.png" />
|
<Content Include="Images\StoreLogo.scale-125.png" />
|
||||||
<Content Include="Images\StoreLogo.scale-150.png" />
|
<Content Include="Images\StoreLogo.scale-150.png" />
|
||||||
<Content Include="Images\StoreLogo.scale-200.png" />
|
<Content Include="Images\StoreLogo.scale-200.png" />
|
||||||
<Content Include="Images\StoreLogo.scale-400.png" />
|
<Content Include="Images\StoreLogo.scale-400.png" />
|
||||||
<Content Include="Images\Wide310x150Logo.scale-100.png" />
|
<Content Include="Images\Wide310x150Logo.scale-100.png" />
|
||||||
<Content Include="Images\Wide310x150Logo.scale-125.png" />
|
<Content Include="Images\Wide310x150Logo.scale-125.png" />
|
||||||
<Content Include="Images\Wide310x150Logo.scale-150.png" />
|
<Content Include="Images\Wide310x150Logo.scale-150.png" />
|
||||||
<Content Include="Images\Wide310x150Logo.scale-200.png" />
|
<Content Include="Images\Wide310x150Logo.scale-200.png" />
|
||||||
<Content Include="Images\Wide310x150Logo.scale-400.png" />
|
<Content Include="Images\Wide310x150Logo.scale-400.png" />
|
||||||
<None Include="Package.StoreAssociation.xml" />
|
<None Include="Package.StoreAssociation.xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
|
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
|
||||||
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
|
<EnableMsixTooling>true</EnableMsixTooling>
|
||||||
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
|
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
|
||||||
</ProjectReference>
|
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
|
||||||
</ItemGroup>
|
</ProjectReference>
|
||||||
<ItemGroup>
|
</ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250513003" />
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||||
</ItemGroup>
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||||
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
</ItemGroup>
|
||||||
|
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
|
||||||
</Project>
|
</Project>
|
||||||
@@ -12,13 +12,13 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="37412.BetterLyrics"
|
Name="37412.BetterLyrics"
|
||||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||||
Version="1.0.32.0" />
|
Version="1.0.76.0" />
|
||||||
|
|
||||||
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>BetterLyrics</DisplayName>
|
<DisplayName>BetterLyrics</DisplayName>
|
||||||
<PublisherDisplayName>founchoo</PublisherDisplayName>
|
<PublisherDisplayName>Zhe Fang</PublisherDisplayName>
|
||||||
<Logo>Images\StoreLogo.png</Logo>
|
<Logo>Images\StoreLogo.png</Logo>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<!-- Merged dictionaries here -->
|
||||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.SettingsControls/SettingsExpander/SettingsExpander.xaml" />
|
||||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.Segmented/Segmented/Segmented.xaml" />
|
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.Segmented/Segmented/Segmented.xaml" />
|
||||||
<!-- Other merged dictionaries here -->
|
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
<!-- Theme -->
|
<!-- Theme -->
|
||||||
@@ -51,6 +51,15 @@
|
|||||||
<converter:TranslationSearchProviderToDisplayNameConverter x:Key="TranslationSearchProviderToDisplayNameConverter" />
|
<converter:TranslationSearchProviderToDisplayNameConverter x:Key="TranslationSearchProviderToDisplayNameConverter" />
|
||||||
<converter:AlbumArtSearchProviderToDisplayNameConverter x:Key="AlbumArtSearchProviderToDisplayNameConverter" />
|
<converter:AlbumArtSearchProviderToDisplayNameConverter x:Key="AlbumArtSearchProviderToDisplayNameConverter" />
|
||||||
<converter:SecondsToFormattedTimeConverter x:Key="SecondsToFormattedTimeConverter" />
|
<converter:SecondsToFormattedTimeConverter x:Key="SecondsToFormattedTimeConverter" />
|
||||||
|
<converter:MillisecondsToFormattedTimeConverter x:Key="MillisecondsToFormattedTimeConverter" />
|
||||||
|
<converter:MediaSourceProviderToLogoUriConverter x:Key="MediaSourceProviderToLogoUriConverter" />
|
||||||
|
<converter:MediaSourceProviderToDisplayedNameConverter x:Key="MediaSourceProviderToDisplayedNameConverter" />
|
||||||
|
<converter:FPSToTimeSpanConverter x:Key="FPSToTimeSpanConverter" />
|
||||||
|
<converter:ShortcutToStringConverter x:Key="ShortcutToStringConverter" />
|
||||||
|
<converter:BoolNegationToVisibilityConverter x:Key="BoolNegationToVisibilityConverter" />
|
||||||
|
<converter:BoolToOpacityConverter x:Key="BoolToOpacityConverter" />
|
||||||
|
<converter:RectToMarginConverter x:Key="RectToMarginConverter" />
|
||||||
|
|
||||||
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||||
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
<converters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||||
<converters:ColorToDisplayNameConverter x:Key="ColorToDisplayNameConverter" />
|
<converters:ColorToDisplayNameConverter x:Key="ColorToDisplayNameConverter" />
|
||||||
@@ -81,7 +90,10 @@
|
|||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style x:Key="TitleBarToggleButtonStyle" TargetType="ToggleButton">
|
<Style
|
||||||
|
x:Key="TitleBarToggleButtonStyle"
|
||||||
|
BasedOn="{StaticResource ToggleButtonRevealStyle}"
|
||||||
|
TargetType="ToggleButton">
|
||||||
<Setter Property="CornerRadius" Value="4" />
|
<Setter Property="CornerRadius" Value="4" />
|
||||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
@@ -292,6 +304,29 @@
|
|||||||
<Setter Property="Padding" Value="0" />
|
<Setter Property="Padding" Value="0" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style
|
||||||
|
x:Key="SettingsScrollViewerStyle"
|
||||||
|
BasedOn="{StaticResource DefaultScrollViewerStyle}"
|
||||||
|
TargetType="ScrollViewer">
|
||||||
|
<Setter Property="Padding" Value="36,0" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="SettingsGridStyle" TargetType="Grid">
|
||||||
|
<Setter Property="Padding" Value="0,0,0,36" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style
|
||||||
|
x:Key="FlyoutPageStyle"
|
||||||
|
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||||
|
TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Opacity" Value="0.9" />
|
||||||
|
<Setter Property="MinWidth" Value="850" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
|
||||||
|
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
|
||||||
|
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
<StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" />
|
<StaticResource x:Key="ToggleButtonBackgroundChecked" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" />
|
<StaticResource x:Key="ToggleButtonBackgroundCheckedPointerOver" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
<StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" />
|
<StaticResource x:Key="ToggleButtonBackgroundCheckedPressed" ResourceKey="TextFillColorPrimaryBrush" />
|
||||||
@@ -302,4 +337,5 @@
|
|||||||
<FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
<FontFamily x:Key="IconFontFamily">ms-appx:///Assets/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Application.Resources>
|
</Application.Resources>
|
||||||
|
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -3,7 +3,16 @@
|
|||||||
using BetterLyrics.WinUI3.Enums;
|
using BetterLyrics.WinUI3.Enums;
|
||||||
using BetterLyrics.WinUI3.Helper;
|
using BetterLyrics.WinUI3.Helper;
|
||||||
using BetterLyrics.WinUI3.Services;
|
using BetterLyrics.WinUI3.Services;
|
||||||
|
using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
|
||||||
|
using BetterLyrics.WinUI3.Services.LastFMService;
|
||||||
|
using BetterLyrics.WinUI3.Services.LibWatcherService;
|
||||||
|
using BetterLyrics.WinUI3.Services.LiveStatesService;
|
||||||
|
using BetterLyrics.WinUI3.Services.LyricsSearchService;
|
||||||
|
using BetterLyrics.WinUI3.Services.MediaSessionsService;
|
||||||
|
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||||
|
using BetterLyrics.WinUI3.Services.TranslateService;
|
||||||
using BetterLyrics.WinUI3.ViewModels;
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel;
|
||||||
using BetterLyrics.WinUI3.Views;
|
using BetterLyrics.WinUI3.Views;
|
||||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -64,7 +73,7 @@ namespace BetterLyrics.WinUI3
|
|||||||
private void EnsureSingleInstance()
|
private void EnsureSingleInstance()
|
||||||
{
|
{
|
||||||
bool createdNew;
|
bool createdNew;
|
||||||
_instanceMutex = new Mutex(true, MetadataHelper.AppName, out createdNew);
|
_instanceMutex = new Mutex(true, Constants.App.AppName, out createdNew);
|
||||||
|
|
||||||
if (!createdNew)
|
if (!createdNew)
|
||||||
{
|
{
|
||||||
@@ -76,13 +85,6 @@ namespace BetterLyrics.WinUI3
|
|||||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
WindowHelper.OpenWindow<LyricsWindow>();
|
WindowHelper.OpenWindow<LyricsWindow>();
|
||||||
|
|
||||||
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
|
||||||
if (lyricsWindow != null)
|
|
||||||
{
|
|
||||||
lyricsWindow.ViewModel.InitLockHotKey();
|
|
||||||
lyricsWindow.AutoSelectLyricsMode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ConfigureServices()
|
private static void ConfigureServices()
|
||||||
@@ -101,13 +103,22 @@ namespace BetterLyrics.WinUI3
|
|||||||
loggingBuilder.AddSerilog();
|
loggingBuilder.AddSerilog();
|
||||||
})
|
})
|
||||||
// Services
|
// Services
|
||||||
|
.AddSingleton<ILiveStatesService, LiveStatesService>()
|
||||||
.AddSingleton<ISettingsService, SettingsService>()
|
.AddSingleton<ISettingsService, SettingsService>()
|
||||||
.AddSingleton<IPlaybackService, PlaybackService>()
|
.AddSingleton<IMediaSessionsService, MediaSessionsService>()
|
||||||
.AddSingleton<IAlbumArtSearchService, AlbumArtSearchService>()
|
.AddSingleton<IAlbumArtSearchService, AlbumArtSearchService>()
|
||||||
.AddSingleton<ILyricsSearchService, LyricsSearchService>()
|
.AddSingleton<ILyricsSearchService, LyricsSearchService>()
|
||||||
.AddSingleton<ILibWatcherService, LibWatcherService>()
|
.AddSingleton<ILibWatcherService, LibWatcherService>()
|
||||||
.AddSingleton<ITranslateService, TranslateService>()
|
.AddSingleton<ITranslateService, TranslateService>()
|
||||||
|
.AddSingleton<ILastFMService, LastFMService>()
|
||||||
// ViewModels
|
// ViewModels
|
||||||
|
.AddSingleton<AppSettingsControlViewModel>()
|
||||||
|
.AddSingleton<LyricsBackgroundSettingsControlViewModel>()
|
||||||
|
.AddSingleton<AlbumArtLayoutSettingsControlViewModel>()
|
||||||
|
.AddSingleton<PlaybackSettingsControlViewModel>()
|
||||||
|
.AddSingleton<MediaSettingsControlViewModel>()
|
||||||
|
.AddSingleton<AllLyricsSettingsControlViewModel>()
|
||||||
|
.AddSingleton<LyricsSearchControlViewModel>()
|
||||||
.AddSingleton<LyricsWindowViewModel>()
|
.AddSingleton<LyricsWindowViewModel>()
|
||||||
.AddSingleton<SettingsWindowViewModel>()
|
.AddSingleton<SettingsWindowViewModel>()
|
||||||
.AddSingleton<SystemTrayViewModel>()
|
.AddSingleton<SystemTrayViewModel>()
|
||||||
|
|||||||
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/AIMP.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Alipay.jpg
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/AppleMusic.png
Normal file
|
After Width: | Height: | Size: 836 B |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Chrome.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Cover.jpg
Normal file
|
After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 14 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Edge.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Empty.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/KugouMusic.png
Normal file
|
After Width: | Height: | Size: 304 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/LXMusic.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/LastFM.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Leaf.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 260 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/MusicBee.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Page.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/PotPlayer.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 166 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/QQMusic.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Question.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Spotify.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 192 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/WeChatReward.png
Normal file
|
After Width: | Height: | Size: 209 KiB |
328503
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Wiki82.profile.xml
Normal file
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/foobar2000.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/iTunes.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
@@ -20,9 +20,19 @@
|
|||||||
<PRIResource Remove="ViewModels\Lyrics\**" />
|
<PRIResource Remove="ViewModels\Lyrics\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Assets\Core14.profile.xml" />
|
|
||||||
<None Remove="Assets\Segoe Fluent Icons.ttf" />
|
<None Remove="Assets\Segoe Fluent Icons.ttf" />
|
||||||
|
<None Remove="Assets\Wiki82.profile.xml" />
|
||||||
|
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\AllLyricsSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\AppSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\ExtendedSlider.xaml" />
|
||||||
|
<None Remove="Controls\LyricsSearchControl.xaml" />
|
||||||
|
<None Remove="Controls\LyricsSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\MediaSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\PlaybackSettingsControl.xaml" />
|
||||||
|
<None Remove="Controls\ShortcutTextBox.xaml" />
|
||||||
<None Remove="Controls\SystemTray.xaml" />
|
<None Remove="Controls\SystemTray.xaml" />
|
||||||
|
<None Remove="Views\LyricsSearchWindow.xaml" />
|
||||||
<None Remove="Views\MusicGalleryPage.xaml" />
|
<None Remove="Views\MusicGalleryPage.xaml" />
|
||||||
<None Remove="Views\MusicGalleryWindow.xaml" />
|
<None Remove="Views\MusicGalleryWindow.xaml" />
|
||||||
<None Remove="Views\SettingsWindow.xaml" />
|
<None Remove="Views\SettingsWindow.xaml" />
|
||||||
@@ -35,6 +45,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="3v.EvtSource" Version="2.0.0" />
|
<PackageReference Include="3v.EvtSource" Version="2.0.0" />
|
||||||
|
<PackageReference Include="ColorThief.ImageSharp" Version="1.0.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.MarqueeText" Version="0.1.230830" />
|
<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.OpacityMaskView" Version="0.1.250703-build.2173" />
|
||||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
|
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
|
||||||
@@ -49,25 +60,27 @@
|
|||||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||||
|
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
|
||||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
|
<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.0" />
|
||||||
|
<PackageReference Include="Hqub.Last.fm" Version="2.5.1" />
|
||||||
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
|
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.7" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.7" />
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
|
||||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||||
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
|
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
|
||||||
<PackageReference Include="NTextCat" Version="0.3.65" />
|
<PackageReference Include="NTextCat" Version="0.3.65" />
|
||||||
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
|
<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="Serilog.Sinks.File" Version="7.0.0" />
|
||||||
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
|
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
|
||||||
<PackageReference Include="System.Drawing.Common" Version="9.0.7" />
|
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.7" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" />
|
||||||
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
<PackageReference Include="TagLibSharp" Version="2.3.0" />
|
||||||
<PackageReference Include="TinyPinyin.Net" Version="1.0.2" />
|
|
||||||
<PackageReference Include="Ude.NetStandard" Version="1.2.0" />
|
<PackageReference Include="Ude.NetStandard" Version="1.2.0" />
|
||||||
<PackageReference Include="Vanara.PInvoke.CoreAudio" Version="4.1.6" />
|
<PackageReference Include="Vanara.PInvoke.CoreAudio" Version="4.1.6" />
|
||||||
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.1.6" />
|
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.1.6" />
|
||||||
@@ -92,9 +105,136 @@
|
|||||||
<TrimmerRootAssembly Include="TagLibSharp" />
|
<TrimmerRootAssembly Include="TagLibSharp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Update="Assets\AIMP.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\AppleMusic.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Chrome.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Edge.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Empty.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\EmptyBox.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\EmptyState.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\foobar2000.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\iTunes.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\KugouMusic.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\LastFM.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Leaf.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Logo.ico">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Logo.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\LXMusic.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\MediaPlayerWindows11.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\MusicBee.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\NetEaseCloudMusic.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Page.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\PotPlayer.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\QQMusic.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Question.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Update="Assets\Segoe Fluent Icons.ttf">
|
<Content Update="Assets\Segoe Fluent Icons.ttf">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Update="Assets\Spotify.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="Assets\Wiki82.profile.xml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Views\LyricsSearchWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\LyricsSearchControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\ShortcutTextBox.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\ExtendedSlider.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\AllLyricsSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\LyricsSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\MediaSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\PlaybackSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\AlbumArtLayoutSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\LyricsBackgroundSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Controls\AppSettingsControl.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Update="Views\MusicGalleryWindow.xaml">
|
<Page Update="Views\MusicGalleryWindow.xaml">
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class AmllTTmlDB
|
||||||
|
{
|
||||||
|
private const string BaseUrl = "https://raw.githubusercontent.com/Steve-xmh/amll-ttml-db/refs/heads/main/";
|
||||||
|
public const string QueryPrefix = $"{BaseUrl}raw-lyrics/";
|
||||||
|
public const string Index = $"{BaseUrl}metadata/raw-lyrics-index.jsonl";
|
||||||
|
}
|
||||||
|
}
|
||||||
16
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/App.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class App
|
||||||
|
{
|
||||||
|
public const string AppAuthor = "Zhe Fang";
|
||||||
|
public const string AppName = "BetterLyrics";
|
||||||
|
|
||||||
|
public const string AutoStartupTaskId = "AutoStartup";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class AppleMusic
|
||||||
|
{
|
||||||
|
public const string MediaUserTokenKey = "AppleMusicMediaUserToken";
|
||||||
|
}
|
||||||
|
}
|
||||||
13
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/LXMusic.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class LXMusic
|
||||||
|
{
|
||||||
|
public const string QuerySuffix = "/subscribe-player-status?filter=progress,duration,picUrl";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class LastFM
|
||||||
|
{
|
||||||
|
public const string ApiKey = "Your api key here";
|
||||||
|
public const string SharedSecret = "Your shared secret here";
|
||||||
|
public const string UnAuthUrl = "https://www.last.fm/settings/applications";
|
||||||
|
public const string SessionKeyCredentialKey = "LastFMSessionKey";
|
||||||
|
}
|
||||||
|
}
|
||||||
17
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Link.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
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 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";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class PlayerID
|
||||||
|
{
|
||||||
|
public const string LXMusic = "cn.toside.music.desktop";
|
||||||
|
public const string MediaPlayerWindows11 = "Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic";
|
||||||
|
public const string AIMP = "AIMP.exe";
|
||||||
|
public const string Foobar2000 = "foobar2000.exe";
|
||||||
|
public const string MusicBee = "MusicBee.exe";
|
||||||
|
public const string PotPlayer = "PotPlayerMini64.exe";
|
||||||
|
public const string Spotify = "Spotify.exe";
|
||||||
|
public const string AppleMusic = "AppleInc.AppleMusicWin_nzyj5cx40ttqa!App";
|
||||||
|
public const string AppleMusicAlternative = "AppleMusic.exe";
|
||||||
|
public const string NetEaseCloudMusic = "cloudmusic.exe";
|
||||||
|
public const string KugouMusic = "kugou";
|
||||||
|
public const string QQMusic = "QQMusic.exe";
|
||||||
|
public const string iTunes = "49586DaveAntoine.MediaControllerforiTunes_9bzempp7dntjg!App";
|
||||||
|
public const string Chrome = "Chrome";
|
||||||
|
public const string Edge = "MSEdge";
|
||||||
|
public const string BetterLyrics = "37412.BetterLyrics_rd1g0rsrrtxw8!App";
|
||||||
|
public const string BetterLyricsDebug = "37412.BetterLyrics_c8mj3v9sysxb4!App";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public class PlayerName
|
||||||
|
{
|
||||||
|
public const string LXMusic = "LX Music";
|
||||||
|
public const string MediaPlayerWindows11 = "Media Player";
|
||||||
|
public const string AIMP = "AIMP";
|
||||||
|
public const string Foobar2000 = "foobar2000";
|
||||||
|
public const string MusicBee = "MusicBee";
|
||||||
|
public const string PotPlayer = "PotPlayer";
|
||||||
|
public const string Spotify = "Spotify";
|
||||||
|
public const string AppleMusic = "Apple Music";
|
||||||
|
public const string AppleMusicAlternative = "Apple Music";
|
||||||
|
public const string NetEaseCloudMusic = "网易云音乐";
|
||||||
|
public const string KugouMusic = "酷狗音乐";
|
||||||
|
public const string QQMusic = "QQ 音乐";
|
||||||
|
public const string iTunes = "iTunes";
|
||||||
|
public const string Chrome = "Google Chrome";
|
||||||
|
public const string Edge = "Microsoft Edge";
|
||||||
|
public const string BetterLyrics = "BetterLyrics";
|
||||||
|
public const string BetterLyricsDebug = "BetterLyrics (Debug)";
|
||||||
|
}
|
||||||
|
}
|
||||||
13
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Time.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class Time
|
||||||
|
{
|
||||||
|
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(300);
|
||||||
|
}
|
||||||
|
}
|
||||||
13
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/iTunes.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Constants
|
||||||
|
{
|
||||||
|
public static class iTunes
|
||||||
|
{
|
||||||
|
public const string QueryPrefix = "https://itunes.apple.com/search?";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.AlbumArtLayoutSettingsControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPageAlbumArt" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="12"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.CoverImageRadius, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAlbumShadowAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="12"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="64"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.CoverImageShadowAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPageSongInfo" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageSongInfoAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.SongInfoAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageSongInfoLeft" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageSongInfoCenter" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageSongInfoRight" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsFontSize" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="18"
|
||||||
|
Frequency="2"
|
||||||
|
Maximum="48"
|
||||||
|
Minimum="12"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.AlbumArtLayoutSettings.SongInfoFontSize, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class AlbumArtLayoutSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public AlbumArtLayoutSettingsControlViewModel ViewModel => (AlbumArtLayoutSettingsControlViewModel)DataContext;
|
||||||
|
public AlbumArtLayoutSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<AlbumArtLayoutSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.AllLyricsSettingsControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<controls:SwitchPresenter Margin="0,72,0,0" Value="{Binding SelectedItem.Tag, ElementName=LyricsSettingsSegmentedControl}">
|
||||||
|
<controls:Case Value="Standard">
|
||||||
|
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.StandardLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.StandardLyricsStyleSettings, Mode=OneWay}" />
|
||||||
|
</controls:Case>
|
||||||
|
<controls:Case Value="Desktop">
|
||||||
|
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsStyleSettings, Mode=OneWay}" />
|
||||||
|
</controls:Case>
|
||||||
|
<controls:Case Value="Dock">
|
||||||
|
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DockLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DockLyricsStyleSettings, Mode=OneWay}" />
|
||||||
|
</controls:Case>
|
||||||
|
<controls:Case Value="PictureInPicture">
|
||||||
|
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsStyleSettings, Mode=OneWay}" />
|
||||||
|
</controls:Case>
|
||||||
|
</controls:SwitchPresenter>
|
||||||
|
<controls:Segmented
|
||||||
|
x:Name="LyricsSettingsSegmentedControl"
|
||||||
|
Margin="36,36,36,0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
SelectedIndex="{x:Bind ViewModel.SelectedTabIndex, Mode=OneWay}">
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlStandard" Tag="Standard" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDock" Tag="Dock" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDesktop" Tag="Desktop" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlPictureInPicture" Tag="PictureInPicture" />
|
||||||
|
</controls:Segmented>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class AllLyricsSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public AllLyricsSettingsControlViewModel ViewModel => (AllLyricsSettingsControlViewModel)DataContext;
|
||||||
|
public AllLyricsSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<AllLyricsSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,385 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.AppSettingsControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<controls:SwitchPresenter Margin="0,72,0,0" Value="{Binding SelectedItem.Tag, ElementName=SegmentedControl}">
|
||||||
|
|
||||||
|
<controls:Case Value="General">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- App appearance -->
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLanguage"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.Language, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageSystemLanguage" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEN" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageSC" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageTC" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageJA" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageKO" />
|
||||||
|
</ComboBox>
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard>
|
||||||
|
<Button x:Uid="SettingsPageRestart" Command="{x:Bind ViewModel.RestartAppCommand}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- App behavior -->
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="AutoStartupToggleSwitch"
|
||||||
|
Loaded="AutoStartupToggleSwitch_Loaded"
|
||||||
|
Unloaded="AutoStartupToggleSwitch_Unloaded" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAutoStartWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.AutoStartWindowType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageAutoStartInAppLyrics" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageAutoStartDockLyrics" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageAutoStartDesktopLyrics" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageAutoStartPIPLyrics" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Name="LyricsWindowManagerExpander"
|
||||||
|
x:Uid="SettingsPageLyricsWindowManager"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True" />
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
Margin="0,-20,0,0"
|
||||||
|
Padding="60,16"
|
||||||
|
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||||
|
CornerRadius="4"
|
||||||
|
Visibility="{Binding ElementName=LyricsWindowManagerExpander, Path=IsExpanded, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<StackPanel Spacing="16">
|
||||||
|
<TextBlock x:Uid="SettingsPageCurrentLyricsWindowStatus" />
|
||||||
|
<StackPanel HorizontalAlignment="Left" Spacing="4">
|
||||||
|
<Grid
|
||||||
|
Width="{x:Bind ViewModel.LiveStates.DemoLyricsWindowMonitorBounds.Width, Mode=OneWay}"
|
||||||
|
Height="{x:Bind ViewModel.LiveStates.DemoLyricsWindowMonitorBounds.Height, Mode=OneWay}"
|
||||||
|
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}">
|
||||||
|
<Grid
|
||||||
|
Width="{x:Bind ViewModel.LiveStates.DemoLyricsWindowBounds.Width, Mode=OneWay}"
|
||||||
|
Height="{x:Bind ViewModel.LiveStates.DemoLyricsWindowBounds.Height, Mode=OneWay}"
|
||||||
|
Margin="{x:Bind ViewModel.LiveStates.DemoLyricsWindowBounds, Converter={StaticResource RectToMarginConverter}, Mode=OneWay}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Background="{ThemeResource AccentFillColorDefaultBrush}"
|
||||||
|
CornerRadius="4" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="ExtraBlack"
|
||||||
|
Opacity="0.7"
|
||||||
|
Text="{x:Bind ViewModel.LiveStates.LyricsWindowMonitorName, Mode=OneWay}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
<Grid>
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageRecord"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Command="{x:Bind ViewModel.RecordCurrentWindowBoundsCommand}"
|
||||||
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,-3,0,0"
|
||||||
|
Padding="60,16"
|
||||||
|
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||||
|
CornerRadius="4"
|
||||||
|
Spacing="16"
|
||||||
|
Visibility="{Binding ElementName=LyricsWindowManagerExpander, Path=IsExpanded, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<TextBlock x:Uid="SettingsPageRecordedWindowStatus" />
|
||||||
|
<GridView
|
||||||
|
Margin="-2"
|
||||||
|
CornerRadius="4"
|
||||||
|
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
|
||||||
|
SelectionMode="None">
|
||||||
|
<GridView.ItemContainerStyle>
|
||||||
|
<Style BasedOn="{StaticResource DefaultGridViewItemStyle}" TargetType="GridViewItem">
|
||||||
|
<Setter Property="Margin" Value="5,5,5,5" />
|
||||||
|
</Style>
|
||||||
|
</GridView.ItemContainerStyle>
|
||||||
|
<GridView.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<ItemsWrapGrid Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</GridView.ItemsPanel>
|
||||||
|
<GridView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid>
|
||||||
|
<StackPanel Spacing="4">
|
||||||
|
<Grid
|
||||||
|
Width="{Binding DemoMonitorBounds.Width}"
|
||||||
|
Height="{Binding DemoMonitorBounds.Height}"
|
||||||
|
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}">
|
||||||
|
<Grid
|
||||||
|
Width="{Binding DemoWindowBounds.Width}"
|
||||||
|
Height="{Binding DemoWindowBounds.Height}"
|
||||||
|
Margin="{Binding DemoWindowBounds, Converter={StaticResource RectToMarginConverter}}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Background="{ThemeResource AccentFillColorDefaultBrush}"
|
||||||
|
CornerRadius="4" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="ExtraBlack"
|
||||||
|
Opacity="0.7"
|
||||||
|
Text="{Binding MonitorDeviceName}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
<Grid ColumnSpacing="4">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageDelete"
|
||||||
|
Grid.Column="0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Click="DeleteWindowBoundsRecordButton_Click" />
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageApply"
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Click="ApplyWindowBoundsRecordButton_Click"
|
||||||
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</GridView.ItemTemplate>
|
||||||
|
</GridView>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageIgnoreFullscreenWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IgnoreFullscreenWindow, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.HideWindowWhenNotPlaying, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageGlobalDrag" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IsDragEverywhereEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<!-- Playback shortcut -->
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
</controls:Case>
|
||||||
|
|
||||||
|
<controls:Case Value="Standard">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- Standard mode -->
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.StandardModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAOT" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.StandardModeSettings.IsAlwaysOnTop, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</controls:Case>
|
||||||
|
|
||||||
|
<controls:Case Value="Desktop">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- Desktop mode -->
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DesktopModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAOT" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.DesktopModeSettings.IsAlwaysOnTop, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAutoLock" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.DesktopModeSettings.AutoLockOnDesktopMode, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLockHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.LockShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</controls:Case>
|
||||||
|
|
||||||
|
<controls:Case Value="Dock">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- Dock mode -->
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DockModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.AppSettings.DockModeSettings.DockMonitorDeviceName, Mode=TwoWay}" />
|
||||||
|
<Button
|
||||||
|
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDockWindowHeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="64"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="200"
|
||||||
|
Minimum="64"
|
||||||
|
Unit="px"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.DockModeSettings.DockWindowHeight, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDockPlacement" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</controls:Case>
|
||||||
|
|
||||||
|
<controls:Case Value="PictureInPicture">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- Picture in picture mode -->
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.PictureInPictureModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
|
||||||
|
<ComboBoxItem x:Uid="MainPageSplitView" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.PictureInPictureModeSettings.ToggleShortcut, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</controls:Case>
|
||||||
|
|
||||||
|
</controls:SwitchPresenter>
|
||||||
|
<controls:Segmented
|
||||||
|
x:Name="SegmentedControl"
|
||||||
|
Margin="36,36,36,0"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
SelectedIndex="0">
|
||||||
|
<controls:SegmentedItem x:Uid="AppSettingsControlGeneral" Tag="General" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlStandard" Tag="Standard" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDock" Tag="Dock" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDesktop" Tag="Desktop" />
|
||||||
|
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlPictureInPicture" Tag="PictureInPicture" />
|
||||||
|
</controls:Segmented>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
using BetterLyrics.WinUI3.Helper;
|
||||||
|
using BetterLyrics.WinUI3.Models;
|
||||||
|
using BetterLyrics.WinUI3.Models.Settings;
|
||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using BetterLyrics.WinUI3.Views;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class AppSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public AppSettingsControlViewModel ViewModel => (AppSettingsControlViewModel)DataContext;
|
||||||
|
|
||||||
|
public AppSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<AppSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void AutoStartupToggleSwitch_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
AutoStartupToggleSwitch.IsOn = await ViewModel.DetectIsAutoStartupEnabledAsync();
|
||||||
|
AutoStartupToggleSwitch.Toggled += AutoStartupToggleSwitch_Toggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AutoStartupToggleSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ViewModel.ToggleAutoStartupAsync(AutoStartupToggleSwitch.IsOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AutoStartupToggleSwitch_Unloaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
AutoStartupToggleSwitch.Toggled -= AutoStartupToggleSwitch_Toggled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteWindowBoundsRecordButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button button)
|
||||||
|
{
|
||||||
|
var data = button.DataContext as WindowBoundsRecord;
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
ViewModel.AppSettings.WindowBoundsRecords.Remove(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyWindowBoundsRecordButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Button button)
|
||||||
|
{
|
||||||
|
var data = button.DataContext as WindowBoundsRecord;
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||||
|
if (lyricsWindow != null)
|
||||||
|
{
|
||||||
|
lyricsWindow.AppWindow.MoveAndResize(data.WindowBounds.ToRectInt32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.ExtendedSlider"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="6,0,2,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Bind Value, Mode=OneWay}" />
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,14,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Bind Unit, Mode=OneWay}" />
|
||||||
|
<Slider
|
||||||
|
Maximum="{x:Bind Maximum, Mode=OneWay}"
|
||||||
|
Minimum="{x:Bind Minimum, Mode=OneWay}"
|
||||||
|
SnapsTo="Ticks"
|
||||||
|
StepFrequency="{x:Bind Frequency, Mode=OneWay}"
|
||||||
|
TickFrequency="{x:Bind Frequency, Mode=OneWay}"
|
||||||
|
TickPlacement="Outside"
|
||||||
|
Value="{x:Bind Value, Mode=TwoWay}" />
|
||||||
|
<Button
|
||||||
|
Margin="3,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Click="ResetButton_Click"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}"
|
||||||
|
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
|
||||||
|
<Button
|
||||||
|
x:Name="SubtractButton"
|
||||||
|
Margin="3,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Click="SubtractButton_Click"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
<Button
|
||||||
|
x:Name="AddButton"
|
||||||
|
Margin="3,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Click="AddButton_Click"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
using Microsoft.UI.Input;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class ExtendedSlider : UserControl
|
||||||
|
{
|
||||||
|
public ExtendedSlider()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Subtract()
|
||||||
|
{
|
||||||
|
if (Value - Frequency < Minimum)
|
||||||
|
{
|
||||||
|
Value = Minimum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Value -= Frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Add()
|
||||||
|
{
|
||||||
|
if (Value + Frequency > Maximum)
|
||||||
|
{
|
||||||
|
Value = Maximum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Value += Frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubtractTimer_Tick(object? sender, object e)
|
||||||
|
{
|
||||||
|
Subtract();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddTimer_Tick(object? sender, object e)
|
||||||
|
{
|
||||||
|
Add();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty FrequencyProperty =
|
||||||
|
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||||
|
public static readonly DependencyProperty MinimumProperty =
|
||||||
|
DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||||
|
public static readonly DependencyProperty MaximumProperty =
|
||||||
|
DependencyProperty.Register(nameof(Maximum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||||
|
public static readonly DependencyProperty ValueProperty =
|
||||||
|
DependencyProperty.Register(nameof(Value), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||||
|
public static readonly DependencyProperty DefaultProperty =
|
||||||
|
DependencyProperty.Register(nameof(Default), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
|
||||||
|
public static readonly DependencyProperty ResetButtonVisibilityProperty =
|
||||||
|
DependencyProperty.Register(nameof(ResetButtonVisibility), typeof(Visibility), typeof(ExtendedSlider), new PropertyMetadata(Visibility.Visible));
|
||||||
|
public static readonly DependencyProperty UnitProperty =
|
||||||
|
DependencyProperty.Register(nameof(Unit), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(""));
|
||||||
|
|
||||||
|
public double Frequency
|
||||||
|
{
|
||||||
|
get => (double)GetValue(FrequencyProperty);
|
||||||
|
set => SetValue(FrequencyProperty, value);
|
||||||
|
}
|
||||||
|
public double Minimum
|
||||||
|
{
|
||||||
|
get => (double)GetValue(MinimumProperty);
|
||||||
|
set => SetValue(MinimumProperty, value);
|
||||||
|
}
|
||||||
|
public double Maximum
|
||||||
|
{
|
||||||
|
get => (double)GetValue(MaximumProperty);
|
||||||
|
set => SetValue(MaximumProperty, value);
|
||||||
|
}
|
||||||
|
public double Value
|
||||||
|
{
|
||||||
|
get => (double)GetValue(ValueProperty);
|
||||||
|
set => SetValue(ValueProperty, value);
|
||||||
|
}
|
||||||
|
public double Default
|
||||||
|
{
|
||||||
|
get => (double)GetValue(DefaultProperty);
|
||||||
|
set => SetValue(DefaultProperty, value);
|
||||||
|
}
|
||||||
|
public Visibility ResetButtonVisibility
|
||||||
|
{
|
||||||
|
get => (Visibility)GetValue(ResetButtonVisibilityProperty);
|
||||||
|
set => SetValue(ResetButtonVisibilityProperty, value);
|
||||||
|
}
|
||||||
|
public string Unit
|
||||||
|
{
|
||||||
|
get => (string)GetValue(UnitProperty);
|
||||||
|
set => SetValue(UnitProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Value = Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubtractButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Subtract();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Add();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.LyricsBackgroundSettingsControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageTheme" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox x:Name="ThemeComboBox" SelectedIndex="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.LyricsBackgroundTheme, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageFollowSystem" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLight" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageDark" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsPureColorBgOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<uc:ExtendedSlider
|
||||||
|
Default="100"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.PureColorOverlayOpacity, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<uc:ExtendedSlider
|
||||||
|
Default="100"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlayOpacity, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundSpeed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<uc:ExtendedSlider
|
||||||
|
Default="50"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlaySpeed, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBackgroundBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<uc:ExtendedSlider
|
||||||
|
Default="100"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverOverlayBlurAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageBackgroundAcrylicEffectAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<uc:ExtendedSlider
|
||||||
|
Default="0"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="10"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind ViewModel.AppSettings.LyricsBackgroundSettings.CoverAcrylicEffectAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class LyricsBackgroundSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public LyricsBackgroundSettingsControlViewModel ViewModel => (LyricsBackgroundSettingsControlViewModel)DataContext;
|
||||||
|
|
||||||
|
public LyricsBackgroundSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<LyricsBackgroundSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.LyricsSearchControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Padding="16" RowSpacing="6">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid Grid.Row="0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
<controls:SettingsExpander x:Uid="LyricsSearchControlSongInfoMapping" IsExpanded="True">
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="LyricsSearchControlTitle" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||||
|
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||||
|
<Button
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="LyricsSearchControlArtist" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
|
||||||
|
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
|
||||||
|
<Button
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard>
|
||||||
|
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
|
||||||
|
<Button
|
||||||
|
x:Uid="LyricsSearchControlSearch"
|
||||||
|
Command="{x:Bind ViewModel.SearchCommand}"
|
||||||
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Column="1">
|
||||||
|
<ListView ItemsSource="{x:Bind ViewModel.LyricsSearchResults, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsSearchResult, Mode=TwoWay}">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<ListViewItem IsEnabled="{Binding IsFound}">
|
||||||
|
<Grid Opacity="{Binding IsFound, Converter={StaticResource BoolToOpacityConverter}}">
|
||||||
|
<RelativePanel Padding="0,6">
|
||||||
|
<TextBlock
|
||||||
|
x:Name="SearchedTitle"
|
||||||
|
RelativePanel.AlignLeftWithPanel="True"
|
||||||
|
Text="{Binding Title}"
|
||||||
|
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||||
|
<TextBlock
|
||||||
|
x:Name="SearchedArtists"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
|
RelativePanel.AlignLeftWithPanel="True"
|
||||||
|
RelativePanel.Below="SearchedTitle"
|
||||||
|
Text="{Binding Artist}"
|
||||||
|
Visibility="{Binding IsFound, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||||
|
<TextBlock
|
||||||
|
x:Name="SearchedProvider"
|
||||||
|
RelativePanel.AlignRightWithPanel="True"
|
||||||
|
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||||
|
Text="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||||
|
</RelativePanel>
|
||||||
|
<TextBlock
|
||||||
|
x:Uid="LyricsSearchControlNotFound"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="Not found"
|
||||||
|
Visibility="{Binding IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
|
||||||
|
</Grid>
|
||||||
|
</ListViewItem>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</ListView>
|
||||||
|
<StackPanel
|
||||||
|
Padding="0,36"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Spacing="12">
|
||||||
|
<Image MaxWidth="100" Source="/Assets/Empty.png" />
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsSearchResults.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</StackPanel>
|
||||||
|
<ProgressBar
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
IsIndeterminate="True"
|
||||||
|
ShowError="False"
|
||||||
|
ShowPaused="False"
|
||||||
|
Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Column="2">
|
||||||
|
<ListView ItemsSource="{x:Bind ViewModel.LyricsData.LyricsLines, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsLine, Mode=TwoWay}">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="{x:Null}">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="{x:Null}">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding StartMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
|
||||||
|
<TextBlock
|
||||||
|
Margin="1,0"
|
||||||
|
Foreground="{ThemeResource SystemFillColorNeutralBrush}"
|
||||||
|
Text="-" />
|
||||||
|
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{Binding EndMs, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
|
||||||
|
<TextBlock Margin="6,0" Text="{Binding OriginalText}" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
<StackPanel
|
||||||
|
Padding="0,36"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Spacing="12">
|
||||||
|
<Image MaxWidth="100" Source="/Assets/Page.png" />
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="{x:Null}">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="{x:Null}">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="1">
|
||||||
|
<RelativePanel>
|
||||||
|
<TextBlock
|
||||||
|
x:Uid="LyricsSearchControlHelp"
|
||||||
|
Margin="0,0,24,0"
|
||||||
|
FontSize="12"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
|
||||||
|
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||||
|
RelativePanel.LeftOf="Reset"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Button
|
||||||
|
x:Name="Reset"
|
||||||
|
x:Uid="LyricsSearchControlReset"
|
||||||
|
Margin="0,0,6,0"
|
||||||
|
Command="{x:Bind ViewModel.ResetCommand}"
|
||||||
|
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||||
|
RelativePanel.LeftOf="SaveChanges" />
|
||||||
|
<Button
|
||||||
|
x:Name="SaveChanges"
|
||||||
|
x:Uid="LyricsSearchControlSaveChanges"
|
||||||
|
Command="{x:Bind ViewModel.SaveCommand}"
|
||||||
|
RelativePanel.AlignRightWithPanel="True"
|
||||||
|
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||||
|
Style="{StaticResource AccentButtonStyle}" />
|
||||||
|
</RelativePanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using BetterLyrics.WinUI3.Models;
|
||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Ude.Core;
|
||||||
|
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 LyricsSearchControl : UserControl
|
||||||
|
{
|
||||||
|
public LyricsSearchControlViewModel ViewModel => (LyricsSearchControlViewModel)DataContext;
|
||||||
|
|
||||||
|
public LyricsSearchControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,438 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.LyricsSettingsControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<!-- Lyrics style -->
|
||||||
|
|
||||||
|
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsAlignmentType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsLeft" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsCenter" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRight" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsFontFamily" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox ItemsSource="{x:Bind SystemFontNames, Mode=OneWay}" SelectedItem="{x:Bind LyricsStyleSettings.LyricsFontFamily, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsFontWeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFontWeight, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsThin" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsExtraLight" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsLight" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsSemiLight" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsNormal" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsMedium" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsSemiBold" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsBold" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBold" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsBlack" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsExtraBlack" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="30"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind LyricsStyleSettings.LyricsBgFontOpacity, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsFontStrokeWidth" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="0"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="5"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind LyricsStyleSettings.LyricsFontStrokeWidth, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsStrokeFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<ColorPicker
|
||||||
|
ColorSpectrumShape="Box"
|
||||||
|
IsAlphaEnabled="True"
|
||||||
|
IsAlphaSliderVisible="True"
|
||||||
|
IsAlphaTextInputVisible="True"
|
||||||
|
IsColorChannelTextInputVisible="True"
|
||||||
|
IsColorSliderVisible="True"
|
||||||
|
IsHexInputVisible="True"
|
||||||
|
IsMoreButtonVisible="True"
|
||||||
|
Color="{x:Bind LyricsStyleSettings.LyricsCustomStrokeFontColor, Mode=TwoWay}">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsStrokeFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</ColorPicker>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<ColorPicker
|
||||||
|
ColorSpectrumShape="Box"
|
||||||
|
IsAlphaEnabled="True"
|
||||||
|
IsAlphaSliderVisible="True"
|
||||||
|
IsAlphaTextInputVisible="True"
|
||||||
|
IsColorChannelTextInputVisible="True"
|
||||||
|
IsColorSliderVisible="True"
|
||||||
|
IsHexInputVisible="True"
|
||||||
|
IsMoreButtonVisible="True"
|
||||||
|
Color="{x:Bind LyricsStyleSettings.LyricsCustomBgFontColor, Mode=TwoWay}">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsBgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</ColorPicker>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsFgFontColor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveColored" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorAdaptiveGrayed" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsFontColorCustom" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<ColorPicker
|
||||||
|
ColorSpectrumShape="Box"
|
||||||
|
IsAlphaEnabled="True"
|
||||||
|
IsAlphaSliderVisible="True"
|
||||||
|
IsAlphaTextInputVisible="True"
|
||||||
|
IsColorChannelTextInputVisible="True"
|
||||||
|
IsColorSliderVisible="True"
|
||||||
|
IsHexInputVisible="True"
|
||||||
|
IsMoreButtonVisible="True"
|
||||||
|
Color="{x:Bind LyricsStyleSettings.LyricsCustomFgFontColor, Mode=TwoWay}">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind LyricsStyleSettings.LyricsFgFontColorType, Mode=OneWay, Converter={StaticResource EnumToIntConverter}}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="2">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</ColorPicker>
|
||||||
|
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLyricsFontSize"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageDynamicLyricsFontSize">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard IsEnabled="{x:Bind LyricsStyleSettings.IsDynamicLyricsFontSize, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Frequency="2"
|
||||||
|
Maximum="96"
|
||||||
|
Minimum="12"
|
||||||
|
ResetButtonVisibility="Collapsed"
|
||||||
|
Value="{x:Bind LyricsStyleSettings.LyricsFontSize, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsLineSpacingFactor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
x:Uid="SettingsPageLyricsLineSpacingFactorSlider"
|
||||||
|
Default="0.5"
|
||||||
|
Frequency="0.1"
|
||||||
|
Maximum="2"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="x"
|
||||||
|
Value="{x:Bind LyricsStyleSettings.LyricsLineSpacingFactor, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsTranslationSeparator" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<TextBox AcceptsReturn="True" Text="{x:Bind LyricsStyleSettings.LyricsTranslationSeparator, Mode=TwoWay}" />
|
||||||
|
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=}" Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<!-- Effect -->
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
x:Uid="SettingsPageLyricsEffect"
|
||||||
|
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||||
|
Text="Effect" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsVerticalEdgeOpacity" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
x:Uid="SettingsPageLyricsVerticalEdgeOpacitySlider"
|
||||||
|
Default="0"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Unit="%"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsVerticalEdgeOpacity, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsBlurAmount" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
x:Uid="SettingsPageLyricsBlurAmountExtendedSlider"
|
||||||
|
Default="5"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="10"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsBlurAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsLineFade" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<!-- 译文高亮 -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLyricsTranslationHighlight"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAmount">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="60"
|
||||||
|
Frequency="5"
|
||||||
|
Maximum="100"
|
||||||
|
Minimum="0"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsTranslationHighlightAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- 原文高亮 -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLyricsHighlightScope"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsHighlightScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||||
|
</ComboBox>
|
||||||
|
<controls: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=}"
|
||||||
|
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="8"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="20"
|
||||||
|
Minimum="1"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- 辉光效果 -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLyricsGlowEffect"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsGlowEffectScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="8"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="20"
|
||||||
|
Minimum="1"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsGlowEffectAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- 浮动动画 -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLyricsFloatAnimation"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsFloatAnimationEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=OneWay}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Default="1"
|
||||||
|
Frequency="1"
|
||||||
|
Maximum="4"
|
||||||
|
Minimum="1"
|
||||||
|
Value="{x:Bind LyricsEffectSettings.LyricsFloatAmount, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- 扇形歌词 -->
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageFan" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsFanLyricsEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<!-- 滚动动画 -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageScrollEasing"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsScrollEasingType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeLinear" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeSmoothStep" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutSine" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuad" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCubic" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuart" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutQuint" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutExpo" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutCirc" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBack" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutElastic" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageEasingTypeEaseInOutBounce" />
|
||||||
|
</ComboBox>
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageScrollTopDuration">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
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>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
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 LyricsSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public ObservableCollection<string> SystemFontNames { get; set; } = [.. FontHelper.SystemFontFamilies];
|
||||||
|
|
||||||
|
public LyricsSettingsControl()
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
|
||||||
|
public LyricsEffectSettings LyricsEffectSettings
|
||||||
|
{
|
||||||
|
get => (LyricsEffectSettings)GetValue(LyricsEffectSettingsProperty);
|
||||||
|
set => SetValue(LyricsEffectSettingsProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.MediaSettingsControl"
|
||||||
|
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>
|
||||||
|
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageMusicLib" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=}" />
|
||||||
|
|
||||||
|
<InfoBar
|
||||||
|
x:Uid="SettingsPageRemoveInfo"
|
||||||
|
BorderThickness="0"
|
||||||
|
CornerRadius="0"
|
||||||
|
IsClosable="False"
|
||||||
|
IsOpen="True"
|
||||||
|
Severity="Success">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.LocalMediaFolders.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.LocalMediaFolders.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</InfoBar>
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
ItemContainerStyle="{StaticResource ListViewStretchedItemContainerStyle}"
|
||||||
|
ItemsSource="{x:Bind ViewModel.AppSettings.LocalMediaFolders, Mode=OneWay}"
|
||||||
|
SelectionMode="None">
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<controls:SettingsExpander>
|
||||||
|
<controls:SettingsExpander.Header>
|
||||||
|
<HyperlinkButton
|
||||||
|
Click="LocalFolderHyperlinkButton_Click"
|
||||||
|
Content="{Binding Path, Mode=OneWay}"
|
||||||
|
Tag="{Binding Path, Mode=OneWay}" />
|
||||||
|
</controls:SettingsExpander.Header>
|
||||||
|
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard>
|
||||||
|
<controls:SettingsCard.Header>
|
||||||
|
<HyperlinkButton
|
||||||
|
x:Uid="SettingsPageRemovePath"
|
||||||
|
Click="SettingsPageRemovePathButton_Click"
|
||||||
|
Tag="{Binding}" />
|
||||||
|
</controls:SettingsCard.Header>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageMusicLibRealTimeWatch">
|
||||||
|
<ToggleSwitch IsOn="{Binding IsRealTimeWatchEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageAddFolder" Style="{StaticResource DefaultSettingsExpanderItemStyle}">
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageAddFolderButton"
|
||||||
|
Command="{x:Bind ViewModel.SelectAndAddFolderCommand}"
|
||||||
|
CommandParameter="{Binding ElementName=RootGrid}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using BetterLyrics.WinUI3.Models;
|
||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.System;
|
||||||
|
|
||||||
|
// 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 MediaSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public MediaSettingsControlViewModel ViewModel => (MediaSettingsControlViewModel)DataContext;
|
||||||
|
public MediaSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<MediaSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SettingsPageRemovePathButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ViewModel.RemoveFolderAsync((LocalMediaFolder)(sender as HyperlinkButton)!.Tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void LocalFolderHyperlinkButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is HyperlinkButton button && button.Tag is string uriStr)
|
||||||
|
{
|
||||||
|
if (Uri.TryCreate(uriStr, UriKind.Absolute, out var uri))
|
||||||
|
{
|
||||||
|
await Launcher.LaunchUriAsync(uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,385 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
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:controls="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:local="using:BetterLyrics.WinUI3.Controls"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:models="using:BetterLyrics.WinUI3.Models"
|
||||||
|
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid ColumnSpacing="6">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid Grid.Column="0">
|
||||||
|
<ScrollViewer Margin="0,72,0,0" Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<!-- 时间轴相关配置 -->
|
||||||
|
<controls:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
Frequency="100"
|
||||||
|
Maximum="1000"
|
||||||
|
Minimum="0"
|
||||||
|
ResetButtonVisibility="Collapsed"
|
||||||
|
Unit="ms"
|
||||||
|
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.TimelineSyncThreshold, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
<controls:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
|
||||||
|
<local:ExtendedSlider
|
||||||
|
x:Uid="SettingsPagePositionOffsetReset"
|
||||||
|
Default="0"
|
||||||
|
Frequency="100"
|
||||||
|
Maximum="5000"
|
||||||
|
Minimum="-5000"
|
||||||
|
Unit="ms"
|
||||||
|
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.PositionOffset, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.ResetPositionOffsetOnSongChanged, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
|
||||||
|
<!-- 专辑封面源配置 -->
|
||||||
|
<TextBlock x:Uid="SettingsPageAlbumArtSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
<ListView
|
||||||
|
x:Name="AlbumArtSearchProvidersListView"
|
||||||
|
AllowDrop="True"
|
||||||
|
CanDragItems="True"
|
||||||
|
CanReorderItems="True"
|
||||||
|
DragItemsCompleted="AlbumArtSearchProvidersListView_DragItemsCompleted"
|
||||||
|
ItemContainerStyle="{StaticResource ListViewStretchedItemContainerStyle}"
|
||||||
|
ItemsSource="{x:Bind ViewModel.SelectedMediaSourceProvider.AlbumArtSearchProvidersInfo, Mode=OneWay}"
|
||||||
|
SelectionMode="None">
|
||||||
|
<ListView.OpacityTransition>
|
||||||
|
<ScalarTransition />
|
||||||
|
</ListView.OpacityTransition>
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:AlbumArtSearchProviderInfo">
|
||||||
|
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||||
|
<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon FontFamily="Segoe UI Symbol" Glyph="⠿" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>
|
||||||
|
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
<!-- 歌词源配置 -->
|
||||||
|
<TextBlock x:Uid="SettingsPageLyricsSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
<ListView
|
||||||
|
x:Name="LyricsSearchProvidersListView"
|
||||||
|
AllowDrop="True"
|
||||||
|
CanDragItems="True"
|
||||||
|
CanReorderItems="True"
|
||||||
|
DragItemsCompleted="LyricsSearchProvidersListView_DragItemsCompleted"
|
||||||
|
ItemsSource="{x:Bind ViewModel.SelectedMediaSourceProvider.LyricsSearchProvidersInfo, Mode=OneWay}"
|
||||||
|
SelectionMode="None">
|
||||||
|
<ListView.OpacityTransition>
|
||||||
|
<ScalarTransition />
|
||||||
|
</ListView.OpacityTransition>
|
||||||
|
<ListView.ItemContainerStyle>
|
||||||
|
<Style TargetType="ListViewItem">
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Margin" Value="0" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
</Style>
|
||||||
|
</ListView.ItemContainerStyle>
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:LyricsSearchProviderInfo">
|
||||||
|
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
|
||||||
|
<controls:SettingsCard.HeaderIcon>
|
||||||
|
<FontIcon FontFamily="Segoe UI Symbol" Glyph="⠿" />
|
||||||
|
</controls:SettingsCard.HeaderIcon>
|
||||||
|
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
<ListView
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
ItemsSource="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo, Mode=OneWay}"
|
||||||
|
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||||
|
ScrollViewer.HorizontalScrollMode="Enabled"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||||
|
ScrollViewer.VerticalScrollMode="Disabled"
|
||||||
|
SelectedItem="{x:Bind ViewModel.SelectedMediaSourceProvider, Mode=TwoWay}">
|
||||||
|
<ListView.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<ItemsStackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ListView.ItemsPanel>
|
||||||
|
<ListView.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="models:MediaSourceProviderInfo">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<ImageIcon Height="16" Source="{Binding Provider, Converter={StaticResource MediaSourceProviderToLogoUriConverter}, Mode=OneWay}" />
|
||||||
|
<TextBlock
|
||||||
|
MaxWidth="200"
|
||||||
|
Text="{Binding Provider, Converter={StaticResource MediaSourceProviderToDisplayedNameConverter}, Mode=OneWay}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListView.ItemTemplate>
|
||||||
|
</ListView>
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</Grid>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Spacing="12">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
<interactivity:DataTriggerBehavior
|
||||||
|
Binding="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo.Count, Mode=OneWay}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="0">
|
||||||
|
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
|
||||||
|
</interactivity:DataTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
<Image MaxWidth="200" Source="/Assets/Leaf.png" />
|
||||||
|
<TextBlock
|
||||||
|
x:Uid="SettingsPagePlaybackNotFound"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
|
||||||
|
</StackPanel>
|
||||||
|
<Grid Grid.Column="1">
|
||||||
|
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
|
||||||
|
<Grid Style="{StaticResource SettingsGridStyle}">
|
||||||
|
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||||
|
<!-- Last.fm -->
|
||||||
|
<TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageLastFMManager"
|
||||||
|
HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/LastFM.png}"
|
||||||
|
IsExpanded="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageLastFMAuth"
|
||||||
|
Command="{x:Bind ViewModel.LastFMAuthCommand}"
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageLastFMUnAuth"
|
||||||
|
Command="{x:Bind ViewModel.LastFMUnAuthCommand}"
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<HyperlinkButton Content="{x:Bind ViewModel.LastFMUser.Name, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.LastFMUser.Url, Mode=OneWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Playcount, Mode=OneWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLastFMRegistered" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<TextBlock Text="{x:Bind ViewModel.LastFMUser.Registered.ToLongDateString(), Mode=OneWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
|
||||||
|
<Button x:Uid="SettingsPageLastFMRefresh" Command="{x:Bind ViewModel.LastFMRefreshCommand}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
<!-- Lyrics translation -->
|
||||||
|
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="LyricsPageTranslationEnabled"
|
||||||
|
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem Content="العربية" Tag="ar" />
|
||||||
|
<ComboBoxItem Content="Azərbaycan dili" Tag="az" />
|
||||||
|
<ComboBoxItem Content="Български" Tag="bg" />
|
||||||
|
<ComboBoxItem Content="বাংলা" Tag="bn" />
|
||||||
|
<ComboBoxItem Content="Català" Tag="ca" />
|
||||||
|
<ComboBoxItem Content="Čeština" Tag="cs" />
|
||||||
|
<ComboBoxItem Content="Dansk" Tag="da" />
|
||||||
|
<ComboBoxItem Content="Deutsch" Tag="de" />
|
||||||
|
<ComboBoxItem Content="Ελληνικά" Tag="el" />
|
||||||
|
<ComboBoxItem Content="English" Tag="en" />
|
||||||
|
<ComboBoxItem Content="Esperanto" Tag="eo" />
|
||||||
|
<ComboBoxItem Content="Español" Tag="es" />
|
||||||
|
<ComboBoxItem Content="Eesti" Tag="et" />
|
||||||
|
<ComboBoxItem Content="Euskara" Tag="eu" />
|
||||||
|
<ComboBoxItem Content="فارسی" Tag="fa" />
|
||||||
|
<ComboBoxItem Content="Suomi" Tag="fi" />
|
||||||
|
<ComboBoxItem Content="Français" Tag="fr" />
|
||||||
|
<ComboBoxItem Content="Gaeilge" Tag="ga" />
|
||||||
|
<ComboBoxItem Content="Galego" Tag="gl" />
|
||||||
|
<ComboBoxItem Content="עברית" Tag="he" />
|
||||||
|
<ComboBoxItem Content="हिन्दी" Tag="hi" />
|
||||||
|
<ComboBoxItem Content="Magyar" Tag="hu" />
|
||||||
|
<ComboBoxItem Content="Bahasa Indonesia" Tag="id" />
|
||||||
|
<ComboBoxItem Content="Italiano" Tag="it" />
|
||||||
|
<ComboBoxItem Content="日本語" Tag="ja" />
|
||||||
|
<ComboBoxItem Content="한국어" Tag="ko" />
|
||||||
|
<ComboBoxItem Content="Кыргызча" Tag="ky" />
|
||||||
|
<ComboBoxItem Content="Lietuvių" Tag="lt" />
|
||||||
|
<ComboBoxItem Content="Latviešu" Tag="lv" />
|
||||||
|
<ComboBoxItem Content="Bahasa Melayu" Tag="ms" />
|
||||||
|
<ComboBoxItem Content="Norsk bokmål" Tag="nb" />
|
||||||
|
<ComboBoxItem Content="Nederlands" Tag="nl" />
|
||||||
|
<ComboBoxItem Content="Português (Brasil)" Tag="pt-BR" />
|
||||||
|
<ComboBoxItem Content="Polski" Tag="pl" />
|
||||||
|
<ComboBoxItem Content="Português" Tag="pt" />
|
||||||
|
<ComboBoxItem Content="Română" Tag="ro" />
|
||||||
|
<ComboBoxItem Content="Русский" Tag="ru" />
|
||||||
|
<ComboBoxItem Content="Slovenčina" Tag="sk" />
|
||||||
|
<ComboBoxItem Content="Slovenščina" Tag="sl" />
|
||||||
|
<ComboBoxItem Content="Shqip" Tag="sq" />
|
||||||
|
<ComboBoxItem Content="Српски" Tag="sr" />
|
||||||
|
<ComboBoxItem Content="Svenska" Tag="sv" />
|
||||||
|
<ComboBoxItem Content="ไทย" Tag="th" />
|
||||||
|
<ComboBoxItem Content="Filipino" Tag="tl" />
|
||||||
|
<ComboBoxItem Content="Türkçe" Tag="tr" />
|
||||||
|
<ComboBoxItem Content="Українська" Tag="uk" />
|
||||||
|
<ComboBoxItem Content="اردو" Tag="ur" />
|
||||||
|
<ComboBoxItem Content="Tiếng Việt" Tag="vi" />
|
||||||
|
<ComboBoxItem Content="中文" Tag="zh" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||||
|
<controls:SettingsCard.Description>
|
||||||
|
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
|
||||||
|
<TextBlock
|
||||||
|
x:Uid="SettingsPageTranslationInfoLink"
|
||||||
|
FontSize="14"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</HyperlinkButton>
|
||||||
|
</controls:SettingsCard.Description>
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="12">
|
||||||
|
<TextBox
|
||||||
|
x:Name="LibreTranslateServerTextBox"
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
PlaceholderText="http://localhost:5000"
|
||||||
|
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.LibreTranslateServer, Mode=TwoWay}" />
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageServerTestButton"
|
||||||
|
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
<!-- Lyrics phonetic -->
|
||||||
|
<controls:SettingsExpander
|
||||||
|
x:Uid="SettingsPageChinese"
|
||||||
|
IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}"
|
||||||
|
IsExpanded="True">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
|
||||||
|
<controls:SettingsExpander.Items>
|
||||||
|
<controls:SettingsCard>
|
||||||
|
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem x:Uid="SettingsPagePinyin" />
|
||||||
|
<ComboBoxItem x:Uid="SettingsPageJyutping" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</controls:SettingsExpander.Items>
|
||||||
|
</controls:SettingsExpander>
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageJapanese" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<!-- 中文简体繁体偏好 -->
|
||||||
|
<controls:SettingsCard x:Uid="SettingsPageChinesePreference">
|
||||||
|
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<!-- Provider info -->
|
||||||
|
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
|
||||||
|
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
|
||||||
|
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<!-- LX music server -->
|
||||||
|
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||||
|
<controls:SettingsCard>
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<TextBox
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
PlaceholderText="http://127.0.0.1:23330"
|
||||||
|
Text="{x:Bind ViewModel.AppSettings.GeneralSettings.LXMusicServer, Mode=TwoWay}" />
|
||||||
|
<Button
|
||||||
|
x:Uid="SettingsPageServerTestButton"
|
||||||
|
Command="{x:Bind ViewModel.LXMusicServerTestCommand}"
|
||||||
|
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<!-- Apple Music token -->
|
||||||
|
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="media-user-token (for Apple Muisc)" />
|
||||||
|
<controls:SettingsCard
|
||||||
|
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
|
||||||
|
Foreground="{ThemeResource SystemFillColorCautionBrush}"
|
||||||
|
Header="Use at your own risk">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
||||||
|
<TextBox
|
||||||
|
MaxWidth="250"
|
||||||
|
PlaceholderText="media-user-token"
|
||||||
|
Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Button
|
||||||
|
Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using BetterLyrics.WinUI3.ViewModels;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Controls
|
||||||
|
{
|
||||||
|
public sealed partial class PlaybackSettingsControl : UserControl
|
||||||
|
{
|
||||||
|
public PlaybackSettingsControlViewModel ViewModel => (PlaybackSettingsControlViewModel)DataContext;
|
||||||
|
|
||||||
|
public PlaybackSettingsControl()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DataContext = Ioc.Default.GetRequiredService<PlaybackSettingsControlViewModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AlbumArtSearchProvidersListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
|
||||||
|
{
|
||||||
|
// <20><> AlbumArtSearchProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
|
||||||
|
ViewModel.SelectedMediaSourceProvider?.AlbumArtSearchProvidersInfo?.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LyricsSearchProvidersListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
|
||||||
|
{
|
||||||
|
// <20><> LyricsSearchProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
|
||||||
|
ViewModel.SelectedMediaSourceProvider?.LyricsSearchProvidersInfo?.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<UserControl
|
||||||
|
x:Class="BetterLyrics.WinUI3.Controls.ShortcutTextBox"
|
||||||
|
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">
|
||||||
|
<TextBox
|
||||||
|
x:Name="TextBox"
|
||||||
|
IsReadOnly="True"
|
||||||
|
KeyDown="TextBox_KeyDown"
|
||||||
|
Loaded="TextBox_Loaded" />
|
||||||
|
<Button
|
||||||
|
Margin="3,0,0,0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Click="ClearButton_Click"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
<Button
|
||||||
|
Margin="3,0,0,0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Click="CheckButton_Click"
|
||||||
|
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
FontSize=12,
|
||||||
|
Glyph=}"
|
||||||
|
Style="{StaticResource GhostButtonStyle}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
using BetterLyrics.WinUI3.Helper;
|
||||||
|
using Microsoft.UI.Input;
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.UI.Core;
|
||||||
|
|
||||||
|
// 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 ShortcutTextBox : UserControl
|
||||||
|
{
|
||||||
|
public ShortcutTextBox()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ShortcutProperty =
|
||||||
|
DependencyProperty.Register(nameof(Shortcut), typeof(List<string>), typeof(ShortcutTextBox), new PropertyMetadata(default));
|
||||||
|
|
||||||
|
public List<string> Shortcut
|
||||||
|
{
|
||||||
|
get => (List<string>)GetValue(ShortcutProperty);
|
||||||
|
set => SetValue(ShortcutProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
List<string> shortcut = [];
|
||||||
|
|
||||||
|
bool ctrl = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down);
|
||||||
|
bool shift = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down);
|
||||||
|
bool alt = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.Menu).HasFlag(CoreVirtualKeyStates.Down);
|
||||||
|
bool win = InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.LeftWindows).HasFlag(CoreVirtualKeyStates.Down) ||
|
||||||
|
InputKeyboardSource.GetKeyStateForCurrentThread(Windows.System.VirtualKey.RightWindows).HasFlag(CoreVirtualKeyStates.Down);
|
||||||
|
|
||||||
|
if (ctrl)
|
||||||
|
{
|
||||||
|
shortcut.Add("Ctrl");
|
||||||
|
}
|
||||||
|
if (shift)
|
||||||
|
{
|
||||||
|
shortcut.Add("Shift");
|
||||||
|
}
|
||||||
|
if (alt)
|
||||||
|
{
|
||||||
|
shortcut.Add("Alt");
|
||||||
|
}
|
||||||
|
if (win)
|
||||||
|
{
|
||||||
|
shortcut.Add("Win");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Key != Windows.System.VirtualKey.Control &&
|
||||||
|
e.Key != Windows.System.VirtualKey.Shift &&
|
||||||
|
e.Key != Windows.System.VirtualKey.Menu &&
|
||||||
|
e.Key != Windows.System.VirtualKey.LeftWindows &&
|
||||||
|
e.Key != Windows.System.VirtualKey.RightWindows)
|
||||||
|
{
|
||||||
|
shortcut.Add(e.Key.ToString());
|
||||||
|
}
|
||||||
|
Shortcut = shortcut;
|
||||||
|
|
||||||
|
UpdateTextBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTextBox()
|
||||||
|
{
|
||||||
|
TextBox.Text = string.Join(" + ", Shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TextBox_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateTextBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Shortcut = [];
|
||||||
|
UpdateTextBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut);
|
||||||
|
if (registered)
|
||||||
|
{
|
||||||
|
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||||
|
App.ResourceLoader!.GetString("SettingsPageShortcutRegSuccessInfo"),
|
||||||
|
InfoBarSeverity.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
App.Current.SettingsWindowNotificationPanel?.Notify(
|
||||||
|
App.ResourceLoader!.GetString("SettingsPageShortcutRegFailInfo"),
|
||||||
|
InfoBarSeverity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,9 +14,9 @@
|
|||||||
x:Name="TrayIcon"
|
x:Name="TrayIcon"
|
||||||
x:FieldModifier="public"
|
x:FieldModifier="public"
|
||||||
ContextMenuMode="SecondWindow"
|
ContextMenuMode="SecondWindow"
|
||||||
DoubleClickCommand="{x:Bind ViewModel.OpenLyricsWindowCommand}"
|
DoubleClickCommand="{x:Bind ViewModel.OpenLyricsCommand}"
|
||||||
IconSource="ms-appx:///Assets/Logo.ico"
|
IconSource="ms-appx:///Assets/Logo.ico"
|
||||||
LeftClickCommand="{x:Bind ViewModel.OpenLyricsWindowCommand}"
|
LeftClickCommand="{x:Bind ViewModel.OpenLyricsCommand}"
|
||||||
NoLeftClickDelay="True"
|
NoLeftClickDelay="True"
|
||||||
ToolTipText="{x:Bind ViewModel.ToolTipText, Mode=OneWay}">
|
ToolTipText="{x:Bind ViewModel.ToolTipText, Mode=OneWay}">
|
||||||
<tb:TaskbarIcon.ContextFlyout>
|
<tb:TaskbarIcon.ContextFlyout>
|
||||||
@@ -24,13 +24,49 @@
|
|||||||
AreOpenCloseAnimationsEnabled="True"
|
AreOpenCloseAnimationsEnabled="True"
|
||||||
LightDismissOverlayMode="On"
|
LightDismissOverlayMode="On"
|
||||||
ShowMode="TransientWithDismissOnPointerMoveAway">
|
ShowMode="TransientWithDismissOnPointerMoveAway">
|
||||||
<MenuFlyoutItem x:Uid="SystemTrayMusicGallery" Command="{x:Bind ViewModel.OpenMusicGalleryCommand}" />
|
<MenuFlyout.MenuFlyoutPresenterStyle>
|
||||||
<MenuFlyoutItem x:Uid="SystemTraySettings" Command="{x:Bind ViewModel.OpenSettingsCommand}" />
|
<Style BasedOn="{StaticResource DefaultMenuFlyoutPresenterStyle}" TargetType="MenuFlyoutPresenter">
|
||||||
<MenuFlyoutItem x:Uid="SystemTrayExit" Command="{x:Bind ViewModel.ExitAppCommand}" />
|
<Setter Property="MinWidth" Value="600" />
|
||||||
|
</Style>
|
||||||
|
</MenuFlyout.MenuFlyoutPresenterStyle>
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTrayLyrics"
|
||||||
|
Command="{x:Bind ViewModel.OpenLyricsCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTrayMusicGallery"
|
||||||
|
Command="{x:Bind ViewModel.OpenMusicGalleryCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTraySettings"
|
||||||
|
Command="{x:Bind ViewModel.OpenSettingsCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
|
<MenuFlyoutSeparator />
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTrayResetWindowPosition"
|
||||||
|
Command="{x:Bind ViewModel.ResetWindowPositionCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
<MenuFlyoutItem
|
<MenuFlyoutItem
|
||||||
x:Uid="SystemTrayUnlock"
|
x:Uid="SystemTrayUnlock"
|
||||||
Command="{x:Bind ViewModel.UnlockWindowCommand}"
|
Command="{x:Bind ViewModel.UnlockWindowCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}"
|
||||||
Visibility="{x:Bind ViewModel.IsLyricsWindowLocked, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
Visibility="{x:Bind ViewModel.IsLyricsWindowLocked, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||||
|
<MenuFlyoutSeparator />
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTrayRestart"
|
||||||
|
Command="{x:Bind ViewModel.RestartAppCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
|
<MenuFlyoutItem
|
||||||
|
x:Uid="SystemTrayExit"
|
||||||
|
Command="{x:Bind ViewModel.ExitAppCommand}"
|
||||||
|
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||||
|
Glyph=}" />
|
||||||
</MenuFlyout>
|
</MenuFlyout>
|
||||||
</tb:TaskbarIcon.ContextFlyout>
|
</tb:TaskbarIcon.ContextFlyout>
|
||||||
</tb:TaskbarIcon>
|
</tb:TaskbarIcon>
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public partial class BoolNegationToVisibilityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is bool boolValue)
|
||||||
|
{
|
||||||
|
return boolValue ? Visibility.Collapsed : Visibility.Visible;
|
||||||
|
}
|
||||||
|
return Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class BoolToOpacityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is bool boolValue)
|
||||||
|
{
|
||||||
|
return boolValue ? 1.0 : 0.3;
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class FPSToTimeSpanConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is int fps)
|
||||||
|
{
|
||||||
|
return TimeSpan.FromSeconds(1.0 / fps);
|
||||||
|
}
|
||||||
|
return TimeSpan.FromSeconds(1.0 / 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,10 +15,11 @@ namespace BetterLyrics.WinUI3.Converter
|
|||||||
return provider switch
|
return provider switch
|
||||||
{
|
{
|
||||||
LyricsSearchProvider.LrcLib => "LrcLib",
|
LyricsSearchProvider.LrcLib => "LrcLib",
|
||||||
LyricsSearchProvider.QQ => "QQ",
|
LyricsSearchProvider.QQ => "QQ 音乐",
|
||||||
LyricsSearchProvider.Netease => "Netease",
|
LyricsSearchProvider.Netease => "网易云音乐",
|
||||||
LyricsSearchProvider.Kugou => "Kugou",
|
LyricsSearchProvider.Kugou => "酷狗音乐",
|
||||||
LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
LyricsSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||||
|
LyricsSearchProvider.AppleMusic => "Apple Music",
|
||||||
LyricsSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
LyricsSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||||
LyricsSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
LyricsSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||||
LyricsSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
LyricsSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using BetterLyrics.WinUI3.Constants;
|
||||||
|
using BetterLyrics.WinUI3.Helper;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class MediaSourceProviderToDisplayedNameConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is string provider)
|
||||||
|
{
|
||||||
|
return provider switch
|
||||||
|
{
|
||||||
|
PlayerID.Spotify => PlayerName.Spotify,
|
||||||
|
PlayerID.AppleMusic => PlayerName.AppleMusic,
|
||||||
|
PlayerID.iTunes => PlayerName.iTunes,
|
||||||
|
PlayerID.KugouMusic => PlayerName.KugouMusic,
|
||||||
|
PlayerID.NetEaseCloudMusic => PlayerName.NetEaseCloudMusic,
|
||||||
|
PlayerID.QQMusic => PlayerName.QQMusic,
|
||||||
|
PlayerID.LXMusic => PlayerName.LXMusic,
|
||||||
|
PlayerID.MediaPlayerWindows11 => PlayerName.MediaPlayerWindows11,
|
||||||
|
PlayerID.AIMP => PlayerName.AIMP,
|
||||||
|
PlayerID.Foobar2000 => PlayerName.Foobar2000,
|
||||||
|
PlayerID.MusicBee => PlayerName.MusicBee,
|
||||||
|
PlayerID.PotPlayer => PlayerName.PotPlayer,
|
||||||
|
PlayerID.Chrome => PlayerName.Chrome,
|
||||||
|
PlayerID.Edge => PlayerName.Edge,
|
||||||
|
PlayerID.BetterLyrics => PlayerName.BetterLyrics,
|
||||||
|
PlayerID.BetterLyricsDebug => PlayerName.BetterLyricsDebug,
|
||||||
|
_ => provider,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return value?.ToString() ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using BetterLyrics.WinUI3.Constants;
|
||||||
|
using BetterLyrics.WinUI3.Helper;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class MediaSourceProviderToLogoUriConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is string provider)
|
||||||
|
{
|
||||||
|
return provider switch
|
||||||
|
{
|
||||||
|
PlayerID.Spotify => PathHelper.SpotifyLogoPath,
|
||||||
|
PlayerID.AppleMusic => PathHelper.AppleMusicLogoPath,
|
||||||
|
PlayerID.AppleMusicAlternative => PathHelper.AppleMusicLogoPath,
|
||||||
|
PlayerID.iTunes => PathHelper.iTunesLogoPath,
|
||||||
|
PlayerID.KugouMusic => PathHelper.KugouMusicLogoPath,
|
||||||
|
PlayerID.NetEaseCloudMusic => PathHelper.NetEaseCloudMusicLogoPath,
|
||||||
|
PlayerID.QQMusic => PathHelper.QQMusicLogoPath,
|
||||||
|
PlayerID.LXMusic => PathHelper.LXMusicLogoPath,
|
||||||
|
PlayerID.MediaPlayerWindows11 => PathHelper.MediaPlayerWindows11LogoPath,
|
||||||
|
PlayerID.AIMP => PathHelper.AIMPLogoPath,
|
||||||
|
PlayerID.Foobar2000 => PathHelper.Foobar2000LogoPath,
|
||||||
|
PlayerID.MusicBee => PathHelper.MusicBeeLogoPath,
|
||||||
|
PlayerID.PotPlayer => PathHelper.PotPlayerLogoPath,
|
||||||
|
PlayerID.Chrome => PathHelper.ChromeLogoPath,
|
||||||
|
PlayerID.Edge => PathHelper.EdgeLogoPath,
|
||||||
|
PlayerID.BetterLyrics => PathHelper.LogoPath,
|
||||||
|
PlayerID.BetterLyricsDebug => PathHelper.LogoPath,
|
||||||
|
_ => PathHelper.UnknownPlayerLogoPath,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return PathHelper.UnknownPlayerLogoPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class MillisecondsToFormattedTimeConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is int milliseconds)
|
||||||
|
{
|
||||||
|
return TimeSpan.FromMilliseconds(milliseconds).ToString(@"mm\:ss\.fff");
|
||||||
|
}
|
||||||
|
else if (value is double doubleMilliseconds)
|
||||||
|
{
|
||||||
|
return TimeSpan.FromMilliseconds(doubleMilliseconds).ToString(@"mm\:ss\.fff");
|
||||||
|
}
|
||||||
|
return value?.ToString() ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class RectToMarginConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is Windows.Foundation.Rect rect)
|
||||||
|
{
|
||||||
|
return new Microsoft.UI.Xaml.Thickness(rect.X, rect.Y, 0, 0);
|
||||||
|
}
|
||||||
|
return new Microsoft.UI.Xaml.Thickness(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Converter
|
||||||
|
{
|
||||||
|
public class ShortcutToStringConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
if (value is List<string> shortcut)
|
||||||
|
{
|
||||||
|
return string.Join(" + ", shortcut);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,10 +15,11 @@ namespace BetterLyrics.WinUI3.Converter
|
|||||||
return provider switch
|
return provider switch
|
||||||
{
|
{
|
||||||
TranslationSearchProvider.LrcLib => "LrcLib",
|
TranslationSearchProvider.LrcLib => "LrcLib",
|
||||||
TranslationSearchProvider.QQ => "QQ",
|
TranslationSearchProvider.QQ => "QQ 音乐",
|
||||||
TranslationSearchProvider.Netease => "Netease",
|
TranslationSearchProvider.Netease => "网易云音乐",
|
||||||
TranslationSearchProvider.Kugou => "Kugou",
|
TranslationSearchProvider.Kugou => "酷狗音乐",
|
||||||
TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
TranslationSearchProvider.AmllTtmlDb => "amll-ttml-db",
|
||||||
|
TranslationSearchProvider.AppleMusic => "Apple Music",
|
||||||
TranslationSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
TranslationSearchProvider.LocalLrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalLrcFile"),
|
||||||
TranslationSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
TranslationSearchProvider.LocalMusicFile => App.ResourceLoader!.GetString("LyricsSearchProviderLocalMusicFile"),
|
||||||
TranslationSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
TranslationSearchProvider.LocalEslrcFile => App.ResourceLoader!.GetString("LyricsSearchProviderEslrcFile"),
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Enums
|
||||||
|
{
|
||||||
|
public enum ChineseRomanization
|
||||||
|
{
|
||||||
|
Pinyin,
|
||||||
|
Jyutping,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,5 +67,16 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
_ => ".*",
|
_ => ".*",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LyricsSearchProvider? ToLyricsSearchProvider(this LyricsFormat format)
|
||||||
|
{
|
||||||
|
return format switch
|
||||||
|
{
|
||||||
|
LyricsFormat.Lrc => LyricsSearchProvider.LocalLrcFile,
|
||||||
|
LyricsFormat.Eslrc => LyricsSearchProvider.LocalEslrcFile,
|
||||||
|
LyricsFormat.Ttml => LyricsSearchProvider.LocalTtmlFile,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 LyricsLayoutOrientation
|
||||||
|
{
|
||||||
|
Horizontal,
|
||||||
|
Vertical,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
LocalLrcFile,
|
LocalLrcFile,
|
||||||
LocalEslrcFile,
|
LocalEslrcFile,
|
||||||
LocalTtmlFile,
|
LocalTtmlFile,
|
||||||
|
AppleMusic,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class LyricsSearchProviderExtensions
|
public static class LyricsSearchProviderExtensions
|
||||||
@@ -28,6 +29,7 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
LyricsSearchProvider.Netease => PathHelper.NeteaseLyricsCacheDirectory,
|
LyricsSearchProvider.Netease => PathHelper.NeteaseLyricsCacheDirectory,
|
||||||
LyricsSearchProvider.Kugou => PathHelper.KugouLyricsCacheDirectory,
|
LyricsSearchProvider.Kugou => PathHelper.KugouLyricsCacheDirectory,
|
||||||
LyricsSearchProvider.AmllTtmlDb => PathHelper.AmllTtmlDbLyricsCacheDirectory,
|
LyricsSearchProvider.AmllTtmlDb => PathHelper.AmllTtmlDbLyricsCacheDirectory,
|
||||||
|
LyricsSearchProvider.AppleMusic => PathHelper.AppleMusicCacheDirectory,
|
||||||
_ => throw new System.ArgumentOutOfRangeException(nameof(provider)),
|
_ => throw new System.ArgumentOutOfRangeException(nameof(provider)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -41,6 +43,7 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
LyricsSearchProvider.Kugou => LyricsFormat.Krc,
|
LyricsSearchProvider.Kugou => LyricsFormat.Krc,
|
||||||
LyricsSearchProvider.Netease => LyricsFormat.Lrc,
|
LyricsSearchProvider.Netease => LyricsFormat.Lrc,
|
||||||
LyricsSearchProvider.AmllTtmlDb => LyricsFormat.Ttml,
|
LyricsSearchProvider.AmllTtmlDb => LyricsFormat.Ttml,
|
||||||
|
LyricsSearchProvider.AppleMusic => LyricsFormat.Ttml,
|
||||||
LyricsSearchProvider.LocalLrcFile => LyricsFormat.Lrc,
|
LyricsSearchProvider.LocalLrcFile => LyricsFormat.Lrc,
|
||||||
LyricsSearchProvider.LocalEslrcFile => LyricsFormat.Eslrc,
|
LyricsSearchProvider.LocalEslrcFile => LyricsFormat.Eslrc,
|
||||||
LyricsSearchProvider.LocalTtmlFile => LyricsFormat.Ttml,
|
LyricsSearchProvider.LocalTtmlFile => LyricsFormat.Ttml,
|
||||||
@@ -71,6 +74,7 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
LyricsSearchProvider.Kugou => TranslationSearchProvider.Kugou,
|
LyricsSearchProvider.Kugou => TranslationSearchProvider.Kugou,
|
||||||
LyricsSearchProvider.Netease => TranslationSearchProvider.Netease,
|
LyricsSearchProvider.Netease => TranslationSearchProvider.Netease,
|
||||||
LyricsSearchProvider.AmllTtmlDb => TranslationSearchProvider.AmllTtmlDb,
|
LyricsSearchProvider.AmllTtmlDb => TranslationSearchProvider.AmllTtmlDb,
|
||||||
|
LyricsSearchProvider.AppleMusic => TranslationSearchProvider.AppleMusic,
|
||||||
LyricsSearchProvider.LocalMusicFile => TranslationSearchProvider.LocalMusicFile,
|
LyricsSearchProvider.LocalMusicFile => TranslationSearchProvider.LocalMusicFile,
|
||||||
LyricsSearchProvider.LocalLrcFile => TranslationSearchProvider.LocalLrcFile,
|
LyricsSearchProvider.LocalLrcFile => TranslationSearchProvider.LocalLrcFile,
|
||||||
LyricsSearchProvider.LocalEslrcFile => TranslationSearchProvider.LocalEslrcFile,
|
LyricsSearchProvider.LocalEslrcFile => TranslationSearchProvider.LocalEslrcFile,
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
namespace BetterLyrics.WinUI3.Enums
|
namespace BetterLyrics.WinUI3.Enums
|
||||||
{
|
{
|
||||||
public enum AutoStartWindowType
|
public enum LyricsWindowMode
|
||||||
{
|
{
|
||||||
StandardMode,
|
StandardMode,
|
||||||
DockMode,
|
DockMode,
|
||||||
DesktopMode,
|
DesktopMode,
|
||||||
|
PictureInPictureMode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Enums
|
||||||
|
{
|
||||||
|
public enum SettingsStoreType
|
||||||
|
{
|
||||||
|
Container,
|
||||||
|
JSON
|
||||||
|
}
|
||||||
|
}
|
||||||
20
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Enums/ShortcutID.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Enums
|
||||||
|
{
|
||||||
|
public enum ShortcutID
|
||||||
|
{
|
||||||
|
LyricsWindowShowOrHide,
|
||||||
|
DesktopLockOrUnlock,
|
||||||
|
DesktopToggle,
|
||||||
|
DockToggle,
|
||||||
|
PictureInPictureToggle,
|
||||||
|
PlayOrPauseSong,
|
||||||
|
NextSong,
|
||||||
|
PreviousSong,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ namespace BetterLyrics.WinUI3.Enums
|
|||||||
Netease,
|
Netease,
|
||||||
LrcLib,
|
LrcLib,
|
||||||
AmllTtmlDb,
|
AmllTtmlDb,
|
||||||
|
AppleMusic,
|
||||||
LocalMusicFile,
|
LocalMusicFile,
|
||||||
LocalLrcFile,
|
LocalLrcFile,
|
||||||
LocalEslrcFile,
|
LocalEslrcFile,
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ using Windows.UI;
|
|||||||
|
|
||||||
namespace BetterLyrics.WinUI3.Events
|
namespace BetterLyrics.WinUI3.Events
|
||||||
{
|
{
|
||||||
public class AlbumArtChangedEventArgs(SoftwareBitmap? albumArtSwBitmap, Color? albumArtAccentColor) : EventArgs
|
public class AlbumArtChangedEventArgs(byte[]? bytes, SoftwareBitmap? albumArtSwBitmap, Color? albumArtLightAccentColor, Color? albumArtDarkAccentColor) : EventArgs
|
||||||
{
|
{
|
||||||
|
public byte[]? Bytes { get; set; } = bytes;
|
||||||
public SoftwareBitmap? AlbumArtSwBitmap { get; set; } = albumArtSwBitmap;
|
public SoftwareBitmap? AlbumArtSwBitmap { get; set; } = albumArtSwBitmap;
|
||||||
public Color? AlbumArtAccentColor { get; set; } = albumArtAccentColor;
|
public Color? AlbumArtLightAccentColor { get; set; } = albumArtLightAccentColor;
|
||||||
|
public Color? AlbumArtDarkAccentColor { get; set; } = albumArtDarkAccentColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Events
|
||||||
|
{
|
||||||
|
public class LastFMIsAuthenticatedChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public bool IsAuthenticated { get; set; }
|
||||||
|
public LastFMIsAuthenticatedChangedEventArgs(bool isAuthenticated)
|
||||||
|
{
|
||||||
|
IsAuthenticated = isAuthenticated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Hqub.Lastfm.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Events
|
||||||
|
{
|
||||||
|
public class LastFMUserChangedEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public User? User { get; set; }
|
||||||
|
public LastFMUserChangedEventArgs(User? user)
|
||||||
|
{
|
||||||
|
User = user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using BetterLyrics.WinUI3.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Events
|
||||||
|
{
|
||||||
|
public class LyricsChangedEventArgs(LyricsData? lyricsData) : EventArgs
|
||||||
|
{
|
||||||
|
public LyricsData? LyricsData { get; } = lyricsData;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Extensions
|
||||||
|
{
|
||||||
|
// https://stackoverflow.com/a/32013610/11048731
|
||||||
|
public class FullyObservableCollection<T> : ObservableCollection<T>
|
||||||
|
where T : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a property is changed within an item.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ItemPropertyChangedEventArgs> ItemPropertyChanged;
|
||||||
|
|
||||||
|
public FullyObservableCollection() : base()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public FullyObservableCollection(List<T> list) : base(list)
|
||||||
|
{
|
||||||
|
ObserveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FullyObservableCollection(IEnumerable<T> enumerable) : base(enumerable)
|
||||||
|
{
|
||||||
|
ObserveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Action == NotifyCollectionChangedAction.Remove ||
|
||||||
|
e.Action == NotifyCollectionChangedAction.Replace)
|
||||||
|
{
|
||||||
|
foreach (T item in e.OldItems)
|
||||||
|
item.PropertyChanged -= ChildPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Action == NotifyCollectionChangedAction.Add ||
|
||||||
|
e.Action == NotifyCollectionChangedAction.Replace)
|
||||||
|
{
|
||||||
|
foreach (T item in e.NewItems)
|
||||||
|
item.PropertyChanged += ChildPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnCollectionChanged(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnItemPropertyChanged(ItemPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
ItemPropertyChanged?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnItemPropertyChanged(int index, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
OnItemPropertyChanged(new ItemPropertyChangedEventArgs(index, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearItems()
|
||||||
|
{
|
||||||
|
foreach (T item in Items)
|
||||||
|
item.PropertyChanged -= ChildPropertyChanged;
|
||||||
|
|
||||||
|
base.ClearItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ObserveAll()
|
||||||
|
{
|
||||||
|
foreach (T item in Items)
|
||||||
|
item.PropertyChanged += ChildPropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
T typedSender = (T)sender;
|
||||||
|
int i = Items.IndexOf(typedSender);
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
throw new ArgumentException("Received property notification from item not in collection");
|
||||||
|
|
||||||
|
OnItemPropertyChanged(i, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data for the <see cref="FullyObservableCollection{T}.ItemPropertyChanged"/> event.
|
||||||
|
/// </summary>
|
||||||
|
public class ItemPropertyChangedEventArgs : PropertyChangedEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index in the collection for which the property change has occurred.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// Index in parent collection.
|
||||||
|
/// </value>
|
||||||
|
public int CollectionIndex { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ItemPropertyChangedEventArgs"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index in the collection of changed item.</param>
|
||||||
|
/// <param name="name">The name of the property that changed.</param>
|
||||||
|
public ItemPropertyChangedEventArgs(int index, string name) : base(name)
|
||||||
|
{
|
||||||
|
CollectionIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ItemPropertyChangedEventArgs"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index.</param>
|
||||||
|
/// <param name="args">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
|
||||||
|
public ItemPropertyChangedEventArgs(int index, PropertyChangedEventArgs args) : this(index, args.PropertyName)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,9 +11,9 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
{
|
{
|
||||||
public static void SetIcons(this AppWindow appWindow)
|
public static void SetIcons(this AppWindow appWindow)
|
||||||
{
|
{
|
||||||
appWindow.SetIcon(@"Assets/Logo.ico");
|
appWindow.SetIcon(PathHelper.LogoPath);
|
||||||
appWindow.SetTaskbarIcon(@"Assets/Logo.ico");
|
appWindow.SetTaskbarIcon(PathHelper.LogoPath);
|
||||||
appWindow.SetTitleBarIcon(@"Assets/Logo.ico");
|
appWindow.SetTitleBarIcon(PathHelper.LogoPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
126
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppleMusic.cs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
using BetterLyrics.WinUI3.Constants;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Helper
|
||||||
|
{
|
||||||
|
public class AppleMusic
|
||||||
|
{
|
||||||
|
private readonly HttpClient _client;
|
||||||
|
private string _accessToken = "";
|
||||||
|
private string _storefront = "";
|
||||||
|
private string _language = "";
|
||||||
|
|
||||||
|
public AppleMusic()
|
||||||
|
{
|
||||||
|
_client = new HttpClient();
|
||||||
|
_client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36");
|
||||||
|
_client.DefaultRequestHeaders.Add("Accept", "application/json");
|
||||||
|
_client.DefaultRequestHeaders.Add("Origin", "https://music.apple.com");
|
||||||
|
_client.DefaultRequestHeaders.Add("Referer", "https://music.apple.com/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> InitAsync()
|
||||||
|
{
|
||||||
|
await GetAccessTokenAsync();
|
||||||
|
await SetMediaUserTokenAsync();
|
||||||
|
return
|
||||||
|
!string.IsNullOrEmpty(_accessToken) &&
|
||||||
|
!string.IsNullOrEmpty(PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task GetAccessTokenAsync()
|
||||||
|
{
|
||||||
|
var resp = await _client.GetStringAsync("https://music.apple.com/us/browse");
|
||||||
|
var jsMatch = Regex.Match(resp, "(?<=index)(.*?)(?=\\.js\")");
|
||||||
|
if (!jsMatch.Success) throw new Exception("Failed to find index.js");
|
||||||
|
var jsUrl = $"https://music.apple.com/assets/index{jsMatch.Value}.js";
|
||||||
|
var jsResp = await _client.GetStringAsync(jsUrl);
|
||||||
|
var tokenMatch = Regex.Match(jsResp, "(?=eyJh)(.*?)(?=\")");
|
||||||
|
if (!tokenMatch.Success) throw new Exception("Failed to find access token");
|
||||||
|
_accessToken = tokenMatch.Value;
|
||||||
|
_client.DefaultRequestHeaders.Remove("Authorization");
|
||||||
|
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_accessToken}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetMediaUserTokenAsync()
|
||||||
|
{
|
||||||
|
_client.DefaultRequestHeaders.Remove("media-user-token");
|
||||||
|
_client.DefaultRequestHeaders.Add("media-user-token",
|
||||||
|
PasswordVaultHelper.Get(Constants.App.AppName, Constants.AppleMusic.MediaUserTokenKey));
|
||||||
|
var resp = await _client.GetStringAsync("https://amp-api.music.apple.com/v1/me/storefront");
|
||||||
|
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||||
|
_storefront = json.GetProperty("data")[0].GetProperty("id").ToString();
|
||||||
|
_language = json.GetProperty("data")[0].GetProperty("attributes").GetProperty("defaultLanguageTag").ToString();
|
||||||
|
_client.DefaultRequestHeaders.Remove("Accept-Language");
|
||||||
|
_client.DefaultRequestHeaders.Add("Accept-Language", $"{_language},en;q=0.9");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string?> GetLyricsAsync(string title, string artist)
|
||||||
|
{
|
||||||
|
string id = await SearchSongInfoAsync(artist, title);
|
||||||
|
|
||||||
|
var apiUrl = $"https://amp-api.music.apple.com/v1/catalog/{_storefront}/songs/{id}";
|
||||||
|
var url = apiUrl + $"?include[songs]=lyrics,syllable-lyrics&l={_language}";
|
||||||
|
var resp = await _client.GetStringAsync(url);
|
||||||
|
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||||
|
var data = json.GetProperty("data");
|
||||||
|
if (data.GetArrayLength() == 0) return string.Empty;
|
||||||
|
var song = data[0];
|
||||||
|
|
||||||
|
if (!song.TryGetProperty("relationships", out var relationships))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
if (relationships.TryGetProperty("syllable-lyrics", out var syllableLyrics) &&
|
||||||
|
syllableLyrics.GetProperty("data").GetArrayLength() > 0)
|
||||||
|
{
|
||||||
|
var syllableLyric = syllableLyrics.GetProperty("data")[0];
|
||||||
|
if (syllableLyric.TryGetProperty("attributes", out var attributes) &&
|
||||||
|
attributes.TryGetProperty("ttml", out var ttml))
|
||||||
|
{
|
||||||
|
string? raw = ttml.GetString();
|
||||||
|
if (raw != null && raw.Contains("begin=") && raw.Contains("end="))
|
||||||
|
{
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (relationships.TryGetProperty("lyrics", out var lyrics) &&
|
||||||
|
// lyrics.GetProperty("data").GetArrayLength() > 0)
|
||||||
|
//{
|
||||||
|
// var lyric = lyrics.GetProperty("data")[0];
|
||||||
|
// if (lyric.TryGetProperty("attributes", out var attributes) &&
|
||||||
|
// attributes.TryGetProperty("ttml", out var ttml))
|
||||||
|
// {
|
||||||
|
// return ttml.GetString();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> SearchSongInfoAsync(string artist, string title)
|
||||||
|
{
|
||||||
|
var query = $"{artist} {title}";
|
||||||
|
var apiUrl = $"https://amp-api.music.apple.com/v1/catalog/{_storefront}/search";
|
||||||
|
var url = apiUrl + $"?term={WebUtility.UrlEncode(query)}&types=songs&limit=1&l={_language}";
|
||||||
|
var resp = await _client.GetStringAsync(url);
|
||||||
|
var json = JsonSerializer.Deserialize(resp, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||||
|
var results = json.GetProperty("results");
|
||||||
|
if (results.TryGetProperty("songs", out var songs) && songs.GetProperty("data").GetArrayLength() > 0)
|
||||||
|
{
|
||||||
|
var song = songs.GetProperty("data")[0];
|
||||||
|
return song.GetProperty("id").ToString();
|
||||||
|
}
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
360
BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/CanvasHelper.cs
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
using BetterLyrics.WinUI3.Enums;
|
||||||
|
using BetterLyrics.WinUI3.Models;
|
||||||
|
using Microsoft.Graphics.Canvas;
|
||||||
|
using Microsoft.Graphics.Canvas.Brushes;
|
||||||
|
using Microsoft.Graphics.Canvas.Effects;
|
||||||
|
using Microsoft.Graphics.Canvas.Text;
|
||||||
|
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||||
|
using Microsoft.UI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Graphics.Effects;
|
||||||
|
using Windows.UI;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Helper
|
||||||
|
{
|
||||||
|
public class CanvasHelper
|
||||||
|
{
|
||||||
|
public static CanvasLinearGradientBrush CreateHorizontalFillBrush(
|
||||||
|
ICanvasAnimatedControl control,
|
||||||
|
List<(double position, double opacity)> stops,
|
||||||
|
double startX,
|
||||||
|
double width
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return new CanvasLinearGradientBrush(control, stops.Select(stops => new CanvasGradientStop
|
||||||
|
{
|
||||||
|
Position = (float)stops.position,
|
||||||
|
Color = Color.FromArgb((byte)(stops.opacity * 255), 128, 128, 128),
|
||||||
|
}).ToArray())
|
||||||
|
{
|
||||||
|
StartPoint = new Vector2((float)startX, 0),
|
||||||
|
EndPoint = new Vector2((float)(startX + width), 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 背景层
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lyricsLayerOpacity">_lyricsOpacityTransition.Value</param>
|
||||||
|
public static OpacityEffect CreateBackgroundEffect(LyricsLine lyricsLine, CanvasCommandList backgroundFontEffect, double lyricsLayerOpacity)
|
||||||
|
{
|
||||||
|
if (lyricsLine.BlurAmountTransition.Value == 0)
|
||||||
|
{
|
||||||
|
return new OpacityEffect
|
||||||
|
{
|
||||||
|
Source = backgroundFontEffect,
|
||||||
|
Opacity = (float)(lyricsLine.OpacityTransition.Value * lyricsLayerOpacity),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new OpacityEffect
|
||||||
|
{
|
||||||
|
Source = new GaussianBlurEffect
|
||||||
|
{
|
||||||
|
Source = backgroundFontEffect,
|
||||||
|
BlurAmount = (float)lyricsLine.BlurAmountTransition.Value,
|
||||||
|
BorderMode = EffectBorderMode.Soft,
|
||||||
|
Optimization = EffectOptimization.Speed,
|
||||||
|
},
|
||||||
|
Opacity = (float)(lyricsLine.OpacityTransition.Value * lyricsLayerOpacity),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CanvasCommandList CreateFontEffect(LyricsLine lyricsLine, ICanvasAnimatedControl control, Color strokeColor, int strokeWidth, Color fontColor)
|
||||||
|
{
|
||||||
|
CanvasCommandList list = new(control);
|
||||||
|
using var ds = list.CreateDrawingSession();
|
||||||
|
if (strokeWidth > 0)
|
||||||
|
{
|
||||||
|
if (lyricsLine.TextGeometry == null)
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
ds.DrawGeometry(lyricsLine.TextGeometry, lyricsLine.Position, strokeColor, strokeWidth); // 描边
|
||||||
|
}
|
||||||
|
if (lyricsLine.CanvasTextLayout == null)
|
||||||
|
{
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
ds.DrawTextLayout(lyricsLine.CanvasTextLayout, lyricsLine.Position, fontColor); // 绘制文本(填充)
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建辉光效果层
|
||||||
|
/// 仅需在布局重构 (Relayout) 时调用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lineRenderingType">_lyricsGlowEffectScope</param>
|
||||||
|
/// <param name="glowEffectAmount">_lyricsGlowEffectAmount</param>
|
||||||
|
public static GaussianBlurEffect CreateForegroundBlurEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double glowEffectAmount)
|
||||||
|
{
|
||||||
|
return new GaussianBlurEffect
|
||||||
|
{
|
||||||
|
Source = new AlphaMaskEffect
|
||||||
|
{
|
||||||
|
Source = foregroundFontEffect,
|
||||||
|
AlphaMask = mask,
|
||||||
|
},
|
||||||
|
BlurAmount = (float)glowEffectAmount,
|
||||||
|
Optimization = EffectOptimization.Speed,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CanvasCommandList CreateCharMask(ICanvasAnimatedControl control, LyricsLine lyricsLine, int charStartIndex, int charLength, double charProgress)
|
||||||
|
{
|
||||||
|
var mask = new CanvasCommandList(control);
|
||||||
|
using var ds = mask.CreateDrawingSession();
|
||||||
|
|
||||||
|
if (lyricsLine.CanvasTextLayout == null)
|
||||||
|
{
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
var highlightRegion = lyricsLine.CanvasTextLayout.GetCharacterRegions(charStartIndex, charLength).FirstOrDefault();
|
||||||
|
|
||||||
|
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
|
||||||
|
// Draw the highlight for the current character
|
||||||
|
double highlightWidth = highlightTotalWidth * charProgress;
|
||||||
|
|
||||||
|
double fadingWidth = (double)highlightRegion.LayoutBounds.Height / 2;
|
||||||
|
|
||||||
|
// Rects
|
||||||
|
var highlightRect = new Rect(
|
||||||
|
highlightRegion.LayoutBounds.X,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
highlightWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
|
||||||
|
var fadeInRect = new Rect(
|
||||||
|
highlightRect.Right - fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
var fadeOutRect = new Rect(
|
||||||
|
highlightRect.Right,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
|
||||||
|
// Brushes
|
||||||
|
using var fadeInBrush = CanvasHelper.CreateHorizontalFillBrush(
|
||||||
|
control,
|
||||||
|
[(0f, 0f), (1f, 1f)],
|
||||||
|
(double)highlightRect.Right - fadingWidth,
|
||||||
|
fadingWidth
|
||||||
|
);
|
||||||
|
using var fadeOutBrush = CanvasHelper.CreateHorizontalFillBrush(
|
||||||
|
control,
|
||||||
|
[(0f, 1f), (1f, 0f)],
|
||||||
|
(double)highlightRect.Right,
|
||||||
|
fadingWidth
|
||||||
|
);
|
||||||
|
|
||||||
|
ds.FillRectangle(fadeInRect, fadeInBrush);
|
||||||
|
ds.FillRectangle(fadeOutRect, fadeOutBrush);
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CanvasCommandList CreateLineStartToCharMask(ICanvasAnimatedControl control, LyricsLine lyricsLine, int charStartIndex, int charLength, double charProgress, bool fade)
|
||||||
|
{
|
||||||
|
var mask = new CanvasCommandList(control);
|
||||||
|
|
||||||
|
if (lyricsLine.CanvasTextLayout == null)
|
||||||
|
{
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var ds = mask.CreateDrawingSession();
|
||||||
|
|
||||||
|
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, charStartIndex);
|
||||||
|
var highlightRegion = lyricsLine.CanvasTextLayout
|
||||||
|
.GetCharacterRegions(charStartIndex, charLength)
|
||||||
|
.FirstOrDefault();
|
||||||
|
if (regions.Length > 0)
|
||||||
|
{
|
||||||
|
// Draw the mask for the current line
|
||||||
|
for (int j = 0; j < regions.Length; j++)
|
||||||
|
{
|
||||||
|
var region = regions[j];
|
||||||
|
var rect = new Rect(
|
||||||
|
region.LayoutBounds.X,
|
||||||
|
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
region.LayoutBounds.Width,
|
||||||
|
region.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
ds.FillRectangle(rect, Color.FromArgb(255, 128, 128, 128));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double highlightTotalWidth = (double)highlightRegion.LayoutBounds.Width;
|
||||||
|
// Draw the highlight for the current character
|
||||||
|
double highlightWidth = highlightTotalWidth * charProgress;
|
||||||
|
|
||||||
|
double fadingWidth = (double)highlightRegion.LayoutBounds.Height / 2;
|
||||||
|
|
||||||
|
// Rects
|
||||||
|
var highlightRect = new Rect(
|
||||||
|
highlightRegion.LayoutBounds.X,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
highlightWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
|
||||||
|
var fadeInRect = new Rect(
|
||||||
|
highlightRect.Right - fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
|
||||||
|
ds.FillRectangle(highlightRect, Color.FromArgb(255, 128, 128, 128));
|
||||||
|
|
||||||
|
if (fade)
|
||||||
|
{
|
||||||
|
var fadeOutRect = new Rect(
|
||||||
|
highlightRect.Right,
|
||||||
|
highlightRegion.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
fadingWidth,
|
||||||
|
highlightRegion.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
using var fadeOutBrush = CreateHorizontalFillBrush(
|
||||||
|
control,
|
||||||
|
[(0f, 1f), (1f, 0f)],
|
||||||
|
(double)highlightRect.Right,
|
||||||
|
fadingWidth
|
||||||
|
);
|
||||||
|
ds.FillRectangle(fadeOutRect, fadeOutBrush);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CanvasCommandList CreateLineMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
|
||||||
|
{
|
||||||
|
var mask = new CanvasCommandList(control);
|
||||||
|
using var ds = mask.CreateDrawingSession();
|
||||||
|
|
||||||
|
if (lyricsLine.CanvasTextLayout == null)
|
||||||
|
{
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(0, lyricsLine.OriginalText.Length);
|
||||||
|
if (regions.Length > 0)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < regions.Length; j++)
|
||||||
|
{
|
||||||
|
var region = regions[j];
|
||||||
|
var rect = new Rect(
|
||||||
|
region.LayoutBounds.X,
|
||||||
|
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
region.LayoutBounds.Width,
|
||||||
|
region.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
ds.FillRectangle(rect, Colors.White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CanvasCommandList CreateTranslationHighlightMask(ICanvasAnimatedControl control, LyricsLine lyricsLine)
|
||||||
|
{
|
||||||
|
var mask = new CanvasCommandList(control);
|
||||||
|
using var ds = mask.CreateDrawingSession();
|
||||||
|
|
||||||
|
if (lyricsLine.CanvasTextLayout == null)
|
||||||
|
{
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
var regions = lyricsLine.CanvasTextLayout.GetCharacterRegions(lyricsLine.OriginalText.Length, lyricsLine.DisplayedText.Length - lyricsLine.OriginalText.Length);
|
||||||
|
if (regions.Length > 0)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < regions.Length; j++)
|
||||||
|
{
|
||||||
|
var region = regions[j];
|
||||||
|
var rect = new Rect(
|
||||||
|
region.LayoutBounds.X,
|
||||||
|
region.LayoutBounds.Y + lyricsLine.Position.Y,
|
||||||
|
region.LayoutBounds.Width,
|
||||||
|
region.LayoutBounds.Height
|
||||||
|
);
|
||||||
|
ds.FillRectangle(rect, Colors.White);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建高亮效果层
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="control"></param>
|
||||||
|
/// <param name="lineRenderingType"></param>
|
||||||
|
public static OpacityEffect CreateForegroundHighlightEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
|
||||||
|
{
|
||||||
|
return new OpacityEffect
|
||||||
|
{
|
||||||
|
Source = new AlphaMaskEffect
|
||||||
|
{
|
||||||
|
Source = foregroundFontEffect,
|
||||||
|
AlphaMask = mask,
|
||||||
|
},
|
||||||
|
Opacity = (float)opacity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShadowEffect CreateForegroundShadowEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, Color shadowColor, double shadowAmount)
|
||||||
|
{
|
||||||
|
return new ShadowEffect
|
||||||
|
{
|
||||||
|
Source = new AlphaMaskEffect
|
||||||
|
{
|
||||||
|
Source = foregroundFontEffect,
|
||||||
|
AlphaMask = mask,
|
||||||
|
},
|
||||||
|
ShadowColor = shadowColor,
|
||||||
|
BlurAmount = (float)shadowAmount,
|
||||||
|
Optimization = EffectOptimization.Speed,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OpacityEffect CreateForegroundTranslationEffect(CanvasCommandList foregroundFontEffect, IGraphicsEffectSource mask, double opacity)
|
||||||
|
{
|
||||||
|
return new OpacityEffect
|
||||||
|
{
|
||||||
|
Source = new AlphaMaskEffect
|
||||||
|
{
|
||||||
|
Source = foregroundFontEffect,
|
||||||
|
AlphaMask = mask,
|
||||||
|
},
|
||||||
|
Opacity = (float)opacity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IGraphicsEffectSource GetAlphaMask(ICanvasAnimatedControl control, IGraphicsEffectSource charMask, IGraphicsEffectSource lineStartToCharMask, IGraphicsEffectSource lineMask, LineRenderingType lineRenderingType)
|
||||||
|
{
|
||||||
|
var result = lineRenderingType switch
|
||||||
|
{
|
||||||
|
LineRenderingType.CurrentChar => charMask,
|
||||||
|
LineRenderingType.LineStartToCurrentChar => lineStartToCharMask,
|
||||||
|
LineRenderingType.CurrentLine => lineMask,
|
||||||
|
_ => new CanvasCommandList(control),
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
return Color.FromArgb(255, fg.R, fg.G, fg.B);
|
return Color.FromArgb(255, fg.R, fg.G, fg.B);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color GetInterpolatedColor(float progress, Color startColor, Color targetColor)
|
public static Color GetInterpolatedColor(double progress, Color startColor, Color targetColor)
|
||||||
{
|
{
|
||||||
byte Lerp(byte a, byte b) => (byte)(a + (progress * (b - a)));
|
byte Lerp(byte a, byte b) => (byte)(a + (progress * (b - a)));
|
||||||
return Color.FromArgb(
|
return Color.FromArgb(
|
||||||
@@ -94,6 +94,11 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
return Color.FromArgb(alpha, color.R, color.G, color.B);
|
return Color.FromArgb(alpha, color.R, color.G, color.B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Color WithOpacity(this Color color, float opacity)
|
||||||
|
{
|
||||||
|
return Color.FromArgb((byte)(opacity * 255), color.R, color.G, color.B);
|
||||||
|
}
|
||||||
|
|
||||||
public static Color WithBrightness(this Color color, double brightness)
|
public static Color WithBrightness(this Color color, double brightness)
|
||||||
{
|
{
|
||||||
// 确保亮度因子在合理范围内
|
// 确保亮度因子在合理范围内
|
||||||
@@ -106,25 +111,21 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
return CommunityToolkit.WinUI.Helpers.ColorHelper.FromHsl(h, s, brightness);
|
return CommunityToolkit.WinUI.Helpers.ColorHelper.FromHsl(h, s, brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, WindowPixelSampleMode mode)
|
public static System.Drawing.Color GetAccentColor(IntPtr myHwnd, string monitorDeviceName, WindowPixelSampleMode mode)
|
||||||
{
|
{
|
||||||
if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent;
|
if (!User32.GetWindowRect(myHwnd, out RECT myRect)) return System.Drawing.Color.Transparent;
|
||||||
|
|
||||||
|
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(monitorDeviceName);
|
||||||
|
int screenWidth = monitorInfo.rcMonitor.Width;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case WindowPixelSampleMode.BelowWindow:
|
case WindowPixelSampleMode.BelowWindow:
|
||||||
{
|
{
|
||||||
int screenWidth = User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN);
|
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Bottom + 2, screenWidth, 1);
|
||||||
int sampleHeight = 1;
|
|
||||||
int sampleY = myRect.Bottom + 1;
|
|
||||||
return GetAverageColorFromScreenRegion(0, sampleY, screenWidth, sampleHeight);
|
|
||||||
}
|
}
|
||||||
case WindowPixelSampleMode.AboveWindow:
|
case WindowPixelSampleMode.AboveWindow:
|
||||||
{
|
{
|
||||||
int screenWidth = User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN);
|
return GetAverageColorFromScreenRegion(myRect.Left, myRect.Top - 3, screenWidth, 1);
|
||||||
int sampleHeight = 1;
|
|
||||||
int sampleY = myRect.Top - 1;
|
|
||||||
return GetAverageColorFromScreenRegion(0, sampleY, screenWidth, sampleHeight);
|
|
||||||
}
|
}
|
||||||
case WindowPixelSampleMode.WindowArea:
|
case WindowPixelSampleMode.WindowArea:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using BetterLyrics.WinUI3.Enums;
|
using BetterLyrics.WinUI3.Enums;
|
||||||
using BetterLyrics.WinUI3.Services;
|
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
using Microsoft.UI.Windowing;
|
using Microsoft.UI.Windowing;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
@@ -67,24 +67,8 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// <20>Ӵ洢<D3B4><E6B4A2><EFBFBD><EFBFBD>ȡĿ<C8A1><C4BF><EFBFBD><EFBFBD><EFBFBD>ߺ<EFBFBD>λ<EFBFBD><CEBB>
|
|
||||||
int targetWidth = _settingsService.DesktopWindowWidth;
|
|
||||||
int targetHeight = _settingsService.DesktopWindowHeight;
|
|
||||||
int targetX = _settingsService.DesktopWindowLeft;
|
|
||||||
int targetY = _settingsService.DesktopWindowTop;
|
|
||||||
|
|
||||||
if (targetWidth <= 0 || targetHeight <= 0 || targetX < 0 || targetY < 0)
|
|
||||||
{
|
|
||||||
targetWidth = 1200;
|
|
||||||
targetHeight = 600;
|
|
||||||
targetX = 200;
|
|
||||||
targetY = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
// <20><><EFBFBD>ô<EFBFBD><C3B4>ڴ<EFBFBD>С<EFBFBD><D0A1>λ<EFBFBD><CEBB>
|
// <20><><EFBFBD>ô<EFBFBD><C3B4>ڴ<EFBFBD>С<EFBFBD><D0A1>λ<EFBFBD><CEBB>
|
||||||
window.AppWindow.MoveAndResize(
|
window.AppWindow.MoveAndResize(_settingsService.AppSettings.DesktopModeSettings.WindowBounds.ToRectInt32());
|
||||||
new Windows.Graphics.RectInt32(targetX, targetY, targetWidth, targetHeight)
|
|
||||||
);
|
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD>ԭTopMost״̬
|
// <20><><EFBFBD><EFBFBD>ԭTopMost״̬
|
||||||
if (!_originalTopmostStates.ContainsKey(hwnd))
|
if (!_originalTopmostStates.ContainsKey(hwnd))
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Helper
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BetterLyrics.WinUI3.Helper
|
||||||
|
{
|
||||||
|
public class DirectoryHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 递归查找指定文件夹下所有文件(包括子文件夹)。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folderPath">要查找的文件夹路径</param>
|
||||||
|
/// <returns>所有文件的完整路径列表</returns>
|
||||||
|
public static List<string> GetAllFiles(string folderPath, string searchPattern = "*")
|
||||||
|
{
|
||||||
|
var files = new List<string>();
|
||||||
|
if (!Directory.Exists(folderPath))
|
||||||
|
return files;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
files.AddRange(Directory.GetFiles(folderPath, searchPattern));
|
||||||
|
foreach (var dir in Directory.GetDirectories(folderPath))
|
||||||
|
{
|
||||||
|
files.AddRange(GetAllFiles(dir, searchPattern));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// 可根据需要处理异常,如权限不足等
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using BetterLyrics.WinUI3.Enums;
|
using BetterLyrics.WinUI3.Enums;
|
||||||
|
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||||
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
using CommunityToolkit.WinUI;
|
using CommunityToolkit.WinUI;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using System;
|
using System;
|
||||||
@@ -16,10 +18,17 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
{
|
{
|
||||||
public static class DockModeHelper
|
public static class DockModeHelper
|
||||||
{
|
{
|
||||||
|
private static readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||||
|
|
||||||
private static readonly HashSet<IntPtr> _registered = [];
|
private static readonly HashSet<IntPtr> _registered = [];
|
||||||
private static readonly Dictionary<IntPtr, RECT> _originalPositions = [];
|
private static readonly Dictionary<IntPtr, RECT> _originalPositions = [];
|
||||||
private static readonly Dictionary<IntPtr, WindowStyle> _originalWindowStyle = [];
|
private static readonly Dictionary<IntPtr, WindowStyle> _originalWindowStyle = [];
|
||||||
|
|
||||||
|
public static bool IsEnabled(IntPtr hwnd)
|
||||||
|
{
|
||||||
|
return _registered.Contains(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Disable(Window window)
|
public static void Disable(Window window)
|
||||||
{
|
{
|
||||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||||
@@ -52,10 +61,9 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Enable(Window window, int appBarHeight, DockPlacement dockPlacement)
|
public static void Enable(Window window, string monitorDeviceName, int appBarHeight, DockPlacement dockPlacement)
|
||||||
{
|
{
|
||||||
window.SetIsShownInSwitchers(false);
|
window.SetIsShownInSwitchers(false);
|
||||||
//window.ExtendsContentIntoTitleBar = false;
|
|
||||||
window.SetIsAlwaysOnTop(true);
|
window.SetIsAlwaysOnTop(true);
|
||||||
|
|
||||||
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
IntPtr hwnd = WindowNative.GetWindowHandle(window);
|
||||||
@@ -73,16 +81,18 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterAppBar(hwnd, appBarHeight, dockPlacement);
|
RegisterAppBar(hwnd, monitorDeviceName, appBarHeight, dockPlacement);
|
||||||
|
|
||||||
int screenWidth = User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN);
|
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(_settingsService.AppSettings.DockModeSettings.DockMonitorDeviceName);
|
||||||
int screenHeight = User32.GetSystemMetrics(User32.SystemMetric.SM_CYSCREEN);
|
|
||||||
int y = dockPlacement == DockPlacement.Top ? 0 : screenHeight - appBarHeight;
|
int screenWidth = monitorInfo.rcMonitor.Width;
|
||||||
|
int screenHeight = monitorInfo.rcMonitor.Bottom - monitorInfo.rcMonitor.Top;
|
||||||
|
int y = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - appBarHeight;
|
||||||
|
|
||||||
User32.SetWindowPos(
|
User32.SetWindowPos(
|
||||||
hwnd,
|
hwnd,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
0,
|
monitorInfo.rcMonitor.Left,
|
||||||
y,
|
y,
|
||||||
screenWidth,
|
screenWidth,
|
||||||
appBarHeight,
|
appBarHeight,
|
||||||
@@ -93,14 +103,16 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
window.Show();
|
window.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RegisterAppBar(IntPtr hwnd, int height, DockPlacement dockPlacement)
|
private static void RegisterAppBar(IntPtr hwnd, string monitorDeviceName, int height, DockPlacement dockPlacement)
|
||||||
{
|
{
|
||||||
if (_registered.Contains(hwnd)) return;
|
if (_registered.Contains(hwnd)) return;
|
||||||
|
|
||||||
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||||
int screenHeight = User32.GetSystemMetrics(User32.SystemMetric.SM_CYSCREEN);
|
|
||||||
int top = dockPlacement == DockPlacement.Top ? 0 : screenHeight - height;
|
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(monitorDeviceName);
|
||||||
int bottom = dockPlacement == DockPlacement.Top ? height : screenHeight;
|
|
||||||
|
int top = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - height;
|
||||||
|
int bottom = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top + height : monitorInfo.rcMonitor.Bottom;
|
||||||
|
|
||||||
Shell32.APPBARDATA abd = new()
|
Shell32.APPBARDATA abd = new()
|
||||||
{
|
{
|
||||||
@@ -109,14 +121,13 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
uEdge = uEdge,
|
uEdge = uEdge,
|
||||||
rc = new RECT
|
rc = new RECT
|
||||||
{
|
{
|
||||||
Left = 0,
|
Left = monitorInfo.rcMonitor.Left,
|
||||||
Top = top,
|
Top = top,
|
||||||
Right = User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN),
|
Right = monitorInfo.rcMonitor.Right,
|
||||||
Bottom = bottom,
|
Bottom = bottom,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ref: https://github.com/TwilightLemon/AppBarTest/blob/master/AppBarCreator.cs
|
|
||||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_NEW, ref abd);
|
Shell32.SHAppBarMessage(Shell32.ABM.ABM_NEW, ref abd);
|
||||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
Shell32.SHAppBarMessage(Shell32.ABM.ABM_QUERYPOS, ref abd);
|
||||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||||
@@ -140,12 +151,7 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
_registered.Remove(hwnd);
|
_registered.Remove(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RefreshWorkArea()
|
public static void UpdateAppBarHeight(IntPtr hwnd, string monitorDeviceName, int newHeight, DockPlacement dockPlacement)
|
||||||
{
|
|
||||||
User32.SendMessage(HWND.HWND_BROADCAST, User32.WindowMessage.WM_SETTINGCHANGE, IntPtr.Zero, IntPtr.Zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UpdateAppBarHeight(IntPtr hwnd, int newHeight, DockPlacement dockPlacement)
|
|
||||||
{
|
{
|
||||||
App.DispatcherQueueTimer?.Debounce(() =>
|
App.DispatcherQueueTimer?.Debounce(() =>
|
||||||
{
|
{
|
||||||
@@ -153,9 +159,12 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
var uEdge = dockPlacement == DockPlacement.Top ? Shell32.ABE.ABE_TOP : Shell32.ABE.ABE_BOTTOM;
|
||||||
int screenHeight = User32.GetSystemMetrics(User32.SystemMetric.SM_CYSCREEN);
|
|
||||||
int top = dockPlacement == DockPlacement.Top ? 0 : screenHeight - newHeight;
|
var monitorInfo = MonitorHelper.GetMonitorInfoExFromDeviceName(monitorDeviceName);
|
||||||
int bottom = dockPlacement == DockPlacement.Top ? newHeight : screenHeight;
|
|
||||||
|
int screenWidth = monitorInfo.rcMonitor.Width;
|
||||||
|
int top = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - newHeight;
|
||||||
|
int bottom = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top + newHeight : monitorInfo.rcMonitor.Bottom;
|
||||||
|
|
||||||
Shell32.APPBARDATA abd = new()
|
Shell32.APPBARDATA abd = new()
|
||||||
{
|
{
|
||||||
@@ -164,9 +173,9 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
uEdge = uEdge,
|
uEdge = uEdge,
|
||||||
rc = new RECT
|
rc = new RECT
|
||||||
{
|
{
|
||||||
Left = 0,
|
Left = monitorInfo.rcMonitor.Left,
|
||||||
Top = top,
|
Top = top,
|
||||||
Right = User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN),
|
Right = monitorInfo.rcMonitor.Right,
|
||||||
Bottom = bottom,
|
Bottom = bottom,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -175,16 +184,21 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
Shell32.SHAppBarMessage(Shell32.ABM.ABM_SETPOS, ref abd);
|
||||||
|
|
||||||
// 同步窗口实际高度和位置
|
// 同步窗口实际高度和位置
|
||||||
int y = dockPlacement == DockPlacement.Top ? 0 : screenHeight - newHeight;
|
int y = dockPlacement == DockPlacement.Top ? monitorInfo.rcMonitor.Top : monitorInfo.rcMonitor.Bottom - newHeight;
|
||||||
User32.SetWindowPos(
|
int repeatCount = 2;
|
||||||
hwnd,
|
while (repeatCount > 0)
|
||||||
IntPtr.Zero,
|
{
|
||||||
0,
|
repeatCount--;
|
||||||
y,
|
User32.SetWindowPos(
|
||||||
User32.GetSystemMetrics(User32.SystemMetric.SM_CXSCREEN),
|
hwnd,
|
||||||
newHeight,
|
IntPtr.Zero,
|
||||||
newHeight == 0 ? User32.SetWindowPosFlags.SWP_HIDEWINDOW : User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
monitorInfo.rcMonitor.Left,
|
||||||
);
|
y,
|
||||||
|
screenWidth,
|
||||||
|
newHeight,
|
||||||
|
newHeight == 0 ? User32.SetWindowPosFlags.SWP_HIDEWINDOW : User32.SetWindowPosFlags.SWP_SHOWWINDOW
|
||||||
|
);
|
||||||
|
}
|
||||||
}, TimeSpan.FromMilliseconds(100));
|
}, TimeSpan.FromMilliseconds(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,67 +10,67 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
{
|
{
|
||||||
public class EasingHelper
|
public class EasingHelper
|
||||||
{
|
{
|
||||||
public static float EaseInOutSine(float t)
|
public static double EaseInOutSine(double t)
|
||||||
{
|
{
|
||||||
return -(MathF.Cos(MathF.PI * t) - 1f) / 2f;
|
return -(Math.Cos(Math.PI * t) - 1f) / 2f;
|
||||||
}
|
}
|
||||||
public static float EaseInOutQuad(float t)
|
public static double EaseInOutQuad(double t)
|
||||||
{
|
{
|
||||||
return t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
return t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutCubic(float t)
|
public static double EaseInOutCubic(double t)
|
||||||
{
|
{
|
||||||
return t < 0.5f ? 4 * t * t * t : 1 - MathF.Pow(-2 * t + 2, 3) / 2;
|
return t < 0.5f ? 4 * t * t * t : 1 - Math.Pow(-2 * t + 2, 3) / 2;
|
||||||
}
|
}
|
||||||
public static float EaseInOutQuart(float t)
|
public static double EaseInOutQuart(double t)
|
||||||
{
|
{
|
||||||
return t < 0.5f ? 8 * t * t * t * t : 1 - MathF.Pow(-2 * t + 2, 4) / 2;
|
return t < 0.5f ? 8 * t * t * t * t : 1 - Math.Pow(-2 * t + 2, 4) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutQuint(float t)
|
public static double EaseInOutQuint(double t)
|
||||||
{
|
{
|
||||||
return t < 0.5f ? 16 * t * t * t * t * t : 1 - MathF.Pow(-2 * t + 2, 5) / 2;
|
return t < 0.5f ? 16 * t * t * t * t * t : 1 - Math.Pow(-2 * t + 2, 5) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutExpo(float t)
|
public static double EaseInOutExpo(double t)
|
||||||
{
|
{
|
||||||
return t == 0
|
return t == 0
|
||||||
? 0
|
? 0
|
||||||
: t == 1
|
: t == 1
|
||||||
? 1
|
? 1
|
||||||
: t < 0.5 ? MathF.Pow(2, 20 * t - 10) / 2
|
: t < 0.5 ? Math.Pow(2, 20 * t - 10) / 2
|
||||||
: (2 - MathF.Pow(2, -20 * t + 10)) / 2;
|
: (2 - Math.Pow(2, -20 * t + 10)) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutCirc(float t)
|
public static double EaseInOutCirc(double t)
|
||||||
{
|
{
|
||||||
return t < 0.5f
|
return t < 0.5f
|
||||||
? (1 - MathF.Sqrt(1 - MathF.Pow(2 * t, 2))) / 2
|
? (1 - Math.Sqrt(1 - Math.Pow(2 * t, 2))) / 2
|
||||||
: (MathF.Sqrt(1 - MathF.Pow(-2 * t + 2, 2)) + 1) / 2;
|
: (Math.Sqrt(1 - Math.Pow(-2 * t + 2, 2)) + 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutBack(float t)
|
public static double EaseInOutBack(double t)
|
||||||
{
|
{
|
||||||
float c1 = 1.70158f;
|
double c1 = 1.70158f;
|
||||||
float c2 = c1 * 1.525f;
|
double c2 = c1 * 1.525f;
|
||||||
|
|
||||||
return t < 0.5
|
return t < 0.5
|
||||||
? (MathF.Pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
? (Math.Pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
||||||
: (MathF.Pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
|
: (Math.Pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutElastic(float t)
|
public static double EaseInOutElastic(double t)
|
||||||
{
|
{
|
||||||
if (t == 0 || t == 1) return t;
|
if (t == 0 || t == 1) return t;
|
||||||
float p = 0.3f;
|
double p = 0.3f;
|
||||||
float s = p / 4;
|
double s = p / 4;
|
||||||
return t < 0.5f
|
return t < 0.5f
|
||||||
? -(MathF.Pow(2, 20 * t - 10) * MathF.Sin((20 * t - 11.125f) * (2 * MathF.PI) / p)) / 2
|
? -(Math.Pow(2, 20 * t - 10) * Math.Sin((20 * t - 11.125f) * (2 * Math.PI) / p)) / 2
|
||||||
: (MathF.Pow(2, -20 * t + 10) * MathF.Sin((20 * t - 11.125f) * (2 * MathF.PI) / p)) / 2 + 1;
|
: (Math.Pow(2, -20 * t + 10) * Math.Sin((20 * t - 11.125f) * (2 * Math.PI) / p)) / 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float EaseOutBounce(float t)
|
private static double EaseOutBounce(double t)
|
||||||
{
|
{
|
||||||
if (t < 4 / 11f)
|
if (t < 4 / 11f)
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,7 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float EaseInOutBounce(float t)
|
public static double EaseInOutBounce(double t)
|
||||||
{
|
{
|
||||||
if (t < 0.5f)
|
if (t < 0.5f)
|
||||||
{
|
{
|
||||||
@@ -102,11 +102,17 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float SmoothStep(float t)
|
public static double SmoothStep(double t)
|
||||||
{
|
{
|
||||||
return t * t * (3f - 2f * t);
|
return t * t * (3f - 2f * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float Linear(float t) => t;
|
public static double CubicBezier(double t, double p0, double p1, double p2, double p3)
|
||||||
|
{
|
||||||
|
double u = 1 - t;
|
||||||
|
return u * u * u * p0 + 3 * u * u * t * p1 + 3 * u * t * t * p2 + t * t * t * p3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double Linear(double t) => t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
using BetterLyrics.WinUI3.Enums;
|
using BetterLyrics.WinUI3.Enums;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Ude;
|
using Ude;
|
||||||
|
|
||||||
@@ -69,7 +71,7 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
|
|
||||||
public static bool IsSwitchableNormalizedMatch(string fileName, string q1, string q2)
|
public static bool IsSwitchableNormalizedMatch(string fileName, string q1, string q2)
|
||||||
{
|
{
|
||||||
var normFileName = StringHelper.Normalize(fileName.Normalize());
|
var normFileName = StringHelper.Normalize(fileName);
|
||||||
var normQ1 = StringHelper.Normalize(q1);
|
var normQ1 = StringHelper.Normalize(q1);
|
||||||
var normQ2 = StringHelper.Normalize(q2);
|
var normQ2 = StringHelper.Normalize(q2);
|
||||||
|
|
||||||
@@ -78,5 +80,13 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
|| normFileName == normQ2 + normQ1;
|
|| normFileName == normQ2 + normQ1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly string[] MusicExtensions = {
|
||||||
|
".mp3", ".aac", ".m4a", ".ogg", ".opus", ".wma", ".amr",
|
||||||
|
".flac", ".alac", ".ape", ".wv", ".tak",
|
||||||
|
".wav", ".aiff", ".aif", ".pcm", ".cda", ".dsf", ".dff", ".au", ".snd",
|
||||||
|
".mid", ".midi", ".mod", ".xm", ".it", ".s3m"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string MusicSearchPattern => string.Join("|", MusicExtensions.Select(x => $"*{x}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using BetterLyrics.WinUI3.Services;
|
using BetterLyrics.WinUI3.Services.SettingsService;
|
||||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||||
using Microsoft.Graphics.Canvas.Text;
|
using Microsoft.Graphics.Canvas.Text;
|
||||||
using System;
|
using System;
|
||||||
@@ -11,10 +11,6 @@ namespace BetterLyrics.WinUI3.Helper
|
|||||||
{
|
{
|
||||||
public static class FontHelper
|
public static class FontHelper
|
||||||
{
|
{
|
||||||
private static readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
public static string[] SystemFontFamilies => CanvasTextFormat.GetSystemFontFamilies().Order().ToArray();
|
||||||
|
|
||||||
public static string[] SystemFontFamilies => CanvasTextFormat.GetSystemFontFamilies();
|
|
||||||
|
|
||||||
public static string GetUserPreferredFontFamily() => SystemFontFamilies.ElementAtOrDefault(_settingsService.SelectedFontFamilyIndex) ?? "Segoe UI";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||