mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-13 03:34:55 +08:00
add local machine translation func
This commit is contained in:
@@ -63,14 +63,16 @@
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
<Style x:Key="TitleBarButtonStyle" TargetType="Button">
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="CornerRadius" Value="0" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="16,0" />
|
||||
<Setter Property="Padding" Value="16,9,16,11" />
|
||||
<Setter Property="Margin" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
<Style x:Key="GhostButtonStyle" TargetType="Button">
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="Padding" Value="8" />
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
@@ -86,6 +88,7 @@
|
||||
<Setter Property="CornerRadius" Value="4" />
|
||||
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="Padding" Value="8" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace BetterLyrics.WinUI3
|
||||
{
|
||||
|
||||
private readonly ILogger<App> _logger;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public static new App Current => (App)Application.Current;
|
||||
public static DispatcherQueue? DispatcherQueue { get; private set; }
|
||||
@@ -41,7 +42,8 @@ namespace BetterLyrics.WinUI3
|
||||
AppInfo.EnsureDirectories();
|
||||
ConfigureServices();
|
||||
|
||||
_logger = Ioc.Default.GetService<ILogger<App>>()!;
|
||||
_logger = Ioc.Default.GetRequiredService<ILogger<App>>();
|
||||
_settingsService = Ioc.Default.GetRequiredService<ISettingsService>();
|
||||
|
||||
UnhandledException += App_UnhandledException;
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
@@ -53,6 +55,7 @@ namespace BetterLyrics.WinUI3
|
||||
{
|
||||
WindowHelper.OpenOrShowWindow<LyricsWindow>();
|
||||
var lyricsWindow = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (lyricsWindow == null) return;
|
||||
|
||||
string[] commandLineArguments = Environment.GetCommandLineArgs();
|
||||
if (commandLineArguments.Length > 1)
|
||||
@@ -66,10 +69,11 @@ namespace BetterLyrics.WinUI3
|
||||
}
|
||||
lyricsWindow.AutoSelectLyricsMode();
|
||||
}
|
||||
|
||||
private static void ConfigureServices()
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Debug()
|
||||
.MinimumLevel.Is(Serilog.Events.LogEventLevel.Verbose)
|
||||
.WriteTo.File(AppInfo.LogFilePattern, rollingInterval: RollingInterval.Day)
|
||||
.CreateLogger();
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
|
||||
<PackageReference Include="Dubya.WindowsMediaController" Version="2.5.5" />
|
||||
<PackageReference Include="Fluent.LibreTranslate" Version="1.0.6" />
|
||||
<PackageReference Include="H.NotifyIcon.WinUI" Version="2.3.0" />
|
||||
<PackageReference Include="iTunesSearch" Version="1.0.44" />
|
||||
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
|
||||
@@ -49,7 +50,6 @@
|
||||
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.3.2" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250606001" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.10" />
|
||||
|
||||
@@ -16,13 +16,33 @@ namespace BetterLyrics.WinUI3.Enums
|
||||
{
|
||||
public static LyricsFormat? DetectFormat(this string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
return null;
|
||||
|
||||
// TTML
|
||||
if (content.StartsWith("<?xml") && System.Text.RegularExpressions.Regex.IsMatch(content, @"<tt(:\w+)?\b"))
|
||||
{
|
||||
return LyricsFormat.Ttml;
|
||||
}
|
||||
// 检测标准LRC和增强型LRC
|
||||
else if (System.Text.RegularExpressions.Regex.IsMatch(content, @"\[\d{1,2}:\d{2}")
|
||||
|| System.Text.RegularExpressions.Regex.IsMatch(content, @"<\d{1,2}:\d{2}\.\d{2,3}>"))
|
||||
// KRC: 检测主内容格式 [start,duration]<offset,duration,0>字...
|
||||
else if (System.Text.RegularExpressions.Regex.IsMatch(
|
||||
content,
|
||||
@"^\[\d+,\d+\](<\d+,\d+,0>.+)+",
|
||||
System.Text.RegularExpressions.RegexOptions.Multiline))
|
||||
{
|
||||
return LyricsFormat.Krc;
|
||||
}
|
||||
// QRC: 检测主内容格式 [start,duration]字(offset,duration)
|
||||
else if (System.Text.RegularExpressions.Regex.IsMatch(
|
||||
content,
|
||||
@"^\[\d+,\d+\].*?\(\d+,\d+\)",
|
||||
System.Text.RegularExpressions.RegexOptions.Multiline))
|
||||
{
|
||||
return LyricsFormat.Qrc;
|
||||
}
|
||||
// 标准LRC和增强型LRC
|
||||
else if (System.Text.RegularExpressions.Regex.IsMatch(content, @"\[\d{1,2}:\d{2}") ||
|
||||
System.Text.RegularExpressions.Regex.IsMatch(content, @"<\d{1,2}:\d{2}\.\d{2,3}>"))
|
||||
{
|
||||
return LyricsFormat.Lrc;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using Fluent.LibreTranslate;
|
||||
using Lyricify.Lyrics.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -16,7 +17,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
private List<List<LyricsLine>> _multiLangLyricsLines = [];
|
||||
|
||||
public List<List<LyricsLine>> Parse(string? raw, LyricsFormat? lyricsFormat = null, string? title = null, string? artist = null, int durationMs = 0)
|
||||
public List<List<LyricsLine>> Parse(string? raw, int durationMs)
|
||||
{
|
||||
_multiLangLyricsLines = [];
|
||||
if (raw == null)
|
||||
@@ -27,7 +28,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = durationMs,
|
||||
Text = App.ResourceLoader!.GetString("LyricsNotFound"),
|
||||
OriginalText = App.ResourceLoader!.GetString("LyricsNotFound"),
|
||||
CharTimings = [],
|
||||
},
|
||||
]
|
||||
@@ -35,7 +36,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (lyricsFormat)
|
||||
switch (raw.DetectFormat())
|
||||
{
|
||||
case LyricsFormat.Lrc:
|
||||
case LyricsFormat.Eslrc:
|
||||
@@ -136,7 +137,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
StartMs = start,
|
||||
EndMs = 0, // 稍后统一修正
|
||||
Text = text,
|
||||
OriginalText = text,
|
||||
CharTimings = [],
|
||||
};
|
||||
if (syllables != null && syllables.Count > 0)
|
||||
@@ -217,7 +218,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
StartMs = pStartMs,
|
||||
EndMs = 0,
|
||||
Text = text,
|
||||
OriginalText = text,
|
||||
CharTimings = charTimings,
|
||||
}
|
||||
);
|
||||
@@ -306,7 +307,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
StartMs = lineRead.StartTime ?? 0,
|
||||
EndMs = 0,
|
||||
Text = lineRead.Text,
|
||||
OriginalText = lineRead.Text,
|
||||
CharTimings = [],
|
||||
};
|
||||
|
||||
@@ -389,7 +390,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = linesInSingleLang[0].StartMs,
|
||||
Text = "● ● ●",
|
||||
OriginalText = "● ● ●",
|
||||
CharTimings = [],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
App.Current.Exit();
|
||||
}
|
||||
|
||||
public static T GetWindowByWindowType<T>()
|
||||
public static T? GetWindowByWindowType<T>()
|
||||
{
|
||||
foreach (var window in _activeWindows)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ namespace BetterLyrics.WinUI3.Helper
|
||||
return castedWindow;
|
||||
}
|
||||
}
|
||||
throw new InvalidOperationException($"No window of type {typeof(T).Name} found.");
|
||||
return default;
|
||||
}
|
||||
public static void OpenOrShowWindow<T>()
|
||||
{
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Models
|
||||
{
|
||||
public class LyricsData
|
||||
{
|
||||
public int LanguageIndex { get; set; } = 0;
|
||||
|
||||
public List<LyricsLine> LyricsLines => MultiLangLyricsLines[LanguageIndex];
|
||||
|
||||
public List<List<LyricsLine>> MultiLangLyricsLines { get; set; } = [];
|
||||
}
|
||||
}
|
||||
@@ -24,11 +24,10 @@ namespace BetterLyrics.WinUI3.Models
|
||||
public List<CharTiming> CharTimings { get; set; } = [];
|
||||
|
||||
public int DurationMs => EndMs - StartMs;
|
||||
|
||||
public int EndMs { get; set; }
|
||||
|
||||
public int StartMs { get; set; }
|
||||
|
||||
public string Text { get; set; } = "";
|
||||
public string DisplayedText { get; set; } = "";
|
||||
public string OriginalText { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
|
||||
@@ -10,11 +11,12 @@ namespace BetterLyrics.WinUI3.Services
|
||||
{
|
||||
Task <byte[]> SearchAlbumArtAsync(string title, string artist, string album);
|
||||
|
||||
Task<(string?, LyricsFormat?)> SearchLyricsAsync(
|
||||
Task<string?> SearchLyricsAsync(
|
||||
string title,
|
||||
string artist,
|
||||
string album = "",
|
||||
double durationMs = 0.0
|
||||
string album,
|
||||
double durationMs,
|
||||
CancellationToken token
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,12 @@ namespace BetterLyrics.WinUI3.Services
|
||||
int DesktopWindowTop { get; set; }
|
||||
int DesktopWindowWidth { get; set; }
|
||||
int DesktopWindowHeight { get; set; }
|
||||
|
||||
int StandardWindowWidth { get; set; }
|
||||
int StandardWindowHeight { get; set; }
|
||||
int StandardWindowLeft { get; set; }
|
||||
int StandardWindowTop { get; set; }
|
||||
|
||||
bool AutoLockOnDesktopMode { get; set; }
|
||||
|
||||
// Lyrics lib
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
using ATL;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using iTunesSearch.Library;
|
||||
using Lyricify.Lyrics.Providers.Web.Kugou;
|
||||
using Lyricify.Lyrics.Searchers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services
|
||||
@@ -27,10 +30,13 @@ namespace BetterLyrics.WinUI3.Services
|
||||
private readonly iTunesSearchManager _iTunesSearchManager;
|
||||
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public MusicSearchService(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_logger = Ioc.Default.GetRequiredService<ILogger<MusicSearchService>>();
|
||||
|
||||
_lrcLibHttpClient = new();
|
||||
_lrcLibHttpClient.DefaultRequestHeaders.Add(
|
||||
"User-Agent",
|
||||
@@ -102,21 +108,21 @@ namespace BetterLyrics.WinUI3.Services
|
||||
}
|
||||
}
|
||||
|
||||
//var resultItems = await _iTunesSearchManager.GetAlbumsAsync(album, 1, countryCode: GuessCountryCode(album, artist));
|
||||
//var url = resultItems.Albums.Where(al => Normalize(al.ArtistName).Contains(Normalize(artist)))
|
||||
// .FirstOrDefault()?.ArtworkUrl100.Replace("100x100bb.jpg", "100000x100000-999.jpg");
|
||||
//if (url != null)
|
||||
//{
|
||||
// return await _iTunesHttpClinet.GetByteArrayAsync(url);
|
||||
//}
|
||||
var resultItems = await _iTunesSearchManager.GetAlbumsAsync(album, 1, countryCode: GuessCountryCode(album, artist));
|
||||
var url = resultItems.Albums.Where(al => Normalize(al.ArtistName).Contains(Normalize(artist)))
|
||||
.FirstOrDefault()?.ArtworkUrl100.Replace("100x100bb.jpg", "100000x100000-999.jpg");
|
||||
if (url != null)
|
||||
{
|
||||
return await _iTunesHttpClinet.GetByteArrayAsync(url);
|
||||
}
|
||||
|
||||
return await ImageHelper.CreateTextPlaceholderBytesAsync($"{artist} - {title}", 400, 400);
|
||||
}
|
||||
|
||||
public async Task<(string?, LyricsFormat?)> SearchLyricsAsync(
|
||||
string title, string artist, string album = "", double durationMs = 0.0
|
||||
)
|
||||
public async Task<string?> SearchLyricsAsync(string title, string artist, string album, double durationMs, CancellationToken token)
|
||||
{
|
||||
_logger.LogInformation("Searching lyrics for: {Title} - {Artist} (Album: {Album}, Duration: {DurationMs}ms)", title, artist, album, durationMs);
|
||||
|
||||
foreach (var provider in _settingsService.LyricsSearchProvidersInfo)
|
||||
{
|
||||
if (!provider.IsEnabled)
|
||||
@@ -133,7 +139,7 @@ namespace BetterLyrics.WinUI3.Services
|
||||
cachedLyrics = ReadCache(title, artist, lyricsFormat, provider.Provider.GetCacheDirectory());
|
||||
if (!string.IsNullOrWhiteSpace(cachedLyrics))
|
||||
{
|
||||
return (cachedLyrics, lyricsFormat);
|
||||
return cachedLyrics;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,6 +180,8 @@ namespace BetterLyrics.WinUI3.Services
|
||||
}
|
||||
}
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchedLyrics))
|
||||
{
|
||||
if (provider.Provider.IsRemote())
|
||||
@@ -181,11 +189,11 @@ namespace BetterLyrics.WinUI3.Services
|
||||
WriteCache(title, artist, searchedLyrics, lyricsFormat, provider.Provider.GetCacheDirectory());
|
||||
}
|
||||
|
||||
return (searchedLyrics, lyricsFormat == LyricsFormat.NotSpecified ? searchedLyrics.DetectFormat() : lyricsFormat);
|
||||
return searchedLyrics;
|
||||
}
|
||||
}
|
||||
|
||||
return (null, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool MusicMatch(string fileName, string title, string artist)
|
||||
@@ -394,7 +402,7 @@ namespace BetterLyrics.WinUI3.Services
|
||||
Album = album,
|
||||
Artists = [artist],
|
||||
Title = title,
|
||||
} //, Lyricify.Lyrics.Searchers.Helpers.CompareHelper.MatchType.Perfect
|
||||
}
|
||||
);
|
||||
|
||||
if (result is QQMusicSearchResult qqResult)
|
||||
@@ -405,12 +413,12 @@ namespace BetterLyrics.WinUI3.Services
|
||||
}
|
||||
else if (result is NeteaseSearchResult neteaseResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyricNew(neteaseResult.Id);
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.NeteaseApi.GetLyric(neteaseResult.Id);
|
||||
return response?.Lrc.Lyric;
|
||||
}
|
||||
else if (result is KugouSearchResult kugouResult)
|
||||
{
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(kugouResult.Hash);
|
||||
var response = await Lyricify.Lyrics.Helpers.ProviderHelper.KugouApi.GetSearchLyrics(hash: kugouResult.Hash);
|
||||
if (response?.Candidates.FirstOrDefault() is SearchLyricsResponse.Candidate candidate)
|
||||
{
|
||||
return Lyricify.Lyrics.Decrypter.Krc.Helper.GetLyrics(
|
||||
|
||||
@@ -4,27 +4,27 @@ using BetterLyrics.WinUI3.Events;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.UI.Dispatching;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.Media.Control;
|
||||
using Windows.Storage.Streams;
|
||||
using WindowsMediaController;
|
||||
using static Lyricify.Lyrics.Providers.Web.Musixmatch.GetTokenResponse;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services
|
||||
{
|
||||
public partial class PlaybackService : BaseViewModel, IPlaybackService, IRecipient<PropertyChangedMessage<ObservableCollection<MediaSourceProviderInfo>>>
|
||||
{
|
||||
private readonly IMusicSearchService _musicSearchService;
|
||||
private readonly ILogger<PlaybackService> _logger;
|
||||
|
||||
private readonly MediaManager _mediaManager = new();
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace BetterLyrics.WinUI3.Services
|
||||
public PlaybackService(ISettingsService settingsService, IMusicSearchService musicSearchService) : base(settingsService)
|
||||
{
|
||||
_musicSearchService = musicSearchService;
|
||||
_logger = Ioc.Default.GetRequiredService<ILogger<PlaybackService>>();
|
||||
|
||||
_mediaSourceProvidersInfo = _settingsService.MediaSourceProvidersInfo;
|
||||
InitMediaManager();
|
||||
}
|
||||
@@ -91,6 +93,7 @@ namespace BetterLyrics.WinUI3.Services
|
||||
|
||||
private void MediaManager_OnAnyPlaybackStateChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo)
|
||||
{
|
||||
RecordMediaSourceProviderInfo(mediaSession);
|
||||
if (!IsMediaSourceEnabled(mediaSession.ControlSession.SourceAppUserModelId) || mediaSession != _mediaManager.GetFocusedSession()) return;
|
||||
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.High,
|
||||
@@ -107,6 +110,10 @@ namespace BetterLyrics.WinUI3.Services
|
||||
|
||||
private async void MediaManager_OnAnyMediaPropertyChanged(MediaManager.MediaSession mediaSession, GlobalSystemMediaTransportControlsSessionMediaProperties mediaProperties)
|
||||
{
|
||||
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
|
||||
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle);
|
||||
|
||||
RecordMediaSourceProviderInfo(mediaSession);
|
||||
string id = mediaSession.ControlSession.SourceAppUserModelId;
|
||||
if (!IsMediaSourceEnabled(id) || mediaSession != _mediaManager.GetFocusedSession()) return;
|
||||
|
||||
@@ -177,7 +184,14 @@ namespace BetterLyrics.WinUI3.Services
|
||||
|
||||
private void MediaManager_OnAnySessionOpened(MediaManager.MediaSession mediaSession)
|
||||
{
|
||||
string id = mediaSession.ControlSession.SourceAppUserModelId;
|
||||
RecordMediaSourceProviderInfo(mediaSession);
|
||||
}
|
||||
|
||||
private void RecordMediaSourceProviderInfo(MediaManager.MediaSession mediaSession)
|
||||
{
|
||||
var id = mediaSession?.ControlSession?.SourceAppUserModelId;
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
|
||||
var found = _mediaSourceProvidersInfo.FirstOrDefault(x => x.Provider == id);
|
||||
if (found == null)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace BetterLyrics.WinUI3.Services
|
||||
private const string DesktopWindowTopKey = "DesktopWindowTop";
|
||||
private const string DesktopWindowWidthKey = "DesktopWindowWidth";
|
||||
private const string DesktopWindowHeightKey = "DesktopWindowHeight";
|
||||
|
||||
private const string StandardWindowLeftKey = "StandardWindowLeft";
|
||||
private const string StandardWindowTopKey = "StandardWindowTop";
|
||||
private const string StandardWindowWidthKey = "StandardWindowWidth";
|
||||
private const string StandardWindowHeightKey = "StandardWindowHeight";
|
||||
|
||||
private const string AutoLockOnDesktopModeKey = "AutoLockOnDesktopMode";
|
||||
|
||||
private const string IsDynamicCoverOverlayEnabledKey = "IsDynamicCoverOverlayEnabled";
|
||||
@@ -87,10 +93,17 @@ namespace BetterLyrics.WinUI3.Services
|
||||
}
|
||||
// App appearance
|
||||
SetDefault(LanguageKey, (int)Language.FollowSystem);
|
||||
SetDefault(DesktopWindowHeightKey, 400);
|
||||
SetDefault(DesktopWindowLeftKey, 0);
|
||||
SetDefault(DesktopWindowTopKey, 0);
|
||||
SetDefault(DesktopWindowWidthKey, 600);
|
||||
|
||||
SetDefault(DesktopWindowHeightKey, 500);
|
||||
SetDefault(DesktopWindowLeftKey, 200);
|
||||
SetDefault(DesktopWindowTopKey, 200);
|
||||
SetDefault(DesktopWindowWidthKey, 800);
|
||||
|
||||
SetDefault(StandardWindowHeightKey, 800);
|
||||
SetDefault(StandardWindowLeftKey, 200);
|
||||
SetDefault(StandardWindowTopKey, 200);
|
||||
SetDefault(StandardWindowWidthKey, 1000);
|
||||
|
||||
SetDefault(AutoLockOnDesktopModeKey, false);
|
||||
// App behavior
|
||||
SetDefault(AutoStartWindowTypeKey, (int)AutoStartWindowType.StandardMode);
|
||||
@@ -144,6 +157,31 @@ namespace BetterLyrics.WinUI3.Services
|
||||
get => GetValue<int>(DesktopWindowHeightKey);
|
||||
set => SetValue(DesktopWindowHeightKey, value);
|
||||
}
|
||||
|
||||
public int StandardWindowLeft
|
||||
{
|
||||
get => GetValue<int>(StandardWindowLeftKey);
|
||||
set => SetValue(StandardWindowLeftKey, value);
|
||||
}
|
||||
|
||||
public int StandardWindowTop
|
||||
{
|
||||
get => GetValue<int>(StandardWindowTopKey);
|
||||
set => SetValue(StandardWindowTopKey, value);
|
||||
}
|
||||
|
||||
public int StandardWindowWidth
|
||||
{
|
||||
get => GetValue<int>(StandardWindowWidthKey);
|
||||
set => SetValue(StandardWindowWidthKey, value);
|
||||
}
|
||||
|
||||
public int StandardWindowHeight
|
||||
{
|
||||
get => GetValue<int>(StandardWindowHeightKey);
|
||||
set => SetValue(StandardWindowHeightKey, value);
|
||||
}
|
||||
|
||||
public bool AutoLockOnDesktopMode
|
||||
{
|
||||
get => GetValue<bool>(AutoLockOnDesktopModeKey);
|
||||
|
||||
@@ -228,27 +228,15 @@
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>Alignment</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>Alignment</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsBackgroundBlurAmount.Header" xml:space="preserve">
|
||||
<value>Lyrics background blur amount</value>
|
||||
</data>
|
||||
@@ -552,6 +540,18 @@
|
||||
<data name="SettingsPageAutoLock.Header" xml:space="preserve">
|
||||
<value>Auto-lock when activating desktop mode</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>Alignment</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumArt.Text" xml:space="preserve">
|
||||
<value>Album art</value>
|
||||
</data>
|
||||
@@ -570,4 +570,13 @@
|
||||
<data name="SettingsPageMediaSourceProvidersConfig.Description" xml:space="preserve">
|
||||
<value>Enable or disable lyrics display for a specified media source</value>
|
||||
</data>
|
||||
<data name="SettingsPageLog.Header" xml:space="preserve">
|
||||
<value>Log record</value>
|
||||
</data>
|
||||
<data name="SettingsPageTranslation.Content" xml:space="preserve">
|
||||
<value>Lyrics translation</value>
|
||||
</data>
|
||||
<data name="MainPagePositionOffsetSlider.Header" xml:space="preserve">
|
||||
<value>Lyrics timeline offset (ms)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -228,27 +228,15 @@
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>アライメント</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>アライメント</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
|
||||
<value>中心</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>中心</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
|
||||
<value>左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>左</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
|
||||
<value>右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>右</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsBackgroundBlurAmount.Header" xml:space="preserve">
|
||||
<value>歌詞の背景ぼやけ</value>
|
||||
</data>
|
||||
@@ -552,6 +540,18 @@
|
||||
<data name="SettingsPageAutoLock.Header" xml:space="preserve">
|
||||
<value>デスクトップモードをアクティブにするときの自動ロック</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>アライメント</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>中心</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>右</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumArt.Text" xml:space="preserve">
|
||||
<value>アルバムアート</value>
|
||||
</data>
|
||||
@@ -570,4 +570,13 @@
|
||||
<data name="SettingsPageMediaSourceProvidersConfig.Description" xml:space="preserve">
|
||||
<value>指定されたメディアソースの歌詞ディスプレイを有効または無効にする</value>
|
||||
</data>
|
||||
<data name="SettingsPageLog.Header" xml:space="preserve">
|
||||
<value>ログレコード</value>
|
||||
</data>
|
||||
<data name="SettingsPageTranslation.Content" xml:space="preserve">
|
||||
<value>歌詞翻訳</value>
|
||||
</data>
|
||||
<data name="MainPagePositionOffsetSlider.Header" xml:space="preserve">
|
||||
<value>歌詞タイムラインオフセット(ミリ秒)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -228,27 +228,15 @@
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>조정</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>조정</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
|
||||
<value>센터</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>센터</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
|
||||
<value>왼쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>왼쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
|
||||
<value>오른쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>오른쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsBackgroundBlurAmount.Header" xml:space="preserve">
|
||||
<value>가사 배경 블러</value>
|
||||
</data>
|
||||
@@ -552,6 +540,18 @@
|
||||
<data name="SettingsPageAutoLock.Header" xml:space="preserve">
|
||||
<value>데스크탑 모드를 활성화 할 때 자동 잠금</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>조정</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>센터</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>왼쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>오른쪽</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumArt.Text" xml:space="preserve">
|
||||
<value>앨범 아트</value>
|
||||
</data>
|
||||
@@ -570,4 +570,13 @@
|
||||
<data name="SettingsPageMediaSourceProvidersConfig.Description" xml:space="preserve">
|
||||
<value>지정된 미디어 소스의 가사 디스플레이 활성화 또는 비활성화</value>
|
||||
</data>
|
||||
<data name="SettingsPageLog.Header" xml:space="preserve">
|
||||
<value>로그 레코드</value>
|
||||
</data>
|
||||
<data name="SettingsPageTranslation.Content" xml:space="preserve">
|
||||
<value>가사 번역</value>
|
||||
</data>
|
||||
<data name="MainPagePositionOffsetSlider.Header" xml:space="preserve">
|
||||
<value>가사 타임 라인 오프셋 (밀리초)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -228,27 +228,15 @@
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>对齐方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>对齐方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsBackgroundBlurAmount.Header" xml:space="preserve">
|
||||
<value>歌词背景模糊度</value>
|
||||
</data>
|
||||
@@ -552,6 +540,18 @@
|
||||
<data name="SettingsPageAutoLock.Header" xml:space="preserve">
|
||||
<value>启动桌面模式时随即锁定窗口</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>对齐方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumArt.Text" xml:space="preserve">
|
||||
<value>专辑</value>
|
||||
</data>
|
||||
@@ -570,4 +570,13 @@
|
||||
<data name="SettingsPageMediaSourceProvidersConfig.Description" xml:space="preserve">
|
||||
<value>为指定媒体源启用或禁用歌词显示</value>
|
||||
</data>
|
||||
<data name="SettingsPageLog.Header" xml:space="preserve">
|
||||
<value>日志记录</value>
|
||||
</data>
|
||||
<data name="SettingsPageTranslation.Content" xml:space="preserve">
|
||||
<value>歌词翻译</value>
|
||||
</data>
|
||||
<data name="MainPagePositionOffsetSlider.Header" xml:space="preserve">
|
||||
<value>歌词时间轴偏移(毫秒)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -228,27 +228,15 @@
|
||||
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
|
||||
<value>對齊方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>對齊方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageLyricsBackgroundBlurAmount.Header" xml:space="preserve">
|
||||
<value>歌詞背景模糊度</value>
|
||||
</data>
|
||||
@@ -552,6 +540,18 @@
|
||||
<data name="SettingsPageAutoLock.Header" xml:space="preserve">
|
||||
<value>啟動桌面模式時隨即鎖定窗口</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoAlignment.Header" xml:space="preserve">
|
||||
<value>對齊方式</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoCenter.Content" xml:space="preserve">
|
||||
<value>居中</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoLeft.Content" xml:space="preserve">
|
||||
<value>靠左</value>
|
||||
</data>
|
||||
<data name="SettingsPageSongInfoRight.Content" xml:space="preserve">
|
||||
<value>靠右</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumArt.Text" xml:space="preserve">
|
||||
<value>專輯</value>
|
||||
</data>
|
||||
@@ -570,4 +570,13 @@
|
||||
<data name="SettingsPageMediaSourceProvidersConfig.Description" xml:space="preserve">
|
||||
<value>為指定媒體源啟用或禁用歌詞顯示</value>
|
||||
</data>
|
||||
<data name="SettingsPageLog.Header" xml:space="preserve">
|
||||
<value>日誌記錄</value>
|
||||
</data>
|
||||
<data name="SettingsPageTranslation.Content" xml:space="preserve">
|
||||
<value>歌詞翻譯</value>
|
||||
</data>
|
||||
<data name="MainPagePositionOffsetSlider.Header" xml:space="preserve">
|
||||
<value>歌詞時間軸偏移(毫秒)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -9,7 +9,9 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
@@ -33,6 +35,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private void PlaybackService_SongInfoChanged(object? sender, Events.SongInfoChangedEventArgs e)
|
||||
{
|
||||
SongInfo = e.SongInfo;
|
||||
PositionOffset = 0; // Reset position offset when song changes
|
||||
TrySwitchToPreferredDisplayType(e.SongInfo);
|
||||
}
|
||||
|
||||
@@ -44,10 +47,10 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
public partial bool IsFirstRun { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsNotDockMode { get; set; } = true;
|
||||
public partial bool IsWelcomeTeachingTipOpen { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial bool IsWelcomeTeachingTipOpen { get; set; }
|
||||
public partial Visibility BottomCommandGridVisibility { get; set; } = Visibility.Visible;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial int LyricsFontSize { get; set; }
|
||||
@@ -58,13 +61,20 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[ObservableProperty]
|
||||
public partial SongInfo? SongInfo { get; set; } = null;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial int PositionOffset { get; set; } = 0;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial bool IsTranslationEnabled { get; set; } = false;
|
||||
|
||||
public void Receive(PropertyChangedMessage<bool> message)
|
||||
{
|
||||
if (message.Sender is LyricsWindowViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsWindowViewModel.IsDockMode))
|
||||
{
|
||||
IsNotDockMode = !message.NewValue;
|
||||
SetNonStandardModePreferredDisplayType(message.NewValue);
|
||||
TrySwitchToPreferredDisplayType(SongInfo);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
$"[DEBUG]\n" +
|
||||
$"Cur playing {currentPlayingLineIndex}, char start idx {charStartIndex}, length {charLength}, prog {charProgress}\n" +
|
||||
$"Visible lines [{_startVisibleLineIndex}, {_endVisibleLineIndex}]\n" +
|
||||
$"Cur time {TotalTime}\n" +
|
||||
$"Cur time {_totalTime + _positionOffset}\n" +
|
||||
$"Lang size {_multiLangLyrics.Count}\n" +
|
||||
$"Song duration {TimeSpan.FromMilliseconds(SongInfo?.DurationMs ?? 0)}",
|
||||
new Vector2(10, 10),
|
||||
@@ -132,8 +132,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
float scaleFactor = _albumArtSize / Math.Min(imageWidth, imageHeight);
|
||||
if (scaleFactor < 0.1f) return;
|
||||
|
||||
_albumArtY = 36 + (_canvasHeight - 36 * 2) * 3 / 16;
|
||||
|
||||
float cornerRadius = _albumArtCornerRadius / 100f * _albumArtSize / 2;
|
||||
|
||||
using var cornerRadiusMask = new CanvasCommandList(control.Device);
|
||||
@@ -233,8 +231,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
private void DrawSingleTitleAndArtist(ICanvasAnimatedControl control, CanvasDrawingSession ds, string? title, string? artist, float opacity)
|
||||
{
|
||||
float titleY = _albumArtY + _albumArtSize + 12;
|
||||
|
||||
CanvasTextLayout titleLayout = new(
|
||||
control, title ?? string.Empty,
|
||||
_titleTextFormat, _albumArtSize, _canvasHeight
|
||||
@@ -245,11 +241,11 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
);
|
||||
ds.DrawTextLayout(
|
||||
titleLayout,
|
||||
new Vector2(_albumArtXTransition.Value, titleY),
|
||||
new Vector2(_albumArtXTransition.Value, _titleY),
|
||||
_fontColor.WithAlpha((byte)(_albumArtOpacityTransition.Value * 255 * opacity)));
|
||||
ds.DrawTextLayout(
|
||||
artistLayout,
|
||||
new Vector2(_albumArtXTransition.Value, titleY + (float)titleLayout.LayoutBounds.Height),
|
||||
new Vector2(_albumArtXTransition.Value, _titleY + (float)titleLayout.LayoutBounds.Height),
|
||||
_fontColor.WithAlpha((byte)(_albumArtOpacityTransition.Value * 128 * opacity)));
|
||||
}
|
||||
|
||||
@@ -420,12 +416,19 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
float height = 0f;
|
||||
var regions = textLayout.GetCharacterRegions(0, string.Join("", line.CharTimings.Select(x => x.Text)).Length);
|
||||
if (regions.Length > 0)
|
||||
{
|
||||
height = (float)regions[^1].LayoutBounds.Bottom - (float)regions[0].LayoutBounds.Top;
|
||||
}
|
||||
|
||||
maskDs.FillRectangle(
|
||||
new Rect(
|
||||
textLayout.LayoutBounds.X,
|
||||
position.Y,
|
||||
textLayout.LayoutBounds.Width,
|
||||
textLayout.LayoutBounds.Height
|
||||
height
|
||||
),
|
||||
Colors.White
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Windows.UI;
|
||||
|
||||
@@ -20,26 +21,26 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
IRecipient<PropertyChangedMessage<ObservableCollection<LyricsSearchProviderInfo>>>,
|
||||
IRecipient<PropertyChangedMessage<ObservableCollection<LocalLyricsFolder>>>
|
||||
{
|
||||
public async void Receive(PropertyChangedMessage<ObservableCollection<LocalLyricsFolder>> message)
|
||||
public void Receive(PropertyChangedMessage<ObservableCollection<LocalLyricsFolder>> message)
|
||||
{
|
||||
if (message.Sender is SettingsPageViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(SettingsPageViewModel.LocalLyricsFolders))
|
||||
{
|
||||
// Music lib changed, re-fetch lyrics
|
||||
await RefreshLyricsAsync();
|
||||
RefreshLyricsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async void Receive(PropertyChangedMessage<ObservableCollection<LyricsSearchProviderInfo>> message)
|
||||
public void Receive(PropertyChangedMessage<ObservableCollection<LyricsSearchProviderInfo>> message)
|
||||
{
|
||||
if (message.Sender is SettingsPageViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(SettingsPageViewModel.LyricsSearchProvidersInfo))
|
||||
{
|
||||
// Lyrics search providers info changed, re-fetch lyrics
|
||||
await RefreshLyricsAsync();
|
||||
RefreshLyricsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,6 +79,14 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
_isDesktopMode = message.NewValue;
|
||||
}
|
||||
}
|
||||
else if (message.Sender is LyricsPageViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsPageViewModel.IsTranslationEnabled))
|
||||
{
|
||||
_isTranslationEnabled = message.NewValue;
|
||||
UpdateTranslationsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<Color> message)
|
||||
@@ -142,6 +151,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
LyricsFontSize = message.NewValue;
|
||||
}
|
||||
}
|
||||
else if (message.Sender is LyricsPageViewModel)
|
||||
{
|
||||
if (message.PropertyName == nameof(LyricsPageViewModel.PositionOffset))
|
||||
{
|
||||
_positionOffset = TimeSpan.FromMilliseconds(message.NewValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(PropertyChangedMessage<LineRenderingType> message)
|
||||
|
||||
@@ -21,11 +21,14 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
_canvasWidth = (float)control.Size.Width;
|
||||
_canvasHeight = (float)control.Size.Height;
|
||||
|
||||
_albumArtY = 36 + (_canvasHeight - 36 * 2) * 3 / 16f;
|
||||
|
||||
_displayType = _displayTypeReceived;
|
||||
|
||||
if (_isPlaying)
|
||||
{
|
||||
TotalTime += args.Timing.ElapsedTime;
|
||||
_totalTime += args.Timing.ElapsedTime;
|
||||
}
|
||||
|
||||
ElapsedTime = args.Timing.ElapsedTime;
|
||||
@@ -45,6 +48,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
(_canvasWidth - _leftMargin - _middleMargin - _rightMargin) / 2);
|
||||
_albumArtSize = MathF.Max(0, _albumArtSize);
|
||||
|
||||
_titleY = _albumArtY + _albumArtSize * 1.05f;
|
||||
|
||||
if (isDisplayTypeChanged || isCanvasWidthChanged)
|
||||
{
|
||||
bool jumpTo = !isDisplayTypeChanged && isCanvasWidthChanged;
|
||||
@@ -130,7 +135,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
// Calculate layout bounds
|
||||
line.CanvasTextLayout = new CanvasTextLayout(
|
||||
control,
|
||||
line.Text,
|
||||
line.DisplayedText,
|
||||
_lyricsTextFormat,
|
||||
_maxLyricsWidth,
|
||||
_canvasHeight
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
// 2025/6/23 by Zhe Fang
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ABI.Microsoft.UI.Xaml;
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Events;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Models;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Fluent.LibreTranslate;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Graphics.Canvas;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using Microsoft.Graphics.Canvas.UI.Xaml;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Text;
|
||||
using Microsoft.UI.Xaml;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Graphics.Imaging;
|
||||
using Windows.UI;
|
||||
|
||||
@@ -24,6 +29,9 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
public partial class LyricsRendererViewModel : BaseViewModel
|
||||
{
|
||||
private TimeSpan _totalTime = TimeSpan.Zero;
|
||||
private TimeSpan _positionOffset = TimeSpan.Zero;
|
||||
|
||||
private SoftwareBitmap? _lastAlbumArtSwBitmap = null;
|
||||
private SoftwareBitmap? _albumArtSwBitmap = null;
|
||||
|
||||
@@ -35,6 +43,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private string? _lastSongTitle;
|
||||
private string? _songTitle;
|
||||
|
||||
private float _titleY = 0f;
|
||||
|
||||
private string? _lastSongArtist;
|
||||
private string? _songArtist;
|
||||
|
||||
@@ -57,6 +67,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private readonly IMusicSearchService _musicSearchService;
|
||||
private readonly ILibWatcherService _libWatcherService;
|
||||
private readonly IPlaybackService _playbackService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly float _leftMargin = 36f;
|
||||
private readonly float _middleMargin = 36f;
|
||||
@@ -87,6 +98,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private int _langIndex = 0;
|
||||
|
||||
private List<List<LyricsLine>> _multiLangLyrics = [];
|
||||
private List<string> _translations = [];
|
||||
private bool _isTranslationEnabled = false;
|
||||
|
||||
private CanvasTextFormat _lyricsTextFormat = new()
|
||||
{
|
||||
@@ -98,19 +111,26 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
FontSize = 18,
|
||||
FontWeight = FontWeights.Bold,
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
WordWrapping = CanvasWordWrapping.Wrap,
|
||||
WordWrapping = CanvasWordWrapping.NoWrap,
|
||||
TrimmingSign = CanvasTrimmingSign.Ellipsis,
|
||||
TrimmingGranularity = CanvasTextTrimmingGranularity.Character,
|
||||
};
|
||||
private CanvasTextFormat _artistTextFormat = new()
|
||||
{
|
||||
FontSize = 16,
|
||||
FontWeight = FontWeights.Bold,
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
WordWrapping = CanvasWordWrapping.Wrap,
|
||||
WordWrapping = CanvasWordWrapping.NoWrap,
|
||||
TrimmingSign = CanvasTrimmingSign.Ellipsis,
|
||||
TrimmingGranularity = CanvasTextTrimmingGranularity.Character,
|
||||
};
|
||||
|
||||
private Task? _refreshLyricsTask;
|
||||
private CancellationTokenSource? _refreshLyricsCts;
|
||||
|
||||
private Task? _showTranslationsTask;
|
||||
private CancellationTokenSource? _showTranslationsCts;
|
||||
|
||||
public LyricsRendererViewModel(
|
||||
ISettingsService settingsService, IPlaybackService playbackService,
|
||||
IMusicSearchService musicSearchService, ILibWatcherService libWatcherService) : base(settingsService)
|
||||
@@ -118,6 +138,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
_musicSearchService = musicSearchService;
|
||||
_playbackService = playbackService;
|
||||
_libWatcherService = libWatcherService;
|
||||
_logger = Ioc.Default.GetRequiredService<ILogger<LyricsRendererViewModel>>();
|
||||
|
||||
_albumArtCornerRadius = _settingsService.CoverImageRadius;
|
||||
IsDynamicCoverOverlayEnabled = _settingsService.IsDynamicCoverOverlayEnabled;
|
||||
@@ -134,8 +155,9 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
IsLyricsGlowEffectEnabled = _settingsService.IsLyricsGlowEffectEnabled;
|
||||
LyricsGlowEffectScope = _settingsService.LyricsGlowEffectScope;
|
||||
_customFontColor = _settingsService.LyricsCustomFontColor;
|
||||
_isFanLyricsEnabled = _settingsService.IsFanLyricsEnabled;
|
||||
|
||||
_titleTextFormat.HorizontalAlignment = _artistTextFormat.HorizontalAlignment = _settingsService.LyricsAlignmentType.ToCanvasHorizontalAlignment();
|
||||
_titleTextFormat.HorizontalAlignment = _artistTextFormat.HorizontalAlignment = _settingsService.SongInfoAlignmentType.ToCanvasHorizontalAlignment();
|
||||
|
||||
_libWatcherService.MusicLibraryFilesChanged +=
|
||||
LibWatcherService_MusicLibraryFilesChanged;
|
||||
@@ -187,8 +209,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial ElementTheme ThemeTypeSent { get; set; }
|
||||
|
||||
public TimeSpan TotalTime { get; set; } = TimeSpan.Zero;
|
||||
|
||||
private int GetCurrentPlayingLineIndex()
|
||||
{
|
||||
for (int i = 0; i < _multiLangLyrics.SafeGet(_langIndex)?.Count; i++)
|
||||
@@ -199,8 +219,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
line.StartMs <= TotalTime.TotalMilliseconds
|
||||
&& TotalTime.TotalMilliseconds <= line.EndMs
|
||||
line.StartMs <= _totalTime.TotalMilliseconds + _positionOffset.TotalMilliseconds
|
||||
&& _totalTime.TotalMilliseconds + _positionOffset.TotalMilliseconds <= line.EndMs
|
||||
)
|
||||
{
|
||||
return i;
|
||||
@@ -216,7 +236,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
charLength = 0;
|
||||
charProgress = 0f;
|
||||
|
||||
float now = (float)TotalTime.TotalMilliseconds;
|
||||
float now = (float)_totalTime.TotalMilliseconds + (float)_positionOffset.TotalMilliseconds;
|
||||
|
||||
// 1. 还没到本句
|
||||
if (now < line.StartMs)
|
||||
@@ -261,7 +281,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
charProgress = (now - line.StartMs) / line.DurationMs;
|
||||
charProgress = Math.Clamp(charProgress, 0f, 1f);
|
||||
charStartIndex = 0;
|
||||
charLength = line.Text.Length;
|
||||
charLength = line.OriginalText.Length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +299,9 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
return new Tuple<int, int>(0, _multiLangLyrics[_langIndex].Count - 1);
|
||||
}
|
||||
|
||||
private async void LibWatcherService_MusicLibraryFilesChanged(object? sender, LibChangedEventArgs e)
|
||||
private void LibWatcherService_MusicLibraryFilesChanged(object? sender, LibChangedEventArgs e)
|
||||
{
|
||||
await RefreshLyricsAsync();
|
||||
RefreshLyricsAsync();
|
||||
}
|
||||
|
||||
private void PlaybackService_IsPlayingChanged(object? sender, IsPlayingChangedEventArgs e)
|
||||
@@ -291,27 +311,15 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
private void PlaybackService_PositionChanged(object? sender, PositionChangedEventArgs e)
|
||||
{
|
||||
TotalTime = e.Position;
|
||||
if (Math.Abs(_totalTime.TotalMilliseconds - e.Position.TotalMilliseconds) > 300)
|
||||
{
|
||||
_totalTime = e.Position;
|
||||
}
|
||||
}
|
||||
|
||||
private async void PlaybackService_SongInfoChanged(object? sender, SongInfoChangedEventArgs e)
|
||||
{
|
||||
SongInfo = e.SongInfo;
|
||||
if (SongInfo?.Title != _songTitle || SongInfo?.Artist != _songArtist)
|
||||
{
|
||||
_lastSongTitle = _songTitle;
|
||||
_songTitle = SongInfo?.Title;
|
||||
|
||||
_lastSongArtist = _songArtist;
|
||||
_songArtist = SongInfo?.Artist;
|
||||
|
||||
_songInfoOpacityTransition.Reset(0f);
|
||||
_songInfoOpacityTransition.StartTransition(1f);
|
||||
|
||||
await RefreshLyricsAsync();
|
||||
|
||||
TotalTime = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
if (SongInfo?.AlbumArtSwBitmap != _albumArtSwBitmap)
|
||||
{
|
||||
@@ -327,6 +335,22 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
if (!_isDesktopMode && !_isDockMode) _adaptiveFontColor = Helper.ColorHelper.GetForegroundColor(_lyricsWindowBgColor);
|
||||
UpdateFontColor();
|
||||
}
|
||||
|
||||
if (SongInfo?.Title != _songTitle || SongInfo?.Artist != _songArtist)
|
||||
{
|
||||
_lastSongTitle = _songTitle;
|
||||
_songTitle = SongInfo?.Title;
|
||||
|
||||
_lastSongArtist = _songArtist;
|
||||
_songArtist = SongInfo?.Artist;
|
||||
|
||||
_songInfoOpacityTransition.Reset(0f);
|
||||
_songInfoOpacityTransition.StartTransition(1f);
|
||||
|
||||
await RefreshLyricsAsync();
|
||||
|
||||
_totalTime = TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshLyricsAsync()
|
||||
@@ -346,34 +370,123 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
await _refreshLyricsTask;
|
||||
}
|
||||
|
||||
private async Task UpdateTranslationsAsync()
|
||||
{
|
||||
if (_isTranslationEnabled)
|
||||
{
|
||||
await ShowWithTranslationsAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowOriginalsOnly();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ShowWithTranslationsAsync()
|
||||
{
|
||||
_showTranslationsCts?.Cancel();
|
||||
if (_showTranslationsTask != null)
|
||||
{
|
||||
await _showTranslationsTask;
|
||||
}
|
||||
|
||||
var cts = new CancellationTokenSource();
|
||||
_showTranslationsCts = cts;
|
||||
var token = cts.Token;
|
||||
|
||||
_showTranslationsTask = ShowTranslationsCoreAsync(token);
|
||||
await _showTranslationsTask;
|
||||
}
|
||||
|
||||
private async Task ShowTranslationsCoreAsync(CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = string.Join("\n", _multiLangLyrics.FirstOrDefault()?.Select(x => x.OriginalText) ?? []);
|
||||
GlobalLibreTranslateSettings.Server = new LibreTranslateServer("http://localhost:5000");
|
||||
var translated = await text.TranslateAsync(LanguageCode.Chinese);
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
_translations = translated.Split('\n').ToList();
|
||||
bool totallySame = true;
|
||||
foreach (var langLyrics in _multiLangLyrics)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var line in langLyrics)
|
||||
{
|
||||
if (line.OriginalText != _translations[i])
|
||||
{
|
||||
totallySame = false;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (totallySame) return; // No need to show translations
|
||||
|
||||
foreach (var langLyrics in _multiLangLyrics)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var line in langLyrics)
|
||||
{
|
||||
line.DisplayedText = $"{line.OriginalText}\n{_translations[i]}";
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_isRelayoutNeeded = true;
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
private void ShowOriginalsOnly()
|
||||
{
|
||||
foreach (var langLyrics in _multiLangLyrics)
|
||||
{
|
||||
foreach (var line in langLyrics)
|
||||
{
|
||||
line.DisplayedText = line.OriginalText;
|
||||
}
|
||||
}
|
||||
_isRelayoutNeeded = true;
|
||||
}
|
||||
|
||||
private async Task RefreshLyricsCoreAsync(CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Refreshing lyrics...");
|
||||
|
||||
SetLyricsLoadingPlaceholder();
|
||||
|
||||
string? lyricsRaw = null;
|
||||
LyricsFormat? lyricsFormat = null;
|
||||
|
||||
if (SongInfo != null)
|
||||
{
|
||||
(lyricsRaw, lyricsFormat) = await _musicSearchService.SearchLyricsAsync(
|
||||
lyricsRaw = await _musicSearchService.SearchLyricsAsync(
|
||||
SongInfo.Title,
|
||||
SongInfo.Artist,
|
||||
SongInfo.Album ?? "",
|
||||
SongInfo.DurationMs ?? 0
|
||||
SongInfo.DurationMs ?? 0,
|
||||
token
|
||||
);
|
||||
_logger.LogInformation("Lyrics search result: {LyricsRaw}", lyricsRaw ?? "null");
|
||||
token.ThrowIfCancellationRequested();
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("SongInfo is null, cannot search lyrics.");
|
||||
}
|
||||
|
||||
_multiLangLyrics = new LyricsParser().Parse(
|
||||
lyricsRaw,
|
||||
lyricsFormat,
|
||||
SongInfo?.Title,
|
||||
SongInfo?.Artist,
|
||||
(int)(SongInfo?.DurationMs ?? 0)
|
||||
);
|
||||
_isRelayoutNeeded = true;
|
||||
lyricsRaw,
|
||||
(int?)SongInfo?.DurationMs ?? (int)TimeSpan.FromMinutes(99).TotalMilliseconds
|
||||
);
|
||||
_logger.LogInformation("Parsed lyrics: {MultiLangLyricsCount} languages", _multiLangLyrics.Count);
|
||||
ShowOriginalsOnly();
|
||||
await UpdateTranslationsAsync();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
@@ -387,7 +500,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
StartMs = 0,
|
||||
EndMs = (int)TimeSpan.FromMinutes(99).TotalMilliseconds,
|
||||
Text = "● ● ●",
|
||||
OriginalText = "● ● ●",
|
||||
DisplayedText = "● ● ●",
|
||||
CharTimings = [],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -12,6 +12,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.UI;
|
||||
using WinRT.Interop;
|
||||
@@ -110,6 +111,8 @@ namespace BetterLyrics.WinUI3
|
||||
if (IsDockMode)
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
DockModeHelper.UpdateAppBarHeight(
|
||||
WindowNative.GetWindowHandle(window),
|
||||
message.NewValue * 3
|
||||
@@ -121,9 +124,10 @@ namespace BetterLyrics.WinUI3
|
||||
|
||||
public void StartWatchWindowColorChange(WindowColorSampleMode mode)
|
||||
{
|
||||
var hwnd = WindowNative.GetWindowHandle(
|
||||
WindowHelper.GetWindowByWindowType<LyricsWindow>()
|
||||
);
|
||||
var window = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
_watcherHelper = new ForegroundWindowWatcherHelper(
|
||||
hwnd,
|
||||
onWindowChanged =>
|
||||
@@ -158,6 +162,8 @@ namespace BetterLyrics.WinUI3
|
||||
private void ToggleDesktopMode()
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
StopWatchWindowColorChange();
|
||||
|
||||
IsDesktopMode = !IsDesktopMode;
|
||||
|
||||
@@ -97,6 +97,10 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial bool IsDebugOverlayEnabled { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial bool IsLogEnabled { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedRecipients]
|
||||
public partial bool IsDynamicCoverOverlayEnabled { get; set; }
|
||||
@@ -326,11 +330,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
[RelayCommand]
|
||||
private async Task SelectAndAddFolderAsync(UIElement sender)
|
||||
{
|
||||
var picker = new Windows.Storage.Pickers.FolderPicker();
|
||||
var window = WindowHelper.GetWindowByWindowType<SettingsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FolderPicker();
|
||||
picker.FileTypeFilter.Add("*");
|
||||
|
||||
var hwnd = WindowNative.GetWindowHandle(WindowHelper.GetWindowByWindowType<SettingsWindow>());
|
||||
var hwnd = WindowNative.GetWindowHandle(window);
|
||||
InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private void UnlockWindow()
|
||||
{
|
||||
var window = WindowHelper.GetWindowByWindowType<LyricsWindow>();
|
||||
if (window == null) return;
|
||||
|
||||
DesktopModeHelper.Unlock(window);
|
||||
IsLyricsWindowLocked = false;
|
||||
}
|
||||
|
||||
@@ -34,26 +34,106 @@
|
||||
</Grid.OpacityTransition>
|
||||
</Grid>
|
||||
|
||||
<!-- Bottom-right command area -->
|
||||
<!-- Bottom command area -->
|
||||
<Grid
|
||||
x:Name="BottomCommandGrid"
|
||||
Margin="0,0,4,4"
|
||||
Padding="12"
|
||||
VerticalAlignment="Bottom"
|
||||
Opacity="0"
|
||||
PointerEntered="BottomCommandGrid_PointerEntered"
|
||||
PointerExited="BottomCommandGrid_PointerExited"
|
||||
Visibility="{x:Bind ViewModel.IsNotDockMode, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}">
|
||||
Background="Transparent"
|
||||
Opacity="0">
|
||||
<Grid.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</Grid.OpacityTransition>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerEntered">
|
||||
<interactivity:ChangePropertyAction
|
||||
PropertyName="Opacity"
|
||||
TargetObject="{x:Bind BottomCommandGrid}"
|
||||
Value="1" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerExited">
|
||||
<interactivity:ChangePropertyAction
|
||||
PropertyName="Opacity"
|
||||
TargetObject="{x:Bind BottomCommandGrid}"
|
||||
Value="0" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<TextBlock Margin="12,0,0,0" Text="{x:Bind ViewModel.SongInfo.SourceAppUserModelId, Mode=OneWay}" />
|
||||
<StackPanel
|
||||
x:Name="BottomLeftCommandStackPanel"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</StackPanel.OpacityTransition>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" />
|
||||
<StackPanel
|
||||
x:Name="BottomCenterCommandStackPanel"
|
||||
HorizontalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</StackPanel.OpacityTransition>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="BottomRightCommandStackPanel"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</StackPanel.OpacityTransition>
|
||||
|
||||
<!-- Position offset -->
|
||||
<Button Style="{StaticResource GhostButtonStyle}">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
Glyph=""
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<FontIcon.RenderTransform>
|
||||
<RotateTransform Angle="90" CenterX="0.5" CenterY="0.5" />
|
||||
</FontIcon.RenderTransform>
|
||||
</FontIcon>
|
||||
<Button.Flyout>
|
||||
<Flyout>
|
||||
<StackPanel>
|
||||
<Slider
|
||||
x:Uid="MainPagePositionOffsetSlider"
|
||||
Maximum="2000"
|
||||
Minimum="-2000"
|
||||
SnapsTo="Ticks"
|
||||
StepFrequency="100"
|
||||
TickFrequency="100"
|
||||
TickPlacement="Outside"
|
||||
Value="{x:Bind ViewModel.PositionOffset, Mode=TwoWay}" />
|
||||
<RelativePanel>
|
||||
<TextBlock
|
||||
RelativePanel.AlignLeftWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True"
|
||||
Text="{x:Bind ViewModel.PositionOffset, Mode=OneWay}" />
|
||||
<Button
|
||||
Click="PositionOffsetResetButton_Click"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
RelativePanel.AlignRightWithPanel="True"
|
||||
RelativePanel.AlignVerticalCenterWithPanel="True" />
|
||||
</RelativePanel>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
|
||||
<!-- Translation -->
|
||||
<ToggleButton
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
IsChecked="{x:Bind ViewModel.IsTranslationEnabled, Mode=TwoWay}"
|
||||
Style="{StaticResource GhostToggleButtonStyle}" />
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<!-- Display type -->
|
||||
<Button
|
||||
x:Name="DisplayTypeSwitchButton"
|
||||
@@ -85,9 +165,8 @@
|
||||
<Button
|
||||
x:Name="SettingsButton"
|
||||
Command="{x:Bind ViewModel.OpenSettingsWindowCommand}"
|
||||
Content="{ui:FontIcon FontWeight=Bold,
|
||||
FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Content="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Style="{StaticResource GhostButtonStyle}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
@@ -5,6 +5,8 @@ using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
@@ -19,24 +21,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
public LyricsPageViewModel ViewModel => (LyricsPageViewModel)DataContext;
|
||||
|
||||
private void BottomCommandGrid_PointerEntered(
|
||||
object sender,
|
||||
Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e
|
||||
)
|
||||
{
|
||||
if (BottomCommandGrid.Opacity == 0)
|
||||
BottomCommandGrid.Opacity = .5;
|
||||
}
|
||||
|
||||
private void BottomCommandGrid_PointerExited(
|
||||
object sender,
|
||||
Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e
|
||||
)
|
||||
{
|
||||
if (BottomCommandGrid.Opacity == .5)
|
||||
BottomCommandGrid.Opacity = 0;
|
||||
}
|
||||
|
||||
private void WelcomeTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args)
|
||||
{
|
||||
ViewModel.IsFirstRun = false;
|
||||
@@ -56,5 +40,10 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
ViewModel.PreferredDisplayType = ViewModel.DisplayType = LyricsDisplayType.SplitView;
|
||||
}
|
||||
|
||||
private void PositionOffsetResetButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.PositionOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,38 +15,62 @@
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
|
||||
<Grid
|
||||
x:Name="RootGrid"
|
||||
PointerMoved="RootGrid_PointerMoved"
|
||||
RequestedTheme="{x:Bind ViewModel.ThemeType, Mode=OneWay}">
|
||||
<Grid x:Name="RootGrid" RequestedTheme="{x:Bind ViewModel.ThemeType, Mode=OneWay}">
|
||||
|
||||
<local:LyricsPage />
|
||||
|
||||
<!-- Top command -->
|
||||
|
||||
<Grid
|
||||
x:Name="TopCommandGrid"
|
||||
Height="{x:Bind ViewModel.TitleBarHeight, Mode=OneWay}"
|
||||
VerticalAlignment="Top"
|
||||
Background="Transparent"
|
||||
Opacity="0">
|
||||
<Grid.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</Grid.OpacityTransition>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerEntered">
|
||||
<interactivity:ChangePropertyAction
|
||||
PropertyName="Opacity"
|
||||
TargetObject="{x:Bind TopCommandGrid}"
|
||||
Value="1" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
<interactivity:EventTriggerBehavior EventName="PointerExited">
|
||||
<interactivity:ChangePropertyAction
|
||||
PropertyName="Opacity"
|
||||
TargetObject="{x:Bind TopCommandGrid}"
|
||||
Value="0" />
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<StackPanel
|
||||
x:Name="TopLeftCommandStackPanel"
|
||||
Margin="12"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</StackPanel.OpacityTransition>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel
|
||||
x:Name="TopRightCommandStackPanel"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<StackPanel.OpacityTransition>
|
||||
<ScalarTransition />
|
||||
</StackPanel.OpacityTransition>
|
||||
|
||||
<!-- Look -->
|
||||
<Button
|
||||
x:Name="ClickThroughButton"
|
||||
Command="{x:Bind ViewModel.LockWindowCommand}"
|
||||
Style="{StaticResource TitleBarButtonStyle}">
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="Bold"
|
||||
Glyph="" />
|
||||
</Grid>
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip x:Name="LockToolTip" x:Uid="HostWindowLockToolTip" />
|
||||
</ToolTipService.ToolTip>
|
||||
@@ -65,27 +89,12 @@
|
||||
</interactivity:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</Button>
|
||||
|
||||
<!-- More -->
|
||||
<Button x:Name="MoreButton" Style="{StaticResource TitleBarButtonStyle}">
|
||||
<Grid>
|
||||
<FontIcon
|
||||
Margin="0,0,0,8"
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="ExtraBold"
|
||||
Glyph="" />
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="ExtraBold"
|
||||
Glyph="" />
|
||||
<FontIcon
|
||||
Margin="0,8,0,0"
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
FontWeight="ExtraBold"
|
||||
Glyph="" />
|
||||
</Grid>
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
<Button.Flyout>
|
||||
<MenuFlyout>
|
||||
<ToggleMenuFlyoutItem
|
||||
@@ -126,7 +135,7 @@
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Maximise -->
|
||||
<Button
|
||||
@@ -136,7 +145,7 @@
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Restore -->
|
||||
<Button
|
||||
@@ -147,7 +156,7 @@
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
Glyph="" />
|
||||
</Button>
|
||||
<!-- Window Close -->
|
||||
<Button
|
||||
@@ -157,7 +166,7 @@
|
||||
<FontIcon
|
||||
FontFamily="{StaticResource IconFontFamily}"
|
||||
FontSize="{x:Bind ViewModel.TitleBarFontSize, Mode=OneWay}"
|
||||
Glyph="" />
|
||||
Glyph="" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
using BetterLyrics.WinUI3.Enums;
|
||||
using BetterLyrics.WinUI3.Helper;
|
||||
using BetterLyrics.WinUI3.Services;
|
||||
using BetterLyrics.WinUI3.ViewModels;
|
||||
using CommunityToolkit.Mvvm.DependencyInjection;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using CommunityToolkit.Mvvm.Messaging.Messages;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
@@ -34,6 +38,12 @@ namespace BetterLyrics.WinUI3.Views
|
||||
switch (type!)
|
||||
{
|
||||
case AutoStartWindowType.StandardMode:
|
||||
AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(
|
||||
_settingsService.StandardWindowLeft,
|
||||
_settingsService.StandardWindowTop,
|
||||
_settingsService.StandardWindowWidth,
|
||||
_settingsService.StandardWindowHeight
|
||||
));
|
||||
break;
|
||||
case AutoStartWindowType.DockMode:
|
||||
DockFlyoutItem.IsChecked = true;
|
||||
@@ -62,24 +72,32 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
if (args.DidPresenterChange)
|
||||
UpdateTitleBarWindowButtonsVisibility();
|
||||
if (ViewModel.IsDesktopMode && (args.DidPositionChange || args.DidSizeChange))
|
||||
OnPosOrSizeChanged();
|
||||
}
|
||||
|
||||
private void OnPosOrSizeChanged()
|
||||
{
|
||||
var rect = AppWindow.Position;
|
||||
var size = AppWindow.Size;
|
||||
if (args.DidPositionChange || args.DidSizeChange)
|
||||
{
|
||||
var rect = AppWindow.Position;
|
||||
var size = AppWindow.Size;
|
||||
|
||||
_settingsService.DesktopWindowLeft = rect.X;
|
||||
_settingsService.DesktopWindowTop = rect.Y;
|
||||
_settingsService.DesktopWindowWidth = size.Width;
|
||||
_settingsService.DesktopWindowHeight = size.Height;
|
||||
}
|
||||
if (ViewModel.IsDesktopMode)
|
||||
{
|
||||
_settingsService.DesktopWindowLeft = rect.X;
|
||||
_settingsService.DesktopWindowTop = rect.Y;
|
||||
_settingsService.DesktopWindowWidth = size.Width;
|
||||
_settingsService.DesktopWindowHeight = size.Height;
|
||||
}
|
||||
else if (ViewModel.IsDockMode)
|
||||
{
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.ExitAllWindows();
|
||||
}
|
||||
else
|
||||
{
|
||||
_settingsService.StandardWindowLeft = rect.X;
|
||||
_settingsService.StandardWindowTop = rect.Y;
|
||||
_settingsService.StandardWindowWidth = size.Width;
|
||||
_settingsService.StandardWindowHeight = size.Height;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void FullScreenFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
@@ -101,14 +119,6 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void MaximiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.Maximize();
|
||||
}
|
||||
}
|
||||
|
||||
private void MiniFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (MiniFlyoutItem.IsChecked)
|
||||
@@ -121,6 +131,112 @@ namespace BetterLyrics.WinUI3.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingsMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.OpenOrShowWindow<SettingsWindow>();
|
||||
}
|
||||
|
||||
private void UpdateTitleBarWindowButtonsVisibility()
|
||||
{
|
||||
switch (AppWindow.Presenter.Kind)
|
||||
{
|
||||
case AppWindowPresenterKind.Default:
|
||||
break;
|
||||
case AppWindowPresenterKind.CompactOverlay:
|
||||
MinimiseButton.Visibility = MaximiseButton.Visibility = RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility = DesktopFlyoutItem.Visibility = FullScreenFlyoutItem.Visibility = DockFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility = Visibility.Collapsed;
|
||||
|
||||
break;
|
||||
case AppWindowPresenterKind.FullScreen:
|
||||
MinimiseButton.Visibility = MaximiseButton.Visibility = RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
FullScreenFlyoutItem.IsChecked = true;
|
||||
|
||||
break;
|
||||
case AppWindowPresenterKind.Overlapped:
|
||||
DockFlyoutItem.Visibility = Visibility.Visible;
|
||||
var overlappedPresenter = (OverlappedPresenter)AppWindow.Presenter;
|
||||
if (DockFlyoutItem.IsChecked)
|
||||
{
|
||||
overlappedPresenter.IsMinimizable =
|
||||
overlappedPresenter.IsMaximizable = false;
|
||||
|
||||
MinimiseButton.Visibility = MaximiseButton.Visibility = RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
|
||||
}
|
||||
else if (DesktopFlyoutItem.IsChecked)
|
||||
{
|
||||
overlappedPresenter.IsMinimizable =
|
||||
overlappedPresenter.IsMaximizable = false;
|
||||
|
||||
MinimiseButton.Visibility = MaximiseButton.Visibility = RestoreButton.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
|
||||
ClickThroughButton.Visibility = Visibility.Visible;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
overlappedPresenter.IsMinimizable =
|
||||
overlappedPresenter.IsMaximizable = true;
|
||||
|
||||
MinimiseButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
Visibility.Visible;
|
||||
FullScreenFlyoutItem.IsChecked = false;
|
||||
ClickThroughButton.Visibility = Visibility.Collapsed;
|
||||
AOTFlyoutItem.IsChecked = overlappedPresenter.IsAlwaysOnTop;
|
||||
|
||||
if (overlappedPresenter.State == OverlappedPresenterState.Maximized)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
RestoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else if (overlappedPresenter.State == OverlappedPresenterState.Restored)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Visible;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.ExitAllWindows();
|
||||
}
|
||||
|
||||
private void MaximiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
{
|
||||
presenter.Maximize();
|
||||
}
|
||||
}
|
||||
|
||||
private void MinimiseButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AppWindow.Presenter is OverlappedPresenter presenter)
|
||||
@@ -136,119 +252,5 @@ namespace BetterLyrics.WinUI3.Views
|
||||
presenter.Restore();
|
||||
}
|
||||
}
|
||||
|
||||
private void RootGrid_PointerMoved(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
var point = e.GetCurrentPoint(RootGrid);
|
||||
double y = point.Position.Y;
|
||||
|
||||
if (y >= 0 && y <= TopCommandGrid.ActualHeight + 5)
|
||||
{
|
||||
if (TopCommandGrid.Opacity == 0)
|
||||
{
|
||||
TopCommandGrid.Opacity = .5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TopCommandGrid.Opacity == .5)
|
||||
{
|
||||
TopCommandGrid.Opacity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingsMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
WindowHelper.OpenOrShowWindow<SettingsWindow>();
|
||||
}
|
||||
|
||||
private void UpdateTitleBarWindowButtonsVisibility()
|
||||
{
|
||||
switch (AppWindow.Presenter.Kind)
|
||||
{
|
||||
case AppWindowPresenterKind.Default:
|
||||
break;
|
||||
case AppWindowPresenterKind.CompactOverlay:
|
||||
MinimiseButton.Visibility =
|
||||
MaximiseButton.Visibility =
|
||||
RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
break;
|
||||
case AppWindowPresenterKind.FullScreen:
|
||||
MinimiseButton.Visibility =
|
||||
MaximiseButton.Visibility =
|
||||
RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
FullScreenFlyoutItem.IsChecked = true;
|
||||
break;
|
||||
case AppWindowPresenterKind.Overlapped:
|
||||
DockFlyoutItem.Visibility = Visibility.Visible;
|
||||
var overlappedPresenter = (OverlappedPresenter)AppWindow.Presenter;
|
||||
if (DockFlyoutItem.IsChecked)
|
||||
{
|
||||
MinimiseButton.Visibility =
|
||||
MaximiseButton.Visibility =
|
||||
RestoreButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
ClickThroughButton.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
}
|
||||
else if (DesktopFlyoutItem.IsChecked)
|
||||
{
|
||||
MinimiseButton.Visibility =
|
||||
MaximiseButton.Visibility =
|
||||
RestoreButton.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
Visibility.Collapsed;
|
||||
|
||||
ClickThroughButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
MinimiseButton.Visibility =
|
||||
AOTFlyoutItem.Visibility =
|
||||
DesktopFlyoutItem.Visibility =
|
||||
DockFlyoutItem.Visibility =
|
||||
MiniFlyoutItem.Visibility =
|
||||
FullScreenFlyoutItem.Visibility =
|
||||
Visibility.Visible;
|
||||
FullScreenFlyoutItem.IsChecked = false;
|
||||
ClickThroughButton.Visibility = Visibility.Collapsed;
|
||||
AOTFlyoutItem.IsChecked = overlappedPresenter.IsAlwaysOnTop;
|
||||
|
||||
if (overlappedPresenter.State == OverlappedPresenterState.Maximized)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Collapsed;
|
||||
RestoreButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
else if (overlappedPresenter.State == OverlappedPresenterState.Restored)
|
||||
{
|
||||
MaximiseButton.Visibility = Visibility.Visible;
|
||||
RestoreButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
TopCommandGrid.Opacity = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Tag="Lyrics" />
|
||||
<NavigationViewItem
|
||||
x:Uid="SettingsPageTranslation"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
Glyph=}"
|
||||
Tag="Translation" />
|
||||
<NavigationViewItem
|
||||
x:Uid="SettingsPageAbout"
|
||||
Icon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
|
||||
@@ -75,7 +80,6 @@
|
||||
</controls:SwitchPresenter.ContentTransitions>
|
||||
|
||||
<!-- App appearance and behavior -->
|
||||
|
||||
<controls:Case Value="App">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
@@ -125,7 +129,6 @@
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics background -->
|
||||
|
||||
<controls:Case Value="Background">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
@@ -174,7 +177,6 @@
|
||||
</controls:Case>
|
||||
|
||||
<!-- Album art area style -->
|
||||
|
||||
<controls:Case Value="AlbumArtStyle">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
@@ -346,7 +348,6 @@
|
||||
</controls:Case>
|
||||
|
||||
<!-- Lyrics style and effect -->
|
||||
|
||||
<controls:Case Value="Lyrics">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
|
||||
@@ -520,8 +521,19 @@
|
||||
</StackPanel>
|
||||
</controls:Case>
|
||||
|
||||
<!-- About -->
|
||||
<!-- Lyrics translation -->
|
||||
<controls:Case Value="Translation">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<controls:SettingsExpander>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Text="http://127.0.0.1:5000" />
|
||||
<Button Content="Verify" />
|
||||
</StackPanel>
|
||||
</controls:SettingsExpander>
|
||||
</StackPanel>
|
||||
</controls:Case>
|
||||
|
||||
<!-- About -->
|
||||
<controls:Case Value="About">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<controls:SettingsCard Header="BetterLyrics" HeaderIcon="{ui:BitmapIcon Source=ms-appx:///Assets/Logo.png}">
|
||||
@@ -548,6 +560,7 @@
|
||||
</StackPanel>
|
||||
</controls:Case>
|
||||
|
||||
<!-- Dev -->
|
||||
<controls:Case Value="Dev">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<controls:SettingsCard x:Uid="SettingsPageMockMusicPlaying">
|
||||
|
||||
Reference in New Issue
Block a user