add: x animation for lyrics; update: y scroll animation

This commit is contained in:
Zhe Fang
2025-06-22 08:46:39 -04:00
parent 9d193b7b71
commit 11c3002b77
20 changed files with 1324 additions and 200 deletions

View File

@@ -11,7 +11,7 @@
<Identity
Name="37412.BetterLyrics"
Publisher="CN=Zhe"
Version="1.0.4.0" />
Version="1.0.5.0" />
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
@@ -30,6 +30,8 @@
<Resource Language="en-US"/>
<Resource Language="zh-CN"/>
<Resource Language="zh-TW"/>
<Resource Language="ja-JP"/>
<Resource Language="ko-KR"/>
</Resources>
<Applications>
@@ -50,6 +52,5 @@
<Capabilities>
<rescap:Capability Name="runFullTrust" />
<Capability Name="internetClient"/>
</Capabilities>
</Package>

View File

@@ -1,4 +1,6 @@
using System.Text;
using System;
using System.Text;
using System.Threading.Tasks;
using BetterInAppLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Services;
@@ -44,19 +46,46 @@ namespace BetterLyrics.WinUI3
ResourceLoader = new ResourceLoader();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Helper.AppInfo.EnsureDirectories();
AppInfo.EnsureDirectories();
ConfigureServices();
_logger = Ioc.Default.GetService<ILogger<App>>()!;
UnhandledException += App_UnhandledException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}
private void CurrentDomain_FirstChanceException(
object? sender,
System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e
)
{
_logger.LogError(e.Exception, "TaskScheduler_UnobservedTaskException");
}
private void TaskScheduler_UnobservedTaskException(
object? sender,
UnobservedTaskExceptionEventArgs e
)
{
_logger.LogError(e.Exception, "TaskScheduler_UnobservedTaskException");
}
private void CurrentDomain_UnhandledException(
object sender,
System.UnhandledExceptionEventArgs e
)
{
_logger.LogError(e.ExceptionObject.ToString(), "CurrentDomain_UnhandledException");
}
private static void ConfigureServices()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(Helper.AppInfo.LogFilePattern, rollingInterval: RollingInterval.Day)
.WriteTo.File(AppInfo.LogFilePattern, rollingInterval: RollingInterval.Day)
.CreateLogger();
// Register services

View File

@@ -34,16 +34,16 @@
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Helpers" Version="8.2.250402" />
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.250402" />
<PackageReference Include="Lyricify.Lyrics.Helper" Version="0.1.4" />
<PackageReference Include="Lyricify.Lyrics.Helper-NativeAot" Version="0.1.4-alpha.5" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.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="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.2" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
<PackageReference Include="SubtitlesParserV2" Version="2.2.3" />
<PackageReference Include="System.Drawing.Common" Version="9.0.6" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.6" />
<PackageReference Include="Ude.NetStandard" Version="1.2.0" />

View File

@@ -12,5 +12,7 @@ namespace BetterLyrics.WinUI3.Enums
English,
SimplifiedChinese,
TraditionalChinese,
Japanese,
Korean,
}
}

View File

@@ -2,8 +2,13 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Text;
using Microsoft.UI;
using Microsoft.UI.Text;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using Windows.Graphics.Imaging;
@@ -71,5 +76,81 @@ namespace BetterLyrics.WinUI3.Helper
public static async Task<BitmapDecoder> GetDecoderFromByte(byte[] bytes) =>
await BitmapDecoder.CreateAsync(await ByteArrayToStream(bytes));
public static async Task<byte[]> CreateTextPlaceholderBytesAsync(
string text,
int width,
int height
)
{
var device = CanvasDevice.GetSharedDevice();
var renderTarget = new CanvasRenderTarget(device, width, height, 96);
// 居中绘制文字
using (var ds = renderTarget.CreateDrawingSession())
{
// 背景色
ds.Clear(Colors.LightGray);
// 文字格式
var format = new CanvasTextFormat
{
FontSize = Math.Min(width, height) / 6f,
FontWeight = Microsoft.UI.Text.FontWeights.SemiBold,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
VerticalAlignment = CanvasVerticalAlignment.Center,
WordWrapping = CanvasWordWrapping.Wrap,
TrimmingGranularity = CanvasTextTrimmingGranularity.Character,
Options = CanvasDrawTextOptions.Default,
};
// 设定边距
float margin = Math.Min(width, height) / 12f;
float availableWidth = width - 2 * margin;
float availableHeight = height - 2 * margin;
// 计算合适的字体大小以适应内容区域
float fontSize = format.FontSize;
float minFontSize = 8f;
float maxFontSize = format.FontSize;
CanvasTextLayout layout;
do
{
format.FontSize = fontSize;
layout = new CanvasTextLayout(
ds,
text,
format,
availableWidth,
availableHeight
);
if (
layout.LayoutBounds.Width <= availableWidth
&& layout.LayoutBounds.Height <= availableHeight
)
break;
fontSize -= 1f;
} while (fontSize >= minFontSize);
// 居中绘制文字(在内容区域内居中)
var bounds = layout.LayoutBounds;
var x = margin + (availableWidth - (float)bounds.Width) / 2f - (float)bounds.X;
var y = margin + (availableHeight - (float)bounds.Height) / 2f - (float)bounds.Y;
ds.DrawTextLayout(layout, new Vector2(x, y), Colors.DarkGray);
}
// 保存为 PNG 并转为 byte[]
using (var stream = new InMemoryRandomAccessStream())
{
await renderTarget.SaveAsync(stream, CanvasBitmapFileFormat.Png);
var buffer = new byte[stream.Size];
using (var reader = new DataReader(stream.GetInputStreamAt(0)))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(buffer);
}
return buffer;
}
}
}
}

View File

