Compare commits

...

257 Commits

Author SHA1 Message Date
Zhe Fang
a5b3671ce3 chores: bump version code to 147 2025-11-23 14:59:36 -05:00
Zhe Fang
181a06c932 add: support 0 duration for lyrics animation 2025-11-23 09:46:18 -05:00
Zhe Fang
93d567e21d Delete .github/workflows/jekyll-gh-pages.yml 2025-11-22 20:04:09 -05:00
Zhe Fang
9da8510de6 Remove remote_theme from Jekyll GitHub Pages workflow
Removed remote_theme configuration from the workflow.
2025-11-22 20:01:41 -05:00
Zhe Fang
3ed9e599be Add remote theme for Jekyll GitBook deployment 2025-11-22 19:59:24 -05:00
Zhe Fang
e277faea9e Update links in README.CN.md for better navigation 2025-11-22 17:15:38 -05:00
Zhe Fang
21dcd7de4b Update README.md 2025-11-22 17:12:31 -05:00
Zhe Fang
31540beaa0 chores: bump version code to 1.0.146.0 2025-11-22 16:36:27 -05:00
Zhe Fang
63ffe6b661 fix: lyrics matching rule 2025-11-22 14:46:17 -05:00
Zhe Fang
5cb880021c fix: add error parser placeholder 2025-11-22 09:38:49 -05:00
Zhe Fang
b00f2b5865 fix: parse lrc for ncm 2025-11-22 09:27:55 -05:00
Zhe Fang
90a75f1b96 add: globally set lyrics matching threshold 2025-11-21 20:58:28 -05:00
Zhe Fang
735f03542f add: support adjusting matching threshold 2025-11-21 19:53:18 -05:00
Zhe Fang
b7853ded26 fix: ncm transation wrongly tagged with roman 2025-11-21 12:13:10 -05:00
Zhe Fang
88fc0adbec fix: AM album title 2025-11-21 12:08:08 -05:00
Zhe Fang
a3366422a2 chores: code cleanup 2025-11-20 17:35:36 -05:00
Zhe Fang
8f6e106282 chores: bump version code 2025-11-20 13:02:33 -05:00
Zhe Fang
08d4f4ce90 fix: clear all media props when switching tracks (local player) 2025-11-20 12:30:06 -05:00
Zhe Fang
212041a509 fix: can not find local .lrc lyrics file when metadata is missing in the music file 2025-11-20 10:09:31 -05:00
Zhe Fang
c0f2b4106a fix: change discord presence dep 2025-11-19 18:38:18 -05:00
Zhe Fang
c704edde19 chores: code cleanup 2025-11-19 17:50:59 -05:00
Zhe Fang
35de1ef7db add: roman parse for ncm and amll-ttml-db lyrics source 2025-11-19 17:49:24 -05:00
Zhe Fang
1c8840e053 fix: search control title missing 2025-11-19 11:40:58 -05:00
Zhe Fang
2d0839d777 fix: apple music metadata fetch missing 2025-11-19 11:32:05 -05:00
Zhe Fang
7e6ce08c56 fix: amll-ttml-db search rule 2025-11-18 20:38:27 -05:00
Zhe Fang
28f75fa751 chores: rollback media app icon and name fetch algo; add new lyrics search type: best match 2025-11-18 19:07:37 -05:00
Zhe Fang
051a7af21a chores: Change fallback name for playback source 2025-11-18 09:21:13 -05:00
Zhe Fang
c8b8853561 chores: Fix taskbarlist status and progress 2025-11-18 08:50:26 -05:00
Zhe Fang
baab2bcc7a chores: bump version code 2025-11-17 22:16:08 -05:00
Zhe Fang
9a3e4adc0c chores: Fix thread issue 2025-11-17 21:02:11 -05:00
Zhe Fang
8d909da139 chores: Add spliter hint for search control 2025-11-17 19:56:07 -05:00
Zhe Fang
d97f5fec37 chores 2025-11-17 19:22:24 -05:00
Zhe Fang
9a12b06b7e chores: Add fog layer 2025-11-17 17:23:28 -05:00
Zhe Fang
3fca90ca72 chores: Change static media session icon matching to dynamic 2025-11-17 16:10:24 -05:00
Zhe Fang
220e940bbb chores: Import SnowEffect from shadertoy 2025-11-16 20:26:31 -05:00
Zhe Fang
dc627bd1ef chores: Cleanup 2025-11-16 18:02:53 -05:00
Zhe Fang
3c852a9d2f chores: Move LyricsWindowStatusExtensions to Extensions folder 2025-11-16 17:58:42 -05:00
Zhe Fang
ecff788c6c chores 2025-11-16 17:54:37 -05:00
Zhe Fang
c471f128c1 chores: Add new rule for locally search lyrics (only compare file name) 2025-11-16 08:04:22 -05:00
Zhe Fang
4a389d5e33 chores: Improve 2025-11-15 08:30:06 -05:00
Zhe Fang
ae1fa1c54d chores: update docs 2025-11-14 15:21:00 -05:00
Zhe Fang
738a4a0bec chores: update docs 2025-11-14 15:20:10 -05:00
Zhe Fang
37ae278a11 chores: update docs 2025-11-14 15:16:10 -05:00
Zhe Fang
45094bde31 chores: Add discord presence and update docs 2025-11-14 15:15:49 -05:00
Zhe Fang
81b6ebbdf6 chores: update dep 2025-11-14 12:02:20 -05:00
Zhe Fang
8cb8a026ad chores: Fix 2025-11-14 11:11:24 -05:00
Zhe Fang
4eeaf9aeec Fix #104 2025-11-14 10:17:20 -05:00
Zhe Fang
f7f5e127a0 feat: Provie settings to enable or disable word by word effect by force 2025-11-13 19:51:55 -05:00
Zhe Fang
b44a29997b chores: Add spectrum placement settings 2025-11-13 19:13:40 -05:00
Zhe Fang
f19888223e chores: Add status in ShareHub 2025-11-13 13:02:21 -05:00
Zhe Fang
a612e9c6cb chores: Update content in ShareHub 2025-11-13 12:45:08 -05:00
Zhe Fang
e6a035f8e1 chores: Change IsCJK algo 2025-11-13 07:42:01 -05:00
Zhe Fang
d7c56e6b42 chores: bump version code 2025-11-12 20:25:10 -05:00
Zhe Fang
54ec48e365 chores: fix 2025-11-12 20:01:01 -05:00
Zhe Fang
35fa2b6b57 chores: Fix album text related issue 2025-11-12 19:51:04 -05:00
Zhe Fang
4926fe55a3 chores:
- Add album text in lyrics render
- Improve song info update and draw algo
- Upgrade to .NET 10
2025-11-12 19:15:19 -05:00
Zhe Fang
008c80c886 fix: Set CJK and latin font family individually 2025-11-12 16:20:14 -05:00
Zhe Fang
7b2abfbe15 fix: Show correct translation for Netease Cloud Muic lyrics source 2025-11-12 15:48:14 -05:00
Zhe Fang
f81a661a0b chores: remove lyrics x animation to improve performance 2025-11-12 13:59:44 -05:00
Zhe Fang
31f6ce704d chores: improve work area algo 2025-11-12 09:45:39 -05:00
Zhe Fang
44a1f0a809 fix: Lyrics window did not go back to the correct position when automatically showing back for docked mode 2025-11-12 08:37:57 -05:00
Zhe Fang
607cbbe908 chores: update readme 2025-11-11 16:26:38 -05:00
Zhe Fang
e237be5d8a chores: update readme 2025-11-11 16:24:59 -05:00
Zhe Fang
253336903d chores: update readme.md 2025-11-11 16:23:33 -05:00
Zhe Fang
580c16155a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-11 14:28:50 -05:00
Zhe Fang
8ab483d244 chores: update README.md links 2025-11-11 14:28:48 -05:00
Zhe Fang
6820e59597 Update issue templates 2025-11-11 11:55:54 -05:00
Zhe Fang
c7b0d409ad chores: rollback PasswordVaultHelper 2025-11-11 11:22:58 -05:00
Zhe Fang
6c942657fc chores:
- Support reading local album art file passed by LX Music server
- Support listening LX Music portable version
- Fix translation not be read in search window
2025-11-11 10:44:10 -05:00
Zhe Fang
8288d62af2 chores: bump version code 2025-11-10 20:13:59 -05:00
Zhe Fang
bd82deb5ae chores: fix issue switching between top and bottom docked mode 2025-11-10 19:54:31 -05:00
Zhe Fang
5093939bff chores: update templates 2025-11-10 19:38:36 -05:00
Zhe Fang
340a41f920 fix: clone missing properties copy 2025-11-10 18:10:13 -05:00
Zhe Fang
3580f2eb0e chores: bump version code 2025-11-10 17:51:53 -05:00
Zhe Fang
2e792b50b2 chores: disable lyrics x transition 2025-11-10 17:18:14 -05:00
Zhe Fang
7a063a1192 chores: extra about page content from settings page 2025-11-10 14:53:18 -05:00
Zhe Fang
8485990250 fix: support open file/folder picker in flyout 2025-11-10 14:36:09 -05:00
Zhe Fang
fb16874d60 chores: update index.md 2025-11-10 13:27:21 -05:00
Zhe Fang
87afdf539a chores: update index.md in ShareHub 2025-11-10 13:24:47 -05:00
Zhe Fang
ce9cb23d6f chores 2025-11-10 13:21:17 -05:00
Zhe Fang
27629a298b chores: add pre-defined lyrics window status 2025-11-10 13:18:16 -05:00
Zhe Fang
0d051669fc chores: add import and export for lyrics window status 2025-11-10 13:02:13 -05:00
Zhe Fang
a19a97345c chores: bump version code 2025-11-09 17:12:23 -05:00
Zhe Fang
8f12c27d2a chores 2025-11-09 17:00:54 -05:00
Zhe Fang
92f2f20957 fix: lyrics window white space 2025-11-09 14:23:22 -05:00
Zhe Fang
272802214b chores: fix readme 2025-11-08 19:40:39 -05:00
Zhe Fang
7f8455b14e chores: update readme 2025-11-08 19:38:04 -05:00
Zhe Fang
ad421a5541 chores: update readme 2025-11-08 19:33:23 -05:00
Zhe Fang
1eb1d2d72b feat: track stop; chores: ui/ux adjustments, bump version code. 2025-11-08 11:41:59 -05:00
Zhe Fang
252b7e4b25 chores: bump version code 2025-11-08 08:45:27 -05:00
Zhe Fang
bebcfa7819 fix: thread access issue related to ISettingsService 2025-11-08 08:21:31 -05:00
Zhe Fang
073ddfcaee fix: player fail to pass thumbnails 2025-11-07 21:06:37 -05:00
Zhe Fang
1775d947f9 chores: bump version code 2025-11-07 16:26:05 -05:00
Zhe Fang
a5d1831717 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-07 15:51:23 -05:00
Zhe Fang
d4a924accf feat: support presistent play queue and index, add settings item: auto open music gallery and auto play music; fix: auto scroll to playing track in play queue; 2025-11-07 15:51:21 -05:00
Zhe Fang
5d65314522 更新 README.md 2025-11-07 07:00:25 -05:00
Zhe Fang
0684069e52 更新 README.CN.md 2025-11-07 06:59:24 -05:00
Zhe Fang
fea617ff98 chores: edit readme 2025-11-06 17:17:44 -05:00
Zhe Fang
4b33776340 chores: update readme 2025-11-06 17:12:56 -05:00
Zhe Fang
ea73d7ed3b chores: add all deps link in readme 2025-11-06 14:23:40 -05:00
Zhe Fang
b8fd51cbe8 chores: bump version 2025-11-06 11:45:51 -05:00
Zhe Fang
004079a7ee feat: support create and import playlist; fix text in textbox overflow issue in search window; change in-app push style 2025-11-06 11:27:59 -05:00
Zhe Fang
30d1ccf67f chores: fix ui, add lyrics search window entry in system tray 2025-11-04 09:33:01 -05:00
Zhe Fang
a24885c277 chores: update readme 2025-11-03 19:37:46 -05:00
Zhe Fang
a207224bbf chores: add zh edition 2025-11-03 12:36:16 -05:00
Zhe Fang
2c80e0815a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-11-03 11:31:09 -05:00
Zhe Fang
7f65b4addb fix: handle device lost event 2025-11-03 11:31:07 -05:00
Zhe Fang
210df4dd61 Update README.md 2025-11-02 21:33:45 -05:00
Zhe Fang
3c82908890 Update README.md 2025-11-02 21:01:01 -05:00
Zhe Fang
597cc1ec9b Update README.md 2025-11-02 20:59:29 -05:00
Zhe Fang
e354e29ec1 chores: update version code 2025-11-02 19:10:46 -05:00
Zhe Fang
dd5fb91764 chores: add delay when automatically show and hide window 2025-11-02 17:16:40 -05:00
Zhe Fang
041459e564 chores: remove gain 2025-11-02 11:26:27 -05:00
Zhe Fang
7de813b645 fix: audio graph 2025-11-02 11:05:13 -05:00
Zhe Fang
838d663834 chores: add null check in SearchQQNeteaseKugouAsync; fix search page result display issue 2025-11-02 08:47:49 -05:00
Zhe Fang
9add190383 chores: add logo for some music players 2025-11-01 21:20:47 -04:00
Zhe Fang
fa58360884 chores: add pic in faq 2025-11-01 19:27:08 -04:00
Zhe Fang
4dd032655c fix: translation issue caused by mapping 2025-11-01 19:13:10 -04:00
Zhe Fang
80984218ec add: folder filter in music gallery page; chores: add pic screenshoots; 2025-11-01 15:53:15 -04:00
Zhe Fang
df45026638 chores: update readme 2025-10-31 21:04:29 -04:00
Zhe Fang
aafc5c9fb5 chores: update readme 2025-10-31 20:59:24 -04:00
Zhe Fang
c5fccfbb63 Update README.md 2025-10-31 20:44:57 -04:00
Zhe Fang
42f03b4291 chores: relayout pics in readme 2025-10-31 19:30:25 -04:00
Zhe Fang
3339bb0d41 chores: add screenshots in readme 2025-10-31 19:26:47 -04:00
Zhe Fang
7d60f29845 chores: fix kugou translation issue; fix audio graph issue; fix lyrics status switching between different monitors issue 2025-10-31 17:10:10 -04:00
Zhe Fang
bd7e93f3e6 chores: fix i18n issue 2025-10-30 21:29:08 -04:00
Zhe Fang
c37c6ab489 Update README.md 2025-10-30 21:24:50 -04:00
Zhe Fang
125794c44f Update README.md 2025-10-30 21:22:42 -04:00
Zhe Fang
f5bdb3a431 update readme and add snow flake effect 2025-10-30 21:20:06 -04:00
Zhe Fang
e15699bb11 fix: language display 2025-10-30 17:33:13 -04:00
Zhe Fang
780cd302f0 fix: pivot issue 2025-10-30 15:52:43 -04:00
Zhe Fang
345949f536 fix: windows status switching issues 2025-10-30 15:29:31 -04:00
Zhe Fang
8dd178991a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-29 20:05:52 -04:00
Zhe Fang
834d0bf5cc fix: search page language name display 2025-10-29 20:05:50 -04:00
Zhe Fang
6d6ecb39b6 Update README.md 2025-10-29 12:07:49 -04:00
Zhe Fang
7db7c68acc Update README.md 2025-10-29 12:06:04 -04:00
Zhe Fang
7fea4ac900 Update README.md 2025-10-29 09:24:50 -04:00
Zhe Fang
3783227f43 Update README.md 2025-10-29 09:06:44 -04:00
Zhe Fang
222c1d9aa1 chores: replace romaji convert package with a lightweight one; fix search control result lacking languages 2025-10-28 15:28:45 -04:00
Zhe Fang
4e668c9890 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-27 17:31:39 -04:00
Zhe Fang
a823901b13 fix: use x:Bind to prevent properties get function got lost after compiling 2025-10-27 17:31:38 -04:00
Zhe Fang
2f9b3df92c Update README.md 2025-10-27 15:01:36 -04:00
Zhe Fang
5f65021400 chores: support volume adjustment; add more lyrics language preview in search panel; fix audio graph not shown in release mode. 2025-10-27 14:52:32 -04:00
Zhe Fang
c28866fdbe fix: sc and tc convert issue 2025-10-26 22:46:34 -04:00
Zhe Fang
fc606f9d30 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-26 22:11:46 -04:00
Zhe Fang
e5d33177d4 feat: phonetic, original and translated text can be displayed at the same time; support set cjk and western font family individually; phonetic and translated font size can be adjusted 2025-10-26 22:11:44 -04:00
Zhe Fang
ab029c9da3 Update index.md 2025-10-26 10:13:29 -04:00
Zhe Fang
a28eef85a5 Update index.md 2025-10-26 10:12:55 -04:00
Zhe Fang
9905d7642c feature: 3d lyrics (x, y, z and depth) 2025-10-25 18:57:34 -04:00
Zhe Fang
02341ecc4a feature: add angle config for fan lyrics effect 2025-10-25 16:59:03 -04:00
Zhe Fang
13802e7d16 chores: update faq 2025-10-25 16:13:39 -04:00
Zhe Fang
d25920c697 chores: update banner.png 2025-10-25 10:59:20 -04:00
Zhe Fang
639c4171dd chores: add items in faq 2025-10-25 09:55:37 -04:00
Zhe Fang
95a1d65c50 chores: add faq hyperlink btn in no music playing placeholder 2025-10-25 09:43:47 -04:00
Zhe Fang
feb4f47db9 chores: add item in faq; hide horizontal scroll bar 2025-10-25 09:14:47 -04:00
Zhe Fang
81f2c4e34a Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-10-25 08:24:30 -04:00
Zhe Fang
48176cce0f fix: misspelling of restart 2025-10-25 08:24:28 -04:00
Zhe Fang
77d41c4813 Update README.md 2025-10-24 22:49:49 -04:00
Zhe Fang
8d1be745ac chores: update version code 2025-10-24 20:54:12 -04:00
Zhe Fang
978702b6ae fix: remove border indicator on DemoWindowGrid to prevent crash 2025-10-24 20:46:30 -04:00
Zhe Fang
0e1f487ac1 chores: add .gif in readme.md 2025-10-24 18:21:19 -04:00
Zhe Fang
3c8775d2cd chores: reduce .gif fps to 24 2025-10-24 18:09:04 -04:00
Zhe Fang
7c39214f2d chores: replace .mp4 with .gif in docs 2025-10-24 18:03:27 -04:00
Zhe Fang
b7952f5eef chores: edit .csproj content to make it possible for publishing to ms store, update version code 2025-10-24 16:45:26 -04:00
Zhe Fang
8c0d3667e4 chores: add contributors section in settings page 2025-10-24 16:21:09 -04:00
Zhe Fang
e1f900a9e6 chores: add help text in switcher 2025-10-24 15:57:33 -04:00
Zhe Fang
212c1fbcdd chores: add lyrics window switcher entry for top command area ands system tray, add animation when open and close switcher 2025-10-24 15:43:36 -04:00
Zhe Fang
2cb04fa1b7 feature: add support for song title and artist font size automatic adjustment 2025-10-24 14:08:28 -04:00
Zhe Fang
8ab3a53a38 chores: add video width in docs 2025-10-24 13:15:09 -04:00
Zhe Fang
3b4d5b9668 chores: update docs 2025-10-24 13:12:29 -04:00
Zhe Fang
2409165b91 chores: update docs 2025-10-24 12:31:55 -04:00
Zhe Fang
fe1eb2882e chores: update docs 2025-10-24 12:31:15 -04:00
Zhe Fang
51dd58fc74 docs: update Google Drive link 2025-10-24 07:53:18 -04:00
Zhe Fang
0f5f663b32 chores: round value to 1 decimal place in ExtendedSlider control. 2025-10-24 07:48:53 -04:00
Zhe Fang
4815c32dba chores: default to hide in system env in docked mode, desktop mode and fullscreen mode templates 2025-10-24 07:17:49 -04:00
Zhe Fang
3f5a0a0d73 Merge pull request #120 from Storyteller-Studios/dev
chores: Force Dpi to 96
2025-10-24 07:10:48 -04:00
Raspberry-Monster
1b34b28fbe chores: Force Dpi to 96 2025-10-24 16:17:08 +08:00
Zhe Fang
fe4d67c1f1 chores: adjust SongInfoFontSize for fullscreen template mode 2025-10-23 22:42:51 -04:00
Zhe Fang
1ae00257a1 chores: update template mode config (to match with fluid layer enabled by defualt) 2025-10-23 22:26:58 -04:00
Zhe Fang
814de1a4a5 chore: enable fluid layer by default 2025-10-23 22:23:47 -04:00
Zhe Fang
28b568e7a4 chore: add accelerator Escape for close button in LyricsWindowSwitchControl 2025-10-23 22:19:51 -04:00
Zhe Fang
786d23b320 chores: add animation when switching color picker type, enable line fade by default, default to MedianCut, edit displayed text for color picker type for better direct understanding for users. 2025-10-23 21:47:37 -04:00
Zhe Fang
a394527f80 Merge pull request #119 from Storyteller-Studios/dev
Support Multiple Palette Generation Algorithm and Remove ImageSharp
2025-10-23 21:09:12 -04:00
Raspberry-Monster
80422376c3 chores: Use Bitmap's Dpi First 2025-10-24 00:31:24 +08:00
Raspberry-Monster
5114c83843 chores: Reduce Unnecessary Buffer Copies 2025-10-23 23:16:26 +08:00
Raspberry-Monster
835e0d34fc chores: Bump Dependencies, Remove ImageSharp 2025-10-23 22:38:31 +08:00
Raspberry-Monster
7ab833a53a chores: Support Multiple Palette Generation Method 2025-10-23 18:16:23 +08:00
Raspberry-Monster
d348a30237 Merge branch 'dev-upstream' into dev 2025-10-22 23:06:08 +08:00
Zhe Fang
d0b626c508 fix: issue related with docked mode 2025-10-22 10:52:57 -04:00
Raspberry-Monster
9debdc76f9 chores: Change ColorThief to Impressionist 2025-10-22 22:48:10 +08:00
Zhe Fang
67a45e90fa chore: update version code 2025-10-22 10:31:14 -04:00
Zhe Fang
b4c7655043 chores: move window color sampling settings item to general tab, remove useless debug writeline 2025-10-22 10:23:50 -04:00
Zhe Fang
2adc2aced2 fix: window color sampling incorrect behavior 2025-10-22 10:18:49 -04:00
Zhe Fang
e638739638 fix: improve docked mode window sizeing behaviors 2025-10-22 09:24:16 -04:00
Zhe Fang
c24213358e Merge pull request #118 from Storyteller-Studios/dev
Improve identification of NeteaseFamily and fix Lrc Parser unexpected behavior when parsing [Min:Sec:MillSec]
2025-10-22 07:58:28 -04:00
Raspberry-Monster
6e78f849c4 chores: Improve LrcParser 2025-10-22 14:10:23 +08:00
Raspberry-Monster
80444b69e0 chores: Improve identification of NeteaseFamily and fix Lrc Parser unexpected behavior when parsing [Min:Sec:MillSec] 2025-10-22 13:06:33 +08:00
Zhe Fang
78775e9bb3 Update README.md 2025-10-21 22:51:53 -04:00
Zhe Fang
78c81347c8 feat: add window bounds settings in ui, change ExtendedSlider layout 2025-10-21 17:15:15 -04:00
Zhe Fang
65941323eb chore: update version code 2025-10-21 15:34:13 -04:00
Zhe Fang
aee79b9971 Update README.md
chrore: update Google Drive link
2025-10-21 15:33:09 -04:00
Zhe Fang
97df1c1891 fix: MediaSourceProviderInfo ctor with 2 args didn't listen on ItemPropertyChanged and CollectionChanged events of LyricsSearchProvidersInfo and AlbumArtSearchProvidersInfo 2025-10-21 15:22:31 -04:00
Zhe Fang
8a831b17cc add ani for fluid bg 2025-10-21 09:33:07 -04:00
Zhe Fang
78076efe40 Update README.md 2025-10-21 09:09:09 -04:00
Zhe Fang
d0346bf422 fix white edge issue in docked mode 2025-10-21 07:09:36 -04:00
Zhe Fang
7cb4172e84 Update README.md 2025-10-20 22:07:36 -04:00
Zhe Fang
1f2426f51b Update README.md 2025-10-20 21:51:52 -04:00
Zhe Fang
e122fdabe8 add spectrum 2025-10-20 21:38:22 -04:00
Zhe Fang
97078d966d enhance lyrics window status manage, add fluid layer background, fix #111 #96 #91 2025-10-20 14:38:09 -04:00
Zhe Fang
c43b69b4cb rollback window ctrl btn to previous version 2025-10-12 09:40:10 -04:00
Zhe Fang
94b22552e5 update doc 2025-10-10 11:40:44 -04:00
Zhe Fang
6deb16f6cb update version code 2025-10-10 11:34:39 -04:00
Zhe Fang
e467ab9c73 替换 SourceAppUserModelId 为 PlayerId 并新增 SongId
将 SongInfo 中的 SourceAppUserModelId 属性替换为 PlayerId,新增可选属性 SongId 以支持更精确的歌曲标识。
更新了相关服务和方法的参数签名,增加对 SongId 的支持,包括 SearchSmartlyAsync 和 SearchSingleAsync 方法。
调整了 MediaSessionsService 的逻辑,支持不同播放器的 SongId 处理。
优化了代码的灵活性和可扩展性,便于处理多播放器和歌曲标识。
2025-10-10 11:29:50 -04:00
Zhe Fang
ea038c9c56 更新 README.md 2025-10-05 07:59:44 -04:00
Zhe Fang
560250ad30 更新 README.md 2025-10-05 07:57:35 -04:00
Zhe Fang
536acc69a5 更新 README.md 2025-10-05 07:56:00 -04:00
Zhe Fang
0bbb379912 update LICENSE.txt 2025-09-21 21:15:15 -04:00
Zhe Fang
1f4d29e6f2 更新 README.md 2025-09-13 06:49:20 -04:00
Zhe Fang
5d1d7476c9 update screenshots 2025-09-11 21:10:24 -04:00
Zhe Fang
e016baefe1 doc 2025-09-11 20:44:17 -04:00
Zhe Fang
70b6194788 Improve formatting and clarity in README.md 2025-09-11 20:32:26 -04:00
Zhe Fang
9f103b0ea3 Update README with QQ 音乐 details and grammar fixes 2025-09-10 09:30:39 -04:00
Zhe Fang
2924140f95 Refine README.md for grammar and clarity
Corrected grammar and punctuation throughout the README file for improved clarity and consistency.
2025-09-08 18:33:06 -04:00
Zhe Fang
3d3f168926 更新 README.md 2025-09-05 07:23:52 -04:00
Zhe Fang
63b2285a36 Update download link for app in README 2025-09-05 07:03:26 -04:00
Zhe Fang
780689fa05 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-09-04 15:19:36 -04:00
Zhe Fang
01384717c4 更新应用版本和图像处理逻辑
在 `Package.appxmanifest` 中,将版本号更新为 `1.0.73.0`,发布者显示名称更改为 `Zhe Fang`。
在 `ImageHelper.cs` 中新增 `DataUrlToByteArray` 和 `GetImageBytesFromUrlAsync` 方法,以支持数据 URL 和网络图片的处理。
在 `MediaSessionsService.cs` 中,更新了音乐专辑封面图像的下载逻辑,改用新的图像获取方法并记录 URL 信息。
2025-09-04 15:19:33 -04:00
Zhe Fang
e18d78170a Add Apple Music configuration instructions
Added instructions for configuring Apple Music in the README.
2025-09-04 09:38:31 -04:00
Zhe Fang
023bf77afc Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-09-04 09:19:18 -04:00
Zhe Fang
2877ac2101 更新版本并增强媒体处理功能
- 更新 `Package.appxmanifest` 版本号至 `1.0.72.0`。
- 修改 `LXMusic.cs` 中的 `QuerySuffix`,新增 `picUrl` 过滤器。
- 清理 `MediaSourceProviderToLogoUriConverter.cs` 中的 `using` 语句。
- 在 `ImageHelper.cs` 中添加异步方法 `DownloadImageAsByteArrayAsync`,用于下载图像。
- 在 `MediaSessionsService.cs` 中添加 `_lxMusicAlbumArtBytes` 字节数组以存储专辑封面。
- 更新媒体属性处理逻辑,以支持从 `picUrl` 下载专辑封面。
- 修改 SSE 消息接收逻辑,支持异步操作以处理图像下载和更新。
2025-09-04 09:19:16 -04:00
Zhe Fang
16d82109bb 更新 README.md 2025-09-03 12:19:09 -04:00
Zhe Fang
c703f04119 Revise README for Microsoft Store and download options 2025-09-02 18:30:31 -04:00
Zhe Fang
998853f9d2 更新 README.md 2025-09-02 13:40:45 -04:00
Zhe Fang
f560735da0 更新 README.md 2025-09-02 13:35:09 -04:00
Zhe Fang
ab9da73b49 更新 README.md 2025-09-02 13:00:38 -04:00
Zhe Fang
dc364edf75 更新 README.md 2025-09-02 12:59:27 -04:00
Zhe Fang
7fbc8fbfe7 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-09-02 07:38:47 -04:00
Zhe Fang
4a00bb2ddf 更新版本并添加对 Apple Music 的支持
- 将 `Package.appxmanifest` 的版本号更新为 `1.0.71.0`。
- 移除 `BetterLyrics.WinUI3.csproj` 中对 `TinyPinyin.Net` 的引用。
- 在 `PlaybackSettingsControl.xaml` 中更新目标语言选择,移除中文选项并添加多个新语言。
- 新增 Apple Music 令牌输入框和按钮,允许用户保存令牌。
- 在 `LyricsSearchProviderToDisplayNameConverter.cs` 和 `TranslationSearchProviderToDisplayNameConverter.cs` 中添加对 Apple Music 的支持。
- 在 `LyricsSearchProvider.cs` 中新增 `AppleMusic` 作为歌词搜索提供者,并添加相关缓存目录和格式。
- 更新 `LanguageHelper.cs` 中的目标语言列表。
- 将 `TranslationSettings.cs` 中的 `SelectedTargetLanguageIndex` 属性更改为 `SelectedTargetLanguageCode`。
- 在 `LyricsSearchService.cs` 中添加 Apple Music 的歌词搜索功能。
- 更新 `MediaSessionsService.cs` 中的翻译和歌词更新逻辑。
- 移除 `SettingsPageViewModel.cs` 中的库信息支持,添加对媒体会话服务的引用。
- 新增 `AppleMusic.cs` 文件,包含与 Apple Music API 交互的逻辑。
2025-09-02 07:38:45 -04:00
Zhe Fang
7472aa048f 更新 README.md 2025-08-27 22:07:14 -04:00
Zhe Fang
49b0f7a692 Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-08-27 08:28:44 -04:00
Zhe Fang
4d0602ebef 更新版本号并优化歌词窗口边界计算
在 `Package.appxmanifest` 文件中,将应用程序版本号从 `1.0.66.0` 更新为 `1.0.67.0`。
在 `LiveStates.cs` 文件中,修改了 `DemoLyricsWindowBounds` 的计算方式,以更准确地反映歌词窗口在监视器上的位置。
2025-08-27 08:28:42 -04:00
Zhe Fang
626395d93a Update instructions from 'Clone' to 'Fork' 2025-08-26 22:34:18 -04:00
Zhe Fang
0ab5602569 Revise translation contribution instructions
Updated translation instructions for contributors.
2025-08-26 16:50:34 -04:00
Zhe Fang
37a7528762 更新 FAQ.md 2025-08-25 08:56:13 -04:00
Zhe Fang
3ca391a509 更新 FAQ.md 2025-08-25 08:54:43 -04:00
Zhe Fang
f5e542d2f3 更新 How2Install.md 2025-08-25 08:53:10 -04:00
Zhe Fang
107bdf8bee 更新 README.md 2025-08-25 08:51:19 -04:00
Zhe Fang
3e9e56f5cc ignore ttml x-roman span 2025-08-25 07:12:24 -04:00
Zhe Fang
b0fd43ead5 fix input issue in search panel; fix display issue in lyrics window manager 2025-08-24 16:29:28 -04:00
Zhe Fang
81c59495c0 improvement 2025-08-23 21:12:57 -04:00
Zhe Fang
7c5f1a804e Merge branch 'dev' of https://github.com/jayfunc/BetterLyrics into dev 2025-08-23 18:09:14 -04:00
Zhe Fang
13ee4227f7 fix #101 fix #100 2025-08-23 18:09:12 -04:00
Zhe Fang
c1360ac972 更新 README.md 2025-08-22 17:48:53 -04:00
Zhe Fang
c72aa8a58f 更新 FAQ.md 2025-08-22 15:33:46 -04:00
Zhe Fang
9545ed610b update readme 2025-08-22 15:26:51 -04:00
Zhe Fang
1c4515acb9 update readme 2025-08-22 15:18:40 -04:00
Zhe Fang
92a6fe46de update docs 2025-08-22 15:00:57 -04:00
411 changed files with 20047 additions and 9192 deletions

