add support for editing album art corner radius

This commit is contained in:
Zhe Fang
2025-06-05 17:44:04 -04:00
parent b470b91d0e
commit d01be4b883
10 changed files with 345 additions and 196 deletions

View File

@@ -11,6 +11,7 @@ using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml;
using SQLite;
using Ude;
using Windows.Media.Control;
namespace BetterLyrics.WinUI3.Services.Database
{
@@ -18,6 +19,8 @@ namespace BetterLyrics.WinUI3.Services.Database
{
private readonly SQLiteConnection _connection;
private readonly CharsetDetector _charsetDetector = new();
public DatabaseService()
{
_connection = new SQLiteConnection(Helper.AppInfo.DatabasePath);
@@ -53,5 +56,83 @@ namespace BetterLyrics.WinUI3.Services.Database
}
});
}
public Track? GetMusicMetadata(
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
)
{
if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null)
return null;
var founds = _connection
.Table<MetadataIndex>()
// 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 != 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
{
var first = new Track(founds[0].Path);
if (founds.Count == 1)
{
return first;
}
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))
{
_charsetDetector.Feed(fs);
_charsetDetector.DataEnd();
}
string content;
if (_charsetDetector.Charset != null)
{
Encoding encoding = Encoding.GetEncoding(
_charsetDetector.Charset
);
content = File.ReadAllText(found.Path, encoding);
}
else
{
content = File.ReadAllText(found.Path, Encoding.UTF8);
}
first.Lyrics.ParseLRC(content);
return first;
}
}
return first;
}
}
}
}
}
}

View File

@@ -27,6 +27,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
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;
@@ -36,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;
}
}

View File

@@ -26,6 +26,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
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";
@@ -35,5 +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";
}
}

View File

