Expose hotkeys to localisation.

Allows the Settings > Hotkeys screen to be localised, including hotkey decriptions, groups and contexts.

The hotkey names are exposed to localisation via KeycodeExts. Hotkey modifiers are similarly exposed via ModifersExts.

The Settings > Input screen has a Zoom Modifier dropdown, which shows the localised modifier name.

The --check-yaml utility command is taught to recognise all hotkey translation, so it can validate their usage.
This commit is contained in:
RoosterDragon
2024-09-17 19:42:42 +01:00
committed by Gustas
parent 10856ccfd0
commit 6f6fb5b393
39 changed files with 1284 additions and 722 deletions

View File

@@ -25,6 +25,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[FluentReference("key", "context")]
const string DuplicateNotice = "label-duplicate-notice";
[FluentReference]
const string AnyContext = "hotkey-context-any";
readonly ModData modData;
readonly Dictionary<string, MiniYaml> logicArgs;
@@ -37,8 +40,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool isHotkeyValid;
bool isHotkeyDefault;
string currentContext = "Any";
readonly HashSet<string> contexts = new() { "Any" };
string currentContext = AnyContext;
readonly HashSet<string> contexts = new() { AnyContext };
readonly Dictionary<string, HashSet<string>> hotkeyGroups = new();
TextFieldWidget filterInput;
@@ -66,7 +69,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
key.Id = hd.Name;
key.IsVisible = () => true;
key.Get<LabelWidget>("FUNCTION").GetText = () => hd.Description + ":";
var desc = FluentProvider.GetString(hd.Description) + ":";
key.Get<LabelWidget>("FUNCTION").GetText = () => desc;
var remapButton = key.Get<ButtonWidget>("HOTKEY");
WidgetUtils.TruncateButtonToTooltip(remapButton, modData.Hotkeys[hd.Name].GetValue().DisplayString());
@@ -192,7 +196,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
continue;
var header = headerTemplate.Clone();
header.Get<LabelWidget>("LABEL").GetText = () => hg.Key;
var groupName = FluentProvider.GetString(hg.Key);
header.Get<LabelWidget>("LABEL").GetText = () => groupName;
hotkeyList.AddChild(header);
var added = new HashSet<HotkeyDefinition>();
@@ -220,7 +225,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void InitHotkeyRemapDialog(Widget panel)
{
var label = panel.Get<LabelWidget>("HOTKEY_LABEL");
var labelText = new CachedTransform<HotkeyDefinition, string>(hd => hd?.Description + ":");
var labelText = new CachedTransform<HotkeyDefinition, string>(
hd => (hd != null ? FluentProvider.GetString(hd.Description) : "") + ":");
label.IsVisible = () => selectedHotkeyDefinition != null;
label.GetText = () => labelText.Update(selectedHotkeyDefinition);
@@ -228,10 +234,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
duplicateNotice.TextColor = ChromeMetrics.Get<Color>("NoticeErrorColor");
duplicateNotice.IsVisible = () => !isHotkeyValid;
var duplicateNoticeText = new CachedTransform<HotkeyDefinition, string>(hd =>
hd != null ?
FluentProvider.GetString(DuplicateNotice,
"key", hd.Description,
"context", hd.Contexts.First(c => selectedHotkeyDefinition.Contexts.Contains(c))) : "");
hd != null
? FluentProvider.GetString(
DuplicateNotice,
"key", FluentProvider.GetString(hd.Description),
"context", FluentProvider.GetString(hd.Contexts.First(c => selectedHotkeyDefinition.Contexts.Contains(c))))
: "");
duplicateNotice.GetText = () => duplicateNoticeText.Update(duplicateHotkeyDefinition);
var originalNotice = panel.Get<LabelWidget>("ORIGINAL_NOTICE");
@@ -328,8 +336,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var filter = filterInput.Text;
var isFilteredByName = string.IsNullOrWhiteSpace(filter) ||
hd.Description.Contains(filter, StringComparison.CurrentCultureIgnoreCase);
var isFilteredByContext = currentContext == "Any" || hd.Contexts.Contains(currentContext);
FluentProvider.GetString(hd.Description).Contains(filter, StringComparison.CurrentCultureIgnoreCase);
var isFilteredByContext = currentContext == AnyContext || hd.Contexts.Contains(currentContext);
return isFilteredByName && isFilteredByContext;
}
@@ -357,9 +365,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
static string GetContextDisplayName(string context)
{
if (string.IsNullOrEmpty(context))
return "Any";
context = AnyContext;
return context;
return FluentProvider.GetString(context);
}
}
}

View File

@@ -36,21 +36,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[FluentReference]
const string Joystick = "options-mouse-scroll-type.joystick";
[FluentReference]
const string Alt = "options-zoom-modifier.alt";
[FluentReference]
const string Ctrl = "options-zoom-modifier.ctrl";
[FluentReference]
const string Meta = "options-zoom-modifier.meta";
[FluentReference]
const string Shift = "options-zoom-modifier.shift";
[FluentReference]
const string None = "options-zoom-modifier.none";
static InputSettingsLogic() { }
readonly string classic;
@@ -205,11 +190,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var options = new Dictionary<string, Modifiers>()
{
{ FluentProvider.GetString(Alt), Modifiers.Alt },
{ FluentProvider.GetString(Ctrl), Modifiers.Ctrl },
{ FluentProvider.GetString(Meta), Modifiers.Meta },
{ FluentProvider.GetString(Shift), Modifiers.Shift },
{ FluentProvider.GetString(None), Modifiers.None }
{ ModifiersExts.DisplayString(Modifiers.Alt), Modifiers.Alt },
{ ModifiersExts.DisplayString(Modifiers.Ctrl), Modifiers.Ctrl },
{ ModifiersExts.DisplayString(Modifiers.Meta), Modifiers.Meta },
{ ModifiersExts.DisplayString(Modifiers.Shift), Modifiers.Shift },
{ ModifiersExts.DisplayString(Modifiers.None), Modifiers.None }
};
ScrollItemWidget SetupItem(string o, ScrollItemWidget itemTemplate)