22
.github/ISSUE_TEMPLATE/bug-反馈.md vendored Normal file
View File

@@ -0,0 +1,22 @@
---
name: Bug 反馈
about: 帮助我们改进 BetterLyrics
title: ''
labels: ''
assignees: ''
---
**描述问题**
**屏幕截图**
**BetterLyrics 版本**
v1.0.XX.0
**日志**
将日志以单文件形式上传到此处。你可以在此处找到日志文件 `%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\logs`
**附加信息**

21
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,21 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
**Screenshots**
**BetterLyrics Version**
v1.0.XX.0
**Logs**
Upload logs as a file here. You can find logs at `%LocalAppData%\Packages\37412.BetterLyrics_rd1g0rsrrtxw8\LocalCache\logs`
**Additional context**

View File

@@ -0,0 +1,13 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Describe the solution you'd like**
**Additional context**

13
.github/ISSUE_TEMPLATE/功能建议.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: 功能建议
about: 提供宝贵的功能建议
title: ''
labels: ''
assignees: ''
---
**描述你所构想的解决方案**
**附加信息**

1
.gitignore vendored
View File

@@ -407,3 +407,4 @@ FodyWeavers.xsd
*.sln.iml
/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package)_TemporaryKey.pfx
/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/LastFM.cs
/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Constants/Discord.cs

