feat: implement locale switch.

This commit is contained in:
rabbitism
2024-01-28 00:12:35 +08:00
parent e18534d9b2
commit f0c8d5dba5
9 changed files with 113 additions and 34 deletions

View File

@@ -1,9 +1,10 @@
<Application
x:Class="Ursa.Demo.App"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u-semi="https://irihi.tech/ursa/themes/semi">
<Application.Styles>
<StyleInclude Source="avares://Semi.Avalonia/Themes/Index.axaml" />
<StyleInclude Source="avares://Ursa.Themes.Semi/Index.axaml" />
<u-semi:SemiTheme Locale="en-US"/>
</Application.Styles>
</Application>

View File

@@ -115,7 +115,7 @@ public class MessageBoxDemoViewModel: ObservableObject
private async Task OnOkCancelAsync()
{
await Show(MessageBoxButton.OK);
await Show(MessageBoxButton.OKCancel);
}
private async Task Show(MessageBoxButton button)

View File

@@ -0,0 +1,4 @@
using Avalonia.Metadata;
[assembly:XmlnsPrefix("https://irihi.tech/ursa/themes/semi", "u-semi")]
[assembly:XmlnsDefinition("https://irihi.tech/ursa/themes/semi", "Ursa.Themes.Semi")]

View File

@@ -52,7 +52,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
Header="Bring Forward">
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -63,7 +63,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
Header="Bring To Front">
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -74,7 +74,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
Header="Send Backward">
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -85,7 +85,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
Header="Send To Back">
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -161,24 +161,24 @@
Name="{x:Static u:DefaultDialogControl.PART_CancelButton}"
Margin="8,0,0,0"
Classes="Tertiary"
Content="取消" />
Content="{DynamicResource STRING_MENU_DIALOG_CANCEL}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_NoButton}"
Margin="8,0,0,0"
Classes="Danger"
Content=""
Content="{DynamicResource STRING_MENU_DIALOG_NO}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_YesButton}"
Margin="8,0,0,0"
Classes="Primary"
Content=""
Content="{DynamicResource STRING_MENU_DIALOG_YES}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_OKButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="确认"
Content="{DynamicResource STRING_MENU_DIALOG_OK}"
Theme="{DynamicResource SolidButton}" />
</StackPanel>
</Grid>
@@ -311,7 +311,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.BringForward}"
Header="Bring Forward">
Header="{DynamicResource STRING_MENU_BRING_FORWARD}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -322,7 +322,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.BringToFront}"
Header="Bring To Front">
Header="{DynamicResource STRING_MENU_BRING_TO_FRONT}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -333,7 +333,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.SendBackward}"
Header="Send Backward">
Header="{DynamicResource STRING_MENU_SEND_BACKWARD}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -344,7 +344,7 @@
<MenuItem
Command="{Binding $parent[u:DialogControl].UpdateLayer}"
CommandParameter="{x:Static u:DialogLayerChangeType.SendToBack}"
Header="Send To Back">
Header="{DynamicResource STRING_MENU_SEND_TO_BACK}">
<MenuItem.Icon>
<PathIcon
Width="12"
@@ -492,24 +492,24 @@
Name="{x:Static u:DefaultDialogControl.PART_CancelButton}"
Margin="8,0,0,0"
Classes="Tertiary"
Content="取消" />
Content="{DynamicResource STRING_MENU_DIALOG_CANCEL}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_NoButton}"
Margin="8,0,0,0"
Classes="Danger"
Content=""
Content="{DynamicResource STRING_MENU_DIALOG_NO}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_YesButton}"
Margin="8,0,0,0"
Classes="Primary"
Content=""
Content="{DynamicResource STRING_MENU_DIALOG_YES}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:DefaultDialogControl.PART_OKButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="确认"
Content="{DynamicResource STRING_MENU_DIALOG_OK}"
Theme="{DynamicResource SolidButton}" />
</StackPanel>
</Grid>

View File

