diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-100.png index e1b6be5..e3de265 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-125.png index 05bc112..ff17b27 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-150.png index 54df62a..763d97a 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-200.png index 6c9a64c..3befa44 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-400.png index b4c2066..1b094ec 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/LargeTile.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-100.png index 850e2ce..b0147bb 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-125.png index a2b9275..7a57df1 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-150.png index 54239b6..5c4dcb5 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-200.png index f133fde..895f835 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-400.png index fad8443..0cc10e3 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SmallTile.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-100.png index 89b91b5..c333ac8 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-125.png index bccc826..86e1fe9 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-150.png index 8181bad..5a954a6 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-200.png index 7c7775e..223f3a5 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-400.png index dbbd13c..6b407ec 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/SplashScreen.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-100.png index 14412b6..2932e69 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-125.png index 136724d..fd712d1 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-150.png index f8b68d1..e56b0a1 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-200.png index 549d0c0..5cea161 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-400.png index 0873dcf..5c1718e 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square150x150Logo.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png index 8ad2ce0..f8ac680 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png index ab2cde5..5d4353e 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png index 07e582d..92d83f0 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png index c35493f..ac41e62 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png index 8b93016..bc406d8 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-16.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-16.png index 8ad2ce0..f8ac680 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-16.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-16.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-256.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-256.png index 07e582d..92d83f0 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-256.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-256.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-32.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-32.png index c35493f..ac41e62 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-32.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-32.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-48.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-48.png index 8b93016..bc406d8 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-48.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.altform-unplated_targetsize-48.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-100.png index be18505..4150812 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-125.png index 17877b3..53b6947 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-150.png index c618dc0..31667f5 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-200.png index d454412..0898189 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-400.png index 6da4ac7..8cc92f6 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-16.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-16.png index 7295774..a40eb30 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-16.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-16.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24.png index 304436e..76436fd 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24_altform-unplated.png index ab2cde5..5d4353e 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24_altform-unplated.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-256.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-256.png index 89f1ff4..6aaa6a4 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-256.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-256.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-32.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-32.png index 0b5da90..aaa1990 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-32.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-32.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-48.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-48.png index c83974b..d52f24b 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-48.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Square44x44Logo.targetsize-48.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-100.png index 20b45be..89dad03 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-125.png index 7a44552..9153514 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-150.png index a63f751..5dc6af8 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-200.png index cb97225..93606cc 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-400.png index ca57e91..e0e7707 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/StoreLogo.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-100.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-100.png index 6f75e83..70c5788 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-100.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-100.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-125.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-125.png index 2fb9e02..454a94c 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-125.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-125.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-150.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-150.png index ee4c81f..f3e5848 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-150.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-150.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-200.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-200.png index 89b91b5..c333ac8 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-200.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-200.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-400.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-400.png index 7c7775e..223f3a5 100644 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-400.png and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Images/Wide310x150Logo.scale-400.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest index ee9c2f6..cd30aa5 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest @@ -5,12 +5,13 @@ xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" - IgnorableNamespaces="uap rescap"> + xmlns:uap18="http://schemas.microsoft.com/appx/manifest/uap/windows10/18" + IgnorableNamespaces="uap rescap uap18"> + Version="1.0.1.0" /> @@ -26,7 +27,9 @@ - + + + diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml index 0258d61..e9d4b64 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml @@ -44,6 +44,7 @@ + 4 diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs index 853f48b..9dc4393 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs @@ -1,33 +1,34 @@ -using BetterLyrics.WinUI3.Services.Database; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using BetterLyrics.WinUI3.Models; +using BetterLyrics.WinUI3.Services.Database; using BetterLyrics.WinUI3.Services.Settings; using BetterLyrics.WinUI3.ViewModels; 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.Windows.ApplicationModel.Resources; -using System.IO; -using System.Text; -using System; -using Microsoft.Extensions.Logging; -using Serilog; -using Windows.ApplicationModel.Core; -using Serilog.Core; -using BetterLyrics.WinUI3.Models; -using Newtonsoft.Json; -using System.Collections.Generic; using Microsoft.Windows.AppLifecycle; +using Newtonsoft.Json; +using Serilog; +using Serilog.Core; +using Windows.ApplicationModel.Core; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. -namespace BetterLyrics.WinUI3 { +namespace BetterLyrics.WinUI3 +{ /// /// Provides application-specific behavior to supplement the default Application class. /// - public partial class App : Application { - + public partial class App : Application + { private readonly ILogger _logger; public static new App Current => (App)Application.Current; @@ -42,7 +43,8 @@ namespace BetterLyrics.WinUI3 { /// Initializes the singleton application object. This is the first line of authored code /// executed, and as such is the logical equivalent of main() or WinMain(). /// - public App() { + public App() + { this.InitializeComponent(); App.ResourceLoader = new ResourceLoader(); @@ -55,8 +57,8 @@ namespace BetterLyrics.WinUI3 { UnhandledException += App_UnhandledException; } - private static void ConfigureServices() { - + private static void ConfigureServices() + { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.File(Helper.AppInfo.LogFilePattern, rollingInterval: RollingInterval.Day) @@ -65,21 +67,27 @@ namespace BetterLyrics.WinUI3 { // Register services Ioc.Default.ConfigureServices( new ServiceCollection() - .AddSingleton(DispatcherQueue.GetForCurrentThread()) - .AddLogging(loggingBuilder => { - loggingBuilder.ClearProviders(); - loggingBuilder.AddSerilog(); - }) - // Services - .AddSingleton() - .AddSingleton() - // ViewModels - .AddSingleton() - .AddSingleton() - .BuildServiceProvider()); + .AddSingleton(DispatcherQueue.GetForCurrentThread()) + .AddLogging(loggingBuilder => + { + loggingBuilder.ClearProviders(); + loggingBuilder.AddSerilog(); + }) + // Services + .AddSingleton() + .AddSingleton() + // ViewModels + .AddSingleton() + .AddSingleton() + .BuildServiceProvider() + ); } - private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) { + private void App_UnhandledException( + object sender, + Microsoft.UI.Xaml.UnhandledExceptionEventArgs e + ) + { _logger.LogError(e.Exception, "App_UnhandledException"); e.Handled = true; } @@ -88,8 +96,8 @@ namespace BetterLyrics.WinUI3 { /// Invoked when the application is launched. /// /// Details about the launch request and process. - protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) { - + protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) + { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Activate the window @@ -97,6 +105,5 @@ namespace BetterLyrics.WinUI3 { MainWindow!.Navigate(typeof(MainPage)); MainWindow.Activate(); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Icon.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Icon.png deleted file mode 100644 index c8f71a8..0000000 Binary files a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Icon.png and /dev/null differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Logo.png b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Logo.png new file mode 100644 index 0000000..22661c4 Binary files /dev/null and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/Logo.png differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj index a6e5c46..065135b 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj @@ -1,68 +1,67 @@  - - WinExe - net8.0-windows10.0.26100.0 - 10.0.19041.0 - BetterLyrics.WinUI3 - app.manifest - x86;x64;ARM64 - win-x86;win-x64;win-arm64 - true - enable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Never - - - - - - Always - - - - - - False - True - False - True - 10.0.19041.0 - - - - $(DefineConstants);DISABLE_XAML_GENERATED_MAIN - - - \ No newline at end of file + + WinExe + net8.0-windows10.0.26100.0 + 10.0.19041.0 + BetterLyrics.WinUI3 + x86;x64;ARM64 + win-x86;win-x64;win-arm64 + true + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + + False + True + False + True + 10.0.19041.0 + + + $(DefineConstants);DISABLE_XAML_GENERATED_MAIN + app.manifest + Logo.ico + + diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ColorToBrushConverter.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ColorToBrushConverter.cs index 52150e4..933e3ba 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ColorToBrushConverter.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ColorToBrushConverter.cs @@ -1,22 +1,27 @@ -using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Media; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Media; using Windows.UI; -namespace BetterLyrics.WinUI3.Converter { - public class ColorToBrushConverter : IValueConverter { - public object Convert(object value, Type targetType, object parameter, string language) { - if (value is Color color) { +namespace BetterLyrics.WinUI3.Converter +{ + public class ColorToBrushConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is Color color) + { return new SolidColorBrush(color); } return new SolidColorBrush(); } - public object ConvertBack(object value, Type targetType, object parameter, string language) { + public object ConvertBack(object value, Type targetType, object parameter, string language) + { throw new NotImplementedException(); } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ThemeTypeToElementThemeConverter.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ThemeTypeToElementThemeConverter.cs index 86aaf70..addd1ae 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ThemeTypeToElementThemeConverter.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Converter/ThemeTypeToElementThemeConverter.cs @@ -1,21 +1,26 @@ -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Data; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Data; -namespace BetterLyrics.WinUI3.Converter { - internal class ThemeTypeToElementThemeConverter : IValueConverter { - public object Convert(object value, Type targetType, object parameter, string language) { - if (value is int themeType) { +namespace BetterLyrics.WinUI3.Converter +{ + internal class ThemeTypeToElementThemeConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + if (value is int themeType) + { return (ElementTheme)themeType; } return ElementTheme.Default; } - public object ConvertBack(object value, Type targetType, object parameter, string language) { + public object ConvertBack(object value, Type targetType, object parameter, string language) + { return 0; } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs index 6b7d0a4..3ff4df1 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs @@ -1,13 +1,13 @@ -using Microsoft.UI.Xaml; +using System; +using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media.Animation; -using System; -namespace BetterLyrics.WinUI3.Helper { - - public static class AnimationHelper { +namespace BetterLyrics.WinUI3.Helper +{ + public static class AnimationHelper + { public const int StackedNotificationsShowingDuration = 3900; public const int StoryboardDefaultDuration = 200; public const int DebounceDefaultDuration = 200; } - } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs index 9b6bc2e..51d13d2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs @@ -4,20 +4,24 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Helper { +namespace BetterLyrics.WinUI3.Helper +{ using System; using System.IO; using Windows.ApplicationModel; using Windows.Storage; - public static class AppInfo { + public static class AppInfo + { // App Metadata public const string AppName = "BetterLyrics"; public const string AppDisplayName = "Better Lyrics"; public const string AppAuthor = "Zhe Fang"; public const string GithubUrl = "https://github.com/jayfunc/BetterLyrics"; - public static string AppVersion { - get { + public static string AppVersion + { + get + { var version = Package.Current.Id.Version; return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; } @@ -28,7 +32,7 @@ namespace BetterLyrics.WinUI3.Helper { #if DEBUG true; #else - false; + false; #endif // Base Folders @@ -46,10 +50,10 @@ namespace BetterLyrics.WinUI3.Helper { private static string TestMusicFileName => "AI - 甜度爆表.mp3"; public static string TestMusicPath => Path.Combine(AssetsFolder, TestMusicFileName); - public static void EnsureDirectories() { + public static void EnsureDirectories() + { Directory.CreateDirectory(LogDirectory); Directory.CreateDirectory(LocalFolder); } } - } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/CollectionHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/CollectionHelper.cs index 2633064..1a1ac30 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/CollectionHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/CollectionHelper.cs @@ -4,9 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Helper { - public static class CollectionHelper { - public static T? SafeGet(this IList list, int index) { +namespace BetterLyrics.WinUI3.Helper +{ + public static class CollectionHelper + { + public static T? SafeGet(this IList list, int index) + { if (list == null || index < 0 || index >= list.Count) return default; return list[index]; diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorHelper.cs index 5c8747e..ad2c98d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorHelper.cs @@ -1,12 +1,14 @@ -namespace BetterLyrics.WinUI3.Helper { - public class ColorHelper { - public static Windows.UI.Color LerpColor(Windows.UI.Color a, Windows.UI.Color b, double t) { +namespace BetterLyrics.WinUI3.Helper +{ + public class ColorHelper + { + public static Windows.UI.Color LerpColor(Windows.UI.Color a, Windows.UI.Color b, double t) + { byte A = (byte)(a.A + (b.A - a.A) * t); byte R = (byte)(a.R + (b.R - a.R) * t); byte G = (byte)(a.G + (b.G - a.G) * t); byte B = (byte)(a.B + (b.B - a.B) * t); return Windows.UI.Color.FromArgb(A, R, G, B); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs index 17f7457..49816dc 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs @@ -4,51 +4,66 @@ using System.Linq; using System.Threading.Tasks; using Windows.Graphics.Imaging; -namespace BetterLyrics.WinUI3.Helper { +namespace BetterLyrics.WinUI3.Helper +{ /// /// Color map /// - internal class CMap { + internal class CMap + { private readonly List vboxes = new List(); private List? palette; - public void Push(VBox box) { + public void Push(VBox box) + { palette = null; vboxes.Add(box); } - public List GeneratePalette() { - if (palette == null) { - palette = (from vBox in vboxes - let rgb = vBox.Avg(false) - let color = FromRgb(rgb[0], rgb[1], rgb[2]) - select new QuantizedColor(color, vBox.Count(false))).ToList(); + public List GeneratePalette() + { + if (palette == null) + { + palette = ( + from vBox in vboxes + let rgb = vBox.Avg(false) + let color = FromRgb(rgb[0], rgb[1], rgb[2]) + select new QuantizedColor(color, vBox.Count(false)) + ).ToList(); } return palette; } - public int Size() { + public int Size() + { return vboxes.Count; } - public int[]? Map(int[] color) { - foreach (var vbox in vboxes.Where(vbox => vbox.Contains(color))) { + public int[]? Map(int[] color) + { + foreach (var vbox in vboxes.Where(vbox => vbox.Contains(color))) + { return vbox.Avg(false); } return Nearest(color); } - public int[]? Nearest(int[] color) { + public int[]? Nearest(int[] color) + { var d1 = double.MaxValue; int[]? pColor = null; - foreach (var t in vboxes) { + foreach (var t in vboxes) + { var vbColor = t.Avg(false); - var d2 = Math.Sqrt(Math.Pow(color[0] - vbColor[0], 2) - + Math.Pow(color[1] - vbColor[1], 2) - + Math.Pow(color[2] - vbColor[2], 2)); - if (d2 < d1) { + var d2 = Math.Sqrt( + Math.Pow(color[0] - vbColor[0], 2) + + Math.Pow(color[1] - vbColor[1], 2) + + Math.Pow(color[2] - vbColor[2], 2) + ); + if (d2 < d1) + { d1 = d2; pColor = vbColor; } @@ -56,23 +71,44 @@ namespace BetterLyrics.WinUI3.Helper { return pColor; } - public VBox FindColor(double targetLuma, double minLuma, double maxLuma, double targetSaturation, double minSaturation, double maxSaturation) { + public VBox FindColor( + double targetLuma, + double minLuma, + double maxLuma, + double targetSaturation, + double minSaturation, + double maxSaturation + ) + { VBox? max = null; double maxValue = 0; var highestPopulation = vboxes.Select(p => p.Count(false)).Max(); - foreach (var swatch in vboxes) { + foreach (var swatch in vboxes) + { var avg = swatch.Avg(false); var hsl = FromRgb(avg[0], avg[1], avg[2]).ToHsl(); var sat = hsl.S; var luma = hsl.L; - if (sat >= minSaturation && sat <= maxSaturation && - luma >= minLuma && luma <= maxLuma) { - var thisValue = Mmcq.CreateComparisonValue(sat, targetSaturation, luma, targetLuma, - swatch.Count(false), highestPopulation); + if ( + sat >= minSaturation + && sat <= maxSaturation + && luma >= minLuma + && luma <= maxLuma + ) + { + var thisValue = Mmcq.CreateComparisonValue( + sat, + targetSaturation, + luma, + targetLuma, + swatch.Count(false), + highestPopulation + ); - if (max == null || thisValue > maxValue) { + if (max == null || thisValue > maxValue) + { max = swatch; maxValue = thisValue; } @@ -82,12 +118,14 @@ namespace BetterLyrics.WinUI3.Helper { return max; } - public Color FromRgb(int red, int green, int blue) { - var color = new Color { + public RGB FromRgb(int red, int green, int blue) + { + var color = new RGB + { A = 255, R = (byte)red, G = (byte)green, - B = (byte)blue + B = (byte)blue, }; return color; @@ -97,7 +135,8 @@ namespace BetterLyrics.WinUI3.Helper { /// /// Defines a color in RGB space. /// - public struct Color { + public struct RGB + { /// /// Get or Set the Alpha component value for sRGB. /// @@ -122,7 +161,8 @@ namespace BetterLyrics.WinUI3.Helper { /// Get HSL color. /// /// - public HslColor ToHsl() { + public HslColor ToHsl() + { const double toDouble = 1.0 / 255; var r = toDouble * R; var g = toDouble * G; @@ -133,14 +173,20 @@ namespace BetterLyrics.WinUI3.Helper { double h1; // ReSharper disable CompareOfFloatsByEqualityOperator - if (chroma == 0) { + if (chroma == 0) + { h1 = 0; - } else if (max == r) { + } + else if (max == r) + { h1 = (g - b) / chroma % 6; - } else if (max == g) { + } + else if (max == g) + { h1 = 2 + (b - r) / chroma; - } else //if (max == b) - { + } + else //if (max == b) + { h1 = 4 + (r - g) / chroma; } @@ -155,16 +201,20 @@ namespace BetterLyrics.WinUI3.Helper { // ReSharper restore CompareOfFloatsByEqualityOperator } - public string ToHexString() { + public string ToHexString() + { return "#" + R.ToString("X2") + G.ToString("X2") + B.ToString("X2"); } - public string ToHexAlphaString() { + public string ToHexAlphaString() + { return "#" + A.ToString("X2") + R.ToString("X2") + G.ToString("X2") + B.ToString("X2"); } - public override string ToString() { - if (A == 255) { + public override string ToString() + { + if (A == 255) + { return ToHexString(); } @@ -175,7 +225,8 @@ namespace BetterLyrics.WinUI3.Helper { /// /// Defines a color in Hue/Saturation/Lightness (HSL) space. /// - public struct HslColor { + public struct HslColor + { /// /// The Alpha/opacity in 0..1 range. /// @@ -197,7 +248,8 @@ namespace BetterLyrics.WinUI3.Helper { public double S; } - internal static class Mmcq { + internal static class Mmcq + { public const int Sigbits = 5; public const int Rshift = 8 - Sigbits; public const int Mult = 1 << Rshift; @@ -211,7 +263,8 @@ namespace BetterLyrics.WinUI3.Helper { private static readonly VBoxComparer ComparatorProduct = new VBoxComparer(); private static readonly VBoxCountComparer ComparatorCount = new VBoxCountComparer(); - public static int GetColorIndex(int r, int g, int b) { + public static int GetColorIndex(int r, int g, int b) + { return (r << (2 * Sigbits)) + (g << Sigbits) + b; } @@ -220,10 +273,12 @@ namespace BetterLyrics.WinUI3.Helper { /// /// The pixels. /// Histo (1-d array, giving the number of pixels in each quantized region of color space), or null on error. - private static int[] GetHisto(IEnumerable pixels) { + private static int[] GetHisto(IEnumerable pixels) + { var histo = new int[Histosize]; - foreach (var pixel in pixels) { + foreach (var pixel in pixels) + { var rval = pixel[0] >> Rshift; var gval = pixel[1] >> Rshift; var bval = pixel[2] >> Rshift; @@ -233,34 +288,48 @@ namespace BetterLyrics.WinUI3.Helper { return histo; } - private static VBox VboxFromPixels(IList pixels, int[] histo) { - int rmin = 1000000, rmax = 0; - int gmin = 1000000, gmax = 0; - int bmin = 1000000, bmax = 0; + private static VBox VboxFromPixels(IList pixels, int[] histo) + { + int rmin = 1000000, + rmax = 0; + int gmin = 1000000, + gmax = 0; + int bmin = 1000000, + bmax = 0; // find min/max var numPixels = pixels.Count; - for (var i = 0; i < numPixels; i++) { + for (var i = 0; i < numPixels; i++) + { var pixel = pixels[i]; var rval = pixel[0] >> Rshift; var gval = pixel[1] >> Rshift; var bval = pixel[2] >> Rshift; - if (rval < rmin) { + if (rval < rmin) + { rmin = rval; - } else if (rval > rmax) { + } + else if (rval > rmax) + { rmax = rval; } - if (gval < gmin) { + if (gval < gmin) + { gmin = gval; - } else if (gval > gmax) { + } + else if (gval > gmax) + { gmax = gval; } - if (bval < bmin) { + if (bval < bmin) + { bmin = bval; - } else if (bval > bmax) { + } + else if (bval > bmax) + { bmax = bval; } } @@ -268,11 +337,19 @@ namespace BetterLyrics.WinUI3.Helper { return new VBox(rmin, rmax, gmin, gmax, bmin, bmax, histo); } - private static VBox[] DoCut(char color, VBox vbox, IList partialsum, IList lookaheadsum, int total) { + private static VBox[] DoCut( + char color, + VBox vbox, + IList partialsum, + IList lookaheadsum, + int total + ) + { int vboxDim1; int vboxDim2; - switch (color) { + switch (color) + { case 'r': vboxDim1 = vbox.R1; vboxDim2 = vbox.R2; @@ -287,29 +364,35 @@ namespace BetterLyrics.WinUI3.Helper { break; } - for (var i = vboxDim1; i <= vboxDim2; i++) { - if (partialsum[i] > total / 2) { + for (var i = vboxDim1; i <= vboxDim2; i++) + { + if (partialsum[i] > total / 2) + { var vbox1 = vbox.Clone(); var vbox2 = vbox.Clone(); var left = i - vboxDim1; var right = vboxDim2 - i; - var d2 = left <= right - ? Math.Min(vboxDim2 - 1, Math.Abs(i + right / 2)) - : Math.Max(vboxDim1, Math.Abs(Convert.ToInt32(i - 1 - left / 2.0))); + var d2 = + left <= right + ? Math.Min(vboxDim2 - 1, Math.Abs(i + right / 2)) + : Math.Max(vboxDim1, Math.Abs(Convert.ToInt32(i - 1 - left / 2.0))); // avoid 0-count boxes - while (d2 < 0 || partialsum[d2] <= 0) { + while (d2 < 0 || partialsum[d2] <= 0) + { d2++; } var count2 = lookaheadsum[d2]; - while (count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0) { + while (count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0) + { count2 = lookaheadsum[--d2]; } // set dimensions - switch (color) { + switch (color) + { case 'r': vbox1.R2 = d2; vbox2.R1 = d2 + 1; @@ -331,11 +414,14 @@ namespace BetterLyrics.WinUI3.Helper { throw new Exception("VBox can't be cut"); } - private static VBox?[]? MedianCutApply(IList histo, VBox vbox) { - if (vbox.Count(false) == 0) { + private static VBox?[]? MedianCutApply(IList histo, VBox vbox) + { + if (vbox.Count(false) == 0) + { return null; } - if (vbox.Count(false) == 1) { + if (vbox.Count(false) == 1) + { return [vbox.Clone(), null]; } @@ -350,23 +436,33 @@ namespace BetterLyrics.WinUI3.Helper { var total = 0; var partialsum = new int[VboxLength]; // -1 = not set / 0 = 0 - for (var l = 0; l < partialsum.Length; l++) { + for (var l = 0; l < partialsum.Length; l++) + { partialsum[l] = -1; } // -1 = not set / 0 = 0 var lookaheadsum = new int[VboxLength]; - for (var l = 0; l < lookaheadsum.Length; l++) { + for (var l = 0; l < lookaheadsum.Length; l++) + { lookaheadsum[l] = -1; } - int i, j, k, sum, index; + int i, + j, + k, + sum, + index; - if (maxw == rw) { - for (i = vbox.R1; i <= vbox.R2; i++) { + if (maxw == rw) + { + for (i = vbox.R1; i <= vbox.R2; i++) + { sum = 0; - for (j = vbox.G1; j <= vbox.G2; j++) { - for (k = vbox.B1; k <= vbox.B2; k++) { + for (j = vbox.G1; j <= vbox.G2; j++) + { + for (k = vbox.B1; k <= vbox.B2; k++) + { index = GetColorIndex(i, j, k); sum += histo[index]; } @@ -374,11 +470,16 @@ namespace BetterLyrics.WinUI3.Helper { total += sum; partialsum[i] = total; } - } else if (maxw == gw) { - for (i = vbox.G1; i <= vbox.G2; i++) { + } + else if (maxw == gw) + { + for (i = vbox.G1; i <= vbox.G2; i++) + { sum = 0; - for (j = vbox.R1; j <= vbox.R2; j++) { - for (k = vbox.B1; k <= vbox.B2; k++) { + for (j = vbox.R1; j <= vbox.R2; j++) + { + for (k = vbox.B1; k <= vbox.B2; k++) + { index = GetColorIndex(j, i, k); sum += histo[index]; } @@ -386,12 +487,16 @@ namespace BetterLyrics.WinUI3.Helper { total += sum; partialsum[i] = total; } - } else /* maxw == bw */ - { - for (i = vbox.B1; i <= vbox.B2; i++) { + } + else /* maxw == bw */ + { + for (i = vbox.B1; i <= vbox.B2; i++) + { sum = 0; - for (j = vbox.R1; j <= vbox.R2; j++) { - for (k = vbox.G1; k <= vbox.G2; k++) { + for (j = vbox.R1; j <= vbox.R2; j++) + { + for (k = vbox.G1; k <= vbox.G2; k++) + { index = GetColorIndex(j, k, i); sum += histo[index]; } @@ -401,15 +506,18 @@ namespace BetterLyrics.WinUI3.Helper { } } - for (i = 0; i < VboxLength; i++) { - if (partialsum[i] != -1) { + for (i = 0; i < VboxLength; i++) + { + if (partialsum[i] != -1) + { lookaheadsum[i] = total - partialsum[i]; } } // determine the cut planes - return maxw == rw ? DoCut('r', vbox, partialsum, lookaheadsum, total) : maxw == gw - ? DoCut('g', vbox, partialsum, lookaheadsum, total) : DoCut('b', vbox, partialsum, lookaheadsum, total); + return maxw == rw ? DoCut('r', vbox, partialsum, lookaheadsum, total) + : maxw == gw ? DoCut('g', vbox, partialsum, lookaheadsum, total) + : DoCut('b', vbox, partialsum, lookaheadsum, total); } /// @@ -420,13 +528,21 @@ namespace BetterLyrics.WinUI3.Helper { /// The target. /// The histo. /// vbox1 not defined; shouldn't happen! - private static void Iter(List lh, IComparer comparator, int target, IList histo) { + private static void Iter( + List lh, + IComparer comparator, + int target, + IList histo + ) + { var ncolors = 1; var niters = 0; - while (niters < MaxIterations) { + while (niters < MaxIterations) + { var vbox = lh[lh.Count - 1]; - if (vbox.Count(false) == 0) { + if (vbox.Count(false) == 0) + { lh.Sort(comparator); niters++; continue; @@ -439,30 +555,35 @@ namespace BetterLyrics.WinUI3.Helper { var vbox1 = vboxes?[0]; var vbox2 = vboxes?[1]; - if (vbox1 == null) { - throw new Exception( - "vbox1 not defined; shouldn't happen!"); + if (vbox1 == null) + { + throw new Exception("vbox1 not defined; shouldn't happen!"); } lh.Add(vbox1); - if (vbox2 != null) { + if (vbox2 != null) + { lh.Add(vbox2); ncolors++; } lh.Sort(comparator); - if (ncolors >= target) { + if (ncolors >= target) + { return; } - if (niters++ > MaxIterations) { + if (niters++ > MaxIterations) + { return; } } } - public static CMap Quantize(byte[][] pixels, int maxcolors) { + public static CMap Quantize(byte[][] pixels, int maxcolors) + { // short-circuit - if (pixels.Length == 0 || maxcolors < 2 || maxcolors > 256) { + if (pixels.Length == 0 || maxcolors < 2 || maxcolors > 256) + { return null; } @@ -490,24 +611,40 @@ namespace BetterLyrics.WinUI3.Helper { // calculate the actual colors var cmap = new CMap(); - foreach (var vb in pq) { + foreach (var vb in pq) + { cmap.Push(vb); } return cmap; } - public static double CreateComparisonValue(double saturation, double targetSaturation, double luma, double targetLuma, int population, int highestPopulation) { - return WeightedMean(InvertDiff(saturation, targetSaturation), WeightSaturation, - InvertDiff(luma, targetLuma), WeightLuma, - population / (double)highestPopulation, WeightPopulation); + public static double CreateComparisonValue( + double saturation, + double targetSaturation, + double luma, + double targetLuma, + int population, + int highestPopulation + ) + { + return WeightedMean( + InvertDiff(saturation, targetSaturation), + WeightSaturation, + InvertDiff(luma, targetLuma), + WeightLuma, + population / (double)highestPopulation, + WeightPopulation + ); } - private static double WeightedMean(params double[] values) { + private static double WeightedMean(params double[] values) + { double sum = 0; double sumWeight = 0; - for (var i = 0; i < values.Length; i += 2) { + for (var i = 0; i < values.Length; i += 2) + { var value = values[i]; var weight = values[i + 1]; @@ -518,31 +655,38 @@ namespace BetterLyrics.WinUI3.Helper { return sum / sumWeight; } - private static double InvertDiff(double value, double targetValue) { + private static double InvertDiff(double value, double targetValue) + { return 1 - Math.Abs(value - targetValue); } } - public class QuantizedColor { - public QuantizedColor(Color color, int population) { + public class QuantizedColor + { + public QuantizedColor(RGB color, int population) + { Color = color; Population = population; IsDark = CalculateYiqLuma(color) < 128; } - public Color Color { get; private set; } + public RGB Color { get; private set; } public int Population { get; private set; } public bool IsDark { get; private set; } - public int CalculateYiqLuma(Color color) { - return Convert.ToInt32(Math.Round((299 * color.R + 587 * color.G + 114 * color.B) / 1000f)); + public int CalculateYiqLuma(RGB color) + { + return Convert.ToInt32( + Math.Round((299 * color.R + 587 * color.G + 114 * color.B) / 1000f) + ); } } /// /// 3D color space box. /// - internal class VBox { + internal class VBox + { private readonly int[] histo; private int[] avg; public int B1; @@ -554,7 +698,8 @@ namespace BetterLyrics.WinUI3.Helper { public int R2; private int? volume; - public VBox(int r1, int r2, int g1, int g2, int b1, int b2, int[] histo) { + public VBox(int r1, int r2, int g1, int g2, int b1, int b2, int[] histo) + { R1 = r1; R2 = r2; G1 = g1; @@ -565,24 +710,31 @@ namespace BetterLyrics.WinUI3.Helper { this.histo = histo; } - public int Volume(bool force) { - if (volume == null || force) { + public int Volume(bool force) + { + if (volume == null || force) + { volume = (R2 - R1 + 1) * (G2 - G1 + 1) * (B2 - B1 + 1); } return volume.Value; } - public int Count(bool force) { - if (count == null || force) { + public int Count(bool force) + { + if (count == null || force) + { var npix = 0; int i; - for (i = R1; i <= R2; i++) { + for (i = R1; i <= R2; i++) + { int j; - for (j = G1; j <= G2; j++) { + for (j = G1; j <= G2; j++) + { int k; - for (k = B1; k <= B2; k++) { + for (k = B1; k <= B2; k++) + { var index = Mmcq.GetColorIndex(i, j, k); npix += histo[index]; } @@ -595,12 +747,15 @@ namespace BetterLyrics.WinUI3.Helper { return count.Value; } - public VBox Clone() { + public VBox Clone() + { return new VBox(R1, R2, G1, G2, B1, B2, histo); } - public int[] Avg(bool force) { - if (avg == null || force) { + public int[] Avg(bool force) + { + if (avg == null || force) + { var ntot = 0; var rsum = 0; @@ -609,11 +764,14 @@ namespace BetterLyrics.WinUI3.Helper { int i; - for (i = R1; i <= R2; i++) { + for (i = R1; i <= R2; i++) + { int j; - for (j = G1; j <= G2; j++) { + for (j = G1; j <= G2; j++) + { int k; - for (k = B1; k <= B2; k++) { + for (k = B1; k <= B2; k++) + { var histoindex = Mmcq.GetColorIndex(i, j, k); var hval = histo[histoindex]; ntot += hval; @@ -624,18 +782,22 @@ namespace BetterLyrics.WinUI3.Helper { } } - if (ntot > 0) { + if (ntot > 0) + { avg = new[] { - Math.Abs(rsum / ntot), Math.Abs(gsum / ntot), - Math.Abs(bsum / ntot) + Math.Abs(rsum / ntot), + Math.Abs(gsum / ntot), + Math.Abs(bsum / ntot), }; - } else { + } + else + { avg = new[] { Math.Abs(Mmcq.Mult * (R1 + R2 + 1) / 2), Math.Abs(Mmcq.Mult * (G1 + G2 + 1) / 2), - Math.Abs(Mmcq.Mult * (B1 + B2 + 1) / 2) + Math.Abs(Mmcq.Mult * (B1 + B2 + 1) / 2), }; } } @@ -643,7 +805,8 @@ namespace BetterLyrics.WinUI3.Helper { return avg; } - public bool Contains(int[] pixel) { + public bool Contains(int[] pixel) + { var rval = pixel[0] >> Mmcq.Rshift; var gval = pixel[1] >> Mmcq.Rshift; var bval = pixel[2] >> Mmcq.Rshift; @@ -652,16 +815,20 @@ namespace BetterLyrics.WinUI3.Helper { } } - internal class VBoxCountComparer : IComparer { - public int Compare(VBox x, VBox y) { + internal class VBoxCountComparer : IComparer + { + public int Compare(VBox x, VBox y) + { var a = x.Count(false); var b = y.Count(false); return a < b ? -1 : (a > b ? 1 : 0); } } - internal class VBoxComparer : IComparer { - public int Compare(VBox x, VBox y) { + internal class VBoxComparer : IComparer + { + public int Compare(VBox x, VBox y) + { var aCount = x.Count(false); var bCount = y.Count(false); var aVolume = x.Volume(false); @@ -674,17 +841,20 @@ namespace BetterLyrics.WinUI3.Helper { } } - public class ColorThief { + public class ColorThief + { public const int DefaultColorCount = 5; public const int DefaultQuality = 10; public const bool DefaultIgnoreWhite = true; public const int ColorDepth = 4; - private CMap GetColorMap(byte[][] pixelArray, int colorCount) { + private CMap GetColorMap(byte[][] pixelArray, int colorCount) + { // Send array to quantize function which clusters values using median // cut algorithm - if (colorCount > 0) { + if (colorCount > 0) + { --colorCount; } @@ -692,14 +862,18 @@ namespace BetterLyrics.WinUI3.Helper { return cmap; } - private byte[][] ConvertPixels(byte[] pixels, int pixelCount, int quality, bool ignoreWhite) { - - + private byte[][] ConvertPixels(byte[] pixels, int pixelCount, int quality, bool ignoreWhite) + { var expectedDataLength = pixelCount * ColorDepth; - if (expectedDataLength != pixels.Length) { - throw new ArgumentException("(expectedDataLength = " - + expectedDataLength + ") != (pixels.length = " - + pixels.Length + ")"); + if (expectedDataLength != pixels.Length) + { + throw new ArgumentException( + "(expectedDataLength = " + + expectedDataLength + + ") != (pixels.length = " + + pixels.Length + + ")" + ); } // Store the RGB values in an array format suitable for quantize @@ -713,7 +887,8 @@ namespace BetterLyrics.WinUI3.Helper { var numUsedPixels = 0; var pixelArray = new byte[numRegardedPixels][]; - for (var i = 0; i < pixelCount; i += quality) { + for (var i = 0; i < pixelCount; i += quality) + { var offset = i * ColorDepth; var b = pixels[offset]; var g = pixels[offset + 1]; @@ -721,7 +896,8 @@ namespace BetterLyrics.WinUI3.Helper { var a = pixels[offset + 3]; // If pixel is mostly opaque and not white - if (a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250)) { + if (a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250)) + { pixelArray[numUsedPixels] = new[] { r, g, b }; numUsedPixels++; } @@ -745,15 +921,24 @@ namespace BetterLyrics.WinUI3.Helper { /// /// if set to true [ignore white]. /// - public async Task GetColor(BitmapDecoder sourceImage, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite) { + public async Task GetColor( + BitmapDecoder sourceImage, + int quality = DefaultQuality, + bool ignoreWhite = DefaultIgnoreWhite + ) + { var palette = await GetPalette(sourceImage, 3, quality, ignoreWhite); - var dominantColor = new QuantizedColor(new Color { - A = Convert.ToByte(palette.Average(a => a.Color.A)), - R = Convert.ToByte(palette.Average(a => a.Color.R)), - G = Convert.ToByte(palette.Average(a => a.Color.G)), - B = Convert.ToByte(palette.Average(a => a.Color.B)) - }, Convert.ToInt32(palette.Average(a => a.Population))); + var dominantColor = new QuantizedColor( + new RGB + { + A = Convert.ToByte(palette.Average(a => a.Color.A)), + R = Convert.ToByte(palette.Average(a => a.Color.R)), + G = Convert.ToByte(palette.Average(a => a.Color.G)), + B = Convert.ToByte(palette.Average(a => a.Color.B)), + }, + Convert.ToInt32(palette.Average(a => a.Population)) + ); return dominantColor; } @@ -772,24 +957,38 @@ namespace BetterLyrics.WinUI3.Helper { /// if set to true [ignore white]. /// /// true - public async Task> GetPalette(BitmapDecoder sourceImage, int colorCount = DefaultColorCount, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite) { + public async Task> GetPalette( + BitmapDecoder sourceImage, + int colorCount = DefaultColorCount, + int quality = DefaultQuality, + bool ignoreWhite = DefaultIgnoreWhite + ) + { var pixelArray = await GetPixelsFast(sourceImage, quality, ignoreWhite); var cmap = GetColorMap(pixelArray, colorCount); - if (cmap != null) { + if (cmap != null) + { var colors = cmap.GeneratePalette(); return colors; } return new List(); } - private async Task GetIntFromPixel(BitmapDecoder decoder) { + private async Task GetIntFromPixel(BitmapDecoder decoder) + { var pixelsData = await decoder.GetPixelDataAsync(); var pixels = pixelsData.DetachPixelData(); return pixels; } - private async Task GetPixelsFast(BitmapDecoder sourceImage, int quality, bool ignoreWhite) { - if (quality < 1) { + private async Task GetPixelsFast( + BitmapDecoder sourceImage, + int quality, + bool ignoreWhite + ) + { + if (quality < 1) + { quality = DefaultQuality; } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EasingHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EasingHelper.cs index 82e2adb..c1bab09 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EasingHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/EasingHelper.cs @@ -4,9 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Helper { - public class EasingHelper { - +namespace BetterLyrics.WinUI3.Helper +{ + public class EasingHelper + { /// /// No easing /// @@ -25,23 +26,24 @@ namespace BetterLyrics.WinUI3.Helper { /// /// Acceleration until halfway then deceleration /// - public static float EaseInOutQuad(float t) { - return t < 0.5f - ? 2 * t * t - : -1 + (4 - 2 * t) * t; + public static float EaseInOutQuad(float t) + { + return t < 0.5f ? 2 * t * t : -1 + (4 - 2 * t) * t; } /// /// Smoother transition than linear /// - public static float SmoothStep(float t) { + public static float SmoothStep(float t) + { return t * t * (3 - 2 * t); } /// /// Even smoother transition with continuous first and second derivatives /// - public static float SmootherStep(float t) { + public static float SmootherStep(float t) + { return t * t * t * (t * (6 * t - 15) + 10); } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ImageHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ImageHelper.cs index 7a1c7ba..bf8b93c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ImageHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ImageHelper.cs @@ -1,8 +1,9 @@ -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Media.Imaging; -using System; +using System; +using System.IO; using System.Runtime.InteropServices.WindowsRuntime; using System.Threading.Tasks; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Media.Imaging; using Windows.Graphics.Imaging; using Windows.Storage; using Windows.Storage.Streams; @@ -11,7 +12,9 @@ namespace BetterLyrics.WinUI3.Helper { public class ImageHelper { - public static async Task GetStreamFromBytesAsync(byte[] imageBytes) + public static async Task GetStreamFromBytesAsync( + byte[] imageBytes + ) { if (imageBytes == null || imageBytes.Length == 0) return null; @@ -22,5 +25,13 @@ namespace BetterLyrics.WinUI3.Helper return stream; } + + public static async Task ToByteArrayAsync(IRandomAccessStreamReference streamRef) + { + using IRandomAccessStream stream = await streamRef.OpenReadAsync(); + using var memoryStream = new MemoryStream(); + await stream.AsStreamForRead().CopyToAsync(memoryStream); + return memoryStream.ToArray(); + } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MathHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MathHelper.cs index d6b271b..c612f46 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MathHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/MathHelper.cs @@ -4,13 +4,18 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Helper { - public class MathHelper { - public static List GetAllFactors(int n) { +namespace BetterLyrics.WinUI3.Helper +{ + public class MathHelper + { + public static List GetAllFactors(int n) + { var result = new SortedSet(); - for (int i = 1; i <= Math.Sqrt(n); i++) { - if (n % i == 0) { + for (int i = 1; i <= Math.Sqrt(n); i++) + { + if (n % i == 0) + { result.Add(i); result.Add(n / i); } @@ -18,6 +23,5 @@ namespace BetterLyrics.WinUI3.Helper { return [.. result]; } - } -} \ No newline at end of file +} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs index 8b49b41..97cdbf9 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/SystemBackdropHelper.cs @@ -6,8 +6,10 @@ namespace BetterLyrics.WinUI3.Helper { public class SystemBackdropHelper { - public static SystemBackdrop? CreateSystemBackdrop(BackdropType backdropType) { - return backdropType switch { + public static SystemBackdrop? CreateSystemBackdrop(BackdropType backdropType) + { + return backdropType switch + { BackdropType.None => null, BackdropType.Mica => new MicaSystemBackdrop(MicaKind.Base), BackdropType.MicaAlt => new MicaSystemBackdrop(MicaKind.BaseAlt), @@ -18,6 +20,5 @@ namespace BetterLyrics.WinUI3.Helper _ => null, }; } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs index d82e4d8..1527715 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs @@ -1,32 +1,40 @@ -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Media; -namespace BetterLyrics.WinUI3.Helper { - public class VisualHelper { - +namespace BetterLyrics.WinUI3.Helper +{ + public class VisualHelper + { /// /// Source: https://stackoverflow.com/a/61626933/11048731 /// /// /// /// - public static List FindVisualChildren(DependencyObject depObj) where T : DependencyObject { + public static List FindVisualChildren(DependencyObject depObj) + where T : DependencyObject + { List list = []; - if (depObj != null) { - for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) { + if (depObj != null) + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) + { DependencyObject child = VisualTreeHelper.GetChild(depObj, i); - if (child != null && child is T t) { + if (child != null && child is T t) + { list.Add(t); } List childItems = FindVisualChildren(child); - if (childItems != null && childItems.Count > 0) { - foreach (var item in childItems) { + if (childItems != null && childItems.Count > 0) + { + foreach (var item in childItems) + { list.Add(item); } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logo.ico b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logo.ico new file mode 100644 index 0000000..55ac389 Binary files /dev/null and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Logo.ico differ diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml index f1577de..3902f9c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml @@ -57,6 +57,21 @@ + + + + + + + + - - - - - /// An empty window that can be used on its own or navigated to within a Frame. /// - public sealed partial class MainWindow : Window { - + public sealed partial class MainWindow : Window + { private readonly OverlappedPresenter _presenter; private readonly SettingsService _settingsService; - public static StackedNotificationsBehavior? StackedNotificationsBehavior { get; private set; } + public static StackedNotificationsBehavior? StackedNotificationsBehavior + { + get; + private set; + } - public MainWindow() { + public MainWindow() + { this.InitializeComponent(); _settingsService = Ioc.Default.GetService()!; RootGrid.RequestedTheme = (ElementTheme)_settingsService.Theme; - SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop((BackdropType)_settingsService.BackdropType); + SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop( + (BackdropType)_settingsService.BackdropType + ); - WeakReferenceMessenger.Default.Register(this, (r, m) => { - RootGrid.RequestedTheme = m.Value; - }); + WeakReferenceMessenger.Default.Register( + this, + (r, m) => + { + RootGrid.RequestedTheme = m.Value; + } + ); - WeakReferenceMessenger.Default.Register(this, (r, m) => { - SystemBackdrop = null; - SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(m.Value); - }); + WeakReferenceMessenger.Default.Register( + this, + (r, m) => + { + SystemBackdrop = null; + SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop(m.Value); + } + ); // AppWindow.SetIcon("white_round.ico"); StackedNotificationsBehavior = NotificationQueue; @@ -56,50 +72,67 @@ namespace BetterLyrics.WinUI3 { SetTitleBar(TopCommandGrid); } - public void Navigate(Type type) { + public void Navigate(Type type) + { RootFrame.Navigate(type); } - private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) { + private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e) + { throw new Exception("Failed to load Page " + e.SourcePageType.FullName); } - private void CloseButton_Click(object sender, RoutedEventArgs e) { - if (RootFrame.CurrentSourcePageType == typeof(MainPage)) { - ((RootFrame.Content as MainPage)!.FindChild("LyricsCanvas") as CanvasAnimatedControl)!.Paused = true; + private void CloseButton_Click(object sender, RoutedEventArgs e) + { + if (RootFrame.CurrentSourcePageType == typeof(MainPage)) + { + ( + (RootFrame.Content as MainPage)!.FindChild("LyricsCanvas") + as CanvasAnimatedControl + )!.Paused = true; App.Current.Exit(); - } else if (RootFrame.CurrentSourcePageType == typeof(SettingsPage)) { + } + else if (RootFrame.CurrentSourcePageType == typeof(SettingsPage)) + { App.Current.SettingsWindow!.AppWindow.Hide(); } } - private void MaximiseButton_Click(object sender, RoutedEventArgs e) { + private void MaximiseButton_Click(object sender, RoutedEventArgs e) + { _presenter.Maximize(); //MaximiseButton.Visibility = Visibility.Collapsed; //RestoreButton.Visibility = Visibility.Visible; } - private void MinimiseButton_Click(object sender, RoutedEventArgs e) { + private void MinimiseButton_Click(object sender, RoutedEventArgs e) + { _presenter.Minimize(); } - private void RestoreButton_Click(object sender, RoutedEventArgs e) { + private void RestoreButton_Click(object sender, RoutedEventArgs e) + { _presenter.Restore(); //MaximiseButton.Visibility = Visibility.Visible; //RestoreButton.Visibility = Visibility.Collapsed; } - private void Window_SizeChanged(object sender, WindowSizeChangedEventArgs args) { - if (_presenter.State == OverlappedPresenterState.Maximized) { + private void Window_SizeChanged(object sender, WindowSizeChangedEventArgs args) + { + if (_presenter.State == OverlappedPresenterState.Maximized) + { MaximiseButton.Visibility = Visibility.Collapsed; RestoreButton.Visibility = Visibility.Visible; - } else if (_presenter.State == OverlappedPresenterState.Restored) { + } + else if (_presenter.State == OverlappedPresenterState.Restored) + { MaximiseButton.Visibility = Visibility.Visible; RestoreButton.Visibility = Visibility.Collapsed; } } - private void MiniButton_Click(object sender, RoutedEventArgs e) { + private void MiniButton_Click(object sender, RoutedEventArgs e) + { AppWindow.Resize(new Windows.Graphics.SizeInt32(144, 48)); MiniButton.Visibility = Visibility.Collapsed; UnminiButton.Visibility = Visibility.Visible; @@ -109,7 +142,8 @@ namespace BetterLyrics.WinUI3 { CloseButton.Visibility = Visibility.Collapsed; } - private void UnminiButton_Click(object sender, RoutedEventArgs e) { + private void UnminiButton_Click(object sender, RoutedEventArgs e) + { AppWindow.Resize(new Windows.Graphics.SizeInt32(800, 600)); MiniButton.Visibility = Visibility.Visible; UnminiButton.Visibility = Visibility.Collapsed; @@ -119,21 +153,26 @@ namespace BetterLyrics.WinUI3 { CloseButton.Visibility = Visibility.Visible; } - private void RootFrame_Navigated(object sender, NavigationEventArgs e) { - AppWindow.Title = Title = App.ResourceLoader!.GetString($"{e.SourcePageType.Name}Title"); + private void RootFrame_Navigated(object sender, NavigationEventArgs e) + { + AppWindow.Title = Title = App.ResourceLoader!.GetString( + $"{e.SourcePageType.Name}Title" + ); } - private void AOTButton_Click(object sender, RoutedEventArgs e) { + private void AOTButton_Click(object sender, RoutedEventArgs e) + { _presenter.IsAlwaysOnTop = !_presenter.IsAlwaysOnTop; string prefix; - if (_presenter.IsAlwaysOnTop) { + if (_presenter.IsAlwaysOnTop) + { prefix = "Show"; - } else { + } + else + { prefix = "Hide"; } (PinnedFontIcon.Resources[$"{prefix}PinnedFontIconStoryboard"] as Storyboard)!.Begin(); - } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs index 8eba17a..456b562 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs @@ -1,12 +1,13 @@ -using CommunityToolkit.Mvvm.Messaging.Messages; -using DevWinUI; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging.Messages; +using DevWinUI; -namespace BetterLyrics.WinUI3.Messages { - public class SystemBackdropChangedMessage(BackdropType value) : ValueChangedMessage(value) { - } +namespace BetterLyrics.WinUI3.Messages +{ + public class SystemBackdropChangedMessage(BackdropType value) + : ValueChangedMessage(value) { } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs index dede073..3d5bf83 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs @@ -1,12 +1,13 @@ -using CommunityToolkit.Mvvm.Messaging.Messages; -using Microsoft.UI.Xaml; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging.Messages; +using Microsoft.UI.Xaml; -namespace BetterLyrics.WinUI3.Messages { - public class ThemeChangedMessage(ElementTheme value) : ValueChangedMessage(value) { - } +namespace BetterLyrics.WinUI3.Messages +{ + public class ThemeChangedMessage(ElementTheme value) + : ValueChangedMessage(value) { } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs index 1602945..3f33568 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/Language.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models { - public enum Language { +namespace BetterLyrics.WinUI3.Models +{ + public enum Language + { FollowSystem, English, SimplifiedChinese, diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs index 3cedb29..06d1e1f 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsAlignmentType.cs @@ -4,8 +4,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models { - public enum LyricsAlignmentType { +namespace BetterLyrics.WinUI3.Models +{ + public enum LyricsAlignmentType + { Left, Center, Right, diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs index c5d1744..a560f4e 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsFontColorType.cs @@ -4,9 +4,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models { - public enum LyricsFontColorType { +namespace BetterLyrics.WinUI3.Models +{ + public enum LyricsFontColorType + { Default, - Dominant + Dominant, } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs index 5e3858c..e8f5f6c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsLine.cs @@ -1,14 +1,15 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using Microsoft.Graphics.Canvas.Text; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Numerics; +using CommunityToolkit.Mvvm.ComponentModel; +using Microsoft.Graphics.Canvas.Text; using Windows.Foundation; -namespace BetterLyrics.WinUI3.Models { - public class LyricsLine { - +namespace BetterLyrics.WinUI3.Models +{ + public class LyricsLine + { public List Texts { get; set; } = []; public int LanguageIndex { get; set; } = 0; @@ -37,6 +38,5 @@ namespace BetterLyrics.WinUI3.Models { public float Opacity { get; set; } public CanvasTextLayout TextLayout { get; set; } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs index b2cf4c6..de7e486 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/LyricsPlayingState.cs @@ -4,19 +4,23 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Models { - public enum LyricsPlayingState { +namespace BetterLyrics.WinUI3.Models +{ + public enum LyricsPlayingState + { /// /// Not played yet, will be playing in the future /// NotPlayed, + /// /// Playing /// Playing, + /// /// Has already played /// - Played + Played, } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs index 6bf7529..0e2ec9d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs @@ -1,7 +1,9 @@ using SQLite; -namespace BetterLyrics.WinUI3.Models { - public class MetadataIndex { +namespace BetterLyrics.WinUI3.Models +{ + public class MetadataIndex + { [PrimaryKey] public string? Path { get; set; } public string? Title { get; set; } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs index 8d94a64..b0e56ca 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs @@ -7,34 +7,46 @@ using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.Windows.AppLifecycle; -namespace BetterLyrics.WinUI3 { - public class Program { +namespace BetterLyrics.WinUI3 +{ + public class Program + { [STAThread] - static int Main(string[] args) { + static int Main(string[] args) + { WinRT.ComWrappersSupport.InitializeComWrappers(); bool isRedirect = DecideRedirection(); - if (!isRedirect) { - Application.Start((p) => { - var context = new DispatcherQueueSynchronizationContext( - DispatcherQueue.GetForCurrentThread()); - SynchronizationContext.SetSynchronizationContext(context); - _ = new App(); - }); + if (!isRedirect) + { + Application.Start( + (p) => + { + var context = new DispatcherQueueSynchronizationContext( + DispatcherQueue.GetForCurrentThread() + ); + SynchronizationContext.SetSynchronizationContext(context); + _ = new App(); + } + ); } return 0; } - private static bool DecideRedirection() { + private static bool DecideRedirection() + { bool isRedirect = false; AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs(); ExtendedActivationKind kind = args.Kind; AppInstance keyInstance = AppInstance.FindOrRegisterForKey(Helper.AppInfo.AppName); - if (keyInstance.IsCurrent) { + if (keyInstance.IsCurrent) + { keyInstance.Activated += OnActivated; - } else { + } + else + { isRedirect = true; RedirectActivationTo(args, keyInstance); } @@ -44,16 +56,23 @@ namespace BetterLyrics.WinUI3 { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr CreateEvent( - IntPtr lpEventAttributes, bool bManualReset, - bool bInitialState, string lpName); + IntPtr lpEventAttributes, + bool bManualReset, + bool bInitialState, + string lpName + ); [DllImport("kernel32.dll")] private static extern bool SetEvent(IntPtr hEvent); [DllImport("ole32.dll")] private static extern uint CoWaitForMultipleObjects( - uint dwFlags, uint dwMilliseconds, ulong nHandles, - IntPtr[] pHandles, out uint dwIndex); + uint dwFlags, + uint dwMilliseconds, + ulong nHandles, + IntPtr[] pHandles, + out uint dwIndex + ); [DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr hWnd); @@ -62,10 +81,14 @@ namespace BetterLyrics.WinUI3 { // Do the redirection on another thread, and use a non-blocking // wait method to wait for the redirection to complete. - public static void RedirectActivationTo(AppActivationArguments args, - AppInstance keyInstance) { + public static void RedirectActivationTo( + AppActivationArguments args, + AppInstance keyInstance + ) + { redirectEventHandle = CreateEvent(IntPtr.Zero, true, false, null); - Task.Run(() => { + Task.Run(() => + { keyInstance.RedirectActivationToAsync(args).AsTask().Wait(); SetEvent(redirectEventHandle); }); @@ -73,17 +96,21 @@ namespace BetterLyrics.WinUI3 { uint CWMO_DEFAULT = 0; uint INFINITE = 0xFFFFFFFF; _ = CoWaitForMultipleObjects( - CWMO_DEFAULT, INFINITE, 1, - [redirectEventHandle], out uint handleIndex); + CWMO_DEFAULT, + INFINITE, + 1, + [redirectEventHandle], + out uint handleIndex + ); // Bring the window to the foreground Process process = Process.GetProcessById((int)keyInstance.ProcessId); SetForegroundWindow(process.MainWindowHandle); } - private static void OnActivated(object sender, AppActivationArguments args) { + private static void OnActivated(object sender, AppActivationArguments args) + { ExtendedActivationKind kind = args.Kind; } - } -} \ No newline at end of file +} diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs index 5ef7b1a..aeb4b0c 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs @@ -1,77 +1,127 @@ -using ATL; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using ATL; using BetterLyrics.WinUI3.Messages; using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Settings; using CommunityToolkit.Mvvm.Messaging; using Microsoft.UI.Xaml; using SQLite; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; using Ude; +using Windows.Media.Control; -namespace BetterLyrics.WinUI3.Services.Database { - public class DatabaseService { - +namespace BetterLyrics.WinUI3.Services.Database +{ + public class DatabaseService + { private readonly SQLiteConnection _connection; + private readonly CharsetDetector _charsetDetector = new(); - public DatabaseService() { + public DatabaseService() + { _connection = new SQLiteConnection(Helper.AppInfo.DatabasePath); - if (_connection.GetTableInfo("MetadataIndex").Count == 0) { + if (_connection.GetTableInfo("MetadataIndex").Count == 0) + { _connection.CreateTable(); } } - public async Task RebuildMusicMetadataIndexDatabaseAsync(IList paths) { - await Task.Run(() => { + public async Task RebuildMusicMetadataIndexDatabaseAsync(IList paths) + { + await Task.Run(() => + { _connection.DeleteAll(); - foreach (var path in paths) { - if (Directory.Exists(path)) { - foreach (var file in Directory.GetFiles(path)) { + foreach (var path in paths) + { + if (Directory.Exists(path)) + { + foreach (var file in Directory.GetFiles(path)) + { var fileExtension = Path.GetExtension(file); var track = new Track(file); - _connection.Insert(new MetadataIndex { - Path = file, - Title = track.Title, - Artist = track.Artist, - }); + _connection.Insert( + new MetadataIndex + { + Path = file, + Title = track.Title, + Artist = track.Artist, + } + ); } } } }); } - public Track? GetMusicMetadata(string? title, string? artist) { - var founds = _connection.Table() + public Track? GetMusicMetadata( + GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps + ) + { + if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null) + return null; + + var founds = _connection + .Table() // Look up by Title and Artist (these two props were fetched by reading metadata in music file befoe) first // then by Path (music file name usually contains song name and artist so this can be a second way to look up for) // Please note for .lrc file, only the second way works for it - .Where(m => (m.Title.Contains(title) && m.Artist.Contains(artist)) || (m.Path.Contains(title) && m.Path.Contains(artist))).ToList(); - if (founds == null || founds.Count == 0) { + .Where(m => + ( + m.Title != null + && m.Artist != null + && m.Title.Contains(mediaProps.Title) + && m.Artist.Contains(mediaProps.Artist) + ) + || ( + m.Path != null + && m.Path.Contains(mediaProps.Title) + && m.Path.Contains(mediaProps.Artist) + ) + ) + .ToList(); + if (founds == null || founds.Count == 0) + { return null; - } else { + } + else + { var first = new Track(founds[0].Path); - if (founds.Count == 1) { + if (founds.Count == 1) + { return first; - } else { - if (first.Lyrics.Exists()) { + } + else + { + if (first.Lyrics.Exists()) + { return first; - } else { - foreach (var found in founds) { - if (found.Path.EndsWith(".lrc")) { - using (FileStream fs = File.OpenRead(found.Path)) { + } + else + { + foreach (var found in founds) + { + if (found.Path.EndsWith(".lrc")) + { + using (FileStream fs = File.OpenRead(found.Path)) + { _charsetDetector.Feed(fs); _charsetDetector.DataEnd(); } string content; - if (_charsetDetector.Charset != null) { - Encoding encoding = Encoding.GetEncoding(_charsetDetector.Charset); + if (_charsetDetector.Charset != null) + { + Encoding encoding = Encoding.GetEncoding( + _charsetDetector.Charset + ); content = File.ReadAllText(found.Path, encoding); - } else { + } + else + { content = File.ReadAllText(found.Path, Encoding.UTF8); } first.Lyrics.ParseLRC(content); @@ -84,7 +134,5 @@ namespace BetterLyrics.WinUI3.Services.Database { } } } - - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs index 3f773ff..e4b3929 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsDefaultValues.cs @@ -1,26 +1,35 @@ -using BetterLyrics.WinUI3.Models; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using BetterLyrics.WinUI3.Models; -namespace BetterLyrics.WinUI3.Services.Settings { - public static class SettingsDefaultValues { - +namespace BetterLyrics.WinUI3.Services.Settings +{ + public static class SettingsDefaultValues + { public const bool IsFirstRun = true; + // Theme public const int ThemeType = 0; // Follow system + // Language public const int Language = 0; // Default + // Music public const string MusicLibraries = "[]"; + // Backdrop public const int BackdropType = 5; // Acrylic Base public const bool IsCoverOverlayEnabled = true; public const bool IsDynamicCoverOverlay = true; public const int CoverOverlayOpacity = 100; // 1.0 public const int CoverOverlayBlurAmount = 200; + + // Album art + public const int CoverImageRadius = 24; + // Lyrics public const int LyricsAlignmentType = 1; // Center public const int LyricsBlurAmount = 0; @@ -30,5 +39,6 @@ namespace BetterLyrics.WinUI3.Services.Settings { public const bool IsLyricsGlowEffectEnabled = false; public const bool IsLyricsDynamicGlowEffectEnabled = false; public const int LyricsFontColorType = 0; // Default + public const int LyricsFontSelectedAccentColorIndex = 0; } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs index 2c13c4f..6117a88 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsKey.cs @@ -4,22 +4,31 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace BetterLyrics.WinUI3.Services.Settings { - public static class SettingsKeys { - +namespace BetterLyrics.WinUI3.Services.Settings +{ + public static class SettingsKeys + { public const string IsFirstRun = "IsFirstRun"; + // Theme public const string ThemeType = "ThemeType"; + // Language public const string Language = "Language"; + // Music public const string MusicLibraries = "MusicLibraries"; + // Backdrop public const string BackdropType = "BackdropType"; public const string IsCoverOverlayEnabled = "IsCoverOverlayEnabled"; public const string IsDynamicCoverOverlay = "IsDynamicCoverOverlay"; public const string CoverOverlayOpacity = "CoverOverlayOpacity"; public const string CoverOverlayBlurAmount = "CoverOverlayBlurAmount"; + + // Album art + public const string CoverImageRadius = "CoverImageRadius"; + // Lyrics public const string LyricsAlignmentType = "LyricsAlignmentType"; public const string LyricsBlurAmount = "LyricsBlurAmount"; @@ -29,6 +38,7 @@ namespace BetterLyrics.WinUI3.Services.Settings { public const string IsLyricsGlowEffectEnabled = "IsLyricsGlowEffectEnabled"; public const string IsLyricsDynamicGlowEffectEnabled = "IsLyricsDynamicGlowEffectEnabled"; public const string LyricsFontColorType = "LyricsFontColorType"; + public const string LyricsFontSelectedAccentColorIndex = + "LyricsFontSelectedAccentColorIndex"; } - } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs index 09f732f..9908541 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs @@ -1,21 +1,62 @@ -using BetterLyrics.WinUI3.Messages; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using BetterLyrics.WinUI3.Messages; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; using DevWinUI; using Microsoft.UI.Xaml; using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Runtime.CompilerServices; using Windows.Globalization; using Windows.Storage; -namespace BetterLyrics.WinUI3.Services.Settings { - public partial class SettingsService : ObservableObject { +namespace BetterLyrics.WinUI3.Services.Settings +{ + public partial class SettingsService : ObservableObject + { + private readonly ApplicationDataContainer _localSettings; - public bool IsFirstRun { + public SettingsService() + { + _localSettings = ApplicationData.Current.LocalSettings; + + _musicLibraries = + [ + .. JsonConvert.DeserializeObject>( + Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)! + )!, + ]; + + _musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries(); + } + + private void WatchMultipleDirectories(IEnumerable directories) + { + foreach (var dir in directories) + { + if (!Directory.Exists(dir)) + continue; + + var watcher = new FileSystemWatcher + { + Path = dir, + Filter = "*.*", + NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite, + EnableRaisingEvents = true, + }; + } + } + + private void OnFileCreated(object sender, FileSystemEventArgs e) + { + App.DispatcherQueue.TryEnqueue(() => { }); + } + + public bool IsFirstRun + { get => Get(SettingsKeys.IsFirstRun, SettingsDefaultValues.IsFirstRun); set => Set(SettingsKeys.IsFirstRun, value); } @@ -24,9 +65,11 @@ namespace BetterLyrics.WinUI3.Services.Settings { private bool _isRebuildingLyricsIndexDatabase = false; // Theme - public int Theme { + public int Theme + { get => Get(SettingsKeys.ThemeType, SettingsDefaultValues.ThemeType); - set { + set + { Set(SettingsKeys.ThemeType, value); WeakReferenceMessenger.Default.Send(new ThemeChangedMessage((ElementTheme)value)); } @@ -35,12 +78,13 @@ namespace BetterLyrics.WinUI3.Services.Settings { // Music private ObservableCollection _musicLibraries; - public ObservableCollection MusicLibraries { - get { - return _musicLibraries; - } - set { - if (_musicLibraries != null) { + public ObservableCollection MusicLibraries + { + get { return _musicLibraries; } + set + { + if (_musicLibraries != null) + { _musicLibraries.CollectionChanged -= (_, _) => SaveMusicLibraries(); } @@ -51,17 +95,20 @@ namespace BetterLyrics.WinUI3.Services.Settings { } } - private void SaveMusicLibraries() { + private void SaveMusicLibraries() + { Set(SettingsKeys.MusicLibraries, JsonConvert.SerializeObject(MusicLibraries.ToList())); } - // Language - public int Language { + public int Language + { get => Get(SettingsKeys.Language, SettingsDefaultValues.Language); - set { + set + { Set(SettingsKeys.Language, value); - switch ((Models.Language)Language) { + switch ((Models.Language)Language) + { case Models.Language.FollowSystem: ApplicationLanguages.PrimaryLanguageOverride = ""; break; @@ -81,87 +128,142 @@ namespace BetterLyrics.WinUI3.Services.Settings { } // Backdrop - public int BackdropType { + public int BackdropType + { get => Get(SettingsKeys.BackdropType, SettingsDefaultValues.BackdropType); - set { + set + { Set(SettingsKeys.BackdropType, value); - WeakReferenceMessenger.Default.Send(new SystemBackdropChangedMessage((BackdropType)value)); + WeakReferenceMessenger.Default.Send( + new SystemBackdropChangedMessage((BackdropType)value) + ); } } - public bool IsCoverOverlayEnabled { - get => Get(SettingsKeys.IsCoverOverlayEnabled, SettingsDefaultValues.IsCoverOverlayEnabled); + public bool IsCoverOverlayEnabled + { + get => + Get( + SettingsKeys.IsCoverOverlayEnabled, + SettingsDefaultValues.IsCoverOverlayEnabled + ); set => Set(SettingsKeys.IsCoverOverlayEnabled, value); } - public bool IsDynamicCoverOverlay { - get => Get(SettingsKeys.IsDynamicCoverOverlay, SettingsDefaultValues.IsDynamicCoverOverlay); + public bool IsDynamicCoverOverlay + { + get => + Get( + SettingsKeys.IsDynamicCoverOverlay, + SettingsDefaultValues.IsDynamicCoverOverlay + ); set => Set(SettingsKeys.IsDynamicCoverOverlay, value); } - public int CoverOverlayOpacity { + public int CoverOverlayOpacity + { get => Get(SettingsKeys.CoverOverlayOpacity, SettingsDefaultValues.CoverOverlayOpacity); set => Set(SettingsKeys.CoverOverlayOpacity, value); } - public int CoverOverlayBlurAmount { - get => Get(SettingsKeys.CoverOverlayBlurAmount, SettingsDefaultValues.CoverOverlayBlurAmount); + public int CoverOverlayBlurAmount + { + get => + Get( + SettingsKeys.CoverOverlayBlurAmount, + SettingsDefaultValues.CoverOverlayBlurAmount + ); set => Set(SettingsKeys.CoverOverlayBlurAmount, value); } + // Album art + public int CoverImageRadius + { + get => Get(SettingsKeys.CoverImageRadius, SettingsDefaultValues.CoverImageRadius); + set => Set(SettingsKeys.CoverImageRadius, value); + } + // Lyrics - public int LyricsAlignmentType { + public int LyricsAlignmentType + { get => Get(SettingsKeys.LyricsAlignmentType, SettingsDefaultValues.LyricsAlignmentType); set => Set(SettingsKeys.LyricsAlignmentType, value); } - public int LyricsBlurAmount { + public int LyricsBlurAmount + { get => Get(SettingsKeys.LyricsBlurAmount, SettingsDefaultValues.LyricsBlurAmount); set => Set(SettingsKeys.LyricsBlurAmount, value); } - public int LyricsVerticalEdgeOpacity { - get => Get(SettingsKeys.LyricsVerticalEdgeOpacity, SettingsDefaultValues.LyricsVerticalEdgeOpacity); + public int LyricsVerticalEdgeOpacity + { + get => + Get( + SettingsKeys.LyricsVerticalEdgeOpacity, + SettingsDefaultValues.LyricsVerticalEdgeOpacity + ); set => Set(SettingsKeys.LyricsVerticalEdgeOpacity, value); } - public float LyricsLineSpacingFactor { - get => Get(SettingsKeys.LyricsLineSpacingFactor, SettingsDefaultValues.LyricsLineSpacingFactor); + public float LyricsLineSpacingFactor + { + get => + Get( + SettingsKeys.LyricsLineSpacingFactor, + SettingsDefaultValues.LyricsLineSpacingFactor + ); set => Set(SettingsKeys.LyricsLineSpacingFactor, value); } - public int LyricsFontSize { + public int LyricsFontSize + { get => Get(SettingsKeys.LyricsFontSize, SettingsDefaultValues.LyricsFontSize); set => Set(SettingsKeys.LyricsFontSize, value); } - public bool IsLyricsGlowEffectEnabled { - get => Get(SettingsKeys.IsLyricsGlowEffectEnabled, SettingsDefaultValues.IsLyricsGlowEffectEnabled); + public bool IsLyricsGlowEffectEnabled + { + get => + Get( + SettingsKeys.IsLyricsGlowEffectEnabled, + SettingsDefaultValues.IsLyricsGlowEffectEnabled + ); set => Set(SettingsKeys.IsLyricsGlowEffectEnabled, value); } - public bool IsLyricsDynamicGlowEffectEnabled { - get => Get(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled); + public bool IsLyricsDynamicGlowEffectEnabled + { + get => + Get( + SettingsKeys.IsLyricsDynamicGlowEffectEnabled, + SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled + ); set => Set(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, value); } - public int LyricsFontColorType { + public int LyricsFontColorType + { get => Get(SettingsKeys.LyricsFontColorType, SettingsDefaultValues.LyricsFontColorType); set => Set(SettingsKeys.LyricsFontColorType, value); } - - private readonly ApplicationDataContainer _localSettings; - - public SettingsService() { - _localSettings = ApplicationData.Current.LocalSettings; - - _musicLibraries = [.. JsonConvert.DeserializeObject>( - Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!)!]; - - _musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries(); + public int LyricsFontSelectedAccentColorIndex + { + get => + Get( + SettingsKeys.LyricsFontSelectedAccentColorIndex, + SettingsDefaultValues.LyricsFontSelectedAccentColorIndex + ); + set + { + if (value >= 0) + Set(SettingsKeys.LyricsFontSelectedAccentColorIndex, value); + } } - private T? Get(string key, T? defaultValue = default) { - if (_localSettings.Values.TryGetValue(key, out object? value)) { + private T? Get(string key, T? defaultValue = default) + { + if (_localSettings.Values.TryGetValue(key, out object? value)) + { return (T)Convert.ChangeType(value, typeof(T)); } return defaultValue; } - private void Set(string key, T value, [CallerMemberName] string? propertyName = null) { + private void Set(string key, T value, [CallerMemberName] string? propertyName = null) + { _localSettings.Values[key] = value; OnPropertyChanged(propertyName); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw index 05636b2..02afdd6 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw @@ -279,7 +279,7 @@ Lyrics effect - + Album background @@ -363,4 +363,10 @@ Album art accent color + + Album art style + + + Corner radius + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw index f1fb93a..e303bb2 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw @@ -279,7 +279,7 @@ 歌词效果 - + 专辑背景 @@ -363,4 +363,10 @@ 专辑强调色 + + 专辑封面样式 + + + 圆角半径 + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw index 2274e5e..f24bac3 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw @@ -279,7 +279,7 @@ 歌詞效果 - + 專輯背景 @@ -363,4 +363,10 @@ 專輯強調色 + + 專輯封面樣式 + + + 圓角半徑 + \ No newline at end of file diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs index 34aaece..1d0b9ab 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs @@ -1,26 +1,35 @@ -using ATL; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.Common; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ATL; +using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Database; using BetterLyrics.WinUI3.Services.Settings; using CommunityToolkit.Mvvm.ComponentModel; +using DevWinUI; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.UI; using Microsoft.UI.Xaml.Media.Imaging; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Threading.Tasks; +using Ude; using Windows.Graphics.Imaging; using Windows.Media.Control; using Windows.Storage.Streams; using Windows.UI; +using static System.Net.Mime.MediaTypeNames; using static ATL.LyricsInfo; +using static CommunityToolkit.WinUI.Animations.Expressions.ExpressionValues; -namespace BetterLyrics.WinUI3.ViewModels { - public partial class MainViewModel(DatabaseService databaseService) : ObservableObject { - +namespace BetterLyrics.WinUI3.ViewModels +{ + public partial class MainViewModel : ObservableObject + { [ObservableProperty] private bool _isAnyMusicSessionExisted = false; @@ -31,7 +40,7 @@ namespace BetterLyrics.WinUI3.ViewModels { private string? _artist; [ObservableProperty] - private ObservableCollection _coverImageDominantColors = [Colors.Transparent, Colors.Transparent, Colors.Transparent]; + private ObservableCollection _coverImageDominantColors; [ObservableProperty] private BitmapImage? _coverImage; @@ -48,17 +57,33 @@ namespace BetterLyrics.WinUI3.ViewModels { [ObservableProperty] private bool _lyricsExisted = false; - private readonly Helper.ColorThief _colorThief = new(); + private readonly ColorThief _colorThief = new(); - private readonly DatabaseService _databaseService = databaseService; + private readonly SettingsService _settingsService; + private readonly DatabaseService _databaseService; - public List GetLyrics(Track? track) { + private readonly int _accentColorCount = 3; + + public MainViewModel(SettingsService settingsService, DatabaseService databaseService) + { + _settingsService = settingsService; + _databaseService = databaseService; + CoverImageDominantColors = + [ + .. Enumerable.Repeat(Colors.Transparent, _accentColorCount), + ]; + } + + public List GetLyrics(Track? track) + { List result = []; - var lyricsPhrases = track?.Lyrics.SynchronizedLyrics; + var lyricsPhrases = track?.Lyrics?.SynchronizedLyrics; - if (lyricsPhrases?.Count > 0) { - if (lyricsPhrases[0].TimestampMs > 0) { + if (lyricsPhrases?.Count > 0) + { + if (lyricsPhrases[0].TimestampMs > 0) + { var placeholder = new LyricsPhrase(0, " "); lyricsPhrases.Insert(0, placeholder); lyricsPhrases.Insert(0, placeholder); @@ -67,44 +92,50 @@ namespace BetterLyrics.WinUI3.ViewModels { LyricsLine? lyricsLine = null; - for (int i = 0; i < lyricsPhrases?.Count; i++) { + for (int i = 0; i < lyricsPhrases?.Count; i++) + { var lyricsPhrase = lyricsPhrases[i]; int startTimestampMs = lyricsPhrase.TimestampMs; int endTimestampMs; - if (i + 1 < lyricsPhrases.Count) { + if (i + 1 < lyricsPhrases.Count) + { endTimestampMs = lyricsPhrases[i + 1].TimestampMs; - } else { + } + else + { endTimestampMs = (int)track.DurationMs; } - lyricsLine ??= new LyricsLine { - StartPlayingTimestampMs = startTimestampMs, - }; + lyricsLine ??= new LyricsLine { StartPlayingTimestampMs = startTimestampMs }; lyricsLine.Texts.Add(lyricsPhrase.Text); - if (endTimestampMs == startTimestampMs) { + if (endTimestampMs == startTimestampMs) + { continue; - } else { + } + else + { lyricsLine.EndPlayingTimestampMs = endTimestampMs; result.Add(lyricsLine); lyricsLine = null; } - } LyricsExisted = result.Count != 0; - if (!LyricsExisted) { + if (!LyricsExisted) + { ShowLyricsOnly = false; } return result; - } - public async Task<(List, SoftwareBitmap?, uint, uint)> SetSongInfoAsync(GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps) { - + public async Task<(List, SoftwareBitmap?, uint, uint)> SetSongInfoAsync( + GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps + ) + { SoftwareBitmap? coverSoftwareBitmap = null; uint coverImagePixelWidth = 0; uint coverImagePixelHeight = 0; @@ -114,26 +145,37 @@ namespace BetterLyrics.WinUI3.ViewModels { IRandomAccessStream? stream = null; - var track = _databaseService.GetMusicMetadata(Title, Artist); + var track = _databaseService.GetMusicMetadata(mediaProps); - if (mediaProps?.Thumbnail is IRandomAccessStreamReference reference) { + if (mediaProps?.Thumbnail is IRandomAccessStreamReference reference) + { stream = await reference.OpenReadAsync(); - } else { - if (track?.EmbeddedPictures.Count > 0) { + } + else + { + if (track?.EmbeddedPictures.Count > 0) + { var bytes = track.EmbeddedPictures[0].PictureData; - if (bytes != null) { + if (bytes != null) + { stream = await Helper.ImageHelper.GetStreamFromBytesAsync(bytes); } } } // Set cover image and dominant colors - if (stream == null) { + if (stream == null) + { CoverImage = null; - for (int i = 0; i < 3; i++) { - CoverImageDominantColors[i] = Colors.Transparent; - } - } else { + CoverImageDominantColors = + [ + .. Enumerable.Repeat(Colors.Transparent, _accentColorCount), + ]; + _settingsService.LyricsFontSelectedAccentColorIndex = + _settingsService.LyricsFontSelectedAccentColorIndex; + } + else + { CoverImage = new BitmapImage(); await CoverImage.SetSourceAsync(stream); stream.Seek(0); @@ -147,19 +189,24 @@ namespace BetterLyrics.WinUI3.ViewModels { BitmapAlphaMode.Premultiplied ); - var quantizedColors = await _colorThief.GetPalette(decoder, 3); - for (int i = 0; i < 3; i++) { - Helper.QuantizedColor quantizedColor = quantizedColors[i]; - CoverImageDominantColors[i] = Color.FromArgb( - quantizedColor.Color.A, quantizedColor.Color.R, quantizedColor.Color.G, quantizedColor.Color.B); - } + CoverImageDominantColors = + [ + .. (await _colorThief.GetPalette(decoder, _accentColorCount)).Select(color => + Color.FromArgb(color.Color.A, color.Color.R, color.Color.G, color.Color.B) + ), + ]; + _settingsService.LyricsFontSelectedAccentColorIndex = + _settingsService.LyricsFontSelectedAccentColorIndex; stream.Dispose(); } - return (GetLyrics(track), coverSoftwareBitmap, coverImagePixelWidth, coverImagePixelHeight); - + return ( + GetLyrics(track), + coverSoftwareBitmap, + coverImagePixelWidth, + coverImagePixelHeight + ); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs index ce382e4..5dc5448 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs @@ -1,12 +1,12 @@ -using BetterLyrics.WinUI3.Models; +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Database; using BetterLyrics.WinUI3.Services.Settings; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; -using System; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Windows.ApplicationModel.Core; using Windows.Media; using Windows.Media.Playback; @@ -14,9 +14,14 @@ using Windows.Storage.Pickers; using Windows.System; using WinRT.Interop; -namespace BetterLyrics.WinUI3.ViewModels { - public partial class SettingsViewModel(DatabaseService databaseService, SettingsService settingsService, MainViewModel mainViewModel) : ObservableObject { - +namespace BetterLyrics.WinUI3.ViewModels +{ + public partial class SettingsViewModel( + DatabaseService databaseService, + SettingsService settingsService, + MainViewModel mainViewModel + ) : ObservableObject + { private readonly MediaPlayer _mediaPlayer = new(); private readonly DatabaseService _databaseService = databaseService; @@ -28,19 +33,24 @@ namespace BetterLyrics.WinUI3.ViewModels { public string Version => Helper.AppInfo.AppVersion; [RelayCommand] - private async Task RebuildLyricsIndexDatabaseAsync() { + private async Task RebuildLyricsIndexDatabaseAsync() + { SettingsService.IsRebuildingLyricsIndexDatabase = true; - await _databaseService.RebuildMusicMetadataIndexDatabaseAsync(SettingsService.MusicLibraries); + await _databaseService.RebuildMusicMetadataIndexDatabaseAsync( + SettingsService.MusicLibraries + ); SettingsService.IsRebuildingLyricsIndexDatabase = false; } - public async Task RemoveFolderAsync(string path) { + public async Task RemoveFolderAsync(string path) + { SettingsService.MusicLibraries.Remove(path); await RebuildLyricsIndexDatabaseAsync(); } [RelayCommand] - private async Task SelectAndAddFolderAsync() { + private async Task SelectAndAddFolderAsync() + { var picker = new FolderPicker(); picker.FileTypeFilter.Add("*"); @@ -52,48 +62,62 @@ namespace BetterLyrics.WinUI3.ViewModels { App.Current.SettingsWindow!.AppWindow.MoveInZOrderAtTop(); - if (folder != null) { + if (folder != null) + { await AddFolderAsync(folder.Path); } - } - private async Task AddFolderAsync(string path) { + private async Task AddFolderAsync(string path) + { bool existed = SettingsService.MusicLibraries.Any((x) => x == path); - if (existed) { - MainWindow.StackedNotificationsBehavior?.Show(App.ResourceLoader!.GetString("SettingsPagePathExistedInfo"), - Helper.AnimationHelper.StackedNotificationsShowingDuration); - } else { + if (existed) + { + MainWindow.StackedNotificationsBehavior?.Show( + App.ResourceLoader!.GetString("SettingsPagePathExistedInfo"), + Helper.AnimationHelper.StackedNotificationsShowingDuration + ); + } + else + { SettingsService.MusicLibraries.Add(path); await RebuildLyricsIndexDatabaseAsync(); } } [RelayCommand] - private static async Task LaunchProjectGitHubPageAsync() { + private static async Task LaunchProjectGitHubPageAsync() + { await Launcher.LaunchUriAsync(new Uri(Helper.AppInfo.GithubUrl)); } - private static void OpenFolderInFileExplorer(string path) { - Process.Start(new ProcessStartInfo { - FileName = "explorer.exe", - Arguments = path, - UseShellExecute = true - }); + private static void OpenFolderInFileExplorer(string path) + { + Process.Start( + new ProcessStartInfo + { + FileName = "explorer.exe", + Arguments = path, + UseShellExecute = true, + } + ); } - public static void OpenMusicFolder(string path) { + public static void OpenMusicFolder(string path) + { OpenFolderInFileExplorer(path); } [RelayCommand] - private static void RestartApp() { + private static void RestartApp() + { // The restart will be executed immediately. AppRestartFailureReason failureReason = Microsoft.Windows.AppLifecycle.AppInstance.Restart(""); // If the restart fails, handle it here. - switch (failureReason) { + switch (failureReason) + { case AppRestartFailureReason.RestartPending: break; case AppRestartFailureReason.NotInForeground: @@ -106,16 +130,17 @@ namespace BetterLyrics.WinUI3.ViewModels { } [RelayCommand] - private async Task PlayTestingMusicTask() { + private async Task PlayTestingMusicTask() + { await AddFolderAsync(Helper.AppInfo.AssetsFolder); _mediaPlayer.SetUriSource(new Uri(Helper.AppInfo.TestMusicPath)); _mediaPlayer.Play(); } [RelayCommand] - private static void OpenLogFolder() { + private static void OpenLogFolder() + { OpenFolderInFileExplorer(Helper.AppInfo.LogDirectory); } - } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs index 1803797..8f2655d 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml.cs @@ -1,9 +1,16 @@ -using BetterLyrics.WinUI3.Helper; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Numerics; +using System.Threading.Tasks; +using BetterLyrics.WinUI3.Helper; using BetterLyrics.WinUI3.Models; using BetterLyrics.WinUI3.Services.Settings; using BetterLyrics.WinUI3.ViewModels; using CommunityToolkit.Mvvm.DependencyInjection; using CommunityToolkit.WinUI; +using Microsoft.Extensions.Logging; using Microsoft.Graphics.Canvas; using Microsoft.Graphics.Canvas.Brushes; using Microsoft.Graphics.Canvas.Effects; @@ -12,34 +19,28 @@ using Microsoft.Graphics.Canvas.UI.Xaml; using Microsoft.UI; using Microsoft.UI.Dispatching; using Microsoft.UI.Text; +using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Numerics; -using System.Threading.Tasks; using Windows.Foundation; -using Windows.Media.Control; -using Color = Windows.UI.Color; -using System.Linq; -using Microsoft.UI.Windowing; using Windows.Graphics.Imaging; using Windows.Media; -using Microsoft.Extensions.Logging; +using Windows.Media.Control; +using Color = Windows.UI.Color; // 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.Views { +namespace BetterLyrics.WinUI3.Views +{ /// /// An empty page that can be used on its own or navigated to within a Frame. /// - public sealed partial class MainPage : Page { - + public sealed partial class MainPage : Page + { public MainViewModel ViewModel => (MainViewModel)DataContext; - private readonly SettingsService _settingsService; + public SettingsService SettingsService { get; set; } private List _lyricsLines = []; @@ -96,57 +97,75 @@ namespace BetterLyrics.WinUI3.Views { private readonly ILogger _logger; - public MainPage() { + public MainPage() + { this.InitializeComponent(); + _queueTimer = _dispatcherQueue.CreateTimer(); + _logger = Ioc.Default.GetService>()!; + SettingsService = Ioc.Default.GetService()!; + DataContext = Ioc.Default.GetService(); + + SettingsService.PropertyChanged += SettingsService_PropertyChanged; + ViewModel.PropertyChanged += ViewModel_PropertyChanged; SetLyricsColor(); - _settingsService = Ioc.Default.GetService()!; - - if (_settingsService.IsFirstRun) { + if (SettingsService.IsFirstRun) + { WelcomeTeachingTip.IsOpen = true; } - - _settingsService.PropertyChanged += SettingsService_PropertyChanged; - - DataContext = Ioc.Default.GetService(); - - ViewModel.PropertyChanged += ViewModel_PropertyChanged; - - _queueTimer = _dispatcherQueue.CreateTimer(); } - private async Task ForceToScrollToCurrentPlayingLineAsync() { + private async Task ForceToScrollToCurrentPlayingLineAsync() + { _forceToScroll = true; await Task.Delay(1); _forceToScroll = false; } - private async void SettingsService_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { - switch (e.PropertyName) { - case nameof(_settingsService.LyricsFontSize): - case nameof(_settingsService.LyricsLineSpacingFactor): + private async void SettingsService_PropertyChanged( + object? sender, + System.ComponentModel.PropertyChangedEventArgs e + ) + { + switch (e.PropertyName) + { + case nameof(SettingsService.LyricsFontSize): + case nameof(SettingsService.LyricsLineSpacingFactor): LayoutLyrics(); await ForceToScrollToCurrentPlayingLineAsync(); break; - case nameof(_settingsService.IsRebuildingLyricsIndexDatabase): - if (!_settingsService.IsRebuildingLyricsIndexDatabase) { + case nameof(SettingsService.IsRebuildingLyricsIndexDatabase): + if (!SettingsService.IsRebuildingLyricsIndexDatabase) + { CurrentSession_MediaPropertiesChanged(_currentSession, null); } break; - case nameof(_settingsService.Theme): + case nameof(SettingsService.Theme): + case nameof(SettingsService.LyricsFontColorType): + case nameof(SettingsService.LyricsFontSelectedAccentColorIndex): await Task.Delay(1); SetLyricsColor(); break; + case nameof(SettingsService.CoverImageRadius): + CoverImageGrid.CornerRadius = new CornerRadius( + SettingsService.CoverImageRadius / 100f * (CoverImageGrid.ActualHeight / 2) + ); + break; default: break; } } - private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { - switch (e.PropertyName) { + private void ViewModel_PropertyChanged( + object? sender, + System.ComponentModel.PropertyChangedEventArgs e + ) + { + switch (e.PropertyName) + { case nameof(ViewModel.ShowLyricsOnly): RootGrid_SizeChanged(null, null); break; @@ -155,11 +174,31 @@ namespace BetterLyrics.WinUI3.Views { } } - private void SetLyricsColor() { - _lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color; + private void SetLyricsColor() + { + switch ((LyricsFontColorType)SettingsService.LyricsFontColorType) + { + case LyricsFontColorType.Default: + _lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color; + break; + case LyricsFontColorType.Dominant: + _lyricsColor = ViewModel.CoverImageDominantColors[ + Math.Max( + 0, + Math.Min( + ViewModel.CoverImageDominantColors.Count - 1, + SettingsService.LyricsFontSelectedAccentColorIndex + ) + ) + ]; + break; + default: + break; + } } - private async void InitMediaManager() { + private async void InitMediaManager() + { _sessionManager = await GlobalSystemMediaTransportControlsSessionManager.RequestAsync(); _sessionManager.CurrentSessionChanged += SessionManager_CurrentSessionChanged; _sessionManager.SessionsChanged += SessionManager_SessionsChanged; @@ -167,8 +206,13 @@ namespace BetterLyrics.WinUI3.Views { SessionManager_CurrentSessionChanged(_sessionManager, null); } - private void CurrentSession_TimelinePropertiesChanged(GlobalSystemMediaTransportControlsSession? sender, TimelinePropertiesChangedEventArgs? args) { - if (sender == null) { + private void CurrentSession_TimelinePropertiesChanged( + GlobalSystemMediaTransportControlsSession? sender, + TimelinePropertiesChangedEventArgs? args + ) + { + if (sender == null) + { _currentTime = TimeSpan.Zero; return; } @@ -182,62 +226,83 @@ namespace BetterLyrics.WinUI3.Views { /// /// /// - private void CurrentSession_PlaybackInfoChanged(GlobalSystemMediaTransportControlsSession? sender, PlaybackInfoChangedEventArgs? args) { - _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () => { - if (sender == null) { - LyricsCanvas.Paused = true; - return; + private void CurrentSession_PlaybackInfoChanged( + GlobalSystemMediaTransportControlsSession? sender, + PlaybackInfoChangedEventArgs? args + ) + { + _dispatcherQueue.TryEnqueue( + DispatcherQueuePriority.Normal, + () => + { + if (sender == null) + { + LyricsCanvas.Paused = true; + return; + } + + var playbackState = sender.GetPlaybackInfo().PlaybackStatus; + _logger.LogDebug(playbackState.ToString()); + + switch (playbackState) + { + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed: + LyricsCanvas.Paused = true; + break; + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Opened: + LyricsCanvas.Paused = true; + break; + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Changing: + LyricsCanvas.Paused = true; + break; + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Stopped: + LyricsCanvas.Paused = true; + break; + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing: + LyricsCanvas.Paused = false; + break; + case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Paused: + LyricsCanvas.Paused = true; + break; + default: + break; + } } - - var playbackState = sender.GetPlaybackInfo().PlaybackStatus; - _logger.LogDebug(playbackState.ToString()); - - switch (playbackState) { - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed: - LyricsCanvas.Paused = true; - break; - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Opened: - LyricsCanvas.Paused = true; - break; - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Changing: - LyricsCanvas.Paused = true; - break; - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Stopped: - LyricsCanvas.Paused = true; - break; - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Playing: - LyricsCanvas.Paused = false; - break; - case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Paused: - LyricsCanvas.Paused = true; - break; - default: - break; - } - }); - + ); } - private void SessionManager_SessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender, SessionsChangedEventArgs? args) { + private void SessionManager_SessionsChanged( + GlobalSystemMediaTransportControlsSessionManager sender, + SessionsChangedEventArgs? args + ) + { _logger.LogDebug("SessionManager_SessionsChanged"); } - private void SessionManager_CurrentSessionChanged(GlobalSystemMediaTransportControlsSessionManager sender, CurrentSessionChangedEventArgs? args) { + private void SessionManager_CurrentSessionChanged( + GlobalSystemMediaTransportControlsSessionManager sender, + CurrentSessionChangedEventArgs? args + ) + { _logger.LogDebug("SessionManager_CurrentSessionChanged"); - // Unregister events associated with the previous session - if (_currentSession != null) { + // Unregister events associated with the previous session + if (_currentSession != null) + { _currentSession.MediaPropertiesChanged -= CurrentSession_MediaPropertiesChanged; _currentSession.PlaybackInfoChanged -= CurrentSession_PlaybackInfoChanged; - _currentSession.TimelinePropertiesChanged -= CurrentSession_TimelinePropertiesChanged; + _currentSession.TimelinePropertiesChanged -= + CurrentSession_TimelinePropertiesChanged; } // Record and register events for current session _currentSession = sender.GetCurrentSession(); - if (_currentSession != null) { + if (_currentSession != null) + { _currentSession.MediaPropertiesChanged += CurrentSession_MediaPropertiesChanged; _currentSession.PlaybackInfoChanged += CurrentSession_PlaybackInfoChanged; - _currentSession.TimelinePropertiesChanged += CurrentSession_TimelinePropertiesChanged; + _currentSession.TimelinePropertiesChanged += + CurrentSession_TimelinePropertiesChanged; } CurrentSession_MediaPropertiesChanged(_currentSession, null); @@ -248,61 +313,86 @@ namespace BetterLyrics.WinUI3.Views { /// /// /// - private void CurrentSession_MediaPropertiesChanged(GlobalSystemMediaTransportControlsSession? sender, MediaPropertiesChangedEventArgs? args) { - _queueTimer.Debounce(() => { - _logger.LogDebug("CurrentSession_MediaPropertiesChanged"); - _dispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, async () => { + private void CurrentSession_MediaPropertiesChanged( + GlobalSystemMediaTransportControlsSession? sender, + MediaPropertiesChangedEventArgs? args + ) + { + _queueTimer.Debounce( + () => + { + _logger.LogDebug("CurrentSession_MediaPropertiesChanged"); + _dispatcherQueue.TryEnqueue( + DispatcherQueuePriority.High, + async () => + { + GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps = + null; - GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps = null; + if (_currentSession != null) + { + try + { + mediaProps = await _currentSession.TryGetMediaPropertiesAsync(); + } + catch (Exception) { } + } - if (_currentSession != null) { - try { - mediaProps = await _currentSession.TryGetMediaPropertiesAsync(); - } catch (Exception) { + ViewModel.IsAnyMusicSessionExisted = _currentSession != null; + + ViewModel.AboutToUpdateUI = true; + await Task.Delay(AnimationHelper.StoryboardDefaultDuration); + + ( + _lyricsLines, + _coverSoftwareBitmap, + _coverImagePixelWidth, + _coverImagePixelHeight + ) = await ViewModel.SetSongInfoAsync(mediaProps); + + // Force to show lyrics and scroll to current line even if the music is not playing + LyricsCanvas.Paused = false; + await ForceToScrollToCurrentPlayingLineAsync(); + await Task.Delay(1); + // Detect and recover the music state + CurrentSession_PlaybackInfoChanged(_currentSession, null); + CurrentSession_TimelinePropertiesChanged(_currentSession, null); + + ViewModel.AboutToUpdateUI = false; + + if (_lyricsLines.Count == 0) + { + Grid.SetColumnSpan(SongInfoInnerGrid, 3); + } + else + { + Grid.SetColumnSpan(SongInfoInnerGrid, 1); + } } - } - - ViewModel.IsAnyMusicSessionExisted = _currentSession != null; - - ViewModel.AboutToUpdateUI = true; - await Task.Delay(AnimationHelper.StoryboardDefaultDuration); - - (_lyricsLines, _coverSoftwareBitmap, _coverImagePixelWidth, _coverImagePixelHeight) = await ViewModel.SetSongInfoAsync(mediaProps); - - // Force to show lyrics and scroll to current line even if the music is not playing - LyricsCanvas.Paused = false; - await ForceToScrollToCurrentPlayingLineAsync(); - await Task.Delay(1); - // Detect and recover the music state - CurrentSession_PlaybackInfoChanged(_currentSession, null); - CurrentSession_TimelinePropertiesChanged(_currentSession, null); - - ViewModel.AboutToUpdateUI = false; - - if (_lyricsLines.Count == 0) { - Grid.SetColumnSpan(SongInfoInnerGrid, 3); - } else { - Grid.SetColumnSpan(SongInfoInnerGrid, 1); - } - - }); - }, TimeSpan.FromMilliseconds(AnimationHelper.DebounceDefaultDuration)); - + ); + }, + TimeSpan.FromMilliseconds(AnimationHelper.DebounceDefaultDuration) + ); } - private async void RootGrid_SizeChanged(object? sender, SizeChangedEventArgs? e) { + private async void RootGrid_SizeChanged(object? sender, SizeChangedEventArgs? e) + { //_queueTimer.Debounce(async () => { _lyricsAreaHeight = LyricsGrid.ActualHeight; _lyricsAreaWidth = LyricsGrid.ActualWidth; - if (SongInfoColumnDefinition.ActualWidth == 0 || ViewModel.ShowLyricsOnly) { + if (SongInfoColumnDefinition.ActualWidth == 0 || ViewModel.ShowLyricsOnly) + { _lyricsCanvasLeftMargin = 36; - } else { + } + else + { _lyricsCanvasLeftMargin = 36 + SongInfoColumnDefinition.ActualWidth + 36; } - _lyricsCanvasMaxTextWidth = _lyricsAreaWidth - _lyricsCanvasLeftMargin - _lyricsCanvasRightMargin; + _lyricsCanvasMaxTextWidth = + _lyricsAreaWidth - _lyricsCanvasLeftMargin - _lyricsCanvasRightMargin; LayoutLyrics(); await ForceToScrollToCurrentPlayingLineAsync(); @@ -311,7 +401,11 @@ namespace BetterLyrics.WinUI3.Views { } // Comsumes GPU related resources - private void LyricsCanvas_Draw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args) { + private void LyricsCanvas_Draw( + ICanvasAnimatedControl sender, + CanvasAnimatedDrawEventArgs args + ) + { using var ds = args.DrawingSession; var r = _lyricsColor.R; @@ -319,26 +413,40 @@ namespace BetterLyrics.WinUI3.Views { var b = _lyricsColor.B; // Draw (dynamic) cover image as the very first layer - if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) { + if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) + { DrawCoverImage(sender, ds); } // Lyrics only layer using var lyrics = new CanvasCommandList(sender); - using (var lyricsDs = lyrics.CreateDrawingSession()) { + using (var lyricsDs = lyrics.CreateDrawingSession()) + { DrawLyrics(sender, lyricsDs, r, g, b); } using var glowedLyrics = new CanvasCommandList(sender); - using (var glowedLyricsDs = glowedLyrics.CreateDrawingSession()) { - if (_settingsService.IsLyricsGlowEffectEnabled) { - glowedLyricsDs.DrawImage(new GaussianBlurEffect { - Source = lyrics, - BlurAmount = MathF.Sin(_lyricsGlowEffectAngle) * (_lyricsGlowEffectMaxBlurAmount - _lyricsGlowEffectMinBlurAmount) / 2f + - (_lyricsGlowEffectMaxBlurAmount + _lyricsGlowEffectMinBlurAmount) / 2f, - BorderMode = EffectBorderMode.Soft, - Optimization = EffectOptimization.Quality, - }); + using (var glowedLyricsDs = glowedLyrics.CreateDrawingSession()) + { + if (SettingsService.IsLyricsGlowEffectEnabled) + { + glowedLyricsDs.DrawImage( + new GaussianBlurEffect + { + Source = lyrics, + BlurAmount = + MathF.Sin(_lyricsGlowEffectAngle) + * ( + _lyricsGlowEffectMaxBlurAmount + - _lyricsGlowEffectMinBlurAmount + ) + / 2f + + (_lyricsGlowEffectMaxBlurAmount + _lyricsGlowEffectMinBlurAmount) + / 2f, + BorderMode = EffectBorderMode.Soft, + Optimization = EffectOptimization.Quality, + } + ); } glowedLyricsDs.DrawImage(lyrics); } @@ -346,25 +454,44 @@ namespace BetterLyrics.WinUI3.Views { // Mock gradient blurred lyrics layer using var combinedBlurredLyrics = new CanvasCommandList(sender); using var combinedBlurredLyricsDs = combinedBlurredLyrics.CreateDrawingSession(); - if (_settingsService.LyricsBlurAmount == 0) { + if (SettingsService.LyricsBlurAmount == 0) + { combinedBlurredLyricsDs.DrawImage(glowedLyrics); - } else { + } + else + { double step = 0.05; double overlapFactor = 0; - for (double i = 0; i <= 0.5 - step; i += step) { - using var blurredLyrics = new GaussianBlurEffect { + for (double i = 0; i <= 0.5 - step; i += step) + { + using var blurredLyrics = new GaussianBlurEffect + { Source = glowedLyrics, - BlurAmount = (float)(_settingsService.LyricsBlurAmount * (1 - i / (0.5 - step))), + BlurAmount = (float)( + SettingsService.LyricsBlurAmount * (1 - i / (0.5 - step)) + ), Optimization = EffectOptimization.Quality, BorderMode = EffectBorderMode.Soft, }; - using var topCropped = new CropEffect { + using var topCropped = new CropEffect + { Source = blurredLyrics, - SourceRectangle = new Rect(0, sender.Size.Height * i, sender.Size.Width, sender.Size.Height * step * (1 + overlapFactor)) + SourceRectangle = new Rect( + 0, + sender.Size.Height * i, + sender.Size.Width, + sender.Size.Height * step * (1 + overlapFactor) + ), }; - using var bottomCropped = new CropEffect { + using var bottomCropped = new CropEffect + { Source = blurredLyrics, - SourceRectangle = new Rect(0, sender.Size.Height * (1 - i - step * (1 + overlapFactor)), sender.Size.Width, sender.Size.Height * step * (1 + overlapFactor)) + SourceRectangle = new Rect( + 0, + sender.Size.Height * (1 - i - step * (1 + overlapFactor)), + sender.Size.Width, + sender.Size.Height * step * (1 + overlapFactor) + ), }; combinedBlurredLyricsDs.DrawImage(topCropped); combinedBlurredLyricsDs.DrawImage(bottomCropped); @@ -373,35 +500,56 @@ namespace BetterLyrics.WinUI3.Views { // Masked mock gradient blurred lyrics layer using var maskedCombinedBlurredLyrics = new CanvasCommandList(sender); - using (var maskedCombinedBlurredLyricsDs = maskedCombinedBlurredLyrics.CreateDrawingSession()) { - if (_settingsService.LyricsVerticalEdgeOpacity == 100) { + using ( + var maskedCombinedBlurredLyricsDs = + maskedCombinedBlurredLyrics.CreateDrawingSession() + ) + { + if (SettingsService.LyricsVerticalEdgeOpacity == 100) + { maskedCombinedBlurredLyricsDs.DrawImage(combinedBlurredLyrics); - } else { + } + else + { using var mask = new CanvasCommandList(sender); - using (var maskDs = mask.CreateDrawingSession()) { + using (var maskDs = mask.CreateDrawingSession()) + { DrawGradientOpacityMask(sender, maskDs, r, g, b); } - maskedCombinedBlurredLyricsDs.DrawImage(new AlphaMaskEffect { - Source = combinedBlurredLyrics, - AlphaMask = mask - }); + maskedCombinedBlurredLyricsDs.DrawImage( + new AlphaMaskEffect { Source = combinedBlurredLyrics, AlphaMask = mask } + ); } } // Draw the final composed layer ds.DrawImage(maskedCombinedBlurredLyrics); - } - private void DrawLyrics(ICanvasAnimatedControl control, CanvasDrawingSession ds, byte r, byte g, byte b) { - - var (displayStartLineIndex, displayEndLineIndex) = GetVisibleLyricsLineIndexBoundaries(); - - for (int i = displayStartLineIndex; _lyricsLines.Count > 0 && i >= 0 && i < _lyricsLines.Count && i <= displayEndLineIndex; i++) { + private void DrawLyrics( + ICanvasAnimatedControl control, + CanvasDrawingSession ds, + byte r, + byte g, + byte b + ) + { + var (displayStartLineIndex, displayEndLineIndex) = + GetVisibleLyricsLineIndexBoundaries(); + for ( + int i = displayStartLineIndex; + _lyricsLines.Count > 0 + && i >= 0 + && i < _lyricsLines.Count + && i <= displayEndLineIndex; + i++ + ) + { var line = _lyricsLines[i]; - if (line.TextLayout == null) { + if (line.TextLayout == null) + { return; } @@ -412,7 +560,8 @@ namespace BetterLyrics.WinUI3.Views { float centerX = position.X; float centerY = position.Y + (float)line.TextLayout.LayoutBounds.Height / 2; - switch ((LyricsAlignmentType)_settingsService.LyricsAlignmentType) { + switch ((LyricsAlignmentType)SettingsService.LyricsAlignmentType) + { case LyricsAlignmentType.Left: line.TextLayout.HorizontalAlignment = CanvasHorizontalAlignment.Left; break; @@ -428,33 +577,65 @@ namespace BetterLyrics.WinUI3.Views { break; } - int startIndex = 0; // Set brush - for (int j = 0; j < line.TextLayout.LineCount; j++) { - + for (int j = 0; j < line.TextLayout.LineCount; j++) + { int count = line.TextLayout.LineMetrics[j].CharacterCount; var regions = line.TextLayout.GetCharacterRegions(startIndex, count); - float subLinePlayingProgress = Math.Clamp((line.PlayingProgress * line.Text.Length - startIndex) / count, 0, 1); + float subLinePlayingProgress = Math.Clamp( + (line.PlayingProgress * line.Text.Length - startIndex) / count, + 0, + 1 + ); - using var horizontalFillBrush = new CanvasLinearGradientBrush(control, [ - new() { Position = 0, Color = Color.FromArgb((byte)(255 * line.Opacity), r, g, b) }, - new() { Position = subLinePlayingProgress * (1 + progressPerChar) - progressPerChar, Color = Color.FromArgb((byte)(255 * line.Opacity), r, g, b) }, - new() { Position = subLinePlayingProgress * (1 + progressPerChar), Color = Color.FromArgb((byte)(255 * _defaultOpacity), r, g, b) }, - new() { Position = 1.5f, Color = Color.FromArgb((byte)(255 * _defaultOpacity), r, g, b) }, - ]) { - StartPoint = new Vector2((float)(regions[0].LayoutBounds.Left + position.X), 0), - EndPoint = new Vector2((float)(regions[^1].LayoutBounds.Right + position.X), 0) + using var horizontalFillBrush = new CanvasLinearGradientBrush( + control, + [ + new() + { + Position = 0, + Color = Color.FromArgb((byte)(255 * line.Opacity), r, g, b), + }, + new() + { + Position = + subLinePlayingProgress * (1 + progressPerChar) + - progressPerChar, + Color = Color.FromArgb((byte)(255 * line.Opacity), r, g, b), + }, + new() + { + Position = subLinePlayingProgress * (1 + progressPerChar), + Color = Color.FromArgb((byte)(255 * _defaultOpacity), r, g, b), + }, + new() + { + Position = 1.5f, + Color = Color.FromArgb((byte)(255 * _defaultOpacity), r, g, b), + }, + ] + ) + { + StartPoint = new Vector2( + (float)(regions[0].LayoutBounds.Left + position.X), + 0 + ), + EndPoint = new Vector2( + (float)(regions[^1].LayoutBounds.Right + position.X), + 0 + ), }; line.TextLayout.SetBrush(startIndex, count, horizontalFillBrush); startIndex += count; - } // Scale - ds.Transform = Matrix3x2.CreateScale(line.Scale, new Vector2(centerX, centerY)) * Matrix3x2.CreateTranslation(0, _totalYScroll); + ds.Transform = + Matrix3x2.CreateScale(line.Scale, new Vector2(centerX, centerY)) + * Matrix3x2.CreateTranslation(0, _totalYScroll); // _logger.LogDebug(_totalYScroll); ds.DrawTextLayout(line.TextLayout, position, Colors.Transparent); @@ -462,68 +643,96 @@ namespace BetterLyrics.WinUI3.Views { // Reset scale ds.Transform = Matrix3x2.Identity; } - } - private void DrawCoverImage(ICanvasAnimatedControl control, CanvasDrawingSession ds) { + private void DrawCoverImage(ICanvasAnimatedControl control, CanvasDrawingSession ds) + { + ds.Transform = Matrix3x2.CreateRotation( + _coverBitmapRotateAngle, + control.Size.ToVector2() * 0.5f + ); - ds.Transform = Matrix3x2.CreateRotation(_coverBitmapRotateAngle, control.Size.ToVector2() * 0.5f); - - using var coverOverlayEffect = new OpacityEffect { - Opacity = _settingsService.CoverOverlayOpacity / 100f, - Source = new GaussianBlurEffect { - BlurAmount = _settingsService.CoverOverlayBlurAmount, - Source = new ScaleEffect { + using var coverOverlayEffect = new OpacityEffect + { + Opacity = SettingsService.CoverOverlayOpacity / 100f, + Source = new GaussianBlurEffect + { + BlurAmount = SettingsService.CoverOverlayBlurAmount, + Source = new ScaleEffect + { InterpolationMode = CanvasImageInterpolation.HighQualityCubic, BorderMode = EffectBorderMode.Hard, Scale = new Vector2(_coverScaleFactor), - Source = CanvasBitmap.CreateFromSoftwareBitmap(control, _coverSoftwareBitmap), - } - } + Source = CanvasBitmap.CreateFromSoftwareBitmap( + control, + _coverSoftwareBitmap + ), + }, + }, }; ds.DrawImage( coverOverlayEffect, (float)control.Size.Width / 2 - _coverImagePixelWidth * _coverScaleFactor / 2, - (float)control.Size.Height / 2 - _coverImagePixelHeight * _coverScaleFactor / 2); + (float)control.Size.Height / 2 - _coverImagePixelHeight * _coverScaleFactor / 2 + ); ds.Transform = Matrix3x2.Identity; } - private void DrawGradientOpacityMask(ICanvasAnimatedControl control, CanvasDrawingSession ds, byte r, byte g, byte b) { - byte verticalEdgeAlpha = (byte)(255 * _settingsService.LyricsVerticalEdgeOpacity / 100f); - using var maskBrush = new CanvasLinearGradientBrush(control, [ - new() { Position = 0, Color = Color.FromArgb(verticalEdgeAlpha, r, g, b)}, - new() { Position = 0.5f, Color = Color.FromArgb(255, r, g, b)}, - new() { Position = 1, Color = Color.FromArgb(verticalEdgeAlpha, r, g, b)}, - ]) { + private void DrawGradientOpacityMask( + ICanvasAnimatedControl control, + CanvasDrawingSession ds, + byte r, + byte g, + byte b + ) + { + byte verticalEdgeAlpha = (byte)(255 * SettingsService.LyricsVerticalEdgeOpacity / 100f); + using var maskBrush = new CanvasLinearGradientBrush( + control, + [ + new() { Position = 0, Color = Color.FromArgb(verticalEdgeAlpha, r, g, b) }, + new() { Position = 0.5f, Color = Color.FromArgb(255, r, g, b) }, + new() { Position = 1, Color = Color.FromArgb(verticalEdgeAlpha, r, g, b) }, + ] + ) + { StartPoint = new Vector2(0, 0), - EndPoint = new Vector2(0, (float)control.Size.Height) + EndPoint = new Vector2(0, (float)control.Size.Height), }; ds.FillRectangle(new Rect(0, 0, control.Size.Width, control.Size.Height), maskBrush); } - // Comsumes CPU related resources - private void LyricsCanvas_Update(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs args) { + private void LyricsCanvas_Update( + ICanvasAnimatedControl sender, + CanvasAnimatedUpdateEventArgs args + ) + { _currentTime += args.Timing.ElapsedTime; - if (_settingsService.IsDynamicCoverOverlay) { + if (SettingsService.IsDynamicCoverOverlay) + { _coverBitmapRotateAngle += _coverRotateSpeed; _coverBitmapRotateAngle %= MathF.PI * 2; } - if (_settingsService.IsLyricsDynamicGlowEffectEnabled) { + if (SettingsService.IsLyricsDynamicGlowEffectEnabled) + { _lyricsGlowEffectAngle += _lyricsGlowEffectSpeed; _lyricsGlowEffectAngle %= MathF.PI * 2; } - if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) { - - var diagonal = Math.Sqrt(Math.Pow(_lyricsAreaWidth, 2) + Math.Pow(_lyricsAreaHeight, 2)); - - _coverScaleFactor = (float)diagonal / Math.Min(_coverImagePixelWidth, _coverImagePixelHeight); + if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) + { + var diagonal = Math.Sqrt( + Math.Pow(_lyricsAreaWidth, 2) + Math.Pow(_lyricsAreaHeight, 2) + ); + _coverScaleFactor = + (float)diagonal / Math.Min(_coverImagePixelWidth, _coverImagePixelHeight); } - if (_lyricsLines.LastOrDefault()?.TextLayout == null) { + if (_lyricsLines.LastOrDefault()?.TextLayout == null) + { LayoutLyrics(); } @@ -532,47 +741,55 @@ namespace BetterLyrics.WinUI3.Views { UpdatePosition(currentPlayingLineIndex); } - private int GetCurrentPlayingLineIndex() { - for (int i = 0; i < _lyricsLines.Count; i++) { - + private int GetCurrentPlayingLineIndex() + { + for (int i = 0; i < _lyricsLines.Count; i++) + { var line = _lyricsLines[i]; - if (line.EndPlayingTimestampMs < _currentTime.TotalMilliseconds) { + if (line.EndPlayingTimestampMs < _currentTime.TotalMilliseconds) + { continue; } return i; } return -1; - } - private Tuple GetVisibleLyricsLineIndexBoundaries() { + private Tuple GetVisibleLyricsLineIndexBoundaries() + { // _logger.LogDebug($"{_startVisibleLineIndex} {_endVisibleLineIndex}"); return new Tuple(_startVisibleLineIndex, _endVisibleLineIndex); } - private Tuple GetMaxLyricsLineIndexBoundaries() { - if (_lyricsLines.Count == 0) { + private Tuple GetMaxLyricsLineIndexBoundaries() + { + if (_lyricsLines.Count == 0) + { return new Tuple(-1, -1); } return new Tuple(0, _lyricsLines.Count - 1); } - private void UpdateScaleAndOpacity(int currentPlayingLineIndex) { - + private void UpdateScaleAndOpacity(int currentPlayingLineIndex) + { var (startLineIndex, endLineIndex) = GetMaxLyricsLineIndexBoundaries(); - for (int i = startLineIndex; _lyricsLines.Count > 0 && i <= endLineIndex; i++) { - + for (int i = startLineIndex; _lyricsLines.Count > 0 && i <= endLineIndex; i++) + { var line = _lyricsLines[i]; bool linePlaying = i == currentPlayingLineIndex; var lineEnteringDurationMs = Math.Min(line.DurationMs, _lineEnteringDurationMs); var lineExitingDurationMs = _lineExitingDurationMs; - if (i + 1 <= endLineIndex) { - lineExitingDurationMs = Math.Min(_lyricsLines[i + 1].DurationMs, lineExitingDurationMs); + if (i + 1 <= endLineIndex) + { + lineExitingDurationMs = Math.Min( + _lyricsLines[i + 1].DurationMs, + lineExitingDurationMs + ); } float lineEnteringProgress = 0.0f; @@ -586,37 +803,55 @@ namespace BetterLyrics.WinUI3.Views { float playProgress = 0; - if (linePlaying) { + if (linePlaying) + { line.PlayingState = LyricsPlayingState.Playing; scale = _highlightedScale; opacity = _highlightedOpacity; - playProgress = ((float)_currentTime.TotalMilliseconds - line.StartPlayingTimestampMs) / line.DurationMs; + playProgress = + ((float)_currentTime.TotalMilliseconds - line.StartPlayingTimestampMs) + / line.DurationMs; - var durationFromStartMs = _currentTime.TotalMilliseconds - line.StartPlayingTimestampMs; + var durationFromStartMs = + _currentTime.TotalMilliseconds - line.StartPlayingTimestampMs; lineEntering = durationFromStartMs <= lineEnteringDurationMs; - if (lineEntering) { + if (lineEntering) + { lineEnteringProgress = (float)durationFromStartMs / lineEnteringDurationMs; - scale = _defaultScale + (_highlightedScale - _defaultScale) * (float)lineEnteringProgress; - opacity = _defaultOpacity + (_highlightedOpacity - _defaultOpacity) * (float)lineEnteringProgress; + scale = + _defaultScale + + (_highlightedScale - _defaultScale) * (float)lineEnteringProgress; + opacity = + _defaultOpacity + + (_highlightedOpacity - _defaultOpacity) * (float)lineEnteringProgress; } - - } else { - if (i < currentPlayingLineIndex) { + } + else + { + if (i < currentPlayingLineIndex) + { line.PlayingState = LyricsPlayingState.Played; playProgress = 1; - var durationToEndMs = _currentTime.TotalMilliseconds - line.EndPlayingTimestampMs; + var durationToEndMs = + _currentTime.TotalMilliseconds - line.EndPlayingTimestampMs; lineExiting = durationToEndMs <= lineExitingDurationMs; - if (lineExiting) { - + if (lineExiting) + { lineExitingProgress = (float)durationToEndMs / lineExitingDurationMs; - scale = _highlightedScale - (_highlightedScale - _defaultScale) * (float)lineExitingProgress; - opacity = _highlightedOpacity - (_highlightedOpacity - _defaultOpacity) * (float)lineExitingProgress; + scale = + _highlightedScale + - (_highlightedScale - _defaultScale) * (float)lineExitingProgress; + opacity = + _highlightedOpacity + - (_highlightedOpacity - _defaultOpacity) + * (float)lineExitingProgress; } - - } else { + } + else + { line.PlayingState = LyricsPlayingState.NotPlayed; } } @@ -628,14 +863,14 @@ namespace BetterLyrics.WinUI3.Views { line.Opacity = opacity; line.PlayingProgress = playProgress; - } } - private void LayoutLyrics() { - - using CanvasTextFormat textFormat = new() { - FontSize = _settingsService.LyricsFontSize, + private void LayoutLyrics() + { + using CanvasTextFormat textFormat = new() + { + FontSize = SettingsService.LyricsFontSize, HorizontalAlignment = CanvasHorizontalAlignment.Left, VerticalAlignment = CanvasVerticalAlignment.Top, FontWeight = FontWeights.Bold, @@ -644,57 +879,79 @@ namespace BetterLyrics.WinUI3.Views { float y = (float)_lyricsAreaHeight / 2; // Init Positions - for (int i = 0; i < _lyricsLines.Count; i++) { - + for (int i = 0; i < _lyricsLines.Count; i++) + { var line = _lyricsLines[i]; // Calculate layout bounds - line.TextLayout = new CanvasTextLayout(LyricsCanvas.Device, line.Text, textFormat, (float)_lyricsCanvasMaxTextWidth, (float)_lyricsAreaHeight); + line.TextLayout = new CanvasTextLayout( + LyricsCanvas.Device, + line.Text, + textFormat, + (float)_lyricsCanvasMaxTextWidth, + (float)_lyricsAreaHeight + ); line.Position = new Vector2((float)_lyricsCanvasLeftMargin, y); - y += (float)line.TextLayout.LayoutBounds.Height / line.TextLayout.LineCount * (line.TextLayout.LineCount + _settingsService.LyricsLineSpacingFactor); - + y += + (float)line.TextLayout.LayoutBounds.Height + / line.TextLayout.LineCount + * (line.TextLayout.LineCount + SettingsService.LyricsLineSpacingFactor); } - } - private void UpdatePosition(int currentPlayingLineIndex) { - - if (currentPlayingLineIndex < 0) { + private void UpdatePosition(int currentPlayingLineIndex) + { + if (currentPlayingLineIndex < 0) + { return; } var (startLineIndex, endLineIndex) = GetMaxLyricsLineIndexBoundaries(); - if (startLineIndex < 0 || endLineIndex < 0) { + if (startLineIndex < 0 || endLineIndex < 0) + { return; } // Set _scrollOffsetY LyricsLine? currentPlayingLine = _lyricsLines?[currentPlayingLineIndex]; - if (currentPlayingLine == null) { + if (currentPlayingLine == null) + { return; } - if (currentPlayingLine.TextLayout == null) { + if (currentPlayingLine.TextLayout == null) + { return; } var lineScrollingProgress = - (_currentTime.TotalMilliseconds - currentPlayingLine.StartPlayingTimestampMs) / - Math.Min(_lineScrollDurationMs, currentPlayingLine.DurationMs); + (_currentTime.TotalMilliseconds - currentPlayingLine.StartPlayingTimestampMs) + / Math.Min(_lineScrollDurationMs, currentPlayingLine.DurationMs); - var targetYScrollOffset = (float)(-currentPlayingLine.Position.Y + _lyricsLines![0].Position.Y - currentPlayingLine.TextLayout.LayoutBounds.Height / 2 - _lastTotalYScroll); + var targetYScrollOffset = (float)( + -currentPlayingLine.Position.Y + + _lyricsLines![0].Position.Y + - currentPlayingLine.TextLayout.LayoutBounds.Height / 2 + - _lastTotalYScroll + ); - var yScrollOffset = targetYScrollOffset * EasingHelper.SmootherStep((float)Math.Min(1, lineScrollingProgress)); + var yScrollOffset = + targetYScrollOffset + * EasingHelper.SmootherStep((float)Math.Min(1, lineScrollingProgress)); bool isScrollingNow = lineScrollingProgress <= 1; - if (isScrollingNow) { + if (isScrollingNow) + { _totalYScroll = _lastTotalYScroll + yScrollOffset; - } else { - if (_forceToScroll && Math.Abs(targetYScrollOffset) >= 1) { + } + else + { + if (_forceToScroll && Math.Abs(targetYScrollOffset) >= 1) + { _totalYScroll = _lastTotalYScroll + targetYScrollOffset; } _lastTotalYScroll = _totalYScroll; @@ -703,34 +960,44 @@ namespace BetterLyrics.WinUI3.Views { _startVisibleLineIndex = _endVisibleLineIndex = -1; // Update Positions - for (int i = startLineIndex; i >= 0 && i <= endLineIndex; i++) { - + for (int i = startLineIndex; i >= 0 && i <= endLineIndex; i++) + { var line = _lyricsLines[i]; - if (_totalYScroll + line.Position.Y + line.TextLayout.LayoutBounds.Height >= 0) { - if (_startVisibleLineIndex == -1) { + if (_totalYScroll + line.Position.Y + line.TextLayout.LayoutBounds.Height >= 0) + { + if (_startVisibleLineIndex == -1) + { _startVisibleLineIndex = i; } } - if (_totalYScroll + line.Position.Y + line.TextLayout.LayoutBounds.Height >= _lyricsAreaHeight) { - if (_endVisibleLineIndex == -1) { + if ( + _totalYScroll + line.Position.Y + line.TextLayout.LayoutBounds.Height + >= _lyricsAreaHeight + ) + { + if (_endVisibleLineIndex == -1) + { _endVisibleLineIndex = i; } } } - if (_startVisibleLineIndex != -1 && _endVisibleLineIndex == -1) { + if (_startVisibleLineIndex != -1 && _endVisibleLineIndex == -1) + { _endVisibleLineIndex = endLineIndex; } - } - private void LyricsCanvas_Loaded(object sender, RoutedEventArgs e) { + private void LyricsCanvas_Loaded(object sender, RoutedEventArgs e) + { InitMediaManager(); } - private void SettingsButton_Click(object sender, RoutedEventArgs e) { - if (App.Current.SettingsWindow is null) { + private void SettingsButton_Click(object sender, RoutedEventArgs e) + { + if (App.Current.SettingsWindow is null) + { var settingsWindow = new MainWindow(); settingsWindow.Navigate(typeof(SettingsPage)); App.Current.SettingsWindow = settingsWindow; @@ -738,7 +1005,8 @@ namespace BetterLyrics.WinUI3.Views { var appWindow = App.Current.SettingsWindow.AppWindow; - if (appWindow.Presenter is OverlappedPresenter presenter) { + if (appWindow.Presenter is OverlappedPresenter presenter) + { presenter.Restore(); } @@ -746,28 +1014,49 @@ namespace BetterLyrics.WinUI3.Views { appWindow.MoveInZOrderAtTop(); } - private void WelcomeTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) { + private void WelcomeTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) + { TopCommandTeachingTip.IsOpen = true; } - private void TopCommandTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) { + private void TopCommandTeachingTip_Closed( + TeachingTip sender, + TeachingTipClosedEventArgs args + ) + { BottomCommandTeachingTip.IsOpen = true; } - private void BottomCommandTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) { + private void BottomCommandTeachingTip_Closed( + TeachingTip sender, + TeachingTipClosedEventArgs args + ) + { LyricsOnlyTeachingTip.IsOpen = true; } - private void LyricsOnlyTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) { + private void LyricsOnlyTeachingTip_Closed( + TeachingTip sender, + TeachingTipClosedEventArgs args + ) + { InitDatabaseTeachingTip.IsOpen = true; } - private void InitDatabaseTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) { - _settingsService.IsFirstRun = false; + private void InitDatabaseTeachingTip_Closed( + TeachingTip sender, + TeachingTipClosedEventArgs args + ) + { + SettingsService.IsFirstRun = false; } - private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e) { - CoverImageGrid.Width = CoverImageGrid.Height = Math.Min(CoverArea.ActualWidth, CoverArea.ActualHeight); + private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e) + { + CoverImageGrid.Width = CoverImageGrid.Height = Math.Min( + CoverArea.ActualWidth, + CoverArea.ActualHeight + ); } } } diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml index 4428b92..0bbed26 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml @@ -138,7 +138,7 @@ - + + + + + + + + + + + + @@ -207,24 +228,60 @@ + + + + + + + + - + + + + + + + + + - - - - - + + + + + + + + @@ -331,7 +388,7 @@ - + diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs index df2be29..742c1f7 100644 --- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs +++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs @@ -1,29 +1,39 @@ -using Microsoft.UI.Xaml.Controls; using BetterLyrics.WinUI3.ViewModels; using CommunityToolkit.Mvvm.DependencyInjection; 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.Views { +namespace BetterLyrics.WinUI3.Views +{ /// /// An empty page that can be used on its own or navigated to within a Frame. /// - public sealed partial class SettingsPage : Page { - + public sealed partial class SettingsPage : Page + { public SettingsViewModel ViewModel => (SettingsViewModel)DataContext; - public SettingsPage() { + public SettingsPage() + { this.InitializeComponent(); DataContext = Ioc.Default.GetService(); } - private void SettingsPageOpenPathButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { + private void SettingsPageOpenPathButton_Click( + object sender, + Microsoft.UI.Xaml.RoutedEventArgs e + ) + { SettingsViewModel.OpenMusicFolder((string)(sender as HyperlinkButton)!.Tag); } - private async void SettingsPageRemovePathButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) { + private async void SettingsPageRemovePathButton_Click( + object sender, + Microsoft.UI.Xaml.RoutedEventArgs e + ) + { await ViewModel.RemoveFolderAsync((string)(sender as HyperlinkButton)!.Tag); } } diff --git a/README.md b/README.md index 5784f67..3420efe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- +