View File

@@ -1,150 +1,150 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<AssetTargetFallback>net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
<DefaultLanguage>zh-CN</DefaultLanguage>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
<Content Include="Images\LargeTile.scale-100.png" />
<Content Include="Images\LargeTile.scale-125.png" />
<Content Include="Images\LargeTile.scale-150.png" />
<Content Include="Images\LargeTile.scale-200.png" />
<Content Include="Images\LargeTile.scale-400.png" />
<Content Include="Images\SmallTile.scale-100.png" />
<Content Include="Images\SmallTile.scale-125.png" />
<Content Include="Images\SmallTile.scale-150.png" />
<Content Include="Images\SmallTile.scale-200.png" />
<Content Include="Images\SmallTile.scale-400.png" />
<Content Include="Images\SplashScreen.scale-100.png" />
<Content Include="Images\SplashScreen.scale-125.png" />
<Content Include="Images\SplashScreen.scale-150.png" />
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\SplashScreen.scale-400.png" />
<Content Include="Images\Square150x150Logo.scale-100.png" />
<Content Include="Images\Square150x150Logo.scale-125.png" />
<Content Include="Images\Square150x150Logo.scale-150.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-400.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-16.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-256.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-32.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
<Content Include="Images\Square44x44Logo.scale-100.png" />
<Content Include="Images\Square44x44Logo.scale-125.png" />
<Content Include="Images\Square44x44Logo.scale-150.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-400.png" />
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
<Content Include="Images\StoreLogo.scale-100.png" />
<Content Include="Images\StoreLogo.scale-125.png" />
<Content Include="Images\StoreLogo.scale-150.png" />
<Content Include="Images\StoreLogo.scale-200.png" />
<Content Include="Images\StoreLogo.scale-400.png" />
<Content Include="Images\Wide310x150Logo.scale-100.png" />
<Content Include="Images\Wide310x150Logo.scale-125.png" />
<Content Include="Images\Wide310x150Logo.scale-150.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<Content Include="Images\Wide310x150Logo.scale-400.png" />
<None Include="Package.StoreAssociation.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
<EnableMsixTooling>true</EnableMsixTooling>
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
<PathToXAMLWinRTImplementations>BetterLyrics.WinUI3\</PathToXAMLWinRTImplementations>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>6576cd19-ef92-4099-b37d-e2d8ebdb6bf5</ProjectGuid>
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<AssetTargetFallback>net10.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)</AssetTargetFallback>
<DefaultLanguage>zh-CN</DefaultLanguage>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj</EntryPointProjectUniqueName>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundlePlatforms>x86|x64</AppxBundlePlatforms>
<GenerateTemporaryStoreCertificate>True</GenerateTemporaryStoreCertificate>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateKeyFile>BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<AppxBundle>Always</AppxBundle>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<None Include="BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx" />
<Content Include="Images\LargeTile.scale-100.png" />
<Content Include="Images\LargeTile.scale-125.png" />
<Content Include="Images\LargeTile.scale-150.png" />
<Content Include="Images\LargeTile.scale-200.png" />
<Content Include="Images\LargeTile.scale-400.png" />
<Content Include="Images\SmallTile.scale-100.png" />
<Content Include="Images\SmallTile.scale-125.png" />
<Content Include="Images\SmallTile.scale-150.png" />
<Content Include="Images\SmallTile.scale-200.png" />
<Content Include="Images\SmallTile.scale-400.png" />
<Content Include="Images\SplashScreen.scale-100.png" />
<Content Include="Images\SplashScreen.scale-125.png" />
<Content Include="Images\SplashScreen.scale-150.png" />
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\SplashScreen.scale-400.png" />
<Content Include="Images\Square150x150Logo.scale-100.png" />
<Content Include="Images\Square150x150Logo.scale-125.png" />
<Content Include="Images\Square150x150Logo.scale-150.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-400.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-16.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-24.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-256.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-32.png" />
<Content Include="Images\Square44x44Logo.altform-lightunplated_targetsize-48.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-16.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-256.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-32.png" />
<Content Include="Images\Square44x44Logo.altform-unplated_targetsize-48.png" />
<Content Include="Images\Square44x44Logo.scale-100.png" />
<Content Include="Images\Square44x44Logo.scale-125.png" />
<Content Include="Images\Square44x44Logo.scale-150.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-400.png" />
<Content Include="Images\Square44x44Logo.targetsize-16.png" />
<Content Include="Images\Square44x44Logo.targetsize-24.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\Square44x44Logo.targetsize-256.png" />
<Content Include="Images\Square44x44Logo.targetsize-32.png" />
<Content Include="Images\Square44x44Logo.targetsize-48.png" />
<Content Include="Images\StoreLogo.scale-100.png" />
<Content Include="Images\StoreLogo.scale-125.png" />
<Content Include="Images\StoreLogo.scale-150.png" />
<Content Include="Images\StoreLogo.scale-200.png" />
<Content Include="Images\StoreLogo.scale-400.png" />
<Content Include="Images\Wide310x150Logo.scale-100.png" />
<Content Include="Images\Wide310x150Logo.scale-125.png" />
<Content Include="Images\Wide310x150Logo.scale-150.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<Content Include="Images\Wide310x150Logo.scale-400.png" />
<None Include="Package.StoreAssociation.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj">
<EnableMsixTooling>true</EnableMsixTooling>
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7175" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
</Project>

View File

@@ -12,13 +12,13 @@
<Identity
Name="37412.BetterLyrics"
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
Version="1.0.61.0" />
Version="1.0.147.0" />
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>BetterLyrics</DisplayName>
<PublisherDisplayName>founchoo</PublisherDisplayName>
<PublisherDisplayName>Zhe Fang</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>

View File

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

View File

@@ -1,14 +1,15 @@
// 2025/6/23 by Zhe Fang
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services;
using BetterLyrics.WinUI3.Hooks;
using BetterLyrics.WinUI3.Services.AlbumArtSearchService;
using BetterLyrics.WinUI3.Services.DiscordService;
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.ResourceService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.Services.TranslateService;
using BetterLyrics.WinUI3.ViewModels;
@@ -17,15 +18,10 @@ using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources;
using Serilog;
using ShadowViewer.Controls;
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -39,12 +35,6 @@ namespace BetterLyrics.WinUI3
private readonly ILogger<App> _logger;
public static new App Current => (App)Application.Current;
public static DispatcherQueue? DispatcherQueue { get; private set; }
public static DispatcherQueueTimer? DispatcherQueueTimer { get; private set; }
public static ResourceLoader? ResourceLoader { get; private set; }
public NotificationPanel? LyricsWindowNotificationPanel { get; set; }
public NotificationPanel? SettingsWindowNotificationPanel { get; set; }
private static Mutex? _instanceMutex;
@@ -52,10 +42,6 @@ namespace BetterLyrics.WinUI3
{
this.InitializeComponent();
DispatcherQueue = DispatcherQueue.GetForCurrentThread();
DispatcherQueueTimer = DispatcherQueue.CreateTimer();
ResourceLoader = new ResourceLoader();
EnsureSingleInstance();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
@@ -72,19 +58,22 @@ namespace BetterLyrics.WinUI3
private void EnsureSingleInstance()
{
bool createdNew;
_instanceMutex = new Mutex(true, Constants.App.AppName, out createdNew);
_instanceMutex = new Mutex(true, Constants.App.AppName, out bool createdNew);
if (!createdNew)
{
User32.MessageBox(HWND.NULL, ResourceLoader!.GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL);
User32.MessageBox(HWND.NULL, new ResourceLoader().GetString("TryRunMultipleInstance"), null, User32.MB_FLAGS.MB_APPLMODAL);
Environment.Exit(0);
}
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
WindowHelper.OpenWindow<LyricsWindow>();
WindowHook.OpenOrShowWindow<LyricsWindow>();
if (Ioc.Default.GetRequiredService<ISettingsService>().AppSettings.MusicGallerySettings.AutoOpen)
{
WindowHook.OpenOrShowWindow<MusicGalleryWindow>();
}
}
private static void ConfigureServices()
@@ -111,14 +100,16 @@ namespace BetterLyrics.WinUI3
.AddSingleton<ILibWatcherService, LibWatcherService>()
.AddSingleton<ITranslateService, TranslateService>()
.AddSingleton<ILastFMService, LastFMService>()
.AddSingleton<IResourceService, ResourceService>()
.AddSingleton<IDiscordService, DiscordService>()
// ViewModels
.AddSingleton<AppSettingsControlViewModel>()
.AddSingleton<LyricsBackgroundSettingsControlViewModel>()
.AddSingleton<AlbumArtLayoutSettingsControlViewModel>()
.AddSingleton<PlaybackSettingsControlViewModel>()
.AddSingleton<MediaSettingsControlViewModel>()
.AddSingleton<AllLyricsSettingsControlViewModel>()
.AddSingleton<LyricsSearchControlViewModel>()
.AddSingleton<LyricsWindowSettingsControlViewModel>()
.AddSingleton<LyricsWindowSwitchControlViewModel>()
.AddSingleton<LyricsWindowSwitchWindowViewModel>()
.AddSingleton<LyricsWindowViewModel>()
.AddSingleton<SettingsWindowViewModel>()
.AddSingleton<SystemTrayViewModel>()
@@ -126,6 +117,7 @@ namespace BetterLyrics.WinUI3
.AddSingleton<LyricsPageViewModel>()
.AddSingleton<MusicGalleryViewModel>()
.AddSingleton<LyricsRendererViewModel>()
.AddSingleton<AboutControlViewModel>()
.BuildServiceProvider()
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<RootNamespace>BetterLyrics.WinUI3</RootNamespace>
<Platforms>x86;x64;ARM64</Platforms>
@@ -22,16 +22,23 @@
<ItemGroup>
<None Remove="Assets\Segoe Fluent Icons.ttf" />
<None Remove="Assets\Wiki82.profile.xml" />
<None Remove="Controls\AboutControl.xaml" />
<None Remove="Controls\AlbumArtLayoutSettingsControl.xaml" />
<None Remove="Controls\AllLyricsSettingsControl.xaml" />
<None Remove="Controls\AppSettingsControl.xaml" />
<None Remove="Controls\DemoWindowGrid.xaml" />
<None Remove="Controls\ExtendedSlider.xaml" />
<None Remove="Controls\FontFamilyAutoSuggestBox.xaml" />
<None Remove="Controls\LyricsSearchControl.xaml" />
<None Remove="Controls\LyricsSettingsControl.xaml" />
<None Remove="Controls\LyricsStyleSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSettingsControl.xaml" />
<None Remove="Controls\LyricsWindowSwitchControl.xaml" />
<None Remove="Controls\MediaSettingsControl.xaml" />
<None Remove="Controls\PlaybackSettingsControl.xaml" />
<None Remove="Controls\PropertyRow.xaml" />
<None Remove="Controls\ShortcutTextBox.xaml" />
<None Remove="Controls\SystemTray.xaml" />
<None Remove="Views\LyricsSearchWindow.xaml" />
<None Remove="Views\LyricsWindowSwitchWindow.xaml" />
<None Remove="Views\MusicGalleryPage.xaml" />
<None Remove="Views\MusicGalleryWindow.xaml" />
<None Remove="Views\SettingsWindow.xaml" />
@@ -44,49 +51,53 @@
</ItemGroup>
<ItemGroup>
<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.OpacityMaskView" Version="0.1.250703-build.2173" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.Controls.OpacityMaskView" Version="0.1.251021-build.2365" />
<PackageReference Include="CommunityToolkit.Labs.WinUI.Shimmer" Version="0.1.250703-build.2173" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.MetadataControl" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Triggers" Version="8.2.250402" />
<PackageReference Include="ComputeSharp.D2D1.WinUI" Version="3.2.0" />
<PackageReference Include="csharp-kana" Version="1.0.2" />
<PackageReference Include="csharp-pinyin" Version="1.0.1" />
<PackageReference Include="DevWinUI.Controls" Version="9.5.0" />
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.0" />
<PackageReference Include="F23.StringSimilarity" Version="7.0.0" />
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.2" />
<PackageReference Include="Hqub.Last.fm" Version="2.5.1" />
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.0" />
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4654" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.7175" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.8.251106002" />
<PackageReference Include="NAudio.Wasapi" Version="2.2.1" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
<PackageReference Include="NTextCat" Version="0.3.65" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.3-dev-02320" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="ShadowViewer.Controls.Notification" Version="1.2.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="System.Drawing.Common" Version="9.0.8" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" />
<PackageReference Include="System.Drawing.Common" Version="10.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.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="Vanara.PInvoke.CoreAudio" Version="4.1.6" />
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.1.6" />
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.1.6" />
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.1.6" />
<PackageReference Include="Vanara.PInvoke.User32" Version="4.1.6" />
<PackageReference Include="WinUIEx" Version="2.6.0" />
<PackageReference Include="z440.atl.core" Version="7.2.0" />
<PackageReference Include="Vanara.PInvoke.DwmApi" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.Gdi32" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.Shell32" Version="4.2.1" />
<PackageReference Include="Vanara.PInvoke.User32" Version="4.2.1" />
<PackageReference Include="Vanara.Windows.Shell" Version="4.2.1" />
<PackageReference Include="VCollab.DiscordRichPresence" Version="1.7.0" />
<PackageReference Include="WinUIEx" Version="2.9.0" />
<PackageReference Include="z440.atl.core" Version="7.8.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ColorThief.WinUI3\ColorThief.WinUI3.csproj" />
<ProjectReference Include="..\..\Impressionist\Impressionist\Impressionist.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="Rendering\InAppLyricsRenderer.xaml">
@@ -100,22 +111,37 @@
</ItemGroup>
<!--Disable Trimming for Specific Packages-->
<ItemGroup>
<TrimmerRootAssembly Include="NAudio.Wasapi" />
<TrimmerRootAssembly Include="TagLibSharp" />
<TrimmerRootAssembly Include="Vanara.PInvoke.DwmApi" />
<TrimmerRootAssembly Include="Vanara.PInvoke.Gdi32" />
<TrimmerRootAssembly Include="Vanara.PInvoke.Shell32" />
<TrimmerRootAssembly Include="Vanara.PInvoke.User32" />
<TrimmerRootAssembly Include="Vanara.Windows.Shell" />
</ItemGroup>
<ItemGroup>
<Content Update="Assets\AIMP.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\AlbumArtPlaceholder.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Alipay.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\AMLLPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\AppleMusic.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Chrome.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Discord.png">
<Content Update="Assets\Edge.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Edge.png">
<Content Update="Assets\FluidEffect.bin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Empty.png">
@@ -130,6 +156,9 @@
<Content Update="Assets\foobar2000.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\HyPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\iTunes.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -142,6 +171,9 @@
<Content Update="Assets\Leaf.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Listen1.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Logo.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -154,6 +186,9 @@
<Content Update="Assets\MediaPlayerWindows11.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\MoeKoeMusic.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\MusicBee.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@@ -163,10 +198,10 @@
<Content Update="Assets\Page.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\PotPlayer.png">
<Content Update="Assets\PlanetMusic.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\QQ.png">
<Content Update="Assets\PotPlayer.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\QQMusic.png">
@@ -175,19 +210,57 @@
<Content Update="Assets\Question.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\SaltPlayerForWindows.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Segoe Fluent Icons.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Spotify.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Telegram.png">
<Content Update="Assets\WeChatReward.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Wiki82.profile.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\FontFamilyAutoSuggestBox.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsStyleSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Views\LyricsWindowSwitchWindow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsWindowSwitchControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\DemoWindowGrid.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsWindowSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Views\LyricsSearchWindow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsSearchControl.xaml">
<Generator>MSBuild:Compile</Generator>
@@ -204,12 +277,7 @@
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\AllLyricsSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\LyricsSettingsControl.xaml">
<Page Update="Controls\LyricsEffectSettingsControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
@@ -258,6 +326,24 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<PRIResource Update="Strings\en-US\Resources.resw">
<Generator></Generator>
</PRIResource>
</ItemGroup>
<ItemGroup>
<Folder Include="TemplateSelector\" />
</ItemGroup>
<ItemGroup>
<Page Update="Controls\PropertyRow.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="Controls\AboutControl.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
@@ -280,8 +366,5 @@
<AssemblyInfoVersionType>SettingsVersion</AssemblyInfoVersionType>
<InheritWinAppVersionFrom>AssemblyVersion</InheritWinAppVersionFrom>
<PackageVersionSettings>AssemblyVersion.None.None</PackageVersionSettings>
<Version>2025.6.0</Version>
<AssemblyVersion>2025.6.18.0110</AssemblyVersion>
<FileVersion>2025.6.18.0110</FileVersion>
</PropertyGroup>
</Project>

View File

@@ -3,11 +3,8 @@ 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
namespace BetterLyrics.WinUI3.Collections
{
// https://stackoverflow.com/a/32013610/11048731
public class FullyObservableCollection<T> : ObservableCollection<T>

View File

@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
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";
public const string BaseUrl = "https://raw.githubusercontent.com/Steve-xmh/amll-ttml-db/refs/heads/main";
public const string QueryPrefix = "raw-lyrics";
public const string IndexSuffix = "metadata/raw-lyrics-index.jsonl";
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public static class App
{

View File

@@ -0,0 +1,7 @@
namespace BetterLyrics.WinUI3.Constants
{
public static class AppleMusic
{
public const string MediaUserTokenKey = "AppleMusicMediaUserToken";
}
}

View File

@@ -0,0 +1,7 @@
namespace BetterLyrics.WinUI3.Constants
{
class Discord
{
public const string AppID = "Your Discord app ID here";
}
}

View File

@@ -0,0 +1,8 @@
namespace BetterLyrics.WinUI3.Constants
{
public class ExtendedGenreFiled
{
public const string NetEaseCloudMusicTrackID = "NCM-";
public const string FileName = "FILENAME-";
}
}

View File

@@ -1,13 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public static class LXMusic
{
public const string QuerySuffix = "/subscribe-player-status?filter=progress,duration";
public const string QuerySuffix = "/subscribe-player-status?filter=progress,duration,picUrl";
}
}

View File

@@ -1,16 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public static class Link
{
public const string GithubUrl = "https://github.com/jayfunc/BetterLyrics";
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";
public const string MicrosoftStore = "https://apps.microsoft.com/detail/9p1wcd1p597r";
public const string GitHub = "https://github.com/jayfunc/BetterLyrics";
public const string ShareHub = $"{GitHub}/blob/dev/ShareHub/index.md";
public const string TermsOfService = $"{GitHub}/blob/dev/TermsofService.md";
public const string PrivacyPolicy = $"{GitHub}/blob/dev/PrivacyPolicy.md";
public const string UserGuide = $"{GitHub}/wiki/User-Guide";
public const string AppleMusicCfg = $"{UserGuide}#lyrics-source-configuration";
public const string QQGroup = "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 Discord = "https://discord.gg/5yAQPnyCKv";
public const string Telegram = "https://t.me/+svhSLZ7awPsxNGY1";
}
}

View File

@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public static class PlayerID
{
public const string LXMusic = "cn.toside.music.desktop";
public const string LXMusicPortable = "lx-music-desktop.exe";
public const string MediaPlayerWindows11 = "Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic";
public const string AIMP = "AIMP.exe";
public const string Foobar2000 = "foobar2000.exe";
@@ -17,6 +11,7 @@ namespace BetterLyrics.WinUI3.Constants
public const string PotPlayer = "PotPlayerMini64.exe";
public const string Spotify = "Spotify.exe";
public const string AppleMusic = "AppleInc.AppleMusicWin_nzyj5cx40ttqa!App";
public const string AppleMusicAlternative = "AppleMusic.exe";
public const string NetEaseCloudMusic = "cloudmusic.exe";
public const string KugouMusic = "kugou";
public const string QQMusic = "QQMusic.exe";
@@ -25,5 +20,9 @@ namespace BetterLyrics.WinUI3.Constants
public const string Edge = "MSEdge";
public const string BetterLyrics = "37412.BetterLyrics_rd1g0rsrrtxw8!App";
public const string BetterLyricsDebug = "37412.BetterLyrics_c8mj3v9sysxb4!App";
public const string SaltPlayerForWindows = "Sakawish.SaltPlayerforWindows_q65q631pyh094!SaltPlayerforWindows";
public const string MoeKoeMusic = "cn.MoeKoe.Music";
public const string MoeKoeMusicAlternative = "electron.app.MoeKoe Music";
public const string Listen1 = "com.listen1.listen1";
}
}

