Implement mod config translations in NH style

This commit is contained in:
Nick 2024-04-18 15:01:26 -04:00
parent 957bcd25cd
commit 9f240fb40c
8 changed files with 134 additions and 12 deletions

View File

@ -62,6 +62,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OWML.ExampleAPI", "src\Samp
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C7F76E72-1CF2-4C0D-8A39-3D13EB868119}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
LICENSE = LICENSE
.github\workflows\main.yml = .github\workflows\main.yml
owmllogo.png = owmllogo.png
@ -209,7 +210,7 @@ Global
{739D16FB-7848-4047-A173-500CE7C40399} = {C447A599-2700-44E1-BBFA-52880B7BFFBA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.2\lib\NET35;packages\Unity.2.1.505.0\lib\NET35
SolutionGuid = {0E767163-75F9-420A-80EB-320429543CAD}
EnterpriseLibraryConfigurationToolBinariesPath = packages\Unity.2.1.505.2\lib\NET35;packages\Unity.2.1.505.0\lib\NET35
EndGlobalSection
EndGlobal

View File

@ -1,4 +1,5 @@
using OWML.Common.Menus;
using OWML.Common.Interfaces;
using OWML.Common.Menus;
using System;
namespace OWML.Common
@ -31,5 +32,7 @@ namespace OWML.Common
IModInteraction Interaction { get; }
IMenuManager MenuHelper { get; }
IModTranslations MenuTranslations { get; }
}
}

View File

@ -0,0 +1,7 @@
namespace OWML.Common.Interfaces
{
public interface IModTranslations
{
public string GetLocalizedString(string key);
}
}

View File

@ -3,6 +3,7 @@ using System.Linq;
using OWML.Common;
using OWML.Common.Menus;
using OWML.Utils;
using OWML.Common.Interfaces;
namespace OWML.ModHelper.Menus
{
@ -19,6 +20,8 @@ namespace OWML.ModHelper.Menus
private IModNumberInput _numberInputTemplate;
private IModSeparator _seperatorTemplate;
private IModTranslations _translations;
protected abstract void AddInputs();
public abstract void UpdateUIValues();
@ -28,6 +31,8 @@ namespace OWML.ModHelper.Menus
{
Manifest = manifest;
Storage = storage;
_translations = new ModTranslations(manifest, console);
}
public void Initialize(Menu menu, IModToggleInput toggleTemplate, IModSliderInput sliderTemplate,
@ -111,7 +116,7 @@ namespace OWML.ModHelper.Menus
{
var toggle = AddToggleInput(_toggleTemplate.Copy(key), index);
toggle.Element.name = key;
toggle.Title = (string)obj?["title"] ?? key;
SetupTitle(toggle, (string)obj?["title"], key);
SetupInputTooltip(toggle, (string)obj?["tooltip"]);
toggle.Show();
}
@ -122,7 +127,7 @@ namespace OWML.ModHelper.Menus
slider.Min = (float)obj["min"];
slider.Max = (float)obj["max"];
slider.Element.name = key;
slider.Title = (string)obj["title"] ?? key;
SetupTitle(slider, (string)obj?["title"], key);
SetupInputTooltip(slider, (string)obj["tooltip"]);
slider.Show();
}
@ -132,7 +137,7 @@ namespace OWML.ModHelper.Menus
var options = obj["options"].ToObject<string[]>();
var selector = AddSelectorInput(_selectorTemplate.Copy(key), index);
selector.Element.name = key;
selector.Title = (string)obj["title"] ?? key;
SetupTitle(selector, (string)obj?["title"], key);
selector.Initialize((string)obj["value"], options);
SetupInputTooltip(selector, (string)obj["tooltip"]);
selector.Show();
@ -142,7 +147,7 @@ namespace OWML.ModHelper.Menus
{
var textInput = AddTextInput(_textInputTemplate.Copy(key), index);
textInput.Element.name = key;
textInput.Title = (string)obj?["title"] ?? key;
SetupTitle(textInput, (string)obj?["title"], key);
SetupInputTooltip(textInput, (string)obj?["tooltip"]);
textInput.Show();
}
@ -151,7 +156,7 @@ namespace OWML.ModHelper.Menus
{
var numberInput = AddNumberInput(_numberInputTemplate.Copy(key), index);
numberInput.Element.name = key;
numberInput.Title = (string)obj?["title"] ?? key;
SetupTitle(numberInput, (string)obj?["title"], key);
SetupInputTooltip(numberInput, (string)obj?["tooltip"]);
numberInput.Show();
}
@ -160,7 +165,7 @@ namespace OWML.ModHelper.Menus
{
var separator = AddSeparator(_seperatorTemplate.Copy("Inputs"), index);
separator.Element.name = key;
separator.Title = (string)obj?["title"] ?? key;
SetupTitle(separator, (string)obj?["title"], key);
separator.Show();
}
@ -168,7 +173,12 @@ namespace OWML.ModHelper.Menus
{
var menuOption = input.Element.GetComponent<MenuOption>();
menuOption.SetValue("_tooltipTextType", UITextType.None);
menuOption.SetValue("_overrideTooltipText", tooltip?? "");
menuOption.SetValue("_overrideTooltipText", _translations.GetLocalizedString(tooltip) ?? "");
}
internal void SetupTitle(IModInputBase input, string title, string key)
{
input.Title = title == null ? key : _translations.GetLocalizedString(title);
}
}
}

