mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Draft: localisation support
this is a draft as i can't fully test this right now because i'm currently 37000 feet in the air and a 75 MB data quota costs 10 bucks :( this also may be the first documented instance of me using wpf 100% properly as bill gates himself intended
This commit is contained in:
parent
36d8d5fbf4
commit
81d7ffe3da
@ -29,7 +29,7 @@ namespace Bloxstrap
|
||||
|
||||
public static LaunchSettings LaunchSettings { get; private set; } = null!;
|
||||
|
||||
public static CultureInfo CurrentCulture { get; private set; } = CultureInfo.InvariantCulture;
|
||||
public static CultureInfo CurrentCulture { get; set; } = CultureInfo.InvariantCulture;
|
||||
|
||||
public static BuildMetadataAttribute BuildMetadata = Assembly.GetExecutingAssembly().GetCustomAttribute<BuildMetadataAttribute>()!;
|
||||
public static string Version = Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
@ -113,8 +113,7 @@ namespace Bloxstrap
|
||||
{
|
||||
const string LOG_IDENT = "App::OnStartup";
|
||||
|
||||
CultureInfo.DefaultThreadCurrentUICulture = CurrentCulture;
|
||||
Thread.CurrentThread.CurrentUICulture = CurrentCulture;
|
||||
CurrentCulture = Thread.CurrentThread.CurrentUICulture;
|
||||
|
||||
base.OnStartup(e);
|
||||
|
||||
@ -147,6 +146,7 @@ namespace Bloxstrap
|
||||
Settings.Load();
|
||||
State.Load();
|
||||
FastFlags.Load();
|
||||
Locale.Set();
|
||||
}
|
||||
|
||||
LaunchSettings.ParseRoblox();
|
||||
|
@ -302,6 +302,16 @@ namespace Bloxstrap
|
||||
_launchCommandLine += "production";
|
||||
else
|
||||
_launchCommandLine += App.Settings.Prop.Channel.ToLowerInvariant();
|
||||
|
||||
if (App.Settings.Prop.ForceRobloxLanguage)
|
||||
{
|
||||
if (_launchCommandLine.StartsWith("roblox-player:1"))
|
||||
_launchCommandLine += "+robloxLocale:";
|
||||
else
|
||||
_launchCommandLine += " -robloxLocale ";
|
||||
|
||||
_launchCommandLine += App.CurrentCulture.Name.Replace('-', '_');
|
||||
}
|
||||
}
|
||||
|
||||
// whether we should wait for roblox to exit to handle stuff in the background or clean up after roblox closes
|
||||
|
@ -130,6 +130,7 @@ namespace Bloxstrap
|
||||
App.IsSetupComplete = false;
|
||||
|
||||
App.FastFlags.Load();
|
||||
Frontend.ShowLanguageSelection();
|
||||
Frontend.ShowMenu();
|
||||
|
||||
// exit if we don't click the install button on installation
|
||||
|
80
Bloxstrap/Locale.cs
Normal file
80
Bloxstrap/Locale.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Bloxstrap.Resources;
|
||||
|
||||
namespace Bloxstrap
|
||||
{
|
||||
internal static class Locale
|
||||
{
|
||||
// TODO: put translated names
|
||||
public static readonly Dictionary<string, string> SupportedLocales = new()
|
||||
{
|
||||
{ "nil", Strings.Enums_Theme_Default }, // /shrug
|
||||
{ "en", "English" },
|
||||
{ "en-US", "English (United States)" },
|
||||
{ "ar", "Arabic" },
|
||||
{ "bn", "Bengali" },
|
||||
{ "bs", "Bosnian" },
|
||||
{ "bg", "Bulgarian" },
|
||||
{ "zh-CN", "Chinese (Simplified)" },
|
||||
{ "zh-TW", "Chinese (Traditional)" },
|
||||
{ "cs", "Czech" },
|
||||
{ "dk", "Danish" },
|
||||
{ "nl", "Dutch" },
|
||||
{ "fl", "Filipino" },
|
||||
{ "fi", "Finnish" },
|
||||
{ "fr", "French" },
|
||||
{ "de", "German" },
|
||||
{ "he", "Hebrew" },
|
||||
{ "hi", "Hindi" },
|
||||
{ "hu", "Hungarian" },
|
||||
{ "id", "Indonesian" },
|
||||
{ "it", "Italian" },
|
||||
{ "ja", "Japanese" },
|
||||
{ "ko", "Korean" },
|
||||
{ "lt", "Lithuanian" },
|
||||
{ "no", "Norwegian" },
|
||||
{ "pl", "Polish" },
|
||||
{ "pt-BR", "Portuguese" },
|
||||
{ "ro", "Romanian" },
|
||||
{ "ru", "Russian" },
|
||||
{ "es", "Spanish" },
|
||||
{ "sv-SE", "Swedish" },
|
||||
{ "th", "Thai" },
|
||||
{ "tr", "Turkish" },
|
||||
{ "uk", "Ukrainian" },
|
||||
{ "vi", "Vietnamese" }
|
||||
};
|
||||
|
||||
public static string GetIdentifierFromName(string language) => Locale.SupportedLocales.Where(x => x.Value == language).First().Key;
|
||||
|
||||
public static void Set()
|
||||
{
|
||||
string identifier = App.Settings.Prop.Locale;
|
||||
|
||||
if (!SupportedLocales.ContainsKey(identifier))
|
||||
identifier = "nil";
|
||||
|
||||
if (identifier == "nil")
|
||||
return;
|
||||
|
||||
App.CurrentCulture = new CultureInfo(identifier);
|
||||
|
||||
CultureInfo.DefaultThreadCurrentUICulture = App.CurrentCulture;
|
||||
Thread.CurrentThread.CurrentUICulture = App.CurrentCulture;
|
||||
|
||||
if (identifier == "ar" || identifier == "he")
|
||||
{
|
||||
// TODO: credit the SO post i took this from
|
||||
EventManager.RegisterClassHandler(typeof(Window), FrameworkElement.LoadedEvent, new RoutedEventHandler((window, _) =>
|
||||
{
|
||||
((Window)window).FlowDirection = FlowDirection.RightToLeft;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,8 @@ namespace Bloxstrap.Models
|
||||
public bool CheckForUpdates { get; set; } = true;
|
||||
public bool CreateDesktopIcon { get; set; } = true;
|
||||
public bool ConfirmLaunches { get; set; } = false;
|
||||
public string Locale { get; set; } = "nil";
|
||||
public bool ForceRobloxLanguage { get; set; } = false;
|
||||
|
||||
// channel configuration
|
||||
public string Channel { get; set; } = RobloxDeployment.DefaultChannel;
|
||||
|
57
Bloxstrap/Resources/Strings.Designer.cs
generated
57
Bloxstrap/Resources/Strings.Designer.cs
generated
@ -693,6 +693,25 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Choose preferred language.
|
||||
/// </summary>
|
||||
public static string Dialog_LanguageSelector_Header {
|
||||
get {
|
||||
return ResourceManager.GetString("Dialog.LanguageSelector.Header", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Choose a language before continuing with installation.
|
||||
///Scroll for more languages..
|
||||
/// </summary>
|
||||
public static string Dialog_LanguageSelector_Subtext {
|
||||
get {
|
||||
return ResourceManager.GetString("Dialog.LanguageSelector.Subtext", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to 2008.
|
||||
/// </summary>
|
||||
@ -1144,7 +1163,7 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to System Default.
|
||||
/// Looks up a localized string similar to System default.
|
||||
/// </summary>
|
||||
public static string Enums_Theme_Default {
|
||||
get {
|
||||
@ -1497,6 +1516,24 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Scroll to see more. A relaunch is required for changes to take effect..
|
||||
/// </summary>
|
||||
public static string Menu_Appearance_Language_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Appearance.Language.Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Language.
|
||||
/// </summary>
|
||||
public static string Menu_Appearance_Language_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Appearance.Language.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Preview.
|
||||
/// </summary>
|
||||
@ -1596,6 +1633,24 @@ namespace Bloxstrap.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Roblox will be forced to display the same language that Bloxstrap is presently using..
|
||||
/// </summary>
|
||||
public static string Menu_Behaviour_ForceRobloxLanguage_Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Behaviour.ForceRobloxLanguage.Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Force Roblox language.
|
||||
/// </summary>
|
||||
public static string Menu_Behaviour_ForceRobloxLanguage_Title {
|
||||
get {
|
||||
return ResourceManager.GetString("Menu.Behaviour.ForceRobloxLanguage.Title", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Roblox will be installed fresh on next launch..
|
||||
/// </summary>
|
||||
|
@ -484,7 +484,7 @@ Click for more information</value>
|
||||
<value>Dark</value>
|
||||
</data>
|
||||
<data name="Enums.Theme.Default" xml:space="preserve">
|
||||
<value>System Default</value>
|
||||
<value>System default</value>
|
||||
</data>
|
||||
<data name="Enums.Theme.Light" xml:space="preserve">
|
||||
<value>Light</value>
|
||||
@ -1023,4 +1023,23 @@ Selecting 'No' will ignore this warning and continue installation.</value>
|
||||
<data name="Menu.Title" xml:space="preserve">
|
||||
<value>Bloxstrap Menu</value>
|
||||
</data>
|
||||
<data name="Dialog.LanguageSelector.Header" xml:space="preserve">
|
||||
<value>Choose preferred language</value>
|
||||
</data>
|
||||
<data name="Dialog.LanguageSelector.Subtext" xml:space="preserve">
|
||||
<value>Choose a language before continuing with installation.
|
||||
Scroll for more languages.</value>
|
||||
</data>
|
||||
<data name="Menu.Appearance.Language.Title" xml:space="preserve">
|
||||
<value>Language</value>
|
||||
</data>
|
||||
<data name="Menu.Appearance.Language.Description" xml:space="preserve">
|
||||
<value>Scroll to see more. A relaunch is required for changes to take effect.</value>
|
||||
</data>
|
||||
<data name="Menu.Behaviour.ForceRobloxLanguage.Title" xml:space="preserve">
|
||||
<value>Force Roblox language</value>
|
||||
</data>
|
||||
<data name="Menu.Behaviour.ForceRobloxLanguage.Description" xml:space="preserve">
|
||||
<value>Roblox will be forced to display the same language that Bloxstrap is presently using.</value>
|
||||
</data>
|
||||
</root>
|
41
Bloxstrap/UI/Elements/Dialogs/LanguageSelectorDialog.xaml
Normal file
41
Bloxstrap/UI/Elements/Dialogs/LanguageSelectorDialog.xaml
Normal file
@ -0,0 +1,41 @@
|
||||
<ui:UiWindow x:Class="Bloxstrap.UI.Elements.Dialogs.LanguageSelectorDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
xmlns:local="clr-namespace:Bloxstrap.UI.Elements.Dialogs"
|
||||
xmlns:resources="clr-namespace:Bloxstrap.Resources"
|
||||
mc:Ignorable="d"
|
||||
Title="Bloxstrap"
|
||||
MinWidth="0"
|
||||
MinHeight="0"
|
||||
Width="380"
|
||||
SizeToContent="Height"
|
||||
ResizeMode="NoResize"
|
||||
Background="{ui:ThemeResource ApplicationBackgroundBrush}"
|
||||
ExtendsContentIntoTitleBar="True"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<ui:TitleBar Grid.Row="0" Grid.ColumnSpan="2" Padding="8" Title="Bloxstrap" ShowMinimize="False" ShowMaximize="False" CanMaximize="False" KeyboardNavigation.TabNavigation="None" />
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="12">
|
||||
<TextBlock Text="{x:Static resources:Strings.Dialog_LanguageSelector_Header}" FontSize="18" FontWeight="Medium" />
|
||||
<TextBlock Text="{x:Static resources:Strings.Dialog_LanguageSelector_Subtext}" TextWrapping="Wrap" Margin="0,0,0,12" />
|
||||
<ComboBox ItemsSource="{Binding Languages, Mode=OneTime}" Text="{Binding SelectedLanguage, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
|
||||
<Border Grid.Row="2" Margin="0,10,0,0" Padding="15" Background="{ui:ThemeResource SolidBackgroundFillColorSecondaryBrush}">
|
||||
<StackPanel Orientation="Horizontal" FlowDirection="LeftToRight" HorizontalAlignment="Right">
|
||||
<Button MinWidth="100" Content="{x:Static resources:Strings.Common_OK}" Command="{Binding SetLocaleCommand}" />
|
||||
<!--<Button MinWidth="100" Margin="12,0,0,0" Content="{x:Static resources:Strings.Common_Cancel}" IsCancel="True" />-->
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ui:UiWindow>
|
33
Bloxstrap/UI/Elements/Dialogs/LanguageSelectorDialog.xaml.cs
Normal file
33
Bloxstrap/UI/Elements/Dialogs/LanguageSelectorDialog.xaml.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Bloxstrap.UI.ViewModels.Dialogs;
|
||||
|
||||
namespace Bloxstrap.UI.Elements.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for LanguageSelectorDialog.xaml
|
||||
/// </summary>
|
||||
public partial class LanguageSelectorDialog
|
||||
{
|
||||
public LanguageSelectorDialog()
|
||||
{
|
||||
var viewModel = new LanguageSelectorViewModel();
|
||||
|
||||
DataContext = viewModel;
|
||||
InitializeComponent();
|
||||
|
||||
viewModel.CloseRequestEvent += (_, _) => Close();
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,12 @@
|
||||
</ComboBox>
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Appearance_Language_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Appearance_Language_Description}">
|
||||
<ComboBox Width="200" Padding="10,5,10,5" ItemsSource="{Binding Languages, Mode=OneTime}" Text="{Binding SelectedLanguage, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
|
||||
<Grid Margin="0,4,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
|
@ -29,6 +29,18 @@
|
||||
<ui:ToggleSwitch IsChecked="{Binding UpdateCheckingEnabled, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Behaviour_ConfirmLaunches_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Behaviour_ConfirmLaunches_Description}">
|
||||
<ui:ToggleSwitch IsChecked="{Binding ConfirmLaunches, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxLanguage_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxLanguage_Description}">
|
||||
<ui:ToggleSwitch IsChecked="{Binding ForceRobloxLanguage, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Behaviour_ForceRobloxReinstall_Description}">
|
||||
@ -43,11 +55,5 @@
|
||||
</controls:OptionControl.Style>
|
||||
<ui:ToggleSwitch IsChecked="{Binding ForceRobloxReinstallation, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
|
||||
<controls:OptionControl
|
||||
Header="{x:Static resources:Strings.Menu_Behaviour_ConfirmLaunches_Title}"
|
||||
Description="{x:Static resources:Strings.Menu_Behaviour_ConfirmLaunches_Description}">
|
||||
<ui:ToggleSwitch IsChecked="{Binding ConfirmLaunches, Mode=TwoWay}" />
|
||||
</controls:OptionControl>
|
||||
</StackPanel>
|
||||
</ui:UiPage>
|
||||
|
@ -8,6 +8,8 @@ namespace Bloxstrap.UI
|
||||
{
|
||||
static class Frontend
|
||||
{
|
||||
public static void ShowLanguageSelection() => new LanguageSelectorDialog().ShowDialog();
|
||||
|
||||
public static void ShowMenu(bool showAlreadyRunningWarning = false) => new MainWindow(showAlreadyRunningWarning).ShowDialog();
|
||||
|
||||
public static MessageBoxResult ShowMessageBox(string message, MessageBoxImage icon = MessageBoxImage.None, MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.None)
|
||||
|
30
Bloxstrap/UI/ViewModels/Dialogs/LanguageSelectorViewModel.cs
Normal file
30
Bloxstrap/UI/ViewModels/Dialogs/LanguageSelectorViewModel.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bloxstrap.UI.ViewModels.Dialogs
|
||||
{
|
||||
internal class LanguageSelectorViewModel
|
||||
{
|
||||
public event EventHandler? CloseRequestEvent;
|
||||
|
||||
public ICommand SetLocaleCommand => new RelayCommand(SetLocale);
|
||||
|
||||
public static List<string> Languages => Locale.SupportedLocales.Values.ToList();
|
||||
|
||||
public string SelectedLanguage { get; set; } = Locale.SupportedLocales[App.Settings.Prop.Locale];
|
||||
|
||||
private void SetLocale()
|
||||
{
|
||||
App.Settings.Prop.Locale = Locale.GetIdentifierFromName(SelectedLanguage);
|
||||
Locale.Set();
|
||||
|
||||
CloseRequestEvent?.Invoke(this, new());
|
||||
}
|
||||
}
|
||||
}
|
@ -65,6 +65,14 @@ namespace Bloxstrap.UI.ViewModels.Menu
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> Languages => Locale.SupportedLocales.Values.ToList();
|
||||
|
||||
public string SelectedLanguage
|
||||
{
|
||||
get => Locale.SupportedLocales[App.Settings.Prop.Locale];
|
||||
set => App.Settings.Prop.Locale = Locale.GetIdentifierFromName(value);
|
||||
}
|
||||
|
||||
public IEnumerable<BootstrapperStyle> Dialogs { get; } = BootstrapperStyleEx.Selections;
|
||||
|
||||
public BootstrapperStyle Dialog
|
||||
|
@ -23,6 +23,12 @@
|
||||
set => App.Settings.Prop.ConfirmLaunches = value;
|
||||
}
|
||||
|
||||
public bool ForceRobloxLanguage
|
||||
{
|
||||
get => App.Settings.Prop.ForceRobloxLanguage;
|
||||
set => App.Settings.Prop.ForceRobloxLanguage = value;
|
||||
}
|
||||
|
||||
public bool ForceRobloxReinstallation
|
||||
{
|
||||
// wouldnt it be better to check old version guids?
|
||||
|
Loading…
Reference in New Issue
Block a user