View File

@@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public class PlayerName
{
public const string LXMusic = "LX Music";
public const string LXMusicPortable = "LX Music (Portable)";
public const string MediaPlayerWindows11 = "Media Player";
public const string AIMP = "AIMP";
public const string Foobar2000 = "foobar2000";
@@ -16,6 +11,7 @@ namespace BetterLyrics.WinUI3.Constants
public const string PotPlayer = "PotPlayer";
public const string Spotify = "Spotify";
public const string AppleMusic = "Apple Music";
public const string AppleMusicAlternative = "Apple Music";
public const string NetEaseCloudMusic = "网易云音乐";
public const string KugouMusic = "酷狗音乐";
public const string QQMusic = "QQ 音乐";
@@ -24,5 +20,8 @@ namespace BetterLyrics.WinUI3.Constants
public const string Edge = "Microsoft Edge";
public const string BetterLyrics = "BetterLyrics";
public const string BetterLyricsDebug = "BetterLyrics (Debug)";
public const string SaltPlayerForWindows = "Salt Player for Windows";
public const string MoeKoeMusic = "MoeKoe Music";
public const string Listen1 = "Listen 1";
}
}

View File

@@ -1,13 +1,10 @@
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);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(300);
}
}

View File

@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Constants
namespace BetterLyrics.WinUI3.Constants
{
public static class iTunes
{

View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.AboutControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:const="using:BetterLyrics.WinUI3.Constants"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
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}" />
<dev:SettingsExpander HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/Logo.png}" IsExpanded="True">
<dev:SettingsExpander.Header>
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text="BetterLyrics" />
</StackPanel>
</dev:SettingsExpander.Header>
<dev:SettingsExpander.Description>
<StackPanel
Margin="0,2,0,0"
Orientation="Horizontal"
Spacing="2">
<TextBlock Text="©" />
<HyperlinkButton
Margin="0,-1,0,0"
Content="Zhe Fang"
NavigateUri="https://github.com/jayfunc" />
<TextBlock Text="2025" />
</StackPanel>
</dev:SettingsExpander.Description>
<RichTextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}">
<Paragraph>
<Run x:Uid="SettingsPageVersion" />
<Run Text="{x:Bind helper:MetadataHelper.AppVersion}" />
</Paragraph>
</RichTextBlock>
<dev:SettingsExpander.Items>
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Spacing="6">
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="GitHub" NavigateUri="{x:Bind const:Link.GitHub}" />
<HyperlinkButton x:Uid="UserGuide" NavigateUri="{x:Bind const:Link.UserGuide}" />
<HyperlinkButton x:Uid="PrivacyPolicy" NavigateUri="{x:Bind const:Link.PrivacyPolicy}" />
<HyperlinkButton x:Uid="TermsOfService" NavigateUri="{x:Bind const:Link.TermsOfService}" />
</StackPanel>
</StackPanel>
</dev:SettingsCard>
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Spacing="6">
<TextBlock x:Uid="SetingsPageFeedback" />
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton x:Uid="SettingsPageQQGroup" NavigateUri="{x:Bind const:Link.QQGroup}" />
<HyperlinkButton x:Uid="SettingsPageDiscord" NavigateUri="{x:Bind const:Link.Discord}" />
<HyperlinkButton x:Uid="SettingsPageTelegram" NavigateUri="{x:Bind const:Link.Telegram}" />
</StackPanel>
</StackPanel>
</dev:SettingsCard>
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Spacing="6">
<TextBlock x:Uid="SetingsPageDonation" />
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="Buy Me a Coffee" NavigateUri="https://buymeacoffee.com/founchoo" />
<HyperlinkButton Content="PayPal" NavigateUri="https://paypal.me/zhefangpay" />
<Button
Content="支付宝"
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
Style="{StaticResource GhostButtonStyle}">
<Button.Flyout>
<Flyout>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="CornerRadius" Value="12" />
<Setter Property="Padding" Value="0" />
</Style>
</Flyout.FlyoutPresenterStyle>
<Image Height="300" Source="/Assets/Alipay.jpg" />
</Flyout>
</Button.Flyout>
</Button>
<Button
Content="微信"
Foreground="{ThemeResource AccentTextFillColorPrimaryBrush}"
Style="{StaticResource GhostButtonStyle}">
<Button.Flyout>
<Flyout>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="CornerRadius" Value="12" />
<Setter Property="Padding" Value="0" />
</Style>
</Flyout.FlyoutPresenterStyle>
<Image Height="300" Source="/Assets/WeChatReward.png" />
</Flyout>
</Button.Flyout>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="*" />
<TextBlock
x:Uid="SetingsPageThanks"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</dev:SettingsCard>
<dev:SettingsCard HorizontalContentAlignment="Left" ContentAlignment="Left">
<StackPanel Spacing="6">
<TextBlock x:Uid="SetingsPageContributors" />
<StackPanel Margin="-12,0,0,0" Orientation="Horizontal">
<HyperlinkButton Content="jayfunc" NavigateUri="https://github.com/jayfunc" />
<HyperlinkButton Content="Raspberry-Monster" NavigateUri="https://github.com/Raspberry-Monster" />
<HyperlinkButton Content="ZHider" NavigateUri="https://github.com/ZHider" />
<HyperlinkButton Content="kusutori" NavigateUri="https://github.com/kusutori" />
</StackPanel>
</StackPanel>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
<dev:SettingsExpander.ItemsFooter>
<InfoBar
x:Uid="SettingsPageDisclaimer"
BorderThickness="0"
CornerRadius="0"
IsClosable="False"
IsOpen="True"
Severity="Warning" />
</dev:SettingsExpander.ItemsFooter>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageMockMusicPlaying">
<HyperlinkButton x:Uid="SettingsPagePlayingMockMusicButton" NavigateUri="https://soundcloud.com/carlyraejepsen/cut-to-the-feeling" />
</dev:SettingsCard>
<dev:SettingsExpander x:Uid="SettingsPageCache" IsExpanded="True">
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenCacheFolderCommand}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard>
<Button x:Uid="SettingsPageClearCache" Command="{x:Bind ViewModel.ClearCacheFilesCommand}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageSettings">
<Button x:Uid="SettingsPageOpenFolderButton" Command="{x:Bind ViewModel.OpenSettingsFolderCommand}" />
</dev:SettingsCard>
<dev:SettingsExpander x:Uid="SettingsPageSettingsManager" IsExpanded="True">
<StackPanel Orientation="Horizontal" Spacing="6">
<Button x:Uid="SettingsPageImportSettingsButton" Command="{x:Bind ViewModel.ImportSettingsCommand}" />
<Button x:Uid="SettingsPageExportSettingsButton" Command="{x:Bind ViewModel.ExportSettingsCommand}" />
</StackPanel>
<dev:SettingsExpander.ItemsHeader>
<InfoBar
x:Uid="SettingsPageImportSettingsInfo"
BorderThickness="0"
CornerRadius="0"
IsClosable="False"
IsOpen="True"
Severity="Warning" />
</dev:SettingsExpander.ItemsHeader>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageDebugOverlay">
<ToggleSwitch IsOn="{x:Bind ViewModel.IsDebugOverlayEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageFixedTimeStep" Visibility="Collapsed">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.AdvancedSettings.IsFixedTimeStep, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageFPS" Visibility="Collapsed">
<uc:ExtendedSlider
Default="60"
Frequency="10"
Maximum="240"
Minimum="30"
Value="{x:Bind ViewModel.AppSettings.AdvancedSettings.FPS, Mode=TwoWay}" />
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,20 @@
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml.Controls;
// 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 AboutControl : UserControl
{
public AboutControlViewModel ViewModel => (AboutControlViewModel)DataContext;
public AboutControl()
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<AboutControlViewModel>();
}
}
}

View File

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

View File

@@ -1,19 +1,6 @@
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
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.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.
@@ -22,11 +9,18 @@ namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class AlbumArtLayoutSettingsControl : UserControl
{
public AlbumArtLayoutSettingsControlViewModel ViewModel => (AlbumArtLayoutSettingsControlViewModel)DataContext;
public static readonly DependencyProperty AlbumArtLayoutSettingsProperty =
DependencyProperty.Register(nameof(AlbumArtLayoutSettings), typeof(AlbumArtLayoutSettings), typeof(AlbumArtLayoutSettingsControl), new PropertyMetadata(default));
public AlbumArtLayoutSettings AlbumArtLayoutSettings
{
get => (AlbumArtLayoutSettings)GetValue(AlbumArtLayoutSettingsProperty);
set => SetValue(AlbumArtLayoutSettingsProperty, value);
}
public AlbumArtLayoutSettingsControl()
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<AlbumArtLayoutSettingsControlViewModel>();
}
}
}

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.AllLyricsSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
mc:Ignorable="d">
<Grid>
<controls:SwitchPresenter Margin="0,72,0,0" Value="{Binding SelectedItem.Tag, ElementName=LyricsSettingsSegmentedControl}">
<controls:Case Value="Standard">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.StandardLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.StandardLyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<controls:Case Value="Desktop">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DesktopLyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<controls:Case Value="Dock">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.DockLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.DockLyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<controls:Case Value="PictureInPicture">
<uc:LyricsSettingsControl LyricsEffectSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsEffectSettings, Mode=OneWay}" LyricsStyleSettings="{x:Bind ViewModel.AppSettings.PictureInPictureLyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
</controls:SwitchPresenter>
<controls:Segmented
x:Name="LyricsSettingsSegmentedControl"
Margin="36,36,36,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
SelectedIndex="{x:Bind ViewModel.SelectedTabIndex, Mode=OneWay}">
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlStandard" Tag="Standard" />
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDock" Tag="Dock" />
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlDesktop" Tag="Desktop" />
<controls:SegmentedItem x:Uid="AllLyricsSettingsControlPictureInPicture" Tag="PictureInPicture" />
</controls:Segmented>
</Grid>
</UserControl>

View File

@@ -1,32 +0,0 @@
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>();
}
}
}

View File