View File

@ -0,0 +1,94 @@
using Newtonsoft.Json.Linq;
using OWML.Common;
using OWML.Common.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
namespace OWML.ModHelper.Menus
{
public class ModTranslations : IModTranslations
{
private Dictionary<TextTranslation.Language, Dictionary<string, string>> _translationTable = new();
private IModManifest _manifest;
private IModConsole _console;
// Menu translations are stored under UIDictionary
// This means OWML config translations follow the New Horizons format
public static readonly string UIDictionary = nameof(UIDictionary);
private bool _initialized;
public ModTranslations(IModManifest manifest, IModConsole console)
{
_manifest = manifest;
_console = console;
}
private void Init()
{
try
{
var translationsFolder = Path.Combine(_manifest.ModFolderPath, "translations");
foreach (TextTranslation.Language translation in Enum.GetValues(typeof(TextTranslation.Language)))
{
var filename = Path.Combine(translationsFolder, $"{translation}.json");
if (File.Exists(filename))
{
var dict = JObject.Parse(File.ReadAllText(filename)).ToObject<Dictionary<string, object>>();
if (dict.ContainsKey(UIDictionary))
{
_translationTable[translation] = (Dictionary<string, string>)(dict[nameof(UIDictionary)] as JObject).ToObject(typeof(Dictionary<string, string>));
}
}
}
_initialized = true;
}
catch (Exception ex)
{
_console.WriteLine(ex.ToString(), MessageType.Error);
}
}
public string GetLocalizedString(string key)
{
if (!_initialized)
{
Init();
}
_console.WriteLine($"{_translationTable == null} {string.Join(", ", _translationTable.Keys)}", MessageType.Error);
try
{
if (key == null) return null;
if (key == string.Empty) return string.Empty;
if (!_translationTable.TryGetValue(TextTranslation.Get().m_language, out var dict))
{
// Default to English
if (!_translationTable.TryGetValue(TextTranslation.Language.ENGLISH, out dict))
{
// Default to key
return key;
}
}
if (dict.TryGetValue(key, out var value))
{
return value;
}
else
{
return key;
}
}
catch (Exception ex)
{
_console.WriteLine(ex.ToString(), MessageType.Error);
return key;
}
}
}
}

View File

@ -225,12 +225,12 @@ namespace OWML.ModHelper.Menus.NewMenuSystem
{
if (settingObject["title"] != null)
{
label = settingObject["title"].ToString();
label = mod.ModHelper.MenuTranslations.GetLocalizedString(settingObject["title"].ToString());
}
if (settingObject["tooltip"] != null)
{
tooltip = settingObject["tooltip"].ToString();
tooltip = mod.ModHelper.MenuTranslations.GetLocalizedString(settingObject["tooltip"].ToString());
}
}

View File

@ -1,4 +1,5 @@
using OWML.Common;
using OWML.Common.Interfaces;
using OWML.Common.Menus;
namespace OWML.ModHelper
@ -31,6 +32,8 @@ namespace OWML.ModHelper
public IMenuManager MenuHelper { get; }
public IModTranslations MenuTranslations { get; }
public ModHelper(
IModLogger logger,
IModConsole console,
@ -44,7 +47,8 @@ namespace OWML.ModHelper
IModDefaultConfig defaultConfig,
IOwmlConfig owmlConfig,
IModInteraction interaction,
IMenuManager menuHelper)
IMenuManager menuHelper,
IModTranslations menuTranslations)
{
Logger = logger;
Console = console;
@ -59,6 +63,7 @@ namespace OWML.ModHelper
OwmlConfig = owmlConfig;
Interaction = interaction;
MenuHelper = menuHelper;
MenuTranslations = menuTranslations;
}
}
}

View File

@ -11,6 +11,7 @@ using OWML.ModHelper.Assets;
using OWML.ModHelper.Events;
using OWML.ModHelper.Input;
using OWML.ModHelper.Interaction;
using OWML.ModHelper.Menus;
using OWML.Utils;
using System;
using System.Collections.Generic;
@ -245,6 +246,7 @@ namespace OWML.ModLoader
.Add<IModEvents, ModEvents>()
.Add<IInterfaceProxyFactory, InterfaceProxyFactory>()
.Add<IModInteraction, ModInteraction>()
.Add<IModTranslations, ModTranslations>()
.Add<IModHelper, ModHelper.ModHelper>()
.Resolve<IModHelper>();