@@ -1,12 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Enums;
using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json;
namespace BetterLyrics.WinUI3.Models
{

View File

@@ -5,10 +5,10 @@ namespace BetterLyrics.WinUI3.Models
public partial class SongInfo : ObservableObject
{
[ObservableProperty]
public partial string? Title { get; set; }
public partial string Title { get; set; }
[ObservableProperty]
public partial string? Artist { get; set; }
public partial string Artist { get; set; }
[ObservableProperty]
public partial string? Album { get; set; }

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using BetterLyrics.WinUI3.Models;
namespace BetterLyrics.WinUI3.Serialization
{
[JsonSerializable(typeof(List<LyricsSearchProviderInfo>))]
[JsonSerializable(typeof(List<string>))]
[JsonSerializable(typeof(JsonElement))]
[JsonSourceGenerationOptions(WriteIndented = true)]
internal partial class SourceGenerationContext : JsonSerializerContext { }
}

View File

@@ -240,10 +240,14 @@ namespace BetterLyrics.WinUI3.Services
var json = await response.Content.ReadAsStringAsync();
var jArr = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
if (jArr is not null && jArr.Count > 0)
var jArr = JsonSerializer.Deserialize(
json,
Serialization.SourceGenerationContext.Default.JsonElement
);
if (jArr.ValueKind == JsonValueKind.Array && jArr.GetArrayLength() > 0)
{
var syncedLyrics = jArr![0]?.syncedLyrics?.ToString();
var first = jArr[0];
var syncedLyrics = first.GetProperty("syncedLyrics").GetString();
var result = string.IsNullOrWhiteSpace(syncedLyrics) ? null : syncedLyrics;
if (!string.IsNullOrWhiteSpace(result))
{

View File

@@ -117,11 +117,11 @@ namespace BetterLyrics.WinUI3.Services
_currentSession.PlaybackInfoChanged += CurrentSession_PlaybackInfoChanged;
_currentSession.TimelinePropertiesChanged +=
CurrentSession_TimelinePropertiesChanged;
CurrentSession_MediaPropertiesChanged(_currentSession, null);
CurrentSession_PlaybackInfoChanged(_currentSession, null);
CurrentSession_TimelinePropertiesChanged(_currentSession, null);
}
CurrentSession_MediaPropertiesChanged(_currentSession, null);
CurrentSession_PlaybackInfoChanged(_currentSession, null);
CurrentSession_TimelinePropertiesChanged(_currentSession, null);
}
/// <summary>
@@ -147,25 +147,43 @@ namespace BetterLyrics.WinUI3.Services
}
catch (Exception) { }
SongInfo = new SongInfo
if (mediaProps == null)
{
Title = mediaProps?.Title ?? string.Empty,
Artist = mediaProps?.Artist ?? string.Empty,
Album = mediaProps?.AlbumTitle ?? string.Empty,
DurationMs = _currentSession?.GetTimelineProperties().EndTime.TotalMilliseconds,
SourceAppUserModelId = _currentSession?.SourceAppUserModelId,
};
if (mediaProps?.Thumbnail is IRandomAccessStreamReference streamReference)
{
SongInfo.AlbumArt = await ImageHelper.ToByteArrayAsync(streamReference);
SongInfo = null;
}
else
{
SongInfo.AlbumArt = _musicSearchService.SearchAlbumArtAsync(
SongInfo.Title,
SongInfo.Artist
);
SongInfo = new SongInfo
{
Title = mediaProps.Title,
Artist = mediaProps.Artist,
Album = mediaProps?.AlbumTitle ?? string.Empty,
DurationMs = _currentSession
?.GetTimelineProperties()
.EndTime.TotalMilliseconds,
SourceAppUserModelId = _currentSession?.SourceAppUserModelId,
};
if (mediaProps?.Thumbnail is IRandomAccessStreamReference streamReference)
{
SongInfo.AlbumArt = await ImageHelper.ToByteArrayAsync(streamReference);
}
else
{
SongInfo.AlbumArt = _musicSearchService.SearchAlbumArtAsync(
SongInfo.Title,
SongInfo.Artist
);
if (SongInfo.AlbumArt == null)
{
SongInfo.AlbumArt = await ImageHelper.CreateTextPlaceholderBytesAsync(
$"{SongInfo.Artist} - {SongInfo.Title}",
400,
400
);
}
}
}
}
_dispatcherQueue.TryEnqueue(

View File

@@ -1,13 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using BetterLyrics.WinUI3.Enums;
using BetterLyrics.WinUI3.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using BetterLyrics.WinUI3.Serialization;
using Microsoft.UI.Xaml;
using Newtonsoft.Json;
using Windows.Media;
using Windows.Storage;
namespace BetterLyrics.WinUI3.Services
@@ -56,19 +51,35 @@ namespace BetterLyrics.WinUI3.Services
public List<string> MusicLibraries
{
get =>
JsonConvert.DeserializeObject<List<string>>(
GetValue<string>(MusicLibrariesKey) ?? "[]"
System.Text.Json.JsonSerializer.Deserialize(
GetValue<string>(MusicLibrariesKey) ?? "[]",
SourceGenerationContext.Default.ListString
)!;
set => SetValue(MusicLibrariesKey, JsonConvert.SerializeObject(value));
set =>
SetValue(
MusicLibrariesKey,
System.Text.Json.JsonSerializer.Serialize(
value,
SourceGenerationContext.Default.ListString
)
);
}
public List<LyricsSearchProviderInfo> LyricsSearchProvidersInfo
{
get =>
JsonConvert.DeserializeObject<List<LyricsSearchProviderInfo>>(
GetValue<string>(LyricsSearchProvidersInfoKey) ?? "[]"
System.Text.Json.JsonSerializer.Deserialize(
GetValue<string>(LyricsSearchProvidersInfoKey) ?? "[]",
SourceGenerationContext.Default.ListLyricsSearchProviderInfo
)!;
set => SetValue(LyricsSearchProvidersInfoKey, JsonConvert.SerializeObject(value));
set =>
SetValue(
LyricsSearchProvidersInfoKey,
System.Text.Json.JsonSerializer.Serialize(
value,
SourceGenerationContext.Default.ListLyricsSearchProviderInfo
)
);
}
public ElementTheme ThemeType
@@ -194,14 +205,15 @@ namespace BetterLyrics.WinUI3.Services
SetDefault(MusicLibrariesKey, "[]");
SetDefault(
LyricsSearchProvidersInfoKey,
JsonConvert.SerializeObject(
System.Text.Json.JsonSerializer.Serialize(
new List<LyricsSearchProviderInfo>()
{
new(LyricsSearchProvider.LocalMusicFile, true),
new(LyricsSearchProvider.LocalLrcFile, true),
new(LyricsSearchProvider.LrcLib, true),
new(LyricsSearchProvider.QQMusic, true),
}
},
SourceGenerationContext.Default.ListLyricsSearchProviderInfo
)
);
// App appearance

View File

@@ -466,13 +466,13 @@
<value>Loading lyrics...</value>
</data>
<data name="LyricsSearchProviderLocalLrcFile" xml:space="preserve">
<value>Local .lrc files</value>
<value>Local .LRC files</value>
</data>
<data name="LyricsSearchProviderLocalMusicFile" xml:space="preserve">
<value>Local music files</value>
</data>
<data name="LyricsSearchProviderLrcLib" xml:space="preserve">
<value>LrcLib</value>
<value>LRCLIB</value>
</data>
<data name="LyricsSearchProviderQQMusic" xml:space="preserve">
<value>QQ Music</value>
@@ -480,4 +480,10 @@
<data name="LyricsSearchProviderKugouMusic" xml:space="preserve">
<value>Kugou Music</value>
</data>
<data name="SettingsPageJA.Content" xml:space="preserve">
<value>日本語</value>
</data>
<data name="SettingsPageKO.Content" xml:space="preserve">
<value>한국어</value>
</data>
</root>

View File

@@ -0,0 +1,489 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="SettingsPageMusicLib.Header" xml:space="preserve">
<value>地元の音楽図書館</value>
</data>
<data name="SettingsPageMusicLib.Description" xml:space="preserve">
<value>音楽や歌詞を保存するフォルダーを追加します</value>
</data>
<data name="SettingsPageOpenPath.Content" xml:space="preserve">
<value>ファイルエクスプローラーで開きます</value>
</data>
<data name="SettingsPageOpenLogFolderButton.Content" xml:space="preserve">
<value>ファイルエクスプローラーで開きます</value>
</data>
<data name="SettingsPageRemovePath.Content" xml:space="preserve">
<value>アプリから削除します</value>
</data>
<data name="SettingsPageRemoveInfo.Title" xml:space="preserve">
<value>次のアイテムを削除しても安全です</value>
</data>
<data name="SettingsPageRemoveInfo.Message" xml:space="preserve">
<value>このパスの元のファイルとフォルダーは、このアプリから削除するときに削除されません</value>
</data>
<data name="SettingsPageAddFolder.Header" xml:space="preserve">
<value>フォルダーを追加します</value>
</data>
<data name="SettingsPageTheme.Header" xml:space="preserve">
<value>テーマ</value>
</data>
<data name="SettingsPageLanguage.Header" xml:space="preserve">
<value>言語</value>
</data>
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>システムをフォローします</value>
</data>
<data name="SettingsPageLight.Content" xml:space="preserve">
<value>ライト</value>
</data>
<data name="SettingsPageDark.Content" xml:space="preserve">
<value>暗い</value>
</data>
<data name="SettingsPageSC.Content" xml:space="preserve">
<value>简体中文</value>
</data>
<data name="SettingsPageTC.Content" xml:space="preserve">
<value>繁體中文</value>
</data>
<data name="SettingsPageEN.Content" xml:space="preserve">
<value>English</value>
</data>
<data name="SettingsPageGitHub.Header" xml:space="preserve">
<value>これはオープンソースアプリです</value>
</data>
<data name="SettingsPageGitHub.ActionIconToolTip" xml:space="preserve">
<value>新しいウィンドウで開きます</value>
</data>
<data name="SettingsPageGitHub.Description" xml:space="preserve">
<value>GitHubのソースコードを参照してください</value>
</data>
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>バージョン</value>
</data>
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>なし</value>
</data>
<data name="SettingsPageMica.Content" xml:space="preserve">
<value>雲母</value>
</data>
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>マイカル</value>
</data>
<data name="SettingsPageDesktopAcrylic.Content" xml:space="preserve">
<value>デスクトップアクリル</value>
</data>
<data name="SettingsPageAcrylicBase.Content" xml:space="preserve">
<value>アクリルベース</value>
</data>
<data name="SettingsPageAcrylicThin.Content" xml:space="preserve">
<value>アクリル薄い</value>
</data>
<data name="SettingsPageTransparent.Content" xml:space="preserve">
<value>透明</value>
</data>
<data name="SettingsPageBackdrop.Header" xml:space="preserve">
<value>背景</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<value>デフォルト</value>
</data>
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>変更を適用するためのアプリを再起動します</value>
</data>
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>パスはコンピューターでは見つかりません</value>
</data>
<data name="SettingsPagePathExistedInfo" xml:space="preserve">
<value>フォルダーが追加されました。二度と追加しないでください。</value>
</data>
<data name="SettingsPageCoverOverlay.Header" xml:space="preserve">
<value>オーバーレイアルバムアートの背景</value>
</data>
<data name="SettingsPageDynamicCoverOverlay.Header" xml:space="preserve">
<value>ダイナミックアルバムアートの背景</value>
</data>
<data name="SettingsPageCoverOverlayOpacity.Header" xml:space="preserve">
<value>アルバムアートの背景不透明</value>
</data>
<data name="SettingsPageTitle" xml:space="preserve">
<value>設定 - BetterLyrics</value>
</data>
<data name="LyricsPageTitle" xml:space="preserve">
<value>BetterLyrics</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>アライメント</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>中心</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>右</value>
</data>
<data name="SettingsPageCoverOverlayBlurAmount.Header" xml:space="preserve">
<value>アルバムアートバックグラウンドブラー量</value>
</data>
<data name="SettingsPageLyricsBlurAmount.Header" xml:space="preserve">
<value>ぼやけの量</value>
</data>
<data name="SettingsPageLyricsBlurAmountSideEffect.Text" xml:space="preserve">
<value>この値を調整すると、アルバム画像のバックグラウンドブラー強度も増加します。</value>
</data>
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>現在の値:</value>
</data>
<data name="SettingsPageLyricsBlurHighGPUUsage.Text" xml:space="preserve">
<value>ぼかしが有効になっている場合のGPU使用量が大幅に高くなります&gt; 0</value>
</data>
<data name="SettingsPageCoverOverlayGPUUsage.Text" xml:space="preserve">
<value>この機能を有効にすると、GPUの使用率がわずかに増加します</value>
</data>
<data name="SettingsPageLyricsVerticalEdgeOpacity.Header" xml:space="preserve">
<value>上端と下端の不透明度</value>
</data>
<data name="SettingsPageLyricsLineSpacingFactor.Header" xml:space="preserve">
<value>ライン間隔</value>
</data>
<data name="SettingsPageLyricsLineSpacingFactorUnit.Text" xml:space="preserve">
<value>x線の高さ</value>
</data>
<data name="SettingsPageLyricsFontSize.Header" xml:space="preserve">
<value>フォントサイズ</value>
</data>
<data name="MainPageLyriscOnly.Content" xml:space="preserve">
<value>歌詞のみ</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>没入モード</value>
</data>
<data name="SettingsPageAlbumOverlay.Content" xml:space="preserve">
<value>アルバムの背景</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>について</value>
</data>
<data name="SettingsPageLyricsLib.Content" xml:space="preserve">
<value>歌詞ライブラリ</value>
</data>
<data name="SettingsPageAppAppearance.Content" xml:space="preserve">
<value>アプリの外観</value>
</data>
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>グロー効果</value>
</data>
<data name="SettingsPageLyricsGlowEffectScope.Header" xml:space="preserve">
<value>グローエフェクトスコープ</value>
</data>
<data name="SettingsPageLyricsSearchProvidersConfig.Header" xml:space="preserve">
<value>歌詞検索プロバイダーを構成します</value>
</data>
<data name="SettingsPageAddFolderButton.Content" xml:space="preserve">
<value>追加</value>
</data>
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>BetterLyrics へようこそ</value>
</data>
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
<value>今すぐ歌詞データベースをセットアップしましょう</value>
</data>
<data name="MainPageNoMusicPlaying.Text" xml:space="preserve">
<value>今は音楽が再生されていません</value>
</data>
<data name="SettingsPageDev.Content" xml:space="preserve">
<value>開発者オプション</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>テスト音楽を再生します</value>
</data>
<data name="SettingsPagePlayingMockMusicButton.Content" xml:space="preserve">
<value>システムプレーヤーを使用して再生します</value>
</data>
<data name="SettingsPageLog.Header" xml:space="preserve">
<value>ログ</value>
</data>
<data name="SettingsPageLyricsFontColor.Header" xml:space="preserve">
<value>フォントカラー</value>
</data>
<data name="SettingsPageLyricsFontColorDefault.Content" xml:space="preserve">
<value>デフォルト</value>
</data>
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
<value>アルバムアートアクセントカラー</value>
</data>
<data name="SettingsPageAlbumStyle.Content" xml:space="preserve">
<value>アルバムアートスタイル</value>
</data>
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
<value>コーナー半径</value>
</data>
<data name="SettingsPageTitleBarType.Header" xml:space="preserve">
<value>タイトルバーサイズ</value>
</data>
<data name="SettingsPageCompactTitleBar.Content" xml:space="preserve">
<value>コンパクト</value>
</data>
<data name="SettingsPageExtendedTitleBar.Content" xml:space="preserve">
<value>拡張</value>
</data>
<data name="BaseWindowAOTFlyoutItem.Text" xml:space="preserve">
<value>常にトップ</value>
</data>
<data name="BaseWindowFullScreenFlyoutItem.Text" xml:space="preserve">
<value>全画面表示</value>
</data>
<data name="BaseWindowEnterFullScreenHint" xml:space="preserve">
<value>ESCを押して、フルスクリーンモードを終了します</value>
</data>
<data name="MainPageEnterImmersiveModeHint" xml:space="preserve">
<value>再びホバリングして、トグルボタンを表示します</value>
</data>
<data name="BaseWindowHostInfoBarCheckBox.Content" xml:space="preserve">
<value>このメッセージを二度と見せないでください</value>
</data>
<data name="MainPageNoLocalFilesMatched.Text" xml:space="preserve">
<value>一致するローカルファイルはありません</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>アルバムアートのみ</value>
</data>
<data name="MainPageSplitView.Content" xml:space="preserve">
<value>分割ビュー</value>
</data>
<data name="MainPageDisplayTypeSwitcher.ToolTipService.ToolTip" xml:space="preserve">
<value>表示タイプを変更します</value>
</data>
<data name="MainPageDesktopLyricsToggler.ToolTipService.ToolTip" xml:space="preserve">
<value>デスクトップ歌詞モードに切り替えます</value>
</data>
<data name="BaseWindowMiniFlyoutItem.Text" xml:space="preserve">
<value>ピクチャーインピクチャーモード</value>
</data>
<data name="BaseWindowUnMiniFlyoutItem.Text" xml:space="preserve">
<value>ピクチャーインピクチャーモードを終了します</value>
</data>
<data name="MainPageLyricsNotFound.Text" xml:space="preserve">
<value>歌詞が見つかりません</value>
</data>
<data name="SettingsPageLyricsEffect.Content" xml:space="preserve">
<value>歌詞効果</value>
</data>
<data name="SettingsPageLyricsStyle.Content" xml:space="preserve">
<value>歌詞スタイル</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>このフォルダーは既存のフォルダーに既に含まれており、再度追加する必要はありません</value>
</data>
<data name="SettingsPageAppBehavior.Content" xml:space="preserve">
<value>アプリの動作</value>
</data>
<data name="SettingsPageAutoStartWindow.Header" xml:space="preserve">
<value>アプリを起動するとき</value>
</data>
<data name="SettingsPageAutoStartInAppLyrics.Content" xml:space="preserve">
<value>標準モードをアクティブにします</value>
</data>
<data name="SettingsPageAutoStartDesktopLyrics.Content" xml:space="preserve">
<value>ドックモードをアクティブにします</value>
</data>
<data name="DesktopLyricsRendererPageLyricsNotFound.Text" xml:space="preserve">
<value>歌詞が見つかりません</value>
</data>
<data name="SystemTrayPageTitle" xml:space="preserve">
<value>システムトレイ - BetterLyrics</value>
</data>
<data name="HostWindowDockFlyoutItem.Text" xml:space="preserve">
<value>ドックモード</value>
</data>
<data name="SettingsPageLyricsFontWeight.Header" xml:space="preserve">
<value>フォント重量</value>
</data>
<data name="SettingsPageLyricsThin.Content" xml:space="preserve">
<value>薄い</value>
</data>
<data name="SettingsPageLyricsExtraLight.Content" xml:space="preserve">
<value>余分な光</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>ライト</value>
</data>
<data name="SettingsPageLyricsSemiLight.Content" xml:space="preserve">
<value>半光</value>
</data>
<data name="SettingsPageLyricsNormal.Content" xml:space="preserve">
<value>普通</value>
</data>
<data name="SettingsPageLyricsMedium.Content" xml:space="preserve">
<value>中くらい</value>
</data>
<data name="SettingsPageLyricsSemiBold.Content" xml:space="preserve">
<value>セミボールド</value>
</data>
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>大胆な</value>
</data>
<data name="SettingsPageLyricsExtraBold.Content" xml:space="preserve">
<value>余分な太字</value>
</data>
<data name="SettingsPageLyricsBlack.Content" xml:space="preserve">
<value>黒</value>
</data>
<data name="SettingsPageLyricsExtraBlack.Content" xml:space="preserve">
<value>余分な黒</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeWholeLyrics.Content" xml:space="preserve">
<value>歌詞全体</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeCurrentLine.Content" xml:space="preserve">
<value>現在の行</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeCurrentChar.Content" xml:space="preserve">
<value>現在の文字</value>
</data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
<value>設定</value>
</data>
<data name="MainPageLyricsLoading.Text" xml:space="preserve">
<value>歌詞の読み込み...</value>
</data>
<data name="LyricsSearchProviderLocalLrcFile" xml:space="preserve">
<value>ローカル.LRCファイル</value>
</data>
<data name="LyricsSearchProviderLocalMusicFile" xml:space="preserve">
<value>ローカル音楽ファイル</value>
</data>
<data name="LyricsSearchProviderLrcLib" xml:space="preserve">
<value>LRCLIB</value>
</data>
<data name="LyricsSearchProviderQQMusic" xml:space="preserve">
<value>QQ音楽</value>
</data>
<data name="LyricsSearchProviderKugouMusic" xml:space="preserve">
<value>クゴウ音楽</value>
</data>
<data name="SettingsPageJA.Content" xml:space="preserve">
<value>日本語</value>
</data>
<data name="SettingsPageKO.Content" xml:space="preserve">
<value>한국어</value>
</data>
</root>

View File

@@ -0,0 +1,489 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="SettingsPageMusicLib.Header" xml:space="preserve">
<value>로컬 음악 도서관</value>
</data>
<data name="SettingsPageMusicLib.Description" xml:space="preserve">
<value>음악이나 가사를 저장하는 폴더 추가</value>
</data>
<data name="SettingsPageOpenPath.Content" xml:space="preserve">
<value>파일 탐색기에서 열립니다</value>
</data>
<data name="SettingsPageOpenLogFolderButton.Content" xml:space="preserve">
<value>파일 탐색기에서 열립니다</value>
</data>
<data name="SettingsPageRemovePath.Content" xml:space="preserve">
<value>앱에서 제거하십시오</value>
</data>
<data name="SettingsPageRemoveInfo.Title" xml:space="preserve">
<value>다음 항목을 제거하는 것이 안전합니다</value>
</data>
<data name="SettingsPageRemoveInfo.Message" xml:space="preserve">
<value>이 경로의 원본 파일과 폴더는이 앱에서 제거 할 때 삭제되지 않습니다.</value>
</data>
<data name="SettingsPageAddFolder.Header" xml:space="preserve">
<value>폴더를 추가하십시오</value>
</data>
<data name="SettingsPageTheme.Header" xml:space="preserve">
<value>주제</value>
</data>
<data name="SettingsPageLanguage.Header" xml:space="preserve">
<value>언어</value>
</data>
<data name="SettingsPageFollowSystem.Content" xml:space="preserve">
<value>시스템을 따르십시오</value>
</data>
<data name="SettingsPageLight.Content" xml:space="preserve">
<value>빛</value>
</data>
<data name="SettingsPageDark.Content" xml:space="preserve">
<value>어두운</value>
</data>
<data name="SettingsPageSC.Content" xml:space="preserve">
<value>简体中文</value>
</data>
<data name="SettingsPageTC.Content" xml:space="preserve">
<value>繁體中文</value>
</data>
<data name="SettingsPageEN.Content" xml:space="preserve">
<value>English</value>
</data>
<data name="SettingsPageGitHub.Header" xml:space="preserve">
<value>이것은 오픈 소스 앱입니다</value>
</data>
<data name="SettingsPageGitHub.ActionIconToolTip" xml:space="preserve">
<value>새 창에서 열립니다</value>
</data>
<data name="SettingsPageGitHub.Description" xml:space="preserve">
<value>GitHub의 소스 코드를 참조하십시오</value>
</data>
<data name="SettingsPageVersion.Text" xml:space="preserve">
<value>버전</value>
</data>
<data name="SettingsPageNoBackdrop.Content" xml:space="preserve">
<value>없음</value>
</data>
<data name="SettingsPageMica.Content" xml:space="preserve">
<value>운모</value>
</data>
<data name="SettingsPageMicaAlt.Content" xml:space="preserve">
<value>운모 대체</value>
</data>
<data name="SettingsPageDesktopAcrylic.Content" xml:space="preserve">
<value>데스크탑 아크릴</value>
</data>
<data name="SettingsPageAcrylicBase.Content" xml:space="preserve">
<value>아크릴베이스</value>
</data>
<data name="SettingsPageAcrylicThin.Content" xml:space="preserve">
<value>아크릴 얇은</value>
</data>
<data name="SettingsPageTransparent.Content" xml:space="preserve">
<value>투명한</value>
</data>
<data name="SettingsPageBackdrop.Header" xml:space="preserve">
<value>배경</value>
</data>
<data name="SettingsPageSystemLanguage.Content" xml:space="preserve">
<value>기본</value>
</data>
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>변경 사항을 적용하려면 앱을 다시 시작하십시오</value>
</data>
<data name="SettingsPagePathNotFound.Text" xml:space="preserve">
<value>경로는 컴퓨터에서 찾을 수 없습니다</value>
</data>
<data name="SettingsPagePathExistedInfo" xml:space="preserve">
<value>폴더가 추가되었습니다. 다시 추가하지 마십시오.</value>
</data>
<data name="SettingsPageCoverOverlay.Header" xml:space="preserve">
<value>오버레이 앨범 아트 배경</value>
</data>
<data name="SettingsPageDynamicCoverOverlay.Header" xml:space="preserve">
<value>동적 앨범 아트 배경</value>
</data>
<data name="SettingsPageCoverOverlayOpacity.Header" xml:space="preserve">
<value>앨범 아트 배경 불투명도</value>
</data>
<data name="SettingsPageTitle" xml:space="preserve">
<value>설정 - BetterLyrics</value>
</data>
<data name="LyricsPageTitle" xml:space="preserve">
<value>BetterLyrics</value>
</data>
<data name="SettingsPageLyricsAlignment.Header" xml:space="preserve">
<value>조정</value>
</data>
<data name="SettingsPageLyricsCenter.Content" xml:space="preserve">
<value>센터</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageLyricsRight.Content" xml:space="preserve">
<value>오른쪽</value>
</data>
<data name="SettingsPageCoverOverlayBlurAmount.Header" xml:space="preserve">
<value>앨범 아트 배경 흐림 금액</value>
</data>
<data name="SettingsPageLyricsBlurAmount.Header" xml:space="preserve">
<value>흐림 금액</value>
</data>
<data name="SettingsPageLyricsBlurAmountSideEffect.Text" xml:space="preserve">
<value>이 값을 조정하면 앨범 이미지의 배경 흐림 강도가 증가합니다.</value>
</data>
<data name="SettingsPageSliderPrefix.Text" xml:space="preserve">
<value>현재 가치 :</value>
</data>
<data name="SettingsPageLyricsBlurHighGPUUsage.Text" xml:space="preserve">
<value>Blur가 활성화 될 때 상당히 높은 GPU 사용량 (&gt; 0)</value>
</data>
<data name="SettingsPageCoverOverlayGPUUsage.Text" xml:space="preserve">
<value>이 기능을 활성화하면 GPU 사용률이 약간 증가합니다</value>
</data>
<data name="SettingsPageLyricsVerticalEdgeOpacity.Header" xml:space="preserve">
<value>상단 및 하단 가장자리 불투명도</value>
</data>
<data name="SettingsPageLyricsLineSpacingFactor.Header" xml:space="preserve">
<value>라인 간격</value>
</data>
<data name="SettingsPageLyricsLineSpacingFactorUnit.Text" xml:space="preserve">
<value>X 라인 높이</value>
</data>
<data name="SettingsPageLyricsFontSize.Header" xml:space="preserve">
<value>글꼴 크기</value>
</data>
<data name="MainPageLyriscOnly.Content" xml:space="preserve">
<value>가사 만</value>
</data>
<data name="MainWindowImmersiveMode.ToolTipService.ToolTip" xml:space="preserve">
<value>몰입 형 모드</value>
</data>
<data name="SettingsPageAlbumOverlay.Content" xml:space="preserve">
<value>앨범 배경</value>
</data>
<data name="SettingsPageAbout.Content" xml:space="preserve">
<value>에 대한</value>
</data>
<data name="SettingsPageLyricsLib.Content" xml:space="preserve">
<value>가사 도서관</value>
</data>
<data name="SettingsPageAppAppearance.Content" xml:space="preserve">
<value>앱 모양</value>
</data>
<data name="SettingsPageLyricsGlowEffect.Header" xml:space="preserve">
<value>글로우 효과</value>
</data>
<data name="SettingsPageLyricsGlowEffectScope.Header" xml:space="preserve">
<value>글로우 효과 범위</value>
</data>
<data name="SettingsPageLyricsSearchProvidersConfig.Header" xml:space="preserve">
<value>가사 검색 제공 업체를 구성하십시오</value>
</data>
<data name="SettingsPageAddFolderButton.Content" xml:space="preserve">
<value>추가하다</value>
</data>
<data name="MainPageWelcomeTeachingTip.Title" xml:space="preserve">
<value>Betterlyrics에 오신 것을 환영합니다</value>
</data>
<data name="MainPageWelcomeTeachingTip.Subtitle" xml:space="preserve">
<value>지금 가사 데이터베이스를 설정합시다</value>
</data>
<data name="MainPageNoMusicPlaying.Text" xml:space="preserve">
<value>지금 음악이 재생되지 않습니다</value>
</data>
<data name="SettingsPageDev.Content" xml:space="preserve">
<value>개발자 옵션</value>
</data>
<data name="SettingsPageMockMusicPlaying.Header" xml:space="preserve">
<value>테스트 음악을 재생하십시오</value>
</data>
<data name="SettingsPagePlayingMockMusicButton.Content" xml:space="preserve">
<value>시스템 플레이어를 사용하여 재생하십시오</value>
</data>
<data name="SettingsPageLog.Header" xml:space="preserve">
<value>통나무</value>
</data>
<data name="SettingsPageLyricsFontColor.Header" xml:space="preserve">
<value>글꼴 색상</value>
</data>
<data name="SettingsPageLyricsFontColorDefault.Content" xml:space="preserve">
<value>기본</value>
</data>
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
<value>앨범 아트 악센트 색상</value>
</data>
<data name="SettingsPageAlbumStyle.Content" xml:space="preserve">
<value>앨범 아트 스타일</value>
</data>
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
<value>코너 반경</value>
</data>
<data name="SettingsPageTitleBarType.Header" xml:space="preserve">
<value>제목 바 크기</value>
</data>
<data name="SettingsPageCompactTitleBar.Content" xml:space="preserve">
<value>콤팩트</value>
</data>
<data name="SettingsPageExtendedTitleBar.Content" xml:space="preserve">
<value>펼친</value>
</data>
<data name="BaseWindowAOTFlyoutItem.Text" xml:space="preserve">
<value>항상 위에</value>
</data>
<data name="BaseWindowFullScreenFlyoutItem.Text" xml:space="preserve">
<value>전체 화면</value>
</data>
<data name="BaseWindowEnterFullScreenHint" xml:space="preserve">
<value>ESC를 눌러 전체 화면 모드를 종료하십시오</value>
</data>
<data name="MainPageEnterImmersiveModeHint" xml:space="preserve">
<value>토글 버튼을 표시하려면 다시 다시 가져옵니다</value>
</data>
<data name="BaseWindowHostInfoBarCheckBox.Content" xml:space="preserve">
<value>이 메시지를 다시 표시하지 마십시오</value>
</data>
<data name="MainPageNoLocalFilesMatched.Text" xml:space="preserve">
<value>로컬 파일이 일치하지 않습니다</value>
</data>
<data name="MainPageAlbumArtOnly.Content" xml:space="preserve">
<value>앨범 아트 만</value>
</data>
<data name="MainPageSplitView.Content" xml:space="preserve">
<value>분할보기</value>
</data>
<data name="MainPageDisplayTypeSwitcher.ToolTipService.ToolTip" xml:space="preserve">
<value>디스플레이 유형을 변경하십시오</value>
</data>
<data name="MainPageDesktopLyricsToggler.ToolTipService.ToolTip" xml:space="preserve">
<value>데스크탑 가사 모드로 전환하십시오</value>
</data>
<data name="BaseWindowMiniFlyoutItem.Text" xml:space="preserve">
<value>사진 인당 모드</value>
</data>
<data name="BaseWindowUnMiniFlyoutItem.Text" xml:space="preserve">
<value>Picture-in-Picture 모드 종료</value>
</data>
<data name="MainPageLyricsNotFound.Text" xml:space="preserve">
<value>가사를 찾을 수 없습니다</value>
</data>
<data name="SettingsPageLyricsEffect.Content" xml:space="preserve">
<value>가사 효과</value>
</data>
<data name="SettingsPageLyricsStyle.Content" xml:space="preserve">
<value>가사 스타일</value>
</data>
<data name="SettingsPagePathBeIncludedInfo" xml:space="preserve">
<value>이 폴더는 이미 기존 폴더에 포함되어 있으며 다시 추가 할 필요가 없습니다.</value>
</data>
<data name="SettingsPageAppBehavior.Content" xml:space="preserve">
<value>앱 동작</value>
</data>
<data name="SettingsPageAutoStartWindow.Header" xml:space="preserve">
<value>앱을 시작할 때</value>
</data>
<data name="SettingsPageAutoStartInAppLyrics.Content" xml:space="preserve">
<value>표준 모드를 ​​활성화합니다</value>
</data>
<data name="SettingsPageAutoStartDesktopLyrics.Content" xml:space="preserve">
<value>도크 모드를 활성화하십시오</value>
</data>
<data name="DesktopLyricsRendererPageLyricsNotFound.Text" xml:space="preserve">
<value>가사를 찾을 수 없습니다</value>
</data>
<data name="SystemTrayPageTitle" xml:space="preserve">
<value>시스템 트레이 - BetterLyrics</value>
</data>
<data name="HostWindowDockFlyoutItem.Text" xml:space="preserve">
<value>도크 모드</value>
</data>
<data name="SettingsPageLyricsFontWeight.Header" xml:space="preserve">
<value>글꼴 무게</value>
</data>
<data name="SettingsPageLyricsThin.Content" xml:space="preserve">
<value>얇은</value>
</data>
<data name="SettingsPageLyricsExtraLight.Content" xml:space="preserve">
<value>여분의 빛</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>빛</value>
</data>
<data name="SettingsPageLyricsSemiLight.Content" xml:space="preserve">
<value>반 빛</value>
</data>
<data name="SettingsPageLyricsNormal.Content" xml:space="preserve">
<value>정상</value>
</data>
<data name="SettingsPageLyricsMedium.Content" xml:space="preserve">
<value>중간</value>
</data>
<data name="SettingsPageLyricsSemiBold.Content" xml:space="preserve">
<value>반 대담한</value>
</data>
<data name="SettingsPageLyricsBold.Content" xml:space="preserve">
<value>용감한</value>
</data>
<data name="SettingsPageLyricsExtraBold.Content" xml:space="preserve">
<value>추가 대담한</value>
</data>
<data name="SettingsPageLyricsBlack.Content" xml:space="preserve">
<value>검은색</value>
</data>
<data name="SettingsPageLyricsExtraBlack.Content" xml:space="preserve">
<value>여분의 검은 색</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeWholeLyrics.Content" xml:space="preserve">
<value>전체 가사</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeCurrentLine.Content" xml:space="preserve">
<value>현재 라인</value>
</data>
<data name="SettingsPageLyricsGlowEffectScopeCurrentChar.Content" xml:space="preserve">
<value>현재 숯</value>
</data>
<data name="HostWindowSettingsFlyoutItem.Text" xml:space="preserve">
<value>설정</value>
</data>
<data name="MainPageLyricsLoading.Text" xml:space="preserve">
<value>가사로드 ...</value>
</data>
<data name="LyricsSearchProviderLocalLrcFile" xml:space="preserve">
<value>로컬 .LRC 파일</value>
</data>
<data name="LyricsSearchProviderLocalMusicFile" xml:space="preserve">
<value>로컬 음악 파일</value>
</data>
<data name="LyricsSearchProviderLrcLib" xml:space="preserve">
<value>LRCLIB</value>
</data>
<data name="LyricsSearchProviderQQMusic" xml:space="preserve">
<value>QQ 음악</value>
</data>
<data name="LyricsSearchProviderKugouMusic" xml:space="preserve">
<value>쿠구 음악</value>
</data>
<data name="SettingsPageJA.Content" xml:space="preserve">
<value>日本語</value>
</data>
<data name="SettingsPageKO.Content" xml:space="preserve">
<value>한국어</value>
</data>
</root>

View File

@@ -466,13 +466,13 @@
<value>加载歌词中...</value>
</data>
<data name="LyricsSearchProviderLocalLrcFile" xml:space="preserve">
<value>本地 .lrc 文件</value>
<value>本地 .LRC 文件</value>
</data>
<data name="LyricsSearchProviderLocalMusicFile" xml:space="preserve">
<value>本地音乐文件</value>
</data>
<data name="LyricsSearchProviderLrcLib" xml:space="preserve">
<value>LrcLib</value>
<value>LRCLIB</value>
</data>
<data name="LyricsSearchProviderQQMusic" xml:space="preserve">
<value>QQ 音乐</value>
@@ -480,4 +480,10 @@
<data name="LyricsSearchProviderKugouMusic" xml:space="preserve">
<value>酷狗音乐</value>
</data>
<data name="SettingsPageJA.Content" xml:space="preserve">
<value>日本語</value>
</data>
<data name="SettingsPageKO.Content" xml:space="preserve">
<value>한국어</value>
</data>
</root>

View File

@@ -472,7 +472,7 @@
<value>本地音樂文件</value>
</data>
<data name="LyricsSearchProviderLrcLib" xml:space="preserve">
<value>LrcLib</value>
<value>LRCLIB</value>
</data>
<data name="LyricsSearchProviderQQMusic" xml:space="preserve">
<value>QQ 音樂</value>
@@ -480,4 +480,10 @@
<data name="LyricsSearchProviderKugouMusic" xml:space="preserve">
<value>酷狗音乐</value>
</data>
<data name="SettingsPageJA.Content" xml:space="preserve">
<value>日本語</value>
</data>
<data name="SettingsPageKO.Content" xml:space="preserve">
<value>한국어</value>
</data>
</root>

View File

@@ -96,24 +96,15 @@ namespace BetterLyrics.WinUI3.ViewModels
private readonly int _lineEnteringDurationMs = 800;
private readonly int _lineExitingDurationMs = 800;
private readonly int _lineScrollDurationMs = 800;
private float _lastTotalYScroll = 0.0f;
private float _totalYScroll = 0.0f;
private int _startVisibleLineIndex = -1;
private int _endVisibleLineIndex = -1;
private bool _forceToScroll = false;
private readonly float _lyricsGlowEffectAmount = 6f;
private readonly double _rightMargin = 36;
private readonly float _topMargin = 0f;
[ObservableProperty]
public partial double LimitedLineWidth { get; set; }
private protected bool _isRelayoutNeeded = true;
[ObservableProperty]
@@ -156,6 +147,20 @@ namespace BetterLyrics.WinUI3.ViewModels
interpolator: (from, to, progress) => from + (to - from) * progress
);
private readonly ValueTransition<float> _canvasYScrollTransition = new(
initialValue: 0f,
durationSeconds: 0.8f,
interpolator: (from, to, progress) =>
from + (to - from) * EasingHelper.SmootherStep(progress)
);
private readonly ValueTransition<float> _limitedLineWidthTransition = new(
initialValue: 0f,
durationSeconds: 0.8f,
interpolator: (from, to, progress) =>
from + (to - from) * EasingHelper.SmootherStep(progress)
);
public LyricsRendererViewModel(
ISettingsService settingsService,
IPlaybackService playbackService,
@@ -215,25 +220,31 @@ namespace BetterLyrics.WinUI3.ViewModels
_lyrics = [];
_isRelayoutNeeded = true;
LyricsStatus = LyricsStatus.Loading;
(var lyricsRaw, var lyricsFormat) = await _musicSearchService.SearchLyricsAsync(
SongInfo?.Title ?? "",
SongInfo?.Artist ?? "",
SongInfo?.Album ?? "",
SongInfo?.DurationMs ?? 0
);
string? lyricsRaw = null;
LyricsFormat? lyricsFormat = null;
if (SongInfo != null)
{
(lyricsRaw, lyricsFormat) = await _musicSearchService.SearchLyricsAsync(
SongInfo.Title,
SongInfo.Artist,
SongInfo.Album ?? "",
SongInfo.DurationMs ?? 0
);
}
if (lyricsRaw == null)
{
LyricsStatus = LyricsStatus.NotFound;
}
else
else if (SongInfo != null)
{
_lyrics = new LyricsParser().Parse(
lyricsRaw,
lyricsFormat,
SongInfo.Title,
SongInfo.Artist,
(int)(SongInfo.DurationMs)
(int)(SongInfo.DurationMs ?? 0)
);
_isRelayoutNeeded = true;
LyricsStatus = LyricsStatus.Found;
@@ -267,18 +278,8 @@ namespace BetterLyrics.WinUI3.ViewModels
TotalTime = _playbackService.Position;
}
partial void OnLimitedLineWidthChanged(double value)
{
_isRelayoutNeeded = true;
}
async partial void OnSongInfoChanged(SongInfo? oldValue, SongInfo? newValue)
{
if (oldValue?.Title == newValue?.Title && oldValue?.Artist == newValue?.Artist)
{
return;
}
TotalTime = TimeSpan.Zero;
_lastAlbumArtBitmap = _albumArtBitmap;
@@ -426,7 +427,7 @@ namespace BetterLyrics.WinUI3.ViewModels
control,
line?.Text,
_textFormat,
(float)LimitedLineWidth,
(float)_limitedLineWidthTransition.Value,
(float)control.Size.Height
);
@@ -444,11 +445,11 @@ namespace BetterLyrics.WinUI3.ViewModels
break;
case LyricsAlignmentType.Center:
textLayout.HorizontalAlignment = CanvasHorizontalAlignment.Center;
centerX += (float)LimitedLineWidth / 2;
centerX += (float)_limitedLineWidthTransition.Value / 2;
break;
case LyricsAlignmentType.Right:
textLayout.HorizontalAlignment = CanvasHorizontalAlignment.Right;
centerX += (float)LimitedLineWidth;
centerX += (float)_limitedLineWidthTransition.Value;
break;
default:
break;
@@ -530,8 +531,10 @@ namespace BetterLyrics.WinUI3.ViewModels
ds.Transform =
Matrix3x2.CreateScale(line.Scale, new Vector2(centerX, centerY))
* Matrix3x2.CreateTranslation(
(float)(control.Size.Width - _rightMargin - LimitedLineWidth),
_totalYScroll + (float)(control.Size.Height / 2)
(float)(
control.Size.Width - _rightMargin - _limitedLineWidthTransition.Value
),
_canvasYScrollTransition.Value + (float)(control.Size.Height / 2)
);
ds.DrawTextLayout(textLayout, position, Colors.Transparent);
@@ -855,6 +858,10 @@ namespace BetterLyrics.WinUI3.ViewModels
ds.FillRectangle(new Rect(0, 0, control.Size.Width, control.Size.Height), maskBrush);
}
/// <summary>
/// Reassigns positions (x,y) to lyrics lines based on the current control size and font size.
/// </summary>
/// <param name="control"></param>
private void ReLayout(ICanvasAnimatedControl control)
{
if (control == null)
@@ -874,7 +881,7 @@ namespace BetterLyrics.WinUI3.ViewModels
control,
line.Text,
_textFormat,
(float)LimitedLineWidth,
(float)_limitedLineWidthTransition.Value,
(float)control.Size.Height
);
line.Position = new Vector2(0, y);
@@ -911,17 +918,20 @@ namespace BetterLyrics.WinUI3.ViewModels
_rotateAngle %= MathF.PI * 2;
}
if (_limitedLineWidthTransition.IsTransitioning)
{
_limitedLineWidthTransition.Update(ElapsedTime);
_isRelayoutNeeded = true;
}
if (_isRelayoutNeeded)
{
ReLayout(control);
_isRelayoutNeeded = false;
_forceToScroll = true;
}
int currentPlayingLineIndex = GetCurrentPlayingLineIndex();
UpdateLinesProps(_lyrics, currentPlayingLineIndex, _defaultOpacity);
UpdateCanvasYScrollOffset(control, currentPlayingLineIndex);
UpdateLinesProps(_lyrics, _defaultOpacity);
UpdateCanvasYScrollOffset(control);
if (IsLyricsGlowEffectEnabled)
{
@@ -932,10 +942,10 @@ namespace BetterLyrics.WinUI3.ViewModels
case LyricsGlowEffectScope.WholeLyrics:
break;
case LyricsGlowEffectScope.CurrentLine:
UpdateLinesProps(_lyricsForGlowEffect, currentPlayingLineIndex, 0);
UpdateLinesProps(_lyricsForGlowEffect, 0);
break;
case LyricsGlowEffectScope.CurrentChar:
UpdateLinesProps(_lyricsForGlowEffect, currentPlayingLineIndex, 0);
UpdateLinesProps(_lyricsForGlowEffect, 0);
break;
default:
break;
@@ -998,21 +1008,22 @@ namespace BetterLyrics.WinUI3.ViewModels
return playProgress;
}
private void UpdateLinesProps(
List<LyricsLine>? source,
int currentPlayingLineIndex,
float defaultOpacity
)
private void UpdateLinesProps(List<LyricsLine>? source, float defaultOpacity)
{
var (startLineIndex, endLineIndex) = GetMaxLyricsLineIndexBoundaries();
var currentPlayingLineIndex = GetCurrentPlayingLineIndex();
for (int i = startLineIndex; source?.Count > 0 && i <= endLineIndex; i++)
{
var line = source?[i];
bool linePlaying = i == currentPlayingLineIndex;
var lineEnteringDurationMs = Math.Min(line.DurationMs, _lineEnteringDurationMs);
var lineEnteringDurationMs = Math.Min(
line?.DurationMs ?? 0,
_lineEnteringDurationMs
);
var lineExitingDurationMs = _lineExitingDurationMs;
if (i + 1 <= endLineIndex)
{
@@ -1092,11 +1103,9 @@ namespace BetterLyrics.WinUI3.ViewModels
}
}
private void UpdateCanvasYScrollOffset(
ICanvasAnimatedControl control,
int currentPlayingLineIndex
)
private void UpdateCanvasYScrollOffset(ICanvasAnimatedControl control)
{
var currentPlayingLineIndex = GetCurrentPlayingLineIndex();
if (currentPlayingLineIndex < 0)
{
return;
@@ -1121,40 +1130,25 @@ namespace BetterLyrics.WinUI3.ViewModels
control,
currentPlayingLine.Text,
_textFormat,
(float)LimitedLineWidth,
(float)_limitedLineWidthTransition.Value,
(float)control.Size.Height
);
var lineScrollingProgress =
(TotalTime.TotalMilliseconds - currentPlayingLine.StartMs)
/ Math.Min(_lineScrollDurationMs, currentPlayingLine.DurationMs);
float targetYScrollOffset =
(float?)(
-currentPlayingLine.Position.Y
+ _lyrics?[0].Position.Y
- playingTextLayout.LayoutBounds.Height / 2
- _lastTotalYScroll
) ?? 0f;
var yScrollOffset =
targetYScrollOffset
* EasingHelper.SmootherStep((float)Math.Min(1, lineScrollingProgress));
bool isScrollingNow = lineScrollingProgress <= 1;
if (isScrollingNow)
if (!_canvasYScrollTransition.IsTransitioning)
{
_totalYScroll = _lastTotalYScroll + yScrollOffset;
_canvasYScrollTransition.StartTransition(targetYScrollOffset);
}
else
if (_canvasYScrollTransition.IsTransitioning)
{
if (_forceToScroll && Math.Abs(targetYScrollOffset) >= 1)
{
_totalYScroll = _lastTotalYScroll + targetYScrollOffset;
_forceToScroll = false;
}
_lastTotalYScroll = _totalYScroll;
_canvasYScrollTransition.Update(ElapsedTime);
}
_startVisibleLineIndex = _endVisibleLineIndex = -1;
@@ -1168,12 +1162,12 @@ namespace BetterLyrics.WinUI3.ViewModels
control,
line?.Text,
_textFormat,
(float)LimitedLineWidth,
(float)_limitedLineWidthTransition.Value,
(float)control.Size.Height
);
if (
_totalYScroll
_canvasYScrollTransition.Value
+ (float)(control.Size.Height / 2)
+ line.Position.Y
+ textLayout.LayoutBounds.Height
@@ -1186,7 +1180,7 @@ namespace BetterLyrics.WinUI3.ViewModels
}
}
if (
_totalYScroll
_canvasYScrollTransition.Value
+ (float)(control.Size.Height / 2)
+ line.Position.Y
+ textLayout.LayoutBounds.Height
@@ -1370,7 +1364,7 @@ namespace BetterLyrics.WinUI3.ViewModels
{
if (message.PropertyName == nameof(LyricsPageViewModel.LimitedLineWidth))
{
LimitedLineWidth = message.NewValue;
_limitedLineWidthTransition.StartTransition((float)message.NewValue);
}
}
}

View File

@@ -13,7 +13,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml;
using Newtonsoft.Json.Linq;
using Windows.ApplicationModel.Core;
using Windows.Globalization;
using Windows.Media.Playback;
@@ -126,6 +125,12 @@ namespace BetterLyrics.WinUI3.ViewModels
case Enums.Language.TraditionalChinese:
ApplicationLanguages.PrimaryLanguageOverride = "zh-TW";
break;
case Enums.Language.Japanese:
ApplicationLanguages.PrimaryLanguageOverride = "ja-JP";
break;
case Enums.Language.Korean:
ApplicationLanguages.PrimaryLanguageOverride = "ko-KR";
break;
default:
break;
}

View File

@@ -130,44 +130,41 @@
</controls:SettingsExpander.ItemsFooter>
</controls:SettingsExpander>
<Grid>
<controls:SettingsExpander
x:Name="LyricsSearchProvidersSettingsExpander"
x:Uid="SettingsPageLyricsSearchProvidersConfig"
VerticalAlignment="Top"
Collapsed="LyricsSearchProvidersSettingsExpander_Collapsed"
Expanded="LyricsSearchProvidersSettingsExpander_Expanded"
HeaderIcon="{ui:FontIcon Glyph=&#xF6FA;}"
IsExpanded="True" />
<ListView
x:Name="LyricsSearchProvidersListView"
Margin="0,70,0,0"
AllowDrop="True"
CanDragItems="True"
CanReorderItems="True"
DragItemsCompleted="LyricsSearchProvidersListView_DragItemsCompleted"
ItemsSource="{x:Bind ViewModel.LyricsSearchProvidersInfo, Mode=OneWay}"
Opacity="1"
SelectionMode="None">
<ListView.OpacityTransition>
<ScalarTransition />
</ListView.OpacityTransition>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:LyricsSearchProviderInfo">
<controls:SettingsCard Padding="60,0,48,0" Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" Toggled="LyricsSearchProviderToggleSwitch_Toggled" />
</controls:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<controls:SettingsExpander
x:Name="LyricsSearchProvidersSettingsExpander"
x:Uid="SettingsPageLyricsSearchProvidersConfig"
VerticalAlignment="Top"
HeaderIcon="{ui:FontIcon Glyph=&#xF6FA;}"
IsExpanded="True">
<controls:SettingsExpander.Items>
<ListView
x:Name="LyricsSearchProvidersListView"
AllowDrop="True"
CanDragItems="True"
CanReorderItems="True"
DragItemsCompleted="LyricsSearchProvidersListView_DragItemsCompleted"
ItemsSource="{x:Bind ViewModel.LyricsSearchProvidersInfo, Mode=OneWay}"
SelectionMode="None">
<ListView.OpacityTransition>
<ScalarTransition />
</ListView.OpacityTransition>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="models:LyricsSearchProviderInfo">
<controls:SettingsCard Padding="60,0,48,0" Header="{Binding Provider, Converter={StaticResource LyricsSearchProviderToDisplayNameConverter}, Mode=OneWay}">
<ToggleSwitch IsOn="{Binding IsEnabled, Mode=TwoWay}" Toggled="LyricsSearchProviderToggleSwitch_Toggled" />
</controls:SettingsCard>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</controls:SettingsExpander.Items>
</controls:SettingsExpander>
</StackPanel>
</controls:Case>
@@ -188,8 +185,6 @@
<ComboBoxItem x:Uid="SettingsPageMica" />
<ComboBoxItem x:Uid="SettingsPageMicaAlt" />
<ComboBoxItem x:Uid="SettingsPageDesktopAcrylic" />
<!--<ComboBoxItem x:Uid="SettingsPageAcrylicThin" />
<ComboBoxItem x:Uid="SettingsPageAcrylicBase" />-->
<ComboBoxItem x:Uid="SettingsPageTransparent" />
</ComboBox>
</controls:SettingsCard>
@@ -210,6 +205,8 @@
<ComboBoxItem x:Uid="SettingsPageEN" />
<ComboBoxItem x:Uid="SettingsPageSC" />
<ComboBoxItem x:Uid="SettingsPageTC" />
<ComboBoxItem x:Uid="SettingsPageJA" />
<ComboBoxItem x:Uid="SettingsPageKO" />
</ComboBox>
<controls:SettingsExpander.Items>
<controls:SettingsCard>

View File

@@ -63,31 +63,6 @@ namespace BetterLyrics.WinUI3.Views
}
}
private void LyricsSearchProvidersSettingsExpander_Expanded(
object sender,
System.EventArgs e
)
{
if (LyricsSearchProvidersListView != null)
{
LyricsSearchProvidersListView.Visibility = Visibility.Visible;
LyricsSearchProvidersListView.Opacity = 1;
}
}
private async void LyricsSearchProvidersSettingsExpander_Collapsed(
object sender,
System.EventArgs e
)
{
if (LyricsSearchProvidersListView != null)
{
LyricsSearchProvidersListView.Opacity = 0;
await Task.Delay(300);
LyricsSearchProvidersListView.Visibility = Visibility.Collapsed;
}
}
private void LyricsSearchProvidersListView_DragItemsCompleted(
ListViewBase sender,
DragItemsCompletedEventArgs args