@@ -5,8 +5,12 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:globalization="using:Windows.Globalization"
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
@@ -19,174 +23,89 @@
<TextBlock x:Uid="SettingsPageAppAppearance" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander
<dev:SettingsExpander
x:Uid="SettingsPageLanguage"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF2B7;}"
IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.Language, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageSystemLanguage" />
<ComboBoxItem x:Uid="SettingsPageEN" />
<ComboBoxItem x:Uid="SettingsPageSC" />
<ComboBoxItem x:Uid="SettingsPageTC" />
<ComboBoxItem x:Uid="SettingsPageJA" />
<ComboBoxItem x:Uid="SettingsPageKO" />
<ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedDisplayLanguages}" SelectedIndex="{x:Bind ViewModel.AppSettings.GeneralSettings.LanguageCode, Mode=TwoWay, Converter={StaticResource DisplayLanguageCodeToIndexConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="models:ExtendedLanguage">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<controls:SettingsExpander.Items>
<controls:SettingsCard>
<dev:SettingsExpander.Items>
<dev:SettingsCard>
<Button x:Uid="SettingsPageRestart" Command="{x:Bind ViewModel.RestartAppCommand}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- App behavior -->
<TextBlock x:Uid="SettingsPageAppBehavior" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF71C;}">
<dev:SettingsCard x:Uid="SettingsPageAutoStart" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF71C;}">
<ToggleSwitch
x:Name="AutoStartupToggleSwitch"
Loaded="AutoStartupToggleSwitch_Loaded"
Unloaded="AutoStartupToggleSwitch_Unloaded" />
</controls:SettingsCard>
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageAutoStartWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE736;}">
<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>
<dev:SettingsCard x:Uid="SettingsPageAutoOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8F1;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoOpen, Mode=TwoWay}" />
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageIgnoreFullscreenWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE967;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IgnoreFullscreenWindow, Mode=TwoWay}" />
</controls:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAutoPlayWhenOpenMusicGalleryWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE768;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.MusicGallerySettings.AutoPlay, Mode=TwoWay}" />
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED1A;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.HideWindowWhenNotPlaying, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageGlobalDrag" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C2;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IsDragEverywhereEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E8;}">
<dev:SettingsCard x:Uid="SettingsPageExitOnLyricsWindowClosed" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE711;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ExitOnLyricsWindowClosed, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
<!-- Standard mode -->
<dev:SettingsCard x:Uid="SettingsPageListenNewSession" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF270;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.ListenOnNewPlaybackSource, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageAppStandard" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="LyricsSearchControlIgnoreCache" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8D8;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IgnoreCacheWhenSearching, Mode=TwoWay}" />
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF246;}">
<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>
<dev:SettingsCard x:Uid="SettingsPageShowHideHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ShowOrHideLyricsWindowShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- Desktop mode -->
<dev:SettingsCard x:Uid="SettingsPageBorderlessHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.BorderlessShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageAppDesktop" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageClickThroughHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.ClickThroughShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.ToggleShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF246;}">
<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="SettingsPageAutoLock" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE755;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.DesktopModeSettings.AutoLockOnDesktopMode, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLockHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DesktopModeSettings.LockShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
<!-- Dock mode -->
<TextBlock x:Uid="SettingsPageAppDock" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.DockModeSettings.ToggleShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF246;}">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
<ComboBoxItem x:Uid="MainPageSplitView" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDockMonitor" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7F4;}">
<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=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDockWindowHeight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED5E;}">
<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=&#xE8E3;}">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.DockModeSettings.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
</ComboBox>
</controls:SettingsCard>
<!-- Picture in picture mode -->
<TextBlock x:Uid="SettingsPageAppPictureInPicture" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageToggleHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.PictureInPictureModeSettings.ToggleShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageDisplayTypeSwitcher" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xF246;}">
<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>
<dev:SettingsCard x:Uid="SettingsPageLyricsWindowSwitchHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.LyricsWindowSwitchShortcut, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- Playback shortcut -->
<TextBlock x:Uid="SettingsPagePlaybackShortcut" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPagePlayOrPauseSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PlayOrPauseShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPageNextSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.NextSongShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<dev:SettingsCard x:Uid="SettingsPagePreviousSongHotKey" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEDA7;}">
<local:ShortcutTextBox Shortcut="{x:Bind ViewModel.AppSettings.GeneralSettings.PreviousSongShortcut, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
</StackPanel>
</Grid>

View File

@@ -1,20 +1,7 @@
using BetterLyrics.WinUI3.Models.Settings;
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.

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.DemoWindowGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid
Width="{x:Bind LyricsWindowStatus.DemoMonitorBounds.Width, Mode=OneWay}"
Height="{x:Bind LyricsWindowStatus.DemoMonitorBounds.Height, Mode=OneWay}"
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4">
<Grid
Width="{x:Bind LyricsWindowStatus.DemoWindowBounds.Width, Mode=OneWay}"
Height="{x:Bind LyricsWindowStatus.DemoWindowBounds.Height, Mode=OneWay}"
Margin="{x:Bind LyricsWindowStatus.DemoWindowBounds, Converter={StaticResource RectToMarginConverter}, Mode=OneWay}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{ThemeResource AccentAcrylicBackgroundFillColorDefaultBrush}"
CornerRadius="4" />
<!-- Is default -->
<Grid
Margin="4"
Padding="6,3"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4"
Opacity="0.7"
Visibility="{x:Bind LyricsWindowStatus.IsDefault, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<TextBlock
x:Uid="DemoWindowControlDefault"
FontSize="12"
TextWrapping="Wrap" />
</Grid>
<!-- Is always on top -->
<Grid
Margin="4"
Padding="6,3"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4"
Opacity="0.7"
Visibility="{x:Bind LyricsWindowStatus.IsAlwaysOnTop, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="12"
Glyph="&#xE718;" />
<FontIcon
FontFamily="{StaticResource IconFontFamily}"
FontSize="12"
Glyph="&#xE841;"
Visibility="{x:Bind LyricsWindowStatus.IsAlwaysOnTopPolling, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Grid>
<!-- Moniter name -->
<Grid
Margin="4"
Padding="6,3"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Background="{ThemeResource AcrylicBackgroundFillColorBaseBrush}"
CornerRadius="4"
Opacity="0.7">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,0,3,0"
FontSize="12"
Text="{x:Bind LyricsWindowStatus.MonitorDeviceName, Mode=OneWay}"
TextWrapping="Wrap" />
<TextBlock FontSize="12" Text="[" />
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Width, Mode=OneWay}" />
<TextBlock FontSize="12" Text="×" />
<TextBlock FontSize="12" Text="{x:Bind LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}" />
<TextBlock FontSize="12" Text="]" />
</StackPanel>
</Grid>
<!-- Config name -->
<Grid
Padding="6,3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CornerRadius="4"
Opacity="0.7">
<TextBlock
FontWeight="ExtraBlack"
Text="{x:Bind LyricsWindowStatus.Name, Mode=OneWay}"
TextWrapping="Wrap" />
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,25 @@
using BetterLyrics.WinUI3.Models;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls;
public sealed partial class DemoWindowGrid : UserControl
{
public DemoWindowGrid()
{
InitializeComponent();
}
public static readonly DependencyProperty LyricsWindowStatusProperty =
DependencyProperty.Register(nameof(LyricsWindowStatus), typeof(LyricsWindowStatus), typeof(DemoWindowGrid), new PropertyMetadata(default));
public LyricsWindowStatus LyricsWindowStatus
{
get => (LyricsWindowStatus)GetValue(LyricsWindowStatusProperty);
set => SetValue(LyricsWindowStatusProperty, value);
}
}

View File

@@ -4,54 +4,60 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="6,0,2,0"
VerticalAlignment="Center"
Text="{x:Bind Value, Mode=OneWay}" />
<TextBlock
Margin="0,0,14,0"
VerticalAlignment="Center"
Text="{x:Bind Unit, Mode=OneWay}" />
<StackPanel>
<Slider
IsEnabled="{x:Bind IsSliderEnabled, Mode=OneWay}"
Maximum="{x:Bind Maximum, Mode=OneWay}"
Minimum="{x:Bind Minimum, Mode=OneWay}"
SnapsTo="Ticks"
StepFrequency="{x:Bind Frequency, Mode=OneWay}"
Tapped="Slider_Tapped"
TickFrequency="{x:Bind Frequency, Mode=OneWay}"
TickPlacement="Outside"
TickPlacement="None"
Value="{x:Bind Value, Mode=TwoWay}" />
<Button
Margin="3,0,0,0"
VerticalAlignment="Center"
Click="ResetButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
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=&#xE738;}"
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=&#xE710;}"
Style="{StaticResource GhostButtonStyle}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
VerticalAlignment="Center"
Click="ResetButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}"
Visibility="{x:Bind ResetButtonVisibility, Mode=OneWay}" />
<Button
x:Name="SubtractButton"
VerticalAlignment="Center"
Click="SubtractButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE738;}"
Style="{StaticResource GhostButtonStyle}" />
<StackPanel
Margin="3,-2,3,0"
Orientation="Horizontal"
Spacing="2">
<TextBlock VerticalAlignment="Center" Text="{x:Bind RoundedValue, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind Unit, Mode=OneWay}" />
</StackPanel>
<Button
x:Name="AddButton"
VerticalAlignment="Center"
Click="AddButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE710;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -1,18 +1,8 @@
using Microsoft.UI.Input;
using BetterLyrics.WinUI3.Events;
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.
@@ -21,6 +11,8 @@ namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class ExtendedSlider : UserControl
{
public event EventHandler<ExtendedSliderValueChangedByUserEventArgs>? ValueChangedByUser;
public ExtendedSlider()
{
InitializeComponent();
@@ -61,19 +53,23 @@ namespace BetterLyrics.WinUI3.Controls
}
public static readonly DependencyProperty FrequencyProperty =
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
DependencyProperty.Register(nameof(Frequency), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(1.0));
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register(nameof(Minimum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register(nameof(Maximum), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(nameof(Value), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
private static readonly DependencyProperty RoundedValueProperty =
DependencyProperty.Register(nameof(Value), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(default));
public static readonly DependencyProperty DefaultProperty =
DependencyProperty.Register(nameof(Default), typeof(double), typeof(ExtendedSlider), new PropertyMetadata(default));
public static readonly DependencyProperty ResetButtonVisibilityProperty =
DependencyProperty.Register(nameof(ResetButtonVisibility), typeof(Visibility), typeof(ExtendedSlider), new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty UnitProperty =
DependencyProperty.Register(nameof(Unit), typeof(string), typeof(ExtendedSlider), new PropertyMetadata(""));
public static readonly DependencyProperty IsSliderEnabledProperty =
DependencyProperty.Register(nameof(IsSliderEnabled), typeof(bool), typeof(ExtendedSlider), new PropertyMetadata(true));
public double Frequency
{
@@ -93,7 +89,16 @@ namespace BetterLyrics.WinUI3.Controls
public double Value
{
get => (double)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
set
{
SetValue(ValueProperty, value);
SetValue(RoundedValueProperty, value.ToString("F1").Replace(".0", ""));
}
}
private string RoundedValue
{
get => (string)GetValue(RoundedValueProperty);
set => SetValue(RoundedValueProperty, value);
}
public double Default
{
@@ -110,20 +115,33 @@ namespace BetterLyrics.WinUI3.Controls
get => (string)GetValue(UnitProperty);
set => SetValue(UnitProperty, value);
}
public bool IsSliderEnabled
{
get => (bool)GetValue(IsSliderEnabledProperty);
set => SetValue(IsSliderEnabledProperty, value);
}
private void ResetButton_Click(object sender, RoutedEventArgs e)
{
Value = Default;
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
}
private void SubtractButton_Click(object sender, RoutedEventArgs e)
{
Subtract();
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
}
private void AddButton_Click(object sender, RoutedEventArgs e)
{
Add();
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
}
private void Slider_Tapped(object sender, TappedRoutedEventArgs e)
{
ValueChangedByUser?.Invoke(this, new ExtendedSliderValueChangedByUserEventArgs(Value));
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,174 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using System.Collections.Generic;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
namespace BetterLyrics.WinUI3.Controls
{
public static class InstantTip
{
public static readonly DependencyProperty ContentProperty =
DependencyProperty.RegisterAttached("Content", typeof(object), typeof(InstantTip), new PropertyMetadata(null, OnContentChanged));
public static void SetContent(DependencyObject element, object value) => element.SetValue(ContentProperty, value);
public static object GetContent(DependencyObject element) => element.GetValue(ContentProperty);
private static Dictionary<int, Popup> _activePopups = [];
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement element)
{
element.PointerEntered -= Element_PointerEntered;
element.PointerExited -= Element_PointerExited;
element.Unloaded -= Element_Unloaded;
if (e.NewValue != null)
{
element.PointerEntered += Element_PointerEntered;
element.PointerExited += Element_PointerExited;
element.Unloaded += Element_Unloaded;
}
}
}
private static void Element_PointerEntered(object sender, PointerRoutedEventArgs e)
{
if (sender is FrameworkElement element)
{
int hashCode = element.GetHashCode();
if (_activePopups.ContainsKey(hashCode))
{
_activePopups.TryGetValue(hashCode, out var popup);
if (popup != null)
{
popup.IsOpen = true;
}
}
else
{
var rawContent = GetContent(element);
if (rawContent == null) return;
// 创建可视卡片容器 (Visual Card)
var visualCard = new Grid
{
Background = (Brush)Application.Current.Resources["AcrylicBackgroundFillColorDefaultBrush"],
CornerRadius = new CornerRadius(4),
Shadow = new ThemeShadow(),
Translation = new Vector3(0, 0, 32),
Padding = new Thickness(8, 4, 8, 4)
};
var popupContent = new Grid
{
IsHitTestVisible = false,
Opacity = 0,
Padding = new Thickness(16)
};
popupContent.Children.Add(visualCard);
var popup = new Popup
{
Child = popupContent,
IsHitTestVisible = false,
ShouldConstrainToRootBounds = false,
XamlRoot = element.XamlRoot,
};
object finalContent = rawContent;
if (rawContent is ToolTip toolTipWrapper)
{
finalContent = toolTipWrapper.Content;
}
if (finalContent is string text)
{
var textBlock = new TextBlock
{
Text = text,
FontSize = 12,
MaxWidth = 320,
TextWrapping = TextWrapping.Wrap,
Foreground = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]
};
visualCard.Children.Add(textBlock);
}
else if (finalContent != null)
{
var textBlock = new TextBlock
{
Text = finalContent.ToString(),
FontSize = 12,
MaxWidth = 320,
TextWrapping = TextWrapping.Wrap,
Foreground = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"]
};
visualCard.Children.Add(textBlock);
}
var transform = element.TransformToVisual(null);
var point = transform.TransformPoint(new Point(0, element.ActualHeight));
popup.VerticalOffset = point.Y;
popup.HorizontalOffset = point.X - popupContent.Padding.Left;
popup.IsOpen = true;
App.Current.Resources.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Low, () =>
{
popupContent.OpacityTransition = new ScalarTransition();
popupContent.Opacity = 1;
});
_activePopups.Add(hashCode, popup);
}
}
}
private static void Element_PointerExited(object sender, PointerRoutedEventArgs e)
{
var element = sender as FrameworkElement;
if (element != null)
{
int hashCode = element.GetHashCode();
if (!_activePopups.ContainsKey(hashCode))
{
return;
}
_activePopups.TryGetValue(hashCode, out var popup);
if (popup != null)
{
if (popup.Child is Grid popupContent)
{
popupContent.Opacity = 0;
}
popup.IsOpen = false;
_activePopups.Remove(hashCode);
}
}
}
private static void Element_Unloaded(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement element)
{
element.PointerEntered -= Element_PointerEntered;
element.PointerExited -= Element_PointerExited;
element.Unloaded -= Element_Unloaded;
}
}
}
}

View File

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

View File

@@ -1,19 +1,6 @@
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
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.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.
@@ -22,12 +9,18 @@ namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class LyricsBackgroundSettingsControl : UserControl
{
public LyricsBackgroundSettingsControlViewModel ViewModel => (LyricsBackgroundSettingsControlViewModel)DataContext;
public static readonly DependencyProperty LyricsBackgroundSettingsProperty =
DependencyProperty.Register(nameof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettings), typeof(LyricsBackgroundSettingsControl), new PropertyMetadata(default));
public LyricsBackgroundSettings LyricsBackgroundSettings
{
get => (LyricsBackgroundSettings)GetValue(LyricsBackgroundSettingsProperty);
set => SetValue(LyricsBackgroundSettingsProperty, value);
}
public LyricsBackgroundSettingsControl()
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsBackgroundSettingsControlViewModel>();
}
}
}

View File

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

View File

@@ -0,0 +1,27 @@
using BetterLyrics.WinUI3.Models.Settings;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
// 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 LyricsEffectSettingsControl : UserControl
{
public LyricsEffectSettingsControl()
{
InitializeComponent();
}
public static readonly DependencyProperty LyricsEffectSettingsProperty =
DependencyProperty.Register(nameof(LyricsEffectSettings), typeof(LyricsEffectSettings), typeof(LyricsEffectSettingsControl), new PropertyMetadata(default));
public LyricsEffectSettings LyricsEffectSettings
{
get => (LyricsEffectSettings)GetValue(LyricsEffectSettingsProperty);
set => SetValue(LyricsEffectSettingsProperty, value);
}
}
}

View File