@@ -1,54 +1,62 @@
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;
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 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 SettingsService() {
public SettingsService()
{
_localSettings = ApplicationData.Current.LocalSettings;
_musicLibraries = [.. JsonConvert.DeserializeObject<List<string>>(
Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!)!];
_musicLibraries =
[
.. JsonConvert.DeserializeObject<List<string>>(
Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!
)!,
];
_musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries();
}
private void WatchMultipleDirectories(IEnumerable<string> directories) {
foreach (var dir in directories) {
if (!Directory.Exists(dir)) continue;
private void WatchMultipleDirectories(IEnumerable<string> directories)
{
foreach (var dir in directories)
{
if (!Directory.Exists(dir))
continue;
var watcher = new FileSystemWatcher {
var watcher = new FileSystemWatcher
{
Path = dir,
Filter = "*.*",
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
EnableRaisingEvents = true
EnableRaisingEvents = true,
};
}
}
private void OnFileCreated(object sender, FileSystemEventArgs e) {
App.DispatcherQueue.TryEnqueue(() =>
{
Debug.WriteLine($"[Created] {e.FullPath}");
});
private void OnFileCreated(object sender, FileSystemEventArgs e)
{
App.DispatcherQueue.TryEnqueue(() => { });
}
public bool IsFirstRun {
public bool IsFirstRun
{
get => Get(SettingsKeys.IsFirstRun, SettingsDefaultValues.IsFirstRun);
set => Set(SettingsKeys.IsFirstRun, value);
}
@@ -57,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));
}
@@ -68,12 +78,13 @@ namespace BetterLyrics.WinUI3.Services.Settings {
// Music
private ObservableCollection<string> _musicLibraries;
public ObservableCollection<string> MusicLibraries {
get {
return _musicLibraries;
}
set {
if (_musicLibraries != null) {
public ObservableCollection<string> MusicLibraries
{
get { return _musicLibraries; }
set
{
if (_musicLibraries != null)
{
_musicLibraries.CollectionChanged -= (_, _) => SaveMusicLibraries();
}
@@ -84,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;
@@ -114,76 +128,138 @@ 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);
}
public int LyricsFontSelectedAccentColorIndex
{
get =>
Get(
SettingsKeys.LyricsFontSelectedAccentColorIndex,
SettingsDefaultValues.LyricsFontSelectedAccentColorIndex
);
set => Set(SettingsKeys.LyricsFontSelectedAccentColorIndex, value);
}
private T? Get<T>(string key, T? defaultValue = default) {
if (_localSettings.Values.TryGetValue(key, out object? value)) {
private T? Get<T>(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<T>(string key, T value, [CallerMemberName] string? propertyName = null) {
private void Set<T>(string key, T value, [CallerMemberName] string? propertyName = null)
{
_localSettings.Values[key] = value;
OnPropertyChanged(propertyName);
}
}
}

View File

@@ -279,7 +279,7 @@
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>Lyrics effect</value>
</data>
<data name="SettingsPageAlbum.Text" xml:space="preserve">
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
<value>Album background</value>
</data>
<data name="SettingsPageAbout.Text" xml:space="preserve">
@@ -363,4 +363,10 @@
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
<value>Album art accent color</value>
</data>
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>Album art style</value>
</data>
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
<value>Corner radius</value>
</data>
</root>

View File

@@ -279,7 +279,7 @@
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>歌词效果</value>
</data>
<data name="SettingsPageAlbum.Text" xml:space="preserve">
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
<value>专辑背景</value>
</data>
<data name="SettingsPageAbout.Text" xml:space="preserve">
@@ -363,4 +363,10 @@
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
<value>专辑强调色</value>
</data>
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>专辑封面样式</value>
</data>
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
<value>圆角半径</value>
</data>
</root>

View File

@@ -279,7 +279,7 @@
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
<value>歌詞效果</value>
</data>
<data name="SettingsPageAlbum.Text" xml:space="preserve">
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
<value>專輯背景</value>
</data>
<data name="SettingsPageAbout.Text" xml:space="preserve">
@@ -363,4 +363,10 @@
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
<value>專輯強調色</value>
</data>
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
<value>專輯封面樣式</value>
</data>
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
<value>圓角半徑</value>
</data>
</root>

View File

@@ -28,10 +28,11 @@ using static CommunityToolkit.WinUI.Animations.Expressions.ExpressionValues;
namespace BetterLyrics.WinUI3.ViewModels
{
public partial class MainViewModel(SettingsService settingsService) : ObservableObject
public partial class MainViewModel(
SettingsService settingsService,
DatabaseService databaseService
) : ObservableObject
{
private readonly CharsetDetector _charsetDetector = new();
[ObservableProperty]
private bool _isAnyMusicSessionExisted = false;
@@ -67,12 +68,13 @@ namespace BetterLyrics.WinUI3.ViewModels
private readonly Helper.ColorThief _colorThief = new();
private readonly SettingsService _settingsService = settingsService;
private readonly DatabaseService _databaseService = databaseService;
public List<LyricsLine> GetLyrics(Track? track)
{
List<LyricsLine> result = [];
var lyricsPhrases = track?.Lyrics.SynchronizedLyrics;
var lyricsPhrases = track?.Lyrics?.SynchronizedLyrics;
if (lyricsPhrases?.Count > 0)
{
@@ -126,91 +128,6 @@ namespace BetterLyrics.WinUI3.ViewModels
return result;
}
public async Task<Track?> FindTrackFromDirectories(
IEnumerable<string> directories,
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
)
{
Track? finalResult = null;
if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null)
return finalResult;
finalResult = new() { Title = mediaProps.Title, Artist = mediaProps.Artist };
bool coverFound = false;
bool lyricsFound = false;
if (mediaProps.Thumbnail is IRandomAccessStreamReference streamReference)
{
coverFound = true;
PictureInfo pictureInfo = PictureInfo.fromBinaryData(
await ImageHelper.ToByteArrayAsync(streamReference)
);
finalResult.EmbeddedPictures.Add(pictureInfo);
}
foreach (var dir in directories)
{
if (!Directory.Exists(dir))
continue;
foreach (
var file in Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories)
)
{
string content = File.ReadAllText(file);
var result = new Track(content);
if (
result.Title.Contains(mediaProps.Title)
&& result.Artist.Contains(mediaProps.Artist)
)
{
if (!coverFound && result.EmbeddedPictures.Count > 0)
{
coverFound = true;
finalResult.EmbeddedPictures.AddRange(result.EmbeddedPictures);
}
if (!lyricsFound && result.Lyrics != null)
{
lyricsFound = true;
finalResult.Lyrics = result.Lyrics;
}
}
if (!lyricsFound && file.EndsWith(".lrc"))
{
using (FileStream fs = File.OpenRead(file))
{
_charsetDetector.Feed(fs);
_charsetDetector.DataEnd();
}
if (_charsetDetector.Charset != null)
{
Encoding encoding = Encoding.GetEncoding(_charsetDetector.Charset);
content = File.ReadAllText(file, encoding);
}
else
{
content = File.ReadAllText(file, Encoding.UTF8);
}
lyricsFound = true;
finalResult.Lyrics = new();
finalResult.Lyrics.ParseLRC(content);
}
if (coverFound && lyricsFound)
return finalResult;
}
}
return finalResult;
}
public async Task<(List<LyricsLine>, SoftwareBitmap?, uint, uint)> SetSongInfoAsync(
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
)
@@ -224,10 +141,23 @@ namespace BetterLyrics.WinUI3.ViewModels
IRandomAccessStream? stream = null;
var track = await FindTrackFromDirectories(_settingsService.MusicLibraries, mediaProps);
var track = _databaseService.GetMusicMetadata(mediaProps);
if (track?.EmbeddedPictures?[0].PictureData is byte[] bytes)
stream = await ImageHelper.GetStreamFromBytesAsync(bytes);
if (mediaProps?.Thumbnail is IRandomAccessStreamReference reference)
{
stream = await reference.OpenReadAsync();
}
else
{
if (track?.EmbeddedPictures.Count > 0)
{
var bytes = track.EmbeddedPictures[0].PictureData;
if (bytes != null)
{
stream = await Helper.ImageHelper.GetStreamFromBytesAsync(bytes);
}
}
}
// Set cover image and dominant colors
if (stream == null)

View File

@@ -40,7 +40,7 @@ namespace BetterLyrics.WinUI3.Views
public sealed partial class MainPage : Page
{
public MainViewModel ViewModel => (MainViewModel)DataContext;
private readonly SettingsService _settingsService;
public SettingsService SettingsService { get; set; }
private List<LyricsLine> _lyricsLines = [];
@@ -101,24 +101,21 @@ namespace BetterLyrics.WinUI3.Views
{
this.InitializeComponent();
_queueTimer = _dispatcherQueue.CreateTimer();
_logger = Ioc.Default.GetService<ILogger<MainPage>>()!;
SettingsService = Ioc.Default.GetService<SettingsService>()!;
DataContext = Ioc.Default.GetService<MainViewModel>();
SettingsService.PropertyChanged += SettingsService_PropertyChanged;
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
SetLyricsColor();
_settingsService = Ioc.Default.GetService<SettingsService>()!;
if (_settingsService.IsFirstRun)
if (SettingsService.IsFirstRun)
{
WelcomeTeachingTip.IsOpen = true;
}
_settingsService.PropertyChanged += SettingsService_PropertyChanged;
DataContext = Ioc.Default.GetService<MainViewModel>();
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
_queueTimer = _dispatcherQueue.CreateTimer();
}
private async Task ForceToScrollToCurrentPlayingLineAsync()
@@ -135,21 +132,28 @@ namespace BetterLyrics.WinUI3.Views
{
switch (e.PropertyName)
{
case nameof(_settingsService.LyricsFontSize):
case nameof(_settingsService.LyricsLineSpacingFactor):
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;
}
@@ -172,7 +176,19 @@ namespace BetterLyrics.WinUI3.Views
private void SetLyricsColor()
{
_lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color;
switch ((LyricsFontColorType)SettingsService.LyricsFontColorType)
{
case LyricsFontColorType.Default:
_lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color;
break;
case LyricsFontColorType.Dominant:
_lyricsColor = ViewModel.CoverImageDominantColors[
SettingsService.LyricsFontSelectedAccentColorIndex
];
break;
default:
break;
}
}
private async void InitMediaManager()
@@ -391,7 +407,7 @@ 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);
}
@@ -406,7 +422,7 @@ namespace BetterLyrics.WinUI3.Views
using var glowedLyrics = new CanvasCommandList(sender);
using (var glowedLyricsDs = glowedLyrics.CreateDrawingSession())
{
if (_settingsService.IsLyricsGlowEffectEnabled)
if (SettingsService.IsLyricsGlowEffectEnabled)
{
glowedLyricsDs.DrawImage(
new GaussianBlurEffect
@@ -432,7 +448,7 @@ 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);
}
@@ -446,7 +462,7 @@ namespace BetterLyrics.WinUI3.Views
{
Source = glowedLyrics,
BlurAmount = (float)(
_settingsService.LyricsBlurAmount * (1 - i / (0.5 - step))
SettingsService.LyricsBlurAmount * (1 - i / (0.5 - step))
),
Optimization = EffectOptimization.Quality,
BorderMode = EffectBorderMode.Soft,
@@ -483,7 +499,7 @@ namespace BetterLyrics.WinUI3.Views
maskedCombinedBlurredLyrics.CreateDrawingSession()
)
{
if (_settingsService.LyricsVerticalEdgeOpacity == 100)
if (SettingsService.LyricsVerticalEdgeOpacity == 100)
{
maskedCombinedBlurredLyricsDs.DrawImage(combinedBlurredLyrics);
}
@@ -538,7 +554,7 @@ 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;
@@ -632,10 +648,10 @@ namespace BetterLyrics.WinUI3.Views
using var coverOverlayEffect = new OpacityEffect
{
Opacity = _settingsService.CoverOverlayOpacity / 100f,
Opacity = SettingsService.CoverOverlayOpacity / 100f,
Source = new GaussianBlurEffect
{
BlurAmount = _settingsService.CoverOverlayBlurAmount,
BlurAmount = SettingsService.CoverOverlayBlurAmount,
Source = new ScaleEffect
{
InterpolationMode = CanvasImageInterpolation.HighQualityCubic,
@@ -664,9 +680,7 @@ namespace BetterLyrics.WinUI3.Views
byte b
)
{
byte verticalEdgeAlpha = (byte)(
255 * _settingsService.LyricsVerticalEdgeOpacity / 100f
);
byte verticalEdgeAlpha = (byte)(255 * SettingsService.LyricsVerticalEdgeOpacity / 100f);
using var maskBrush = new CanvasLinearGradientBrush(
control,
[
@@ -690,18 +704,18 @@ namespace BetterLyrics.WinUI3.Views
{
_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)
if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null)
{
var diagonal = Math.Sqrt(
Math.Pow(_lyricsAreaWidth, 2) + Math.Pow(_lyricsAreaHeight, 2)
@@ -850,7 +864,7 @@ namespace BetterLyrics.WinUI3.Views
{
using CanvasTextFormat textFormat = new()
{
FontSize = _settingsService.LyricsFontSize,
FontSize = SettingsService.LyricsFontSize,
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
FontWeight = FontWeights.Bold,
@@ -876,7 +890,7 @@ namespace BetterLyrics.WinUI3.Views
y +=
(float)line.TextLayout.LayoutBounds.Height
/ line.TextLayout.LineCount
* (line.TextLayout.LineCount + _settingsService.LyricsLineSpacingFactor);
* (line.TextLayout.LineCount + SettingsService.LyricsLineSpacingFactor);
}
}
@@ -1028,7 +1042,7 @@ namespace BetterLyrics.WinUI3.Views
TeachingTipClosedEventArgs args
)
{
_settingsService.IsFirstRun = false;
SettingsService.IsFirstRun = false;
}
private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e)

View File

@@ -138,7 +138,7 @@
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<TextBlock x:Uid="SettingsPageAlbum" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<TextBlock x:Uid="SettingsPageAlbumOverlay" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsExpander
x:Uid="SettingsPageCoverOverlay"
@@ -196,6 +196,27 @@
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
<TextBlock x:Uid="SettingsPageAlbumStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon Glyph=&#xE71A;}">
<StackPanel Orientation="Horizontal">
<TextBlock x:Uid="SettingsPageSliderPrefix" VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center" Text="{x:Bind ViewModel.SettingsService.CoverImageRadius, Mode=OneWay}" />
<TextBlock
Margin="0,0,14,0"
VerticalAlignment="Center"
Text=" %" />
<Slider
Maximum="100"
Minimum="0"
SnapsTo="Ticks"
StepFrequency="2"
TickFrequency="2"
TickPlacement="Outside"
Value="{x:Bind ViewModel.SettingsService.CoverImageRadius, Mode=TwoWay}" />
</StackPanel>
</controls:SettingsCard>
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon Glyph=&#xE8E3;}">
@@ -241,7 +262,7 @@
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
</interactivity:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
<GridView ItemsSource="{x:Bind ViewModel.MainViewModel.CoverImageDominantColors, Mode=OneWay}" SelectedIndex="0">
<GridView ItemsSource="{x:Bind ViewModel.MainViewModel.CoverImageDominantColors, Mode=OneWay}" SelectedIndex="{x:Bind ViewModel.SettingsService.LyricsFontSelectedAccentColorIndex, Mode=TwoWay}">
<GridView.ItemTemplate>
<DataTemplate>
<GridViewItem>