A game framework written with osu! in mind.
at master 4.4 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System.Collections.Generic; 5using System.Globalization; 6using osu.Framework.Bindables; 7using osu.Framework.Configuration; 8 9#nullable enable 10 11namespace osu.Framework.Localisation 12{ 13 public partial class LocalisationManager 14 { 15 private readonly List<LocaleMapping> locales = new List<LocaleMapping>(); 16 17 private readonly Bindable<string> configLocale = new Bindable<string>(); 18 private readonly Bindable<bool> configPreferUnicode = new BindableBool(); 19 20 private readonly Bindable<LocalisationParameters> currentParameters = new Bindable<LocalisationParameters>(new LocalisationParameters(null, false)); 21 22 public LocalisationManager(FrameworkConfigManager config) 23 { 24 config.BindWith(FrameworkSetting.Locale, configLocale); 25 configLocale.BindValueChanged(updateLocale); 26 27 config.BindWith(FrameworkSetting.ShowUnicode, configPreferUnicode); 28 configPreferUnicode.BindValueChanged(updateUnicodePreference, true); 29 } 30 31 public void AddLanguage(string language, ILocalisationStore storage) 32 { 33 locales.Add(new LocaleMapping(language, storage)); 34 configLocale.TriggerChange(); 35 } 36 37 /// <summary> 38 /// Creates an <see cref="ILocalisedBindableString"/> which automatically updates its text according to information provided in <see cref="ILocalisedBindableString.Text"/>. 39 /// </summary> 40 /// <returns>The <see cref="ILocalisedBindableString"/>.</returns> 41 public ILocalisedBindableString GetLocalisedString(LocalisableString original) => new LocalisedBindableString(original, this); 42 43 private void updateLocale(ValueChangedEvent<string> locale) 44 { 45 if (locales.Count == 0) 46 return; 47 48 var validLocale = locales.Find(l => l.Name == locale.NewValue); 49 50 if (validLocale == null) 51 { 52 var culture = string.IsNullOrEmpty(locale.NewValue) ? CultureInfo.CurrentCulture : new CultureInfo(locale.NewValue); 53 54 for (var c = culture; !EqualityComparer<CultureInfo>.Default.Equals(c, CultureInfo.InvariantCulture); c = c.Parent) 55 { 56 validLocale = locales.Find(l => l.Name == c.Name); 57 if (validLocale != null) 58 break; 59 } 60 61 validLocale ??= locales[0]; 62 } 63 64 ChangeSettings(CreateNewLocalisationParameters(validLocale.Storage, currentParameters.Value.PreferOriginalScript)); 65 } 66 67 private void updateUnicodePreference(ValueChangedEvent<bool> preferUnicode) 68 => ChangeSettings(CreateNewLocalisationParameters(currentParameters.Value.Store, preferUnicode.NewValue)); 69 70 /// <summary> 71 /// Changes the localisation parameters. 72 /// </summary> 73 /// <param name="parameters">The new localisation parameters.</param> 74 protected void ChangeSettings(LocalisationParameters parameters) => currentParameters.Value = parameters; 75 76 /// <summary> 77 /// Creates new <see cref="LocalisationParameters"/>. 78 /// </summary> 79 /// <remarks> 80 /// Can be overridden to provide custom parameters for <see cref="ILocalisableStringData"/> implementations. 81 /// </remarks> 82 /// <param name="store">The <see cref="ILocalisationStore"/> to be used for string lookups and culture-specific formatting.</param> 83 /// <param name="preferOriginalScript">Whether to prefer the "original" script of <see cref="RomanisableString"/>s.</param> 84 /// <returns>The resultant <see cref="LocalisationParameters"/>.</returns> 85 protected virtual LocalisationParameters CreateNewLocalisationParameters(ILocalisationStore? store, bool preferOriginalScript) 86 => new LocalisationParameters(store, preferOriginalScript); 87 88 private class LocaleMapping 89 { 90 public readonly string Name; 91 public readonly ILocalisationStore Storage; 92 93 public LocaleMapping(string name, ILocalisationStore storage) 94 { 95 Name = name; 96 Storage = storage; 97 } 98 } 99 } 100}