@@ -5,99 +5,207 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:BetterLyrics.WinUI3.Models"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid Padding="16" RowSpacing="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="0,0,0,6">
<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=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="LyricsSearchControlArtist" Description="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock x:Uid="LyricsSearchControlMappedAs" VerticalAlignment="Center" />
<TextBox Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}" TextWrapping="Wrap" />
<Button
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard>
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
<Button
x:Uid="LyricsSearchControlSearch"
Command="{x:Bind ViewModel.SearchCommand}"
Style="{StaticResource AccentButtonStyle}" />
</controls:SettingsCard>
</StackPanel>
</Grid>
<!-- 结果列表及原始歌词文件展示区域 -->
<Grid Grid.Row="1">
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" RowSpacing="12">
<Grid Grid.Column="0">
<ScrollViewer>
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsSearchControlSongInfoMapping" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="LyricsSearchControlTitle" Value="{x:Bind ViewModel.MappedSongSearchQuery.OriginalTitle, Mode=OneWay}" />
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Uid="LyricsSearchControlMappedAs"
Grid.Column="0"
VerticalAlignment="Center" />
<TextBox
Grid.Column="1"
Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedTitle, Mode=TwoWay}"
TextWrapping="Wrap" />
<Button
Grid.Column="2"
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedTitleCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</Grid>
</StackPanel>
</Grid>
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="LyricsSearchControlArtist" Value="{x:Bind ViewModel.MappedSongSearchQuery.OriginalArtist, Mode=OneWay}" />
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Uid="LyricsSearchControlMappedAs"
Grid.Column="0"
VerticalAlignment="Center" />
<TextBox
Grid.Column="1"
Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedArtist, Mode=TwoWay}"
TextWrapping="Wrap" />
<Button
Grid.Column="2"
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedArtistCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</Grid>
<RichTextBlock
FontSize="12"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
TextWrapping="Wrap">
<Paragraph>
<Run Text="*" />
<Run x:Uid="ArtistsSplitHint" />
</Paragraph>
</RichTextBlock>
<RichTextBlock
FontSize="12"
FontWeight="Bold"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Loaded="ArtistsSplitHintRichTextBlock_Loaded"
TextWrapping="Wrap">
<Paragraph>
<Run Text="; , / " />
</Paragraph>
</RichTextBlock>
</StackPanel>
</Grid>
<Grid
Padding="16"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="LyricsSearchControlAlbum" Value="{x:Bind ViewModel.MappedSongSearchQuery.OriginalAlbum, Mode=OneWay}" />
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
x:Uid="LyricsSearchControlMappedAs"
Grid.Column="0"
VerticalAlignment="Center" />
<TextBox
Grid.Column="1"
Text="{x:Bind ViewModel.MappedSongSearchQuery.MappedAlbum, Mode=TwoWay}"
TextWrapping="Wrap" />
<Button
Grid.Column="2"
VerticalAlignment="Center"
Command="{x:Bind ViewModel.ResetMappedAlbumCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE777;}"
Style="{StaticResource GhostButtonStyle}" />
</Grid>
</StackPanel>
</Grid>
<dev:SettingsCard>
<CheckBox x:Uid="LyricsSearchControlMarkAsPureMusic" IsChecked="{x:Bind ViewModel.MappedSongSearchQuery.IsMarkedAsPureMusic, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="LyricsSearchControlTargetSearchProvider">
<Button
x:Uid="LyricsSearchControlSearch"
Command="{x:Bind ViewModel.SearchCommand}"
Style="{StaticResource AccentButtonStyle}" />
</dev:SettingsCard>
</StackPanel>
</ScrollViewer>
</Grid>
<Grid Grid.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>
<DataTemplate x:DataType="models:LyricsSearchResult">
<ListViewItem IsEnabled="{x:Bind IsFound}">
<StackPanel Padding="0,6" Opacity="{x:Bind IsFound, Converter={StaticResource BoolToPartialOpacityConverter}}">
<local:PropertyRow
Margin="-8,0,0,0"
Link="{x:Bind Reference, Mode=OneWay}"
ToolTipService.ToolTip="{x:Bind Reference, TargetNullValue=N/A, Mode=OneWay}"
Value="{x:Bind Provider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
<!-- Lyrics search result -->
<StackPanel Visibility="{x:Bind IsFound, Converter={StaticResource BoolToVisibilityConverter}}">
<local:PropertyRow x:Uid="SettingsPageSongTitle" Value="{x:Bind Title, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageArtist" Value="{x:Bind DisplayArtists, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageAlbum" Value="{x:Bind Album, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsSearchControlDurauion"
Unit="s"
Value="{x:Bind Duration, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsPageMatchPercentage"
Unit="%"
Value="{x:Bind MatchPercentage, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsPageCachePath"
Link="{x:Bind SelfPath, TargetNullValue=N/A, Mode=OneWay}"
ToolTipService.ToolTip="{x:Bind SelfPath, TargetNullValue=N/A, Mode=OneWay}" />
</StackPanel>
<!-- NOT FOUND -->
<TextBlock
x:Uid="LyricsSearchControlNotFound"
VerticalAlignment="Center"
Text="Not found"
Visibility="{Binding IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
</Grid>
Visibility="{x:Bind IsFound, Converter={StaticResource BoolNegationToVisibilityConverter}}" />
</StackPanel>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
@@ -144,36 +252,54 @@
ShowPaused="False"
Visibility="{x:Bind ViewModel.IsSearching, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</Grid>
<Grid Grid.Column="1">
<ListView ItemsSource="{x:Bind ViewModel.LyricsData.LyricsLines, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.SelectedLyricsLine, Mode=TwoWay}">
<Grid Grid.Column="2">
<Pivot ItemsSource="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}">
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="Equal"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="NotEqual"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="models:LyricsData">
<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}" />
<TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="{x:Bind LanguageCode, Mode=OneWay, Converter={StaticResource LanguageCodeToDisplayedNameConverter}}" />
<InfoBadge
x:Uid="LyricsSearchControlAutoGenerated"
Margin="6,0,0,0"
Style="{StaticResource StringInfoBadgeStyle}"
Visibility="{x:Bind AutoGenerated, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate x:DataType="models:LyricsData">
<ListView ItemsSource="{x:Bind LyricsLines, Mode=OneWay}" SelectionChanged="ListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:LyricsLine">
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{x:Bind StartMs, Mode=OneWay, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock
Margin="1,0"
Foreground="{ThemeResource SystemFillColorNeutralBrush}"
Text="-" />
<TextBlock Foreground="{ThemeResource SystemFillColorNeutralBrush}" Text="{x:Bind EndMs, Mode=OneWay, Converter={StaticResource MillisecondsToFormattedTimeConverter}}" />
<TextBlock Margin="6,0" Text="{x:Bind OriginalText, Mode=OneWay}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
<StackPanel
Padding="0,36"
HorizontalAlignment="Center"
@@ -182,13 +308,13 @@
<Image MaxWidth="100" Source="/Assets/Page.png" />
<interactivity:Interaction.Behaviors>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="NotEqual"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Collapsed" />
</interactivity:DataTriggerBehavior>
<interactivity:DataTriggerBehavior
Binding="{x:Bind ViewModel.LyricsData, Mode=OneWay}"
Binding="{x:Bind ViewModel.LyricsDataArr, Mode=OneWay}"
ComparisonCondition="Equal"
Value="{x:Null}">
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
@@ -197,7 +323,7 @@
</StackPanel>
</Grid>
</Grid>
<Grid Grid.Row="2">
<Grid Grid.Row="1">
<RelativePanel>
<TextBlock
x:Uid="LyricsSearchControlHelp"

View File

@@ -1,21 +1,10 @@
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI;
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.Documents;
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.
@@ -31,5 +20,31 @@ namespace BetterLyrics.WinUI3.Controls
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsSearchControlViewModel>();
}
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel.SelectedLyricsLine = e.OriginalSource as LyricsLine;
}
private void ArtistsSplitHintRichTextBlock_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
if (sender is RichTextBlock richTextBlock)
{
TextHighlighter highlighter = new()
{
Background = App.Current.Resources["AccentTextFillColorPrimaryBrush"] as SolidColorBrush,
Ranges =
{
new() { StartIndex = 0, Length = 1 },
new() { StartIndex = 5, Length = 1 },
new() { StartIndex = 10, Length = 1 },
new() { StartIndex = 15, Length = 1 },
new() { StartIndex = 20, Length = 1 },
new() { StartIndex = 25, Length = 1 },
}
};
richTextBlock.TextHighlighters.Add(highlighter);
}
}
}
}

View File

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

View File

@@ -1,53 +0,0 @@
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);
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
using BetterLyrics.WinUI3.Models.Settings;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class LyricsStyleSettingsControl : UserControl
{
public LyricsStyleSettingsControl()
{
InitializeComponent();
}
public static readonly DependencyProperty LyricsStyleSettingsProperty =
DependencyProperty.Register(nameof(LyricsStyleSettings), typeof(LyricsStyleSettings), typeof(LyricsStyleSettingsControl), new PropertyMetadata(default));
public LyricsStyleSettings LyricsStyleSettings
{
get => (LyricsStyleSettings)GetValue(LyricsStyleSettingsProperty);
set => SetValue(LyricsStyleSettingsProperty, value);
}
}
}

View File

@@ -0,0 +1,399 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsWindowSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock
x:Uid="SettingsPageRecordedWindowStatus"
RelativePanel.AlignLeftWithPanel="True"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<StackPanel Orientation="Horizontal" Spacing="3">
<!-- Create from templates -->
<Button Content="{ui:FontIcon FontSize=16, FontFamily={StaticResource IconFontFamily}, Glyph=&#xE710;}" Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip x:Uid="SettingsPageCreateFromTemplates" />
</ToolTipService.ToolTip>
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem x:Uid="SettingsPageStandardMode" Command="{x:Bind ViewModel.CreateStandardLyricsWindowStatusCommand}" />
<MenuFlyoutItem x:Uid="SettingsPageDesktopMode" Command="{x:Bind ViewModel.CreateTransparentLyricsWindowStatusCommand}" />
<MenuFlyoutItem x:Uid="SettingsPageDockedMode" Command="{x:Bind ViewModel.CreateDockedLyricsWindowStatusCommand}" />
<MenuFlyoutItem x:Uid="SettingsPageFullscreenMode" Command="{x:Bind ViewModel.CreateFullLyricsWindowStatusCommand}" />
<MenuFlyoutItem x:Uid="SettingsPageNarrowMode" Command="{x:Bind ViewModel.CreateNarrowLyricsWindowStatusCommand}" />
</MenuFlyout>
</Button.Flyout>
</Button>
<!-- Import -->
<Button
Click="ImportButton_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=16,
Glyph=&#xE74B;}"
Style="{StaticResource GhostButtonStyle}">
<ToolTipService.ToolTip>
<ToolTip x:Uid="SettingsPageImport" />
</ToolTipService.ToolTip>
</Button>
<!-- Sharing hub -->
<HyperlinkButton x:Uid="SettingsPageShareHub" NavigateUri="{x:Bind constants:Link.ShareHub}" />
</StackPanel>
<StackPanel
Padding="24,0"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="4"
Spacing="16"
Visibility="{Binding ElementName=LyricsWindowManagerExpander, Path=IsExpanded, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<ListView
x:Name="WindowStatusListView"
Padding="0,12"
CornerRadius="4"
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Padding="0,10"
RightTapped="StackPanel_RightTapped"
Spacing="6">
<StackPanel.ContextFlyout>
<MenuBarItemFlyout>
<MenuFlyoutItem
x:Uid="LyricsWindowSettingsControlSetDefault"
Click="SetDefaultMenuFlyoutItem_Click"
IsEnabled="{Binding IsDefault, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
<MenuFlyoutItem x:Uid="SettingsPageCreateFromCurrent" Click="CopyMenuFlyoutItem_Click" />
<MenuFlyoutItem x:Uid="LyricsWindowSettingsControlShare" Click="ShareMenuFlyoutItem_Click" />
<MenuFlyoutItem
x:Uid="SettingsPageDelete"
Click="DeleteMenuFlyoutItem_Click"
IsEnabled="{Binding IsDefault, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}" />
</MenuBarItemFlyout>
</StackPanel.ContextFlyout>
<uc:DemoWindowGrid LyricsWindowStatus="{Binding}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
<Grid Grid.Column="1">
<Grid Padding="36,0" Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock x:Uid="LyricsWindowSettingsControlCurrentLyricsWindowConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<Pivot SelectionChanged="Pivot_SelectionChanged">
<PivotItem Tag="General">
<PivotItem.Header>
<TextBlock
x:Uid="AppSettingsControlGeneral"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="AlbumArtStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAlbumStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsStyle">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsStyle"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsEffect">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageLyricsEffect"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="LyricsBackground">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageBackgroundOverlay"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
<PivotItem Tag="Advanced">
<PivotItem.Header>
<TextBlock
x:Uid="SettingsPageAdvanced"
VerticalAlignment="Center"
Style="{StaticResource BodyTextBlockStyle}" />
</PivotItem.Header>
</PivotItem>
</Pivot>
</StackPanel>
</Grid>
<controls:SwitchPresenter Margin="0,110,0,0" Value="{x:Bind ViewModel.ListViewSelectedItemTag, Mode=OneWay}">
<controls:SwitchPresenter.ContentTransitions>
<TransitionCollection>
<PopupThemeTransition />
</TransitionCollection>
</controls:SwitchPresenter.ContentTransitions>
<!-- General -->
<controls:Case Value="General">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageConfigName" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8AC;}">
<StackPanel
Margin="0,6,0,0"
Orientation="Horizontal"
Spacing="6">
<TextBox Text="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.Name, Mode=TwoWay}" TextWrapping="Wrap" />
<Button Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, FontSize=12, Glyph=&#xE8FB;}" Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</dev:SettingsCard>
<dev:SettingsExpander
x:Uid="SettingsPageDisplayTypeSwitcher"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF246;}"
IsExpanded="True">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsDisplayType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="MainPageAlbumArtOnly" />
<ComboBoxItem x:Uid="MainPageLyriscOnly" />
<ComboBoxItem x:Uid="MainPageSplitView" />
</ComboBox>
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageLayoutOrientation">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsLayoutOrientation, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationHorizontal" />
<ComboBoxItem x:Uid="SettingsPageLayoutOrientationVertical" />
</ComboBox>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageWorkArea"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE78B;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageWorkAreaHeight" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<uc:ExtendedSlider
Default="64"
Maximum="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorBounds.Height, Mode=OneWay}"
Minimum="64"
Unit="px"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockHeight, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDockPlacement" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.DockPlacement, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageDockPlacementTop" />
<ComboBoxItem x:Uid="SettingsPageDockPlacementBottom" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDockMonitor" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsWorkArea, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ComboBox ItemsSource="{x:Bind ViewModel.MonitorDeviceNames, Mode=OneWay}" SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MonitorDeviceName, Mode=TwoWay}" />
<Button
Command="{x:Bind ViewModel.RefreshMonitorDeviceNamesCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE72C;}"
Style="{StaticResource GhostButtonStyle}" />
</StackPanel>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageAdaptEnvColor"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE88F;}"
IsExpanded="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard
x:Uid="SettingsPageEnvColorSample"
Header="Environment color sample mode"
IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAdaptToEnvironment, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.EnvironmentSampleMode, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleBelow" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleAbove" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleInner" />
<ComboBoxItem x:Uid="SettingsPageEnvColorSampleEdge" />
</ComboBox>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageWindowBounds"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF16B;}"
IsExpanded="True">
<dev:SettingsExpander.Items>
<dev:SettingsCard Header="X">
<NumberBox
SmallChange="10"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowX, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard Header="Y">
<NumberBox
SmallChange="10"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowY, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageWidth">
<NumberBox
SmallChange="10"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowWidth, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageHeight">
<NumberBox
SmallChange="10"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.WindowHeight, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander
x:Uid="SettingsPageAOT"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE718;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageForceAlwaysOnTop" IsEnabled="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTop, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsAlwaysOnTopPolling, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageHideWindow" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xED1A;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AutoShowOrHideWindow, Mode=TwoWay}" />
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</controls:Case>
<!-- Album art area style -->
<controls:Case Value="AlbumArtStyle">
<uc:AlbumArtLayoutSettingsControl AlbumArtLayoutSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics style -->
<controls:Case Value="LyricsStyle">
<uc:LyricsStyleSettingsControl LyricsStyleSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsStyleSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics effect -->
<controls:Case Value="LyricsEffect">
<uc:LyricsEffectSettingsControl LyricsEffectSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsEffectSettings, Mode=OneWay}" />
</controls:Case>
<!-- Lyrics background -->
<controls:Case Value="LyricsBackground">
<uc:LyricsBackgroundSettingsControl LyricsBackgroundSettings="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsBackgroundSettings, Mode=OneWay}" />
</controls:Case>
<!-- Advanced -->
<controls:Case Value="Advanced">
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<dev:SettingsCard x:Uid="SettingsPageShowInSwitchers" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C4;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsShownInSwitchers, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageClickThrough" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7C9;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsClickThrough, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageBorderless" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8B2;}">
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.IsBorderless, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDragArea" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xEB41;}">
<ComboBox SelectedIndex="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TitleBarArea, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaNone" />
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaTop" />
<ComboBoxItem x:Uid="SettingsPageTitleBarAreaWhole" />
</ComboBox>
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
</controls:Case>
</controls:SwitchPresenter>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,153 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Serialization;
using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.DependencyInjection;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using NTextCat.Commons;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Storage;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class LyricsWindowSettingsControl : UserControl
{
public LyricsWindowSettingsControlViewModel ViewModel => (LyricsWindowSettingsControlViewModel)DataContext;
private readonly ISettingsService _settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
private readonly ILiveStatesService _liveStatesService = Ioc.Default.GetRequiredService<ILiveStatesService>();
public LyricsWindowSettingsControl()
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSettingsControlViewModel>();
}
private void DeleteMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
if (sender is MenuFlyoutItem menuFlyoutItem)
{
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
{
if (_liveStatesService.LiveStates.LyricsWindowStatus == data)
{
_liveStatesService.LiveStates.LyricsWindowStatus = ViewModel.AppSettings.WindowBoundsRecords.First();
}
ViewModel.AppSettings.WindowBoundsRecords.Remove(data);
}
}
}
private void SetDefaultMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
if (sender is MenuFlyoutItem menuFlyoutItem)
{
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
{
ViewModel.AppSettings.WindowBoundsRecords.ForEach(x => x.IsDefault = false);
data.IsDefault = true;
}
}
}
private async void ShareMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
if (sender is MenuFlyoutItem menuFlyoutItem)
{
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
{
IDictionary<string, IList<string>> fileTypeChoices = new Dictionary<string, IList<string>>()
{
{ "JSON", new List<string>() { ".json" } }
};
StorageFile? file;
if (this.Parent is FlyoutPresenter)
{
file = await PickerHelper.PickSaveFileAsync<LyricsWindow>(fileTypeChoices);
}
else
{
file = await PickerHelper.PickSaveFileAsync<SettingsWindow>(fileTypeChoices);
}
if (file != null)
{
var clonedData = (LyricsWindowStatus)data.Clone();
clonedData.IsDefault = false;
var json = System.Text.Json.JsonSerializer.Serialize(clonedData, SourceGenerationContext.Default.LyricsWindowStatus);
File.WriteAllText(file.Path, json);
ToastHelper.ShowToast("ExportSettingsSuccess", null, InfoBarSeverity.Success);
}
}
}
}
private void CopyMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
if (sender is MenuFlyoutItem menuFlyoutItem)
{
if (menuFlyoutItem.DataContext is LyricsWindowStatus data)
{
var clonedData = (LyricsWindowStatus)data.Clone();
clonedData.IsDefault = false;
ViewModel.AppSettings.WindowBoundsRecords.Add(clonedData);
}
}
}
private void StackPanel_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
if (sender is StackPanel stackPanel)
{
if (stackPanel.DataContext is MenuBarItemFlyout menuBarItemFlyout)
{
menuBarItemFlyout.ShowAt(stackPanel);
}
}
}
private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is Pivot pivot)
{
if (pivot.SelectedItem is PivotItem pivotItem)
{
ViewModel?.ListViewSelectedItemTag = pivotItem.Tag;
}
}
}
private async void ImportButton_Click(object sender, RoutedEventArgs e)
{
string[] fileTypeFilter = [".json"];
StorageFile? file;
if (this.Parent is FlyoutPresenter)
{
file = await PickerHelper.PickSingleFileAsync<LyricsWindow>(fileTypeFilter);
}
else
{
file = await PickerHelper.PickSingleFileAsync<SettingsWindow>(fileTypeFilter);
}
if (file != null)
{
var json = File.ReadAllText(file.Path);
var data = System.Text.Json.JsonSerializer.Deserialize(json, SourceGenerationContext.Default.LyricsWindowStatus);
if (data != null)
{
ViewModel.AppSettings.WindowBoundsRecords.Add(data);
ToastHelper.ShowToast("ImportSettingsSuccess", null, InfoBarSeverity.Success);
}
}
}
}
}

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.LyricsWindowSwitchControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uc="using:BetterLyrics.WinUI3.Controls"
xmlns:ui="using:CommunityToolkit.WinUI"
mc:Ignorable="d">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid x:Name="ShadowCastGrid" />
<Border
x:Name="ShadowRect"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
CornerRadius="12"
Loaded="ShadowRect_Loaded"
Translation="0,0,64">
<Border.Shadow>
<ThemeShadow x:Name="Shadow" />
</Border.Shadow>
</Border>
<Grid Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}" CornerRadius="12">
<TextBlock
x:Uid="SystemTraySwitch"
Margin="20"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<Button
Margin="12"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="Button_Click"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE73C;}"
Style="{StaticResource GhostButtonStyle}">
<Button.KeyboardAccelerators>
<KeyboardAccelerator Key="Escape" />
</Button.KeyboardAccelerators>
</Button>
<ListView
Margin="48,56"
ItemsSource="{x:Bind ViewModel.AppSettings.WindowBoundsRecords, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.LiveStates.LyricsWindowStatus, Mode=TwoWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:WrapPanel HorizontalSpacing="0" VerticalSpacing="0" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid
Margin="0,10"
Padding="5"
AllowFocusOnInteraction="True"
CornerRadius="4"
Tapped="Grid_Tapped">
<uc:DemoWindowGrid LyricsWindowStatus="{Binding}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel
Margin="20"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Orientation="Horizontal"
Spacing="6">
<HyperlinkButton Click="SettingsHypelinkButton_Click">
<HyperlinkButton.Content>
<TextBlock x:Uid="LyricsWindowSwitchWindowHelp" />
</HyperlinkButton.Content>
</HyperlinkButton>
</StackPanel>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,54 @@
using BetterLyrics.WinUI3.Hooks;
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.Input;
using System.Threading.Tasks;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class LyricsWindowSwitchControl : UserControl
{
public LyricsWindowSwitchControlViewModel ViewModel => (LyricsWindowSwitchControlViewModel)DataContext;
public LyricsWindowSwitchControl()
{
InitializeComponent();
DataContext = Ioc.Default.GetRequiredService<LyricsWindowSwitchControlViewModel>();
}
private async void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
await HideAsync();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
await HideAsync();
}
private async Task HideAsync()
{
var lyricsWindowSwitchWindow = WindowHook.GetWindow<LyricsWindowSwitchWindow>();
lyricsWindowSwitchWindow?.ViewModel.RootGridOpacity = 0;
await Task.Delay(300);
WindowHook.HideWindow<LyricsWindowSwitchWindow>();
}
private void ShadowRect_Loaded(object sender, RoutedEventArgs e)
{
Shadow.Receivers.Add(ShadowCastGrid);
}
private async void SettingsHypelinkButton_Click(object sender, RoutedEventArgs e)
{
await HideAsync();
WindowHook.OpenOrShowWindow<SettingsWindow>();
}
}
}

