Expose mod.yaml content to localisation.
Mod metadata, load screens and mod content is all now sourced from ftl files, allowing these items to be translated. Translations are now initialized as part of ModData creation, as currently they are made available too late for the usage we need here. The "modcontent" mod learns a new parameter for "Content.TranslationFile" - this allows a mod to provide the path of a translation file to the mod which it can load. This allows mods such as ra, cnc, d2k, ts to own the translations for their ModContent, yet still make them accessible to the modcontent mod. CheckFluentReference learns to validate all these new fields to ensure translations have been set.
This commit is contained in:
@@ -193,7 +193,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var switchButton = panel.Get<ButtonWidget>("SWITCH_BUTTON");
|
||||
|
||||
var mod = CurrentServerSettings.ServerExternalMod;
|
||||
var modTitle = mod.Title;
|
||||
var modTitle = mod.Id;
|
||||
var modVersion = mod.Version;
|
||||
|
||||
switchButton.OnClick = () =>
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly ModData modData;
|
||||
readonly ModContent content;
|
||||
readonly Dictionary<string, ModContent.ModSource> sources;
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
|
||||
readonly Widget panel;
|
||||
readonly LabelWidget titleLabel;
|
||||
@@ -116,11 +117,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
Mode visible = Mode.Progress;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public InstallFromSourceLogic(Widget widget, ModData modData, ModContent content, Dictionary<string, ModContent.ModSource> sources)
|
||||
public InstallFromSourceLogic(
|
||||
Widget widget, ModData modData, ModContent content, Dictionary<string, ModContent.ModSource> sources, FluentBundle externalFluentBundle)
|
||||
{
|
||||
this.modData = modData;
|
||||
this.content = content;
|
||||
this.sources = sources;
|
||||
this.externalFluentBundle = externalFluentBundle;
|
||||
|
||||
Log.AddChannel("install", "install.log");
|
||||
|
||||
@@ -339,7 +342,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var containerWidget = (ContainerWidget)checkboxListTemplate.Clone();
|
||||
var checkboxWidget = containerWidget.Get<CheckboxWidget>("PACKAGE_CHECKBOX");
|
||||
checkboxWidget.GetText = () => package.Title;
|
||||
var title = externalFluentBundle.GetString(package.Title);
|
||||
checkboxWidget.GetText = () => title;
|
||||
checkboxWidget.IsDisabled = () => package.Required;
|
||||
checkboxWidget.IsChecked = () => selectedPackages[package.Identifier];
|
||||
checkboxWidget.OnClick = () => selectedPackages[package.Identifier] = !selectedPackages[package.Identifier];
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Widgets;
|
||||
@@ -30,10 +31,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
readonly Dictionary<string, ModContent.ModSource> sources = new();
|
||||
readonly Dictionary<string, ModContent.ModDownload> downloads = new();
|
||||
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
|
||||
bool sourceAvailable;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel)
|
||||
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel, string translationFilePath)
|
||||
{
|
||||
this.content = content;
|
||||
|
||||
@@ -58,20 +61,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
modFileSystem.UnmountAll();
|
||||
|
||||
externalFluentBundle = new FluentBundle(Game.Settings.Player.Language, File.ReadAllText(translationFilePath), _ => { });
|
||||
|
||||
scrollPanel = panel.Get<ScrollPanelWidget>("PACKAGES");
|
||||
template = scrollPanel.Get<ContainerWidget>("PACKAGE_TEMPLATE");
|
||||
|
||||
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
|
||||
var headerLines = !string.IsNullOrEmpty(content.HeaderMessage) ? content.HeaderMessage.Replace("\\n", "\n").Split('\n') : Array.Empty<string>();
|
||||
var headerLines =
|
||||
!string.IsNullOrEmpty(content.HeaderMessage)
|
||||
? externalFluentBundle.GetString(content.HeaderMessage)
|
||||
: null;
|
||||
var headerHeight = 0;
|
||||
foreach (var l in headerLines)
|
||||
if (headerLines != null)
|
||||
{
|
||||
var line = (LabelWidget)headerTemplate.Clone();
|
||||
line.GetText = () => l;
|
||||
line.Bounds.Y += headerHeight;
|
||||
panel.AddChild(line);
|
||||
var label = (LabelWidget)headerTemplate.Clone();
|
||||
label.GetText = () => headerLines;
|
||||
label.IncreaseHeightToFitCurrentText();
|
||||
panel.AddChild(label);
|
||||
|
||||
headerHeight += headerTemplate.Bounds.Height;
|
||||
headerHeight += label.Bounds.Height;
|
||||
}
|
||||
|
||||
panel.Bounds.Height += headerHeight;
|
||||
@@ -85,7 +93,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
sourceButton.OnClick = () => Ui.OpenWindow("SOURCE_INSTALL_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "sources", sources },
|
||||
{ "content", content }
|
||||
{ "content", content },
|
||||
{ "externalFluentBundle", externalFluentBundle },
|
||||
});
|
||||
|
||||
var backButton = panel.Get<ButtonWidget>("BACK_BUTTON");
|
||||
@@ -109,7 +118,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var container = template.Clone();
|
||||
var titleWidget = container.Get<LabelWidget>("TITLE");
|
||||
var title = p.Value.Title;
|
||||
var title = externalFluentBundle.GetString(p.Value.Title);
|
||||
titleWidget.GetText = () => title;
|
||||
|
||||
var requiredWidget = container.Get<LabelWidget>("REQUIRED");
|
||||
|
||||
@@ -27,14 +27,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
const string Quit = "button-quit";
|
||||
|
||||
readonly ModContent content;
|
||||
readonly FluentBundle externalFluentBundle;
|
||||
bool requiredContentInstalled;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ModContentPromptLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action continueLoading)
|
||||
public ModContentPromptLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action continueLoading, string translationFilePath)
|
||||
{
|
||||
this.content = content;
|
||||
CheckRequiredContentInstalled();
|
||||
|
||||
externalFluentBundle = new FluentBundle(Game.Settings.Player.Language, File.ReadAllText(translationFilePath), _ => { });
|
||||
|
||||
var continueMessage = FluentProvider.GetString(Continue);
|
||||
var quitMessage = FluentProvider.GetString(Quit);
|
||||
|
||||
@@ -42,17 +45,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
|
||||
var headerLines =
|
||||
!string.IsNullOrEmpty(content.InstallPromptMessage)
|
||||
? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n')
|
||||
: Array.Empty<string>();
|
||||
? externalFluentBundle.GetString(content.InstallPromptMessage)
|
||||
: null;
|
||||
var headerHeight = 0;
|
||||
foreach (var l in headerLines)
|
||||
if (headerLines != null)
|
||||
{
|
||||
var line = (LabelWidget)headerTemplate.Clone();
|
||||
line.GetText = () => l;
|
||||
line.Bounds.Y += headerHeight;
|
||||
panel.AddChild(line);
|
||||
var label = (LabelWidget)headerTemplate.Clone();
|
||||
label.GetText = () => headerLines;
|
||||
label.IncreaseHeightToFitCurrentText();
|
||||
panel.AddChild(label);
|
||||
|
||||
headerHeight += headerTemplate.Bounds.Height;
|
||||
headerHeight += label.Bounds.Height;
|
||||
}
|
||||
|
||||
panel.Bounds.Height += headerHeight;
|
||||
@@ -64,9 +67,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
Ui.OpenWindow("CONTENT_PANEL", new WidgetArgs
|
||||
{
|
||||
{ "onCancel", CheckRequiredContentInstalled },
|
||||
{ "mod", mod },
|
||||
{ "content", content },
|
||||
{ "onCancel", CheckRequiredContentInstalled }
|
||||
{ "translationFilePath", translationFilePath },
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -93,7 +93,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
return;
|
||||
|
||||
var content = modData.Manifest.Get<ModContent>();
|
||||
Game.InitializeMod(content.ContentInstallerMod, new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id }));
|
||||
string translationPath;
|
||||
using (var fs = (FileStream)modData.DefaultFileSystem.Open(content.Translation))
|
||||
translationPath = fs.Name;
|
||||
Game.InitializeMod(
|
||||
content.ContentInstallerMod,
|
||||
new Arguments(new[] { "Content.Mod=" + modData.Manifest.Id, "Content.TranslationFile=" + translationPath }));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user