@@ -88,24 +88,24 @@
Name="{x:Static u:MessageBoxWindow.PART_CancelButton}"
Margin="8,0,0,0"
Classes="Tertiary"
Content="Cancel" />
Content="{DynamicResource STRING_MENU_DIALOG_CANCEL}" />
<Button
Name="{x:Static u:MessageBoxWindow.PART_NoButton}"
Margin="8,0,0,0"
Classes="Danger"
Content="No"
Content="{DynamicResource STRING_MENU_DIALOG_NO}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:MessageBoxWindow.PART_YesButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="Yes"
Content="{DynamicResource STRING_MENU_DIALOG_YES}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:MessageBoxWindow.PART_OKButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="OK"
Content="{DynamicResource STRING_MENU_DIALOG_OK}"
Theme="{DynamicResource SolidButton}" />
</StackPanel>
</Grid>
@@ -219,24 +219,24 @@
Name="{x:Static u:MessageBoxControl.PART_CancelButton}"
Margin="8,0,0,0"
Classes="Tertiary"
Content="Cancel" />
Content="{DynamicResource STRING_MENU_DIALOG_CANCEL}" />
<Button
Name="{x:Static u:MessageBoxControl.PART_NoButton}"
Margin="8,0,0,0"
Classes="Danger"
Content="No"
Content="{DynamicResource STRING_MENU_DIALOG_NO}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:MessageBoxControl.PART_YesButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="Yes"
Content="{DynamicResource STRING_MENU_DIALOG_YES}"
Theme="{DynamicResource SolidButton}" />
<Button
Name="{x:Static u:MessageBoxControl.PART_OKButton}"
Margin="8,0,0,0"
Classes="Primary"
Content="OK"
Content="{DynamicResource STRING_MENU_DIALOG_OK}"
Theme="{DynamicResource SolidButton}" />
</StackPanel>
</Grid>

View File

@@ -1,9 +1,4 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Design.PreviewWith>
<Border Padding="20">
<!-- Add Controls for Previewer Here -->
</Border>
</Design.PreviewWith>
<Styles x:Class="Ursa.Themes.Semi.SemiTheme" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
@@ -13,11 +8,11 @@
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="../Controls/_index.axaml" />
<ResourceInclude Source="Themes/Shared/_index.axaml" />
<ResourceInclude Source="Locale/zh-cn.axaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Styles.Resources>
<StyleInclude Source="../Styles/_index.axaml" />
<!-- Add Styles Here -->
</Styles>

View File

@@ -0,0 +1,55 @@
using System.Globalization;
using System.Runtime.CompilerServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Platform;
using Avalonia.Styling;
namespace Ursa.Themes.Semi;
public class SemiTheme: Styles
{
private static readonly Dictionary<CultureInfo, string> _localeToResource = new()
{
{ new CultureInfo("zh-CN"), "avares://Ursa.Themes.Semi/Locale/zh-CN.axaml" },
{ new CultureInfo("en-US"), "avares://Ursa.Themes.Semi/Locale/en-US.axaml" },
};
private readonly IServiceProvider? sp;
public SemiTheme(IServiceProvider? provider = null)
{
AvaloniaXamlLoader.Load(provider, this);
}
private CultureInfo? _locale;
public CultureInfo? Locale
{
get => _locale;
set
{
_locale = value;
var resource = TryGetLocaleResource(value);
var d = AvaloniaXamlLoader.Load(sp, new Uri(resource)) as ResourceDictionary;
foreach (var kv in d)
{
this.Resources.Add(kv);
}
}
}
private string TryGetLocaleResource(CultureInfo? locale)
{
if (locale is null)
{
return _localeToResource[new CultureInfo("zh-CN")];
}
if (_localeToResource.TryGetValue(locale, out var resource))
{
return resource;
}
return _localeToResource[new CultureInfo("zh-CN")];
}
}

View File

@@ -0,0 +1,12 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Add Resources Here -->
<x:String x:Key="STRING_MENU_BRING_TO_FRONT">Bring to Front</x:String>
<x:String x:Key="STRING_MENU_BRING_FORWARD">Bring Forward</x:String>
<x:String x:Key="STRING_MENU_SEND_BACKWARD">Send Backward</x:String>
<x:String x:Key="STRING_MENU_SEND_TO_BACK">Send to Back</x:String>
<x:String x:Key="STRING_MENU_DIALOG_OK">OK</x:String>
<x:String x:Key="STRING_MENU_DIALOG_CANCEL">Cancel</x:String>
<x:String x:Key="STRING_MENU_DIALOG_YES">Yes</x:String>
<x:String x:Key="STRING_MENU_DIALOG_NO">No</x:String>
</ResourceDictionary>

View File

@@ -0,0 +1,12 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Add Resources Here -->
<x:String x:Key="STRING_MENU_BRING_TO_FRONT">置于顶层</x:String>
<x:String x:Key="STRING_MENU_BRING_FORWARD">上移一层</x:String>
<x:String x:Key="STRING_MENU_SEND_BACKWARD">下移一层</x:String>
<x:String x:Key="STRING_MENU_SEND_TO_BACK">置于底层</x:String>
<x:String x:Key="STRING_MENU_DIALOG_OK">确认</x:String>
<x:String x:Key="STRING_MENU_DIALOG_CANCEL">取消</x:String>
<x:String x:Key="STRING_MENU_DIALOG_YES">是</x:String>
<x:String x:Key="STRING_MENU_DIALOG_NO">否</x:String>
</ResourceDictionary>