View File

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

View File

@@ -3,18 +3,7 @@ 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,

View File

@@ -3,8 +3,12 @@
x:Class="BetterLyrics.WinUI3.Controls.PlaybackSettingsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:constants="using:BetterLyrics.WinUI3.Constants"
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dev="using:DevWinUI"
xmlns:globalization="using:Windows.Globalization"
xmlns:helper="using:BetterLyrics.WinUI3.Helper"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:local="using:BetterLyrics.WinUI3.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@@ -17,24 +21,113 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<ScrollViewer Margin="0,72,0,0" Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Grid.Column="0" RowSpacing="18">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<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>
<!-- 播放源列表 -->
<ListView
x:Name="MediaSourceProvidersListView"
Grid.Row="0"
AllowDrop="True"
CanDragItems="True"
CanReorderItems="True"
DragItemsCompleted="MediaSourceProvidersListView_DragItemsCompleted"
ItemsSource="{x:Bind ViewModel.AppSettings.MediaSourceProvidersInfo, Mode=OneWay}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
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">
<ToolTipService.ToolTip>
<ToolTip Content="{Binding Provider, Mode=OneWay}" />
</ToolTipService.ToolTip>
<FontIcon
FontFamily="Segoe UI Symbol"
FontSize="12"
Glyph="&#x283F;" />
<Grid
Width="16"
Height="16"
CornerRadius="4">
<ImageIcon Source="{Binding LogoPath}" />
</Grid>
<TextBlock
MaxWidth="200"
Text="{Binding DisplayName, Mode=OneWay}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ScrollViewer Grid.Row="1" Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<controls:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
<dev:SettingsCard x:Uid="SettingsPageMediaSourceProvidersConfig">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<dev:SettingsCard x:Uid="SettingsPageLastFMTrack" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLastFMTrackEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageDiscordPresence">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsDiscordPresenceEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- LX music server -->
<dev:SettingsCard x:Uid="SettingsPageLXMusicServer" Visibility="{x:Bind ViewModel.SelectedMediaSourceProvider.IsLXMusic, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
x:Uid="SettingsPageLXMusicServerInput"
Grid.Column="0"
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
Text="{x:Bind ViewModel.AppSettings.GeneralSettings.LXMusicServer, Mode=TwoWay}"
TextWrapping="Wrap" />
<Button
x:Uid="SettingsPageServerTestButton"
Grid.Column="1"
Command="{x:Bind ViewModel.LXMusicServerTestCommand}"
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</Grid>
</dev:SettingsCard>
<!-- 时间轴相关配置 -->
<controls:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
<dev:SettingsExpander x:Uid="SettingsPageLyricsTimeline" IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageLyricsTimelineThreshold" IsEnabled="{x:Bind ViewModel.SelectedMediaSourceProvider.IsTimelineSyncEnabled, Mode=OneWay}">
<local:ExtendedSlider
Frequency="100"
Maximum="1000"
@@ -42,10 +135,10 @@
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">
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsExpander x:Uid="MainPagePositionOffsetSlider" IsExpanded="True">
<local:ExtendedSlider
x:Uid="SettingsPagePositionOffsetReset"
Default="0"
@@ -54,12 +147,12 @@
Minimum="-5000"
Unit="ms"
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.PositionOffset, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="LyricsPagePositionOffsetHint">
<ToggleSwitch IsOn="{x:Bind ViewModel.SelectedMediaSourceProvider.ResetPositionOffsetOnSongChanged, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 专辑封面源配置 -->
<TextBlock x:Uid="SettingsPageAlbumArtSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
@@ -77,18 +170,33 @@
</ListView.OpacityTransition>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:AlbumArtSearchProviderInfo">
<controls:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<controls:SettingsCard.HeaderIcon>
<dev:SettingsCard Header="{Binding Provider, Converter={StaticResource AlbumArtSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<dev:SettingsCard.HeaderIcon>
<FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" />
</controls:SettingsCard.HeaderIcon>
</dev:SettingsCard.HeaderIcon>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
</dev:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- 歌词源配置 -->
<TextBlock x:Uid="SettingsPageLyricsSearchProvidersConfig" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageLyricsSearchType">
<ComboBox SelectedIndex="{x:Bind ViewModel.SelectedMediaSourceProvider.LyricsSearchType, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsSearchSequential" />
<ComboBoxItem x:Uid="SettingsPageLyricsSearchBestMatch" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageMatchingThreshold">
<local:ExtendedSlider
Default="0"
Maximum="100"
Minimum="0"
Unit="%"
Value="{x:Bind ViewModel.SelectedMediaSourceProvider.MatchingThreshold, Mode=TwoWay}" />
</dev:SettingsCard>
<ListView
x:Name="LyricsSearchProvidersListView"
AllowDrop="True"
@@ -109,12 +217,48 @@
</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="&#x283F;" />
</controls:SettingsCard.HeaderIcon>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<Grid>
<dev:SettingsExpander Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}" IsExpanded="{Binding IsMatchingThresholdOverwritten, Mode=OneWay}">
<dev:SettingsExpander.HeaderIcon>
<FontIcon FontFamily="Segoe UI Symbol" Glyph="&#x283F;" />
</dev:SettingsExpander.HeaderIcon>
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageOverwriteMatchingThreshold">
<ToggleSwitch IsOn="{Binding IsMatchingThresholdOverwritten, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageMatchingThreshold" IsEnabled="{Binding IsMatchingThresholdOverwritten, Mode=OneWay}">
<local:ExtendedSlider
Default="0"
Maximum="100"
Minimum="0"
Unit="%"
Value="{Binding MatchingThreshold, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<Grid
Width="48"
HorizontalAlignment="Left"
Background="{ThemeResource ControlStrokeColorDefaultBrush}"
CornerRadius="4,0,0,4"
Opacity="0">
<interactivity:Interaction.Behaviors>
<interactivity:EventTriggerBehavior EventName="PointerEntered">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="1" />
</interactivity:EventTriggerBehavior>
<interactivity:EventTriggerBehavior EventName="PointerExited">
<interactivity:ChangePropertyAction PropertyName="Opacity" Value="0" />
</interactivity:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
<Grid.OpacityTransition>
<ScalarTransition />
</Grid.OpacityTransition>
<ToolTipService.ToolTip>
<ToolTip x:Uid="SettingsPageHoldDragSort" />
</ToolTipService.ToolTip>
</Grid>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
@@ -122,46 +266,9 @@
</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"
@@ -191,9 +298,134 @@
<ScrollViewer Style="{StaticResource SettingsScrollViewerStyle}">
<Grid Style="{StaticResource SettingsGridStyle}">
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
<!-- Realtime info -->
<TextBlock x:Uid="SettingsPageRealtimeStatus" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<!-- Playback source info -->
<Expander
x:Uid="SettingsPagePlaybackStatus"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="SettingsPagePlaybackSource" Value="{x:Bind ViewModel.MediaSessionsService.CurrentMediaSourceProviderInfo.DisplayName, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPagePlaybackSourceID" Value="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.PlayerId, TargetNullValue=N/A, Mode=OneWay}" />
</StackPanel>
</Expander>
<!-- Song info -->
<Expander
x:Uid="SettingsPageSongStatus"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="SettingsPageSongTitle" Value="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.Title, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageArtist" Value="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.DisplayArtists, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageAlbum" Value="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.Album, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsSearchControlDurauion"
Unit="s"
Value="{x:Bind ViewModel.MediaSessionsService.CurrentSongInfo.Duration, TargetNullValue=N/A, Mode=OneWay}" />
</StackPanel>
</Expander>
<!-- Search result info -->
<Expander
x:Uid="SettingsPageSearchResultStatus"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left">
<StackPanel Spacing="6">
<local:PropertyRow x:Uid="SettingsPageSongTitle" Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.Title, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageArtist" Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.DisplayArtists, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow x:Uid="SettingsPageAlbum" Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.Album, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsSearchControlDurauion"
Unit="s"
Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.Duration, TargetNullValue=N/A, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsPageLyricsProviderPrefix"
Link="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.Reference, Mode=OneWay}"
ToolTipService.ToolTip="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.Reference, TargetNullValue=N/A, Mode=OneWay}"
Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.ProviderIfFound, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
<local:PropertyRow x:Uid="LyricsPageTranslationProviderPrefix" Value="{x:Bind ViewModel.MediaSessionsService.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
<local:PropertyRow
x:Uid="LyricsPageMatchPercentage"
Unit="%"
Value="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.MatchPercentage, Mode=OneWay}" />
<local:PropertyRow
x:Uid="LyricsPageCachePath"
Link="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.SelfPath, TargetNullValue=N/A, Mode=OneWay}"
ToolTipService.ToolTip="{x:Bind ViewModel.MediaSessionsService.CurrentLyricsSearchResult.SelfPath, TargetNullValue=N/A, Mode=OneWay}" />
</StackPanel>
</Expander>
<dev:SettingsCard x:Uid="SettingsPageForceWordByWordEffect">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.GeneralSettings.IsForceWordByWordEffect, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- Lyrics translation -->
<TextBlock x:Uid="SettingsPageTranslation" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander x:Uid="LyricsPageTranslationEnabled" IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageTargetLanguage" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<ComboBox ItemsSource="{x:Bind helper:LanguageHelper.SupportedTranslationTargetLanguages}" SelectedIndex="{x:Bind ViewModel.SelectedTargetLanguageIndex, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="models:ExtendedLanguage">
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageTranslationConfig" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<dev:SettingsCard.Description>
<HyperlinkButton Content="https://github.com/LibreTranslate/LibreTranslate" NavigateUri="https://github.com/LibreTranslate/LibreTranslate" />
</dev:SettingsCard.Description>
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="12">
<TextBox
x:Uid="LibreTranslateServerTextBox"
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
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>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- Lyrics phonetic -->
<TextBlock x:Uid="SettingsPagePhonetic" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander x:Uid="SettingsPageChinese" IsExpanded="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsChineseRomanizationEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.ChineseRomanization, Converter={StaticResource EnumToIntConverter}, Mode=TwoWay}">
<ComboBoxItem x:Uid="SettingsPagePinyin" />
<ComboBoxItem x:Uid="SettingsPageJyutping" />
</ComboBox>
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageJapanese">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsJapaneseRomanizationEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- 中文简体繁体偏好 -->
<TextBlock x:Uid="SettingsPageChineseLyrics" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageChinesePreference">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTraditionalChineseEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- Last.fm -->
<TextBlock x:Uid="SettingsPageLastFM" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander
<dev:SettingsExpander
x:Uid="SettingsPageLastFMManager"
HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/LastFM.png}"
IsExpanded="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
@@ -207,114 +439,77 @@
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}">
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageLastFMUsername" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
<HyperlinkButton Content="{x:Bind ViewModel.LastFMUser.Name, Mode=OneWay}" NavigateUri="{x:Bind ViewModel.LastFMUser.Url, Mode=OneWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLastFMPlaycount" IsEnabled="{x:Bind ViewModel.IsLastFMAuthenticated, Mode=OneWay}">
</dev:SettingsCard>
<dev: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}">
</dev:SettingsCard>
<dev: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}">
</dev:SettingsCard>
<dev: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=&#xE774;}"
IsExpanded="True">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=TwoWay}" />
<controls:SettingsExpander.Items>
<controls:SettingsCard x:Uid="SettingsPageTargetLanguage">
<ComboBox SelectedIndex="{x:Bind ViewModel.AppSettings.TranslationSettings.SelectedTargetLanguageIndex, Mode=TwoWay}">
<ComboBoxItem Content="العربية" Tag="ar" />
<ComboBoxItem Content="Azərbaycan dili" Tag="az" />
<ComboBoxItem Content="简体中文" Tag="zh-Hans" />
<ComboBoxItem Content="繁體中文" Tag="zh-Hant" />
<ComboBoxItem Content="Čeština" Tag="cs" />
<ComboBoxItem Content="Dansk" Tag="da" />
<ComboBoxItem Content="Nederlands" Tag="nl" />
<ComboBoxItem Content="English" Tag="en" />
<ComboBoxItem Content="Esperanto" Tag="eo" />
<ComboBoxItem Content="Suomi" Tag="fi" />
<ComboBoxItem Content="Français" Tag="fr" />
<ComboBoxItem Content="Deutsch" Tag="de" />
<ComboBoxItem Content="Ελληνικά" Tag="el" />
<ComboBoxItem Content="עברית" Tag="he" />
<ComboBoxItem Content="हिन्दी" Tag="hi" />
<ComboBoxItem Content="Magyar" Tag="hu" />
<ComboBoxItem Content="Bahasa Indonesia" Tag="id" />
<ComboBoxItem Content="Gaeilge" Tag="ga" />
<ComboBoxItem Content="Italiano" Tag="it" />
<ComboBoxItem Content="日本語" Tag="ja" />
<ComboBoxItem Content="한국어" Tag="ko" />
<ComboBoxItem Content="فارسی" Tag="fa" />
<ComboBoxItem Content="Polski" Tag="pl" />
<ComboBoxItem Content="Português" Tag="pt" />
<ComboBoxItem Content="Русский" Tag="ru" />
<ComboBoxItem Content="Slovenčina" Tag="sk" />
<ComboBoxItem Content="Español" Tag="es" />
<ComboBoxItem Content="Svenska" Tag="sv" />
<ComboBoxItem Content="Türkçe" Tag="tr" />
<ComboBoxItem Content="Українська" Tag="uk" />
<ComboBoxItem Content="Tiếng Việt" Tag="vi" />
</ComboBox>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageTranslationConfig">
<controls:SettingsCard.Description>
<HyperlinkButton Margin="0,6,0,0" NavigateUri="https://github.com/LibreTranslate/LibreTranslate">
<TextBlock
x:Uid="SettingsPageTranslationInfoLink"
FontSize="14"
TextWrapping="Wrap" />
</HyperlinkButton>
</controls:SettingsCard.Description>
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="SettingsPageLibreTranslateServer" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsLibreTranslateEnabled, Mode=OneWay}">
<StackPanel Orientation="Horizontal" Spacing="12">
<TextBox
x:Name="LibreTranslateServerTextBox"
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
PlaceholderText="http://localhost:5000"
Text="{x:Bind ViewModel.AppSettings.TranslationSettings.LibreTranslateServer, Mode=TwoWay}" />
<Button
x:Uid="SettingsPageServerTestButton"
Command="{x:Bind ViewModel.LibreTranslateServerTestCommand}"
IsEnabled="{x:Bind ViewModel.IsLibreTranslateServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</StackPanel>
</controls:SettingsCard>
<controls:SettingsCard x:Uid="LyricsPageTranslationOnly" IsEnabled="{x:Bind ViewModel.AppSettings.TranslationSettings.IsTranslationEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind ViewModel.AppSettings.TranslationSettings.ShowTranslationOnly, Mode=TwoWay}" />
</controls:SettingsCard>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<controls:SettingsCard x:Uid="LyricsPageLyricsProviderPrefix">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.LyricsSearchProvider, Mode=OneWay, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}}" />
</controls:SettingsCard>
<controls:SettingsCard x:Uid="LyricsPageTranslationProviderPrefix">
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Text="{x:Bind ViewModel.TranslationSearchProvider, Mode=OneWay, Converter={StaticResource TranslationSearchProviderToDisplayNameConverter}}" />
</controls:SettingsCard>
<!-- LX music server -->
<TextBlock x:Uid="SettingsPageLXMusicServer" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard>
<StackPanel Orientation="Horizontal" Spacing="6">
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- amll-ttml-db -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="amll-ttml-db" />
<dev:SettingsCard x:Uid="SettingsPageAmllTtmlDbBaseUrl">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<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}" />
Grid.Column="0"
Text="{x:Bind ViewModel.AppSettings.GeneralSettings.AmllTtmlDbBaseUrl, Mode=TwoWay}"
TextWrapping="Wrap" />
<Button
x:Uid="SettingsPageServerTestButton"
Command="{x:Bind ViewModel.LXMusicServerTestCommand}"
IsEnabled="{x:Bind ViewModel.IsLXMusicServerTesting, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}" />
</StackPanel>
</controls:SettingsCard>
Grid.Column="1"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE8FB;}"
Style="{StaticResource GhostButtonStyle}" />
</Grid>
</dev:SettingsCard>
<!-- Apple Music token -->
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="Apple Muisc media-user-token" />
<dev:SettingsCard
Background="{ThemeResource SystemFillColorCautionBackgroundBrush}"
Description="Use at your own risk"
Foreground="{ThemeResource SystemFillColorCautionBrush}"
Header="WARNING">
<Grid ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox
Grid.Column="0"
PlaceholderText="media-user-token"
Text="{x:Bind ViewModel.AppleMusicMediaUserToken, Mode=TwoWay}"
TextWrapping="Wrap" />
<HyperlinkButton
Grid.Column="1"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE897;}"
NavigateUri="{x:Bind constants:Link.AppleMusicCfg}" />
<Button
Grid.Column="2"
Command="{x:Bind ViewModel.SaveAppleMusicMediaUserTokenCommand}"
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
FontSize=12,
Glyph=&#xE8FB;}"
Style="{StaticResource GhostButtonStyle}" />
</Grid>
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>

