Centralise game language update logic

This commit is contained in:
Salman Ahmed 2023-06-08 02:47:07 +03:00
parent 93b1f18772
commit 1a90f71540
3 changed files with 39 additions and 41 deletions

View File

@ -14,6 +14,7 @@ using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Configuration;
using osu.Framework.Development; using osu.Framework.Development;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -27,6 +28,7 @@ using osu.Framework.Input.Handlers.Mouse;
using osu.Framework.Input.Handlers.Tablet; using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Input.Handlers.Touch; using osu.Framework.Input.Handlers.Touch;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Localisation;
using osu.Framework.Logging; using osu.Framework.Logging;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Timing; using osu.Framework.Timing;
@ -36,11 +38,13 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Extensions;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Cursor;
using osu.Game.Input; using osu.Game.Input;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Localisation;
using osu.Game.Online; using osu.Game.Online;
using osu.Game.Online.API; using osu.Game.Online.API;
using osu.Game.Online.Chat; using osu.Game.Online.Chat;
@ -157,6 +161,11 @@ namespace osu.Game
protected Storage Storage { get; set; } protected Storage Storage { get; set; }
/// <summary>
/// The language in which the game is currently displayed in.
/// </summary>
public Bindable<Language> CurrentLanguage { get; } = new Bindable<Language>();
protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method protected Bindable<WorkingBeatmap> Beatmap { get; private set; } // cached via load() method
/// <summary> /// <summary>
@ -216,6 +225,10 @@ namespace osu.Game
private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(global_track_volume_adjust); private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(global_track_volume_adjust);
private Bindable<string> frameworkLocale = null!;
private IBindable<LocalisationParameters> localisationParameters = null!;
/// <summary> /// <summary>
/// Number of unhandled exceptions to allow before aborting execution. /// Number of unhandled exceptions to allow before aborting execution.
/// </summary> /// </summary>
@ -238,7 +251,7 @@ namespace osu.Game
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(ReadableKeyCombinationProvider keyCombinationProvider) private void load(ReadableKeyCombinationProvider keyCombinationProvider, FrameworkConfigManager frameworkConfig)
{ {
try try
{ {
@ -284,6 +297,14 @@ namespace osu.Game
MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl; MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl;
dependencies.CacheAs(API ??= new APIAccess(LocalConfig, endpoints, VersionHash)); dependencies.CacheAs(API ??= new APIAccess(LocalConfig, endpoints, VersionHash));
frameworkLocale = frameworkConfig.GetBindable<string>(FrameworkSetting.Locale);
frameworkLocale.BindValueChanged(_ => updateLanguage());
localisationParameters = Localisation.CurrentParameters.GetBoundCopy();
localisationParameters.BindValueChanged(_ => updateLanguage(), true);
CurrentLanguage.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode());
var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures); var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures);
@ -394,6 +415,8 @@ namespace osu.Game
Beatmap.BindValueChanged(onBeatmapChanged); Beatmap.BindValueChanged(onBeatmapChanged);
} }
private void updateLanguage() => CurrentLanguage.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, localisationParameters.Value);
private void addFilesWarning() private void addFilesWarning()
{ {
var realmStore = new RealmFileStore(realm, Storage); var realmStore = new RealmFileStore(realm, Storage);

View File

@ -13,7 +13,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Extensions;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
@ -68,13 +67,12 @@ namespace osu.Game.Overlays.FirstRunSetup
private partial class LanguageSelectionFlow : FillFlowContainer private partial class LanguageSelectionFlow : FillFlowContainer
{ {
private Bindable<string> frameworkLocale = null!; private Bindable<Language> language = null!;
private IBindable<LocalisationParameters> localisationParameters = null!;
private ScheduledDelegate? updateSelectedDelegate; private ScheduledDelegate? updateSelectedDelegate;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(FrameworkConfigManager frameworkConfig, LocalisationManager localisation) private void load(OsuGameBase game)
{ {
Direction = FillDirection.Full; Direction = FillDirection.Full;
Spacing = new Vector2(5); Spacing = new Vector2(5);
@ -82,25 +80,18 @@ namespace osu.Game.Overlays.FirstRunSetup
ChildrenEnumerable = Enum.GetValues<Language>() ChildrenEnumerable = Enum.GetValues<Language>()
.Select(l => new LanguageButton(l) .Select(l => new LanguageButton(l)
{ {
Action = () => frameworkLocale.Value = l.ToCultureCode() Action = () => language.Value = l,
}); });
frameworkLocale = frameworkConfig.GetBindable<string>(FrameworkSetting.Locale); language = game.CurrentLanguage.GetBoundCopy();
frameworkLocale.BindValueChanged(_ => onLanguageChange()); language.BindValueChanged(v =>
{
localisationParameters = localisation.CurrentParameters.GetBoundCopy(); // Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded.
localisationParameters.BindValueChanged(_ => onLanguageChange(), true); // Scheduling ensures the button animation plays smoothly after any blocking operation completes.
} // Note that a delay is required (the alternative would be a double-schedule; delay feels better).
updateSelectedDelegate?.Cancel();
private void onLanguageChange() updateSelectedDelegate = Scheduler.AddDelayed(() => updateSelectedStates(v.NewValue), 50);
{ }, true);
var language = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, localisationParameters.Value);
// Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded.
// Scheduling ensures the button animation plays smoothly after any blocking operation completes.
// Note that a delay is required (the alternative would be a double-schedule; delay feels better).
updateSelectedDelegate?.Cancel();
updateSelectedDelegate = Scheduler.AddDelayed(() => updateSelectedStates(language), 50);
} }
private void updateSelectedStates(Language language) private void updateSelectedStates(Language language)

View File

@ -2,35 +2,27 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Localisation; using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.General namespace osu.Game.Overlays.Settings.Sections.General
{ {
public partial class LanguageSettings : SettingsSubsection public partial class LanguageSettings : SettingsSubsection
{ {
private SettingsDropdown<Language> languageSelection = null!;
private Bindable<string> frameworkLocale = null!;
private IBindable<LocalisationParameters> localisationParameters = null!;
protected override LocalisableString Header => GeneralSettingsStrings.LanguageHeader; protected override LocalisableString Header => GeneralSettingsStrings.LanguageHeader;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager config, LocalisationManager localisation) private void load(OsuGame game, OsuConfigManager config, FrameworkConfigManager frameworkConfig)
{ {
frameworkLocale = frameworkConfig.GetBindable<string>(FrameworkSetting.Locale);
localisationParameters = localisation.CurrentParameters.GetBoundCopy();
Children = new Drawable[] Children = new Drawable[]
{ {
languageSelection = new SettingsEnumDropdown<Language> new SettingsEnumDropdown<Language>
{ {
LabelText = GeneralSettingsStrings.LanguageDropdown, LabelText = GeneralSettingsStrings.LanguageDropdown,
Current = game.CurrentLanguage,
}, },
new SettingsCheckbox new SettingsCheckbox
{ {
@ -43,14 +35,6 @@ namespace osu.Game.Overlays.Settings.Sections.General
Current = config.GetBindable<bool>(OsuSetting.Prefer24HourTime) Current = config.GetBindable<bool>(OsuSetting.Prefer24HourTime)
}, },
}; };
frameworkLocale.BindValueChanged(_ => updateSelection());
localisationParameters.BindValueChanged(_ => updateSelection(), true);
languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode());
} }
private void updateSelection() =>
languageSelection.Current.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, localisationParameters.Value);
} }
} }