Add Fluent.Net sample to DiscoHawk
This commit is contained in:
parent
0dc08f721c
commit
ac27453478
|
@ -3,6 +3,7 @@
|
|||
<PackageVersion Include="CommunityToolkit.HighPerformance" Version="8.4.0" />
|
||||
<PackageVersion Include="Cyotek.Drawing.BitmapFont" Version="2.0.4" />
|
||||
<PackageVersion Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.59" />
|
||||
<PackageVersion Include="Fluent.Net" Version="1.0.63" />
|
||||
<PackageVersion Include="Google.FlatBuffers" Version="23.5.26" /> <!-- last version with .NET Standard 2.0 support -->
|
||||
<PackageVersion Include="ImGui.NET" Version="1.90.6.1" />
|
||||
<PackageVersion Include="JunitXml.TestLogger" Version="3.1.12" />
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fluent.Net" PrivateAssets="all" />
|
||||
<ProjectReference Include="$(ProjectDir)../BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj" />
|
||||
<Content Include="discohawk.ico" />
|
||||
<EmbeddedResource Include="discohawk.ico" />
|
||||
<EmbeddedResource Include="locale/*.ftl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="About.cs" SubType="Form" />
|
||||
|
|
|
@ -114,6 +114,8 @@ namespace BizHawk.Client.DiscoHawk
|
|||
}
|
||||
}
|
||||
|
||||
Sample.RunAll(); // testing Fluent.Net
|
||||
|
||||
// Do something for visuals, I guess
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
#nullable enable
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using Fluent.Net;
|
||||
|
||||
namespace BizHawk.Client.DiscoHawk
|
||||
{
|
||||
public sealed class ArgsDict : Dictionary<string, object?>
|
||||
{
|
||||
public ArgsDict(int? tabCount = null)
|
||||
{
|
||||
Add(nameof(tabCount), tabCount);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct MultiMessageContext
|
||||
{
|
||||
private static IReadOnlyList<MessageContext> ReadEmbeddedAndConcat(string lang, MessageContext[] overlays)
|
||||
{
|
||||
MessageContext mc = new(lang, new() { UseIsolating = false });
|
||||
Stream embeddedStream;
|
||||
try
|
||||
{
|
||||
embeddedStream = ReflectionCache.EmbeddedResourceStream($"locale.{lang}.ftl");
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
return overlays;
|
||||
}
|
||||
using StreamReader sr = new(embeddedStream);
|
||||
var errors = mc.AddMessages(sr);
|
||||
foreach (var error in errors) Console.WriteLine(error);
|
||||
return [ ..overlays, mc ];
|
||||
}
|
||||
|
||||
private readonly IReadOnlyList<MessageContext> _contexts;
|
||||
|
||||
public readonly CultureInfo Culture;
|
||||
|
||||
public MultiMessageContext(IReadOnlyList<MessageContext> contexts)
|
||||
{
|
||||
_contexts = contexts;
|
||||
Culture = new(_contexts.FirstOrDefault()?.Locales?.First());
|
||||
}
|
||||
|
||||
public MultiMessageContext(string lang, params MessageContext[] overlays)
|
||||
: this(ReadEmbeddedAndConcat(lang, overlays)) {}
|
||||
|
||||
public string? this[string id]
|
||||
=> GetString(id);
|
||||
|
||||
public string? GetString(
|
||||
string id,
|
||||
IDictionary<string, object?>? args = null,
|
||||
ICollection<FluentError>? errors = null)
|
||||
{
|
||||
foreach (var context in _contexts)
|
||||
{
|
||||
var msg = context.GetMessage(id);
|
||||
if (msg is not null) return context.Format(msg, args, errors);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Sample
|
||||
{
|
||||
public static void RunAll()
|
||||
{
|
||||
static void RunTest(string lang)
|
||||
{
|
||||
MultiMessageContext translator = new(lang);
|
||||
Console.WriteLine($"\n{lang}:");
|
||||
Console.WriteLine($"tabs-close-button = {translator.GetString("tabs-close-button")}");
|
||||
Console.WriteLine(
|
||||
"tabs-close-tooltip ($tabCount = 1) = "
|
||||
+ translator.GetString("tabs-close-tooltip", new ArgsDict(tabCount: 1)));
|
||||
Console.WriteLine(
|
||||
"tabs-close-tooltip ($tabCount = 2) = "
|
||||
+ translator.GetString("tabs-close-tooltip", new ArgsDict(tabCount: 2)));
|
||||
Console.WriteLine(
|
||||
"tabs-close-warning ($tabCount = 1) = "
|
||||
+ translator.GetString("tabs-close-warning", new ArgsDict(tabCount: 1)));
|
||||
Console.WriteLine(
|
||||
"tabs-close-warning ($tabCount = 2) = "
|
||||
+ translator.GetString("tabs-close-warning", new ArgsDict(tabCount: 2)));
|
||||
Console.WriteLine($"sync-dialog-title = {translator.GetString("sync-dialog-title")}");
|
||||
Console.WriteLine($"sync-headline-title = {translator.GetString("sync-headline-title")}");
|
||||
Console.WriteLine($"sync-signedout-title = {translator.GetString("sync-signedout-title")}");
|
||||
}
|
||||
RunTest("en");
|
||||
RunTest("it");
|
||||
RunTest("pl");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
## Closing tabs
|
||||
|
||||
tabs-close-button = Close
|
||||
tabs-close-tooltip = {$tabCount ->
|
||||
[one] Close {$tabCount} tab
|
||||
*[other] Close {$tabCount} tabs
|
||||
}
|
||||
tabs-close-warning =
|
||||
You are about to close {$tabCount} tabs.
|
||||
Are you sure you want to continue?
|
||||
|
||||
## Syncing
|
||||
|
||||
-sync-brand-name = Firefox Account
|
||||
|
||||
sync-dialog-title = {-sync-brand-name}
|
||||
sync-headline-title =
|
||||
{-sync-brand-name}: The best way to bring
|
||||
your data always with you
|
||||
sync-signedout-title =
|
||||
Connect with your {-sync-brand-name}
|
||||
|
||||
## Datetime
|
||||
date-is = The date is 'DATETIME($dt, weekday: "short", month: "short", year: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric")'.
|
|
@ -0,0 +1,23 @@
|
|||
## Closing tabs
|
||||
|
||||
tabs-close-button = Chiudi
|
||||
tabs-close-tooltip = {$tabCount ->
|
||||
[one] Chiudi {$tabCount} scheda
|
||||
*[other] Chiudi {$tabCount} schede
|
||||
}
|
||||
tabs-close-warning =
|
||||
Verranno chiuse {$tabCount} schede. Proseguire?
|
||||
|
||||
## Syncing
|
||||
|
||||
-sync-brand-name = {$first ->
|
||||
*[uppercase] Account Firefox
|
||||
[lowercase] account Firefox
|
||||
}
|
||||
|
||||
sync-dialog-title = {-sync-brand-name}
|
||||
sync-headline-title =
|
||||
{-sync-brand-name}: il modo migliore
|
||||
per avere i tuoi dati sempre con te
|
||||
sync-signedout-title =
|
||||
Connetti il tuo {-sync-brand-name[lowercase]}
|
|
@ -0,0 +1,29 @@
|
|||
## Closing tabs
|
||||
|
||||
tabs-close-button = Zamknij
|
||||
tabs-close-tooltip = {$tabCount ->
|
||||
[one] Zamknij kartę
|
||||
[few] Zamknij {$tabCount} karty
|
||||
*[many] Zamknij { $tabCount } kart
|
||||
}
|
||||
tabs-close-warning = {$tabCount ->
|
||||
[few] Zostaną zamknięte {$tabCount} karty.
|
||||
Czy chcesz kontynuować?
|
||||
*[many] Zostanie zamkniętych {$tabCount} kart.
|
||||
Czy chcesz kontynuować?
|
||||
}
|
||||
|
||||
## Syncing
|
||||
|
||||
-sync-brand-name = {$case ->
|
||||
*[nominative] Konto Firefox
|
||||
[genitive] Konta Firefox
|
||||
[accusative] Kontem Firefox
|
||||
}
|
||||
|
||||
sync-dialog-title = {-sync-brand-name}
|
||||
sync-headline-title =
|
||||
{-sync-brand-name}: Najlepszy sposób na to,
|
||||
aby mieć swoje dane zawsze przy sobie
|
||||
sync-signedout-title =
|
||||
Zaloguj do {-sync-brand-name[genitive]}
|
Loading…
Reference in New Issue