View File

@@ -1,19 +1,6 @@
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.
@@ -41,5 +28,11 @@ namespace BetterLyrics.WinUI3.Controls
// <20><> LyricsSearchProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
ViewModel.SelectedMediaSourceProvider?.LyricsSearchProvidersInfo?.Refresh();
}
private void MediaSourceProvidersListView_DragItemsCompleted(ListViewBase sender, DragItemsCompletedEventArgs args)
{
// <20><> MediaSourceProvidersInfo <20><><EFBFBD><EFBFBD> CollectionChanged <20>¼<EFBFBD>
ViewModel.AppSettings.MediaSourceProvidersInfo?.Refresh();
}
}
}

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="BetterLyrics.WinUI3.Controls.PropertyRow"
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 HorizontalAlignment="Left" ColumnSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
VerticalAlignment="Top"
Text="{x:Bind Header, Mode=OneWay}" />
<Grid
Grid.Column="1"
VerticalAlignment="Top"
PointerEntered="OnPointerEntered"
PointerExited="OnPointerExited">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<RichTextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Visibility="{x:Bind TextVisibility, Mode=OneWay}">
<Paragraph>
<Run Text="{x:Bind Value, Mode=OneWay}" />
<Run Text="{x:Bind Unit, Mode=OneWay}" />
</Paragraph>
</RichTextBlock>
<HyperlinkButton
Margin="0,-2,0,0"
Padding="0"
HorizontalContentAlignment="Left"
Click="OnLinkClicked"
Visibility="{x:Bind LinkVisibility, Mode=OneWay}">
<TextBlock Text="{x:Bind Value, Mode=OneWay}" TextWrapping="Wrap" />
</HyperlinkButton>
</Grid>
<Button
x:Name="CopyButton"
Grid.Column="1"
Margin="8,-2,0,0"
Padding="4"
VerticalAlignment="Top"
Click="OnCopyClicked"
Opacity="0">
<ToolTipService.ToolTip>
<ToolTip x:Uid="Copy" />
</ToolTipService.ToolTip>
<Button.OpacityTransition>
<ScalarTransition />
</Button.OpacityTransition>
<Grid>
<FontIcon
x:Name="CopyIcon"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE8C8;"
Opacity="1">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
<FontIcon
x:Name="CheckIcon"
FontFamily="{StaticResource IconFontFamily}"
FontSize="16"
Glyph="&#xE73E;"
Opacity="0">
<FontIcon.OpacityTransition>
<ScalarTransition />
</FontIcon.OpacityTransition>
</FontIcon>
</Grid>
</Button>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,115 @@
using BetterLyrics.WinUI3.Helper;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;
// 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 PropertyRow : UserControl
{
public PropertyRow()
{
this.InitializeComponent();
}
public string Header
{
get => (string)GetValue(HeaderProperty);
set => SetValue(HeaderProperty, value);
}
public static readonly DependencyProperty HeaderProperty =
DependencyProperty.Register(nameof(Header), typeof(string), typeof(PropertyRow), new PropertyMetadata(string.Empty));
public string Value
{
get => (string)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(nameof(Value), typeof(string), typeof(PropertyRow), new PropertyMetadata(string.Empty));
public string Link
{
get => (string)GetValue(LinkProperty);
set => SetValue(LinkProperty, value);
}
public static readonly DependencyProperty LinkProperty =
DependencyProperty.Register(nameof(Link), typeof(string), typeof(PropertyRow), new PropertyMetadata(string.Empty));
public string Unit
{
get => (string)GetValue(UnitProperty);
set => SetValue(UnitProperty, value);
}
public static readonly DependencyProperty UnitProperty =
DependencyProperty.Register(nameof(Unit), typeof(string), typeof(PropertyRow), new PropertyMetadata(string.Empty));
private Visibility TextVisibility => Link == string.Empty ? Visibility.Visible : Visibility.Collapsed;
private Visibility LinkVisibility => Link != string.Empty ? Visibility.Visible : Visibility.Collapsed;
private void OnPointerEntered(object sender, PointerRoutedEventArgs e)
{
if (!string.IsNullOrEmpty(Value))
{
CopyButton.Opacity = 1;
}
}
private void OnPointerExited(object sender, PointerRoutedEventArgs e)
{
CopyButton.Opacity = 0;
}
private void OnCopyClicked(object sender, RoutedEventArgs e)
{
var targetValue = string.IsNullOrEmpty(Link) ? Value : Link;
if (string.IsNullOrEmpty(targetValue)) return;
try
{
DataPackage dataPackage = new DataPackage();
dataPackage.SetText(targetValue);
Clipboard.SetContent(dataPackage);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Copy failed: {ex.Message}");
return;
}
CheckIcon.Opacity = 1;
CopyIcon.Opacity = 0;
this.DispatcherQueue.TryEnqueue(async () =>
{
await Task.Delay(1000);
CheckIcon.Opacity = 0;
CopyIcon.Opacity = 1;
});
}
private async void OnLinkClicked(object sender, RoutedEventArgs e)
{
Uri.TryCreate(Link, UriKind.Absolute, out var uri);
if (uri != null)
{
if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
{
await Windows.System.Launcher.LaunchUriAsync(uri);
}
else if (uri.Scheme == Uri.UriSchemeFile)
{
await LauncherHelper.SelectAndShowFile(uri.LocalPath);
}
}
}
}
}

View File

@@ -1,19 +1,12 @@
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Hooks;
using BetterLyrics.WinUI3.Services.ResourceService;
using CommunityToolkit.Mvvm.DependencyInjection;
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,
@@ -23,6 +16,8 @@ namespace BetterLyrics.WinUI3.Controls
{
public sealed partial class ShortcutTextBox : UserControl
{
private readonly IResourceService _resourceService = Ioc.Default.GetRequiredService<IResourceService>();
public ShortcutTextBox()
{
InitializeComponent();
@@ -95,18 +90,14 @@ namespace BetterLyrics.WinUI3.Controls
private void CheckButton_Click(object sender, RoutedEventArgs e)
{
bool registered = GlobalHotKeyHelper.IsHotKeyRegistered(Shortcut);
bool registered = GlobalHotKeyHook.IsHotKeyRegistered(Shortcut);
if (registered)
{
App.Current.SettingsWindowNotificationPanel?.Notify(
App.ResourceLoader!.GetString("SettingsPageShortcutRegSuccessInfo"),
InfoBarSeverity.Success);
ToastHelper.ShowToast("SettingsPageShortcutRegSuccessInfo", null, InfoBarSeverity.Success);
}
else
{
App.Current.SettingsWindowNotificationPanel?.Notify(
App.ResourceLoader!.GetString("SettingsPageShortcutRegFailInfo"),
InfoBarSeverity.Error);
ToastHelper.ShowToast("SettingsPageShortcutRegFailInfo", null, InfoBarSeverity.Error);
}
}
}

View File

@@ -29,6 +29,16 @@
<Setter Property="MinWidth" Value="600" />
</Style>
</MenuFlyout.MenuFlyoutPresenterStyle>
<MenuFlyoutItem
x:Uid="SystemTraySwitch"
Command="{x:Bind ViewModel.OpenLyricsWindowSwitchCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE8AB;}" />
<MenuFlyoutItem
x:Uid="SystemTraySearch"
Command="{x:Bind ViewModel.OpenLyricsSearchWindowCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE721;}" />
<MenuFlyoutItem
x:Uid="SystemTrayLyrics"
Command="{x:Bind ViewModel.OpenLyricsCommand}"
@@ -44,19 +54,11 @@
Command="{x:Bind ViewModel.OpenSettingsCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE713;}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem
x:Uid="SystemTrayResetWindowPosition"
Command="{x:Bind ViewModel.ResetWindowPositionCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE923;}" />
<MenuFlyoutItem
x:Uid="SystemTrayUnlock"
Command="{x:Bind ViewModel.UnlockWindowCommand}"
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xE785;}"
Visibility="{x:Bind ViewModel.IsLyricsWindowLocked, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
<MenuFlyoutSeparator />
<MenuFlyoutItem
x:Uid="SystemTrayRestart"
Command="{x:Bind ViewModel.RestartAppCommand}"

View File

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

View File

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

View File

@@ -1,19 +1,15 @@
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 partial class BoolToOpacityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is bool boolValue)
{
return boolValue ? 1.0 : 0.3;
return boolValue ? 1.0 : 0.0;
}
return 1.0;
}

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
// 2025/6/23 by Zhe Fang
using System;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media;
using System;
using Windows.UI;
namespace BetterLyrics.WinUI3.Converter

View File

@@ -1,5 +1,5 @@
using System;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{

View File

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

View File

@@ -1,7 +1,7 @@
// 2025/6/23 by Zhe Fang
using System;
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{

View File

@@ -1,9 +1,5 @@
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
{

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
// 2025/6/23 by Zhe Fang
using System;
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{

View File

@@ -0,0 +1,22 @@
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{
public class IntToDoubleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is int intValue)
{
return (double)intValue;
}
return 0.0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

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

View File

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

View File

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

View File

@@ -1,47 +0,0 @@
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();
}
}
}

View File

@@ -1,47 +0,0 @@
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 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.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();
}
}
}

View File

@@ -1,9 +1,5 @@
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
{

View File

@@ -0,0 +1,26 @@
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{
public class MillisecondsToSecondsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is int intValue)
{
return intValue / 1000.0;
}
else if (value is double doubleValue)
{
return doubleValue / 1000.0;
}
return 0.0;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

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

View File

@@ -0,0 +1,32 @@
using ATL;
using BetterLyrics.WinUI3.Helper;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Collections.Generic;
using System.Linq;
namespace BetterLyrics.WinUI3.Converter
{
public partial class PictureInfosToImageSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
BitmapImage bitmapImage = new();
if (value is IList<PictureInfo> list && list.FirstOrDefault()?.PictureData is byte[] pictureData)
{
bitmapImage.SetSource(ImageHelper.ToIRandomAccessStream(pictureData));
}
else
{
bitmapImage.UriSource = new Uri(PathHelper.AlbumArtPlaceholderPath);
}
return bitmapImage;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,22 @@
using Microsoft.UI.Xaml.Data;
using System;
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();
}
}
}

View File

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

View File

@@ -1,9 +1,6 @@
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
{

View File

@@ -0,0 +1,24 @@
using ATL;
using BetterLyrics.WinUI3.Extensions;
using Microsoft.UI.Xaml.Data;
using System;
namespace BetterLyrics.WinUI3.Converter
{
public partial class TrackToLyricsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value is Track track)
{
return track.GetRawLyrics();
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
}

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