mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
Fix issues with local settings tab localization
This commit is contained in:
1 parent
28a77f96cb
commit
48aff163f9
9 files changed
+110
-10
No files matched your search
@@ -39,4 +39,9 @@ public interface ILocalSetting
|
|||||||
/// <param name="last">Whether it's the last on the row.</param>
|
/// <param name="last">Whether it's the last on the row.</param>
|
||||||
/// <returns>The created setting's <see cref="GameObject"/>.</returns>
|
/// <returns>The created setting's <see cref="GameObject"/>.</returns>
|
||||||
GameObject? CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last);
|
GameObject? CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to refresh the setting's information, usually for localization.
|
||||||
|
/// </summary>
|
||||||
|
void RefreshOption();
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using MiraAPI.LocalSettings.SettingTypes;
|
||||||
using MiraAPI.Patches.LocalSettings;
|
using MiraAPI.Patches.LocalSettings;
|
||||||
using MiraAPI.Translation;
|
using MiraAPI.Translation;
|
||||||
using MiraAPI.Utilities;
|
using MiraAPI.Utilities;
|
||||||
@@ -53,6 +54,11 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ILocalSetting> Settings { get; } = [];
|
public List<ILocalSetting> Settings { get; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a collection of <see cref="TextMeshPro"/>s alongside the locale keys for them.
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<TextMeshPro, string> Labels { get; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list of <see cref="LocalSettingsButton"/>s.
|
/// Gets the list of <see cref="LocalSettingsButton"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -74,12 +80,21 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to open the tab.
|
/// Refreshes setting names upon opening the tab.
|
||||||
/// Override for custom behavior.
|
/// Override for custom behavior.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Open()
|
public virtual void Open()
|
||||||
{
|
{
|
||||||
OptionsMenuPatches.Instance?.OpenTabGroup(TabIndex);
|
foreach (var setting in Settings)
|
||||||
|
{
|
||||||
|
setting.RefreshOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var label in Labels)
|
||||||
|
{
|
||||||
|
label.Key.text =
|
||||||
|
$"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Chat Message Masked\"><b>{label.Value.Translate()}</b></font>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -273,7 +288,7 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
|||||||
return tabButtonObject.gameObject;
|
return tabButtonObject.gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateLabel(GameObject template, Transform parent, string text, ref float offset)
|
private void CreateLabel(GameObject template, Transform parent, string text, ref float offset)
|
||||||
{
|
{
|
||||||
var label = Object.Instantiate(template, parent);
|
var label = Object.Instantiate(template, parent);
|
||||||
label.transform.localPosition = new Vector3(0, 1.85f - offset);
|
label.transform.localPosition = new Vector3(0, 1.85f - offset);
|
||||||
@@ -281,6 +296,7 @@ public abstract class LocalSettingsTab(ConfigFile config)
|
|||||||
label.name = text;
|
label.name = text;
|
||||||
|
|
||||||
var tmp = label.GetComponent<TextMeshPro>();
|
var tmp = label.GetComponent<TextMeshPro>();
|
||||||
|
Labels.Add(tmp, text);
|
||||||
tmp.text = $"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Chat Message Masked\"><b>{text.Translate()}</b></font>";
|
tmp.text = $"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Chat Message Masked\"><b>{text.Translate()}</b></font>";
|
||||||
tmp.alignment = TextAlignmentOptions.Center;
|
tmp.alignment = TextAlignmentOptions.Center;
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public class LocalEnumSetting : LocalSettingBase<int>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Values { get; }
|
public string[] Values { get; }
|
||||||
|
|
||||||
|
private SpriteRenderer _highlight { get; set; }
|
||||||
|
|
||||||
|
private TextMeshPro _btnText { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="LocalEnumSetting"/> class.
|
/// Initializes a new instance of the <see cref="LocalEnumSetting"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -54,6 +58,7 @@ public class LocalEnumSetting : LocalSettingBase<int>
|
|||||||
{
|
{
|
||||||
var button = Object.Instantiate(toggle, parent).GetComponent<PassiveButton>();
|
var button = Object.Instantiate(toggle, parent).GetComponent<PassiveButton>();
|
||||||
var tmp = button.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
var tmp = button.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
||||||
|
_btnText = tmp;
|
||||||
var rollover = button.GetComponent<ButtonRolloverHandler>();
|
var rollover = button.GetComponent<ButtonRolloverHandler>();
|
||||||
tmp.GetComponent<TextTranslatorTMP>().Destroy();
|
tmp.GetComponent<TextTranslatorTMP>().Destroy();
|
||||||
button.gameObject.SetActive(true);
|
button.gameObject.SetActive(true);
|
||||||
@@ -63,6 +68,7 @@ public class LocalEnumSetting : LocalSettingBase<int>
|
|||||||
var highlight = button.transform.FindChild("ButtonHighlight")?.GetComponent<SpriteRenderer>();
|
var highlight = button.transform.FindChild("ButtonHighlight")?.GetComponent<SpriteRenderer>();
|
||||||
if (highlight != null)
|
if (highlight != null)
|
||||||
{
|
{
|
||||||
|
_highlight = highlight;
|
||||||
highlight.color = Tab!.TabAppearance.EnumHoverColor;
|
highlight.color = Tab!.TabAppearance.EnumHoverColor;
|
||||||
highlight.gameObject.SetActive(false);
|
highlight.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
@@ -125,9 +131,19 @@ public class LocalEnumSetting : LocalSettingBase<int>
|
|||||||
return button.gameObject;
|
return button.gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void RefreshOption()
|
||||||
|
{
|
||||||
|
_btnText.text = GetValueText();
|
||||||
|
if (_highlight)
|
||||||
|
{
|
||||||
|
_highlight.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override string GetValueText()
|
protected override string GetValueText()
|
||||||
{
|
{
|
||||||
return $"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Chat Message Masked\">{Name.Translate()}: <b>{Values[GetValue()]}</font></b>";
|
return $"<font=\"LiberationSans SDF\" material=\"LiberationSans SDF - Chat Message Masked\">{Name.Translate()}: <b>{Values[GetValue()].Translate()}</font></b>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,10 @@ public class LocalNumberSetting : LocalSettingBase<float>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MiraNumberSuffixes SuffixType { get; }
|
public MiraNumberSuffixes SuffixType { get; }
|
||||||
|
|
||||||
|
private SpriteRenderer _highlight { get; set; }
|
||||||
|
|
||||||
|
private TextMeshPro _btnText { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="LocalNumberSetting"/> class.
|
/// Initializes a new instance of the <see cref="LocalNumberSetting"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -65,6 +69,7 @@ public class LocalNumberSetting : LocalSettingBase<float>
|
|||||||
{
|
{
|
||||||
var button = Object.Instantiate(toggle, parent).GetComponent<PassiveButton>();
|
var button = Object.Instantiate(toggle, parent).GetComponent<PassiveButton>();
|
||||||
var tmp = button.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
var tmp = button.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
||||||
|
_btnText = tmp;
|
||||||
var rollover = button.GetComponent<ButtonRolloverHandler>();
|
var rollover = button.GetComponent<ButtonRolloverHandler>();
|
||||||
tmp.GetComponent<TextTranslatorTMP>().Destroy();
|
tmp.GetComponent<TextTranslatorTMP>().Destroy();
|
||||||
button.gameObject.SetActive(true);
|
button.gameObject.SetActive(true);
|
||||||
@@ -74,6 +79,7 @@ public class LocalNumberSetting : LocalSettingBase<float>
|
|||||||
var highlight = button.transform.FindChild("ButtonHighlight")?.GetComponent<SpriteRenderer>();
|
var highlight = button.transform.FindChild("ButtonHighlight")?.GetComponent<SpriteRenderer>();
|
||||||
if (highlight != null)
|
if (highlight != null)
|
||||||
{
|
{
|
||||||
|
_highlight = highlight;
|
||||||
highlight.color = Tab!.TabAppearance.NumberHoverColor;
|
highlight.color = Tab!.TabAppearance.NumberHoverColor;
|
||||||
highlight.gameObject.SetActive(false);
|
highlight.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
@@ -136,6 +142,16 @@ public class LocalNumberSetting : LocalSettingBase<float>
|
|||||||
return button.gameObject;
|
return button.gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void RefreshOption()
|
||||||
|
{
|
||||||
|
_btnText.text = GetValueText();
|
||||||
|
if (_highlight)
|
||||||
|
{
|
||||||
|
_highlight.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override string GetValueText()
|
protected override string GetValueText()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ public abstract class LocalSettingBase<T> : ILocalSetting
|
|||||||
/// <returns>The created setting.</returns>
|
/// <returns>The created setting.</returns>
|
||||||
public abstract GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last);
|
public abstract GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public abstract void RefreshOption();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the formated string to use in the text of the setting.
|
/// Returns the formated string to use in the text of the setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public class LocalSliderSetting : LocalSettingBase<float>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MiraNumberSuffixes SuffixType { get; }
|
public MiraNumberSuffixes SuffixType { get; }
|
||||||
|
|
||||||
|
private SlideBar _slider { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="LocalSliderSetting"/> class.
|
/// Initializes a new instance of the <see cref="LocalSliderSetting"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -71,6 +73,7 @@ public class LocalSliderSetting : LocalSettingBase<float>
|
|||||||
public override GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last)
|
public override GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last)
|
||||||
{
|
{
|
||||||
var newSlider = Object.Instantiate(slider, parent).GetComponent<SlideBar>();
|
var newSlider = Object.Instantiate(slider, parent).GetComponent<SlideBar>();
|
||||||
|
_slider = newSlider;
|
||||||
var rollover = newSlider.GetComponent<ButtonRolloverHandler>();
|
var rollover = newSlider.GetComponent<ButtonRolloverHandler>();
|
||||||
newSlider.Title = newSlider.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>(); // Why the hell slider has a title property that is not even assigned???
|
newSlider.Title = newSlider.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>(); // Why the hell slider has a title property that is not even assigned???
|
||||||
newSlider.Title.GetComponent<TextTranslatorTMP>().Destroy();
|
newSlider.Title.GetComponent<TextTranslatorTMP>().Destroy();
|
||||||
@@ -105,6 +108,12 @@ public class LocalSliderSetting : LocalSettingBase<float>
|
|||||||
return newSlider.gameObject;
|
return newSlider.gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void RefreshOption()
|
||||||
|
{
|
||||||
|
_slider.Title.text = GetValueText();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
protected override string GetValueText()
|
protected override string GetValueText()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ namespace MiraAPI.LocalSettings.SettingTypes;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LocalToggleSetting : LocalSettingBase<bool>
|
public class LocalToggleSetting : LocalSettingBase<bool>
|
||||||
{
|
{
|
||||||
|
private ToggleButtonBehaviour _toggle { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="LocalToggleSetting"/> class.
|
/// Initializes a new instance of the <see cref="LocalToggleSetting"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -32,6 +34,7 @@ public class LocalToggleSetting : LocalSettingBase<bool>
|
|||||||
public override GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last)
|
public override GameObject CreateOption(ToggleButtonBehaviour toggle, SlideBar slider, Transform parent, ref float offset, ref int order, bool last)
|
||||||
{
|
{
|
||||||
var toggleObject = Object.Instantiate(toggle, parent).GetComponent<ToggleButtonBehaviour>();
|
var toggleObject = Object.Instantiate(toggle, parent).GetComponent<ToggleButtonBehaviour>();
|
||||||
|
_toggle = toggleObject;
|
||||||
var tmp = toggleObject.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
var tmp = toggleObject.transform.FindChild("Text_TMP").GetComponent<TextMeshPro>();
|
||||||
var passiveButton = toggleObject.GetComponent<PassiveButton>();
|
var passiveButton = toggleObject.GetComponent<PassiveButton>();
|
||||||
var rollover = toggleObject.GetComponent<ButtonRolloverHandler>();
|
var rollover = toggleObject.GetComponent<ButtonRolloverHandler>();
|
||||||
@@ -86,4 +89,11 @@ public class LocalToggleSetting : LocalSettingBase<bool>
|
|||||||
|
|
||||||
return toggleObject.gameObject;
|
return toggleObject.gameObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void RefreshOption()
|
||||||
|
{
|
||||||
|
_toggle.UpdateText(GetValue());
|
||||||
|
_toggle.Background.color = GetValue() ? Tab!.TabAppearance.ToggleActiveColor : Tab!.TabAppearance.ToggleInactiveColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -213,6 +213,8 @@ public static class OptionsMenuPatches
|
|||||||
|
|
||||||
if (background != null)
|
if (background != null)
|
||||||
background.color = tab.TabAppearance.TabColor;
|
background.color = tab.TabAppearance.TabColor;
|
||||||
|
|
||||||
|
tab.Open();
|
||||||
}
|
}
|
||||||
private static void CustomClose(LocalSettingsTab tab)
|
private static void CustomClose(LocalSettingsTab tab)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using MiraAPI.Utilities;
|
||||||
using Reactor.Localization.Utilities;
|
using Reactor.Localization.Utilities;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -97,7 +98,22 @@ public static class MiraLocaleManager
|
|||||||
var callingAssembly = Assembly.GetCallingAssembly();
|
var callingAssembly = Assembly.GetCallingAssembly();
|
||||||
var dir = GetModLangDir(modGuid);
|
var dir = GetModLangDir(modGuid);
|
||||||
|
|
||||||
LoadInternalStrings(callingAssembly, modGuid, dir);
|
LoadInternalStrings(callingAssembly, callingAssembly.GetName().Name!, modGuid, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers translations for a mod. Copies embedded XML to mira_languages/{modGuid}/ on first run,
|
||||||
|
/// then loads all XML files from that directory into memory.
|
||||||
|
/// Call once per mod during plugin Load().
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modGuid">The mod GUID (e.g., "mira.example").</param>
|
||||||
|
/// <param name="internalName">The mod's root namespace (e.g., "mira.api").</param>
|
||||||
|
public static void Register(string modGuid, string internalName)
|
||||||
|
{
|
||||||
|
var callingAssembly = Assembly.GetCallingAssembly();
|
||||||
|
var dir = GetModLangDir(modGuid);
|
||||||
|
|
||||||
|
LoadInternalStrings(callingAssembly, internalName, modGuid, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -194,7 +210,7 @@ public static class MiraLocaleManager
|
|||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LoadInternalStrings(Assembly assembly, string modGuid, string dir)
|
private static void LoadInternalStrings(Assembly assembly, string internalName, string modGuid, string dir)
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(dir);
|
Directory.CreateDirectory(dir);
|
||||||
|
|
||||||
@@ -203,8 +219,9 @@ public static class MiraLocaleManager
|
|||||||
Locale[modGuid] = [];
|
Locale[modGuid] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourcePrefix = $"{assembly.GetName().Name}.Resources.Locale.";
|
var resourcePrefix = $"{internalName}.Resources.Locale.";
|
||||||
|
|
||||||
|
var atLeastOneLoaded = false;
|
||||||
foreach (var locale in LangList)
|
foreach (var locale in LangList)
|
||||||
{
|
{
|
||||||
using var resourceStream =
|
using var resourceStream =
|
||||||
@@ -221,7 +238,8 @@ public static class MiraLocaleManager
|
|||||||
{
|
{
|
||||||
var dict = ParseXmlFile(xmlContent);
|
var dict = ParseXmlFile(xmlContent);
|
||||||
Locale[modGuid][locale.Key] = dict;
|
Locale[modGuid][locale.Key] = dict;
|
||||||
Info($"Loaded {locale.Key} translation for mod {modGuid} ({dict.Count} keys)");
|
Info($"Loaded {locale.Key.ToDisplayString()} translation for mod {modGuid} ({dict.Count} keys)");
|
||||||
|
atLeastOneLoaded = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -229,6 +247,11 @@ public static class MiraLocaleManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!atLeastOneLoaded)
|
||||||
|
{
|
||||||
|
Error($"No internal strings were found for {internalName}!");
|
||||||
|
}
|
||||||
|
|
||||||
if (!Locale.TryGetValue(modGuid, out _))
|
if (!Locale.TryGetValue(modGuid, out _))
|
||||||
{
|
{
|
||||||
Locale[modGuid] = [];
|
Locale[modGuid] = [];
|
||||||
@@ -247,11 +270,11 @@ public static class MiraLocaleManager
|
|||||||
{
|
{
|
||||||
var dict = ParseXmlFile(filePath);
|
var dict = ParseXmlFile(filePath);
|
||||||
Locale[modGuid][lang] = dict;
|
Locale[modGuid][lang] = dict;
|
||||||
Info($"Loaded {lang} translation for mod {modGuid} ({dict.Count} keys)");
|
Info($"Loaded external {lang.ToDisplayString()} translation for mod {modGuid} ({dict.Count} keys)");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Error($"Failed to load translation {filePath}: {e.Message}");
|
Error($"Failed to load external translation {filePath}: {e.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user