i18n(settings): translate the settings window
The settings window was rebuilt in v1.10.0 and v1.11.0 with its labels written straight into the C#. Every section heading and most row labels across five tabs read English in all 25 languages, which the memory notes had accepted as a known backlog. Forty-nine keys close it: seventeen section headings, the rows under them, and the two layout choices. All 25 languages, 437 keys each, no gaps and no placeholder drift in either direction. The layout labels are a property rather than a static array now. A static one would hold whichever language the plugin started in, and this plugin switches language at runtime. What stays English, deliberately: log lines and thread names, which no user reads; the two developer tools behind Shift plus Ctrl+Shift, per the decision that developer surfaces stay English; and the About tab's brand lines, attributions and licence identifiers, which are names.
This commit is contained in:
@@ -43,15 +43,15 @@ internal sealed class AboutTab
|
||||
// real render can never let the integrations-status SelfTest pass falsely.
|
||||
LastHonorificStatusKey = null;
|
||||
DrawPluginInfo();
|
||||
DrawSectionHeader("Brand");
|
||||
DrawSectionHeader(HellionStrings.Settings_Section_Brand);
|
||||
DrawBrand();
|
||||
DrawSectionHeader("Links");
|
||||
DrawSectionHeader(HellionStrings.Settings_Section_Links);
|
||||
DrawLinks();
|
||||
DrawSectionHeader("Integrations");
|
||||
DrawSectionHeader(HellionStrings.Settings_Section_Integrations);
|
||||
DrawIntegrations();
|
||||
DrawSectionHeader("Credits");
|
||||
DrawSectionHeader(HellionStrings.Settings_Section_Credits);
|
||||
DrawCredits();
|
||||
DrawSectionHeader("License");
|
||||
DrawSectionHeader(HellionStrings.Settings_Section_License);
|
||||
DrawLicense();
|
||||
}
|
||||
|
||||
@@ -94,8 +94,11 @@ internal sealed class AboutTab
|
||||
private void DrawLinks()
|
||||
{
|
||||
DrawLinkButton("Discord (Hellion Forge)", BrandingLinks.HellionForgeDiscordInvite);
|
||||
DrawLinkButton("Gitea repository", BrandingLinks.HellionChatRepo);
|
||||
DrawLinkButton("Custom repo manifest", BrandingLinks.HellionChatCustomRepoManifest);
|
||||
DrawLinkButton(HellionStrings.Settings_About_GiteaRepo, BrandingLinks.HellionChatRepo);
|
||||
DrawLinkButton(
|
||||
HellionStrings.Settings_About_CustomRepo,
|
||||
BrandingLinks.HellionChatCustomRepoManifest
|
||||
);
|
||||
}
|
||||
|
||||
private void DrawIntegrations()
|
||||
|
||||
@@ -77,26 +77,37 @@ internal sealed class ChannelsTab
|
||||
ImGui.TextWrapped(HellionStrings.ChatLog_AutoTellTabs_ConflictHint);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("channels.autoopen"u8), "Tell auto-open"))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("channels.autoopen"u8),
|
||||
HellionStrings.Settings_Section_TellAutoOpen
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("channels.autoopen.mode"u8),
|
||||
"Tell auto-open mode",
|
||||
"Where a tell opens when it arrives.",
|
||||
HellionStrings.Settings_Channels_TellAutoOpenMode_Name,
|
||||
HellionStrings.Settings_Channels_TellAutoOpenMode_Description,
|
||||
() => Plugin.Config.TellAutoOpenMode,
|
||||
v => Plugin.Config.TellAutoOpenMode = v,
|
||||
v => v.Name()
|
||||
);
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("channels.autoopen.switch"u8),
|
||||
"Switch to the tab on every tell",
|
||||
"Otherwise the tab opens in the background after the first one.",
|
||||
HellionStrings.Settings_Channels_TellSwitchAlways_Name,
|
||||
HellionStrings.Settings_Channels_TellSwitchAlways_Description,
|
||||
() => Plugin.Config.TellAutoOpenSwitchAlways,
|
||||
v => Plugin.Config.TellAutoOpenSwitchAlways = v
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("channels.sidebar"u8), "Sidebar", open: false))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("channels.sidebar"u8),
|
||||
HellionStrings.Settings_Section_Sidebar,
|
||||
open: false
|
||||
)
|
||||
)
|
||||
{
|
||||
// Bounds come from the constants rather than repeating the numbers,
|
||||
// so the slider cannot drift away from the clamp in Sidebar.GetWidth.
|
||||
|
||||
@@ -23,18 +23,18 @@ internal sealed class ChatTab
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (_w.Section(ImGui.GetID("chat.display"u8), "Display modes"))
|
||||
if (_w.Section(ImGui.GetID("chat.display"u8), HellionStrings.Settings_Section_DisplayModes))
|
||||
{
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.display.density"u8),
|
||||
"Compact density",
|
||||
"Trades the card layout for one line per message.",
|
||||
HellionStrings.Settings_Chat_CompactDensity_Name,
|
||||
HellionStrings.Settings_Chat_CompactDensity_Description,
|
||||
() => Plugin.Config.UseCompactDensity,
|
||||
v => Plugin.Config.UseCompactDensity = v
|
||||
);
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.display.clock"u8),
|
||||
"24-hour clock",
|
||||
HellionStrings.Settings_Chat_Clock24_Name,
|
||||
null,
|
||||
() => Plugin.Config.Use24HourClock,
|
||||
v => Plugin.Config.Use24HourClock = v
|
||||
@@ -61,7 +61,7 @@ internal sealed class ChatTab
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("chat.history"u8), "History"))
|
||||
if (_w.Section(ImGui.GetID("chat.history"u8), HellionStrings.Settings_Section_History))
|
||||
{
|
||||
// The one setting that decides whether the chat log shows anything
|
||||
// from before this game session. It had no control at all: only the
|
||||
@@ -74,9 +74,8 @@ internal sealed class ChatTab
|
||||
// writes a field nothing reads.
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.history.previoussessions"u8),
|
||||
"Show history from previous sessions",
|
||||
"Off means the log starts empty each time the game launches and "
|
||||
+ "only fills with messages received since.",
|
||||
HellionStrings.Settings_Chat_PreviousSessions_Name,
|
||||
HellionStrings.Settings_Chat_PreviousSessions_Description,
|
||||
() => Plugin.Config.FilterIncludePreviousSessions,
|
||||
v =>
|
||||
{
|
||||
@@ -88,19 +87,31 @@ internal sealed class ChatTab
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("chat.commandhelp"u8), "Command help", open: false))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("chat.commandhelp"u8),
|
||||
HellionStrings.Settings_Section_CommandHelp,
|
||||
open: false
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("chat.commandhelp.side"u8),
|
||||
"Command help side",
|
||||
"Which side the command hint list appears on while typing.",
|
||||
HellionStrings.Settings_Chat_CommandHelpSide_Name,
|
||||
HellionStrings.Settings_Chat_CommandHelpSide_Description,
|
||||
() => Plugin.Config.CommandHelpSide,
|
||||
v => Plugin.Config.CommandHelpSide = v,
|
||||
v => v.Name()
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("chat.disclosure"u8), "Plugin disclosure", open: false))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("chat.disclosure"u8),
|
||||
HellionStrings.Settings_Section_PluginDisclosure,
|
||||
open: false
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.disclosure.notify"u8),
|
||||
|
||||
@@ -34,29 +34,34 @@ internal sealed class GeneralTab
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (_w.Section(ImGui.GetID("general.behaviour"u8), "Behaviour"))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("general.behaviour"u8),
|
||||
HellionStrings.Settings_Section_Behaviour
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("general.behaviour.reducemotion"u8),
|
||||
HellionStrings.Settings_ThemeAndLayout_ReduceMotion_Name,
|
||||
"Turns off theme crossfades, hover fades and the drifting motes.",
|
||||
HellionStrings.Settings_General_ReduceMotion_Description,
|
||||
() => Plugin.Config.ReduceMotion,
|
||||
v => Plugin.Config.ReduceMotion = v
|
||||
);
|
||||
DrawLanguagePicker();
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("general.keybinds"u8), "Keybinds"))
|
||||
if (_w.Section(ImGui.GetID("general.keybinds"u8), HellionStrings.Settings_Section_Keybinds))
|
||||
{
|
||||
ImGui.TextDisabled("Click a button, then press the key combination. Esc clears.");
|
||||
ImGui.TextDisabled(HellionStrings.Settings_Keybinds_Hint);
|
||||
DrawKeybind(
|
||||
"Cycle to next chat tab",
|
||||
HellionStrings.Settings_Keybinds_CycleNext,
|
||||
"ChatTabForwardKeybind",
|
||||
() => Plugin.Config.ChatTabForward,
|
||||
v => Plugin.Config.ChatTabForward = v
|
||||
);
|
||||
DrawKeybind(
|
||||
"Cycle to previous chat tab",
|
||||
HellionStrings.Settings_Keybinds_CyclePrevious,
|
||||
"ChatTabBackwardKeybind",
|
||||
() => Plugin.Config.ChatTabBackward,
|
||||
v => Plugin.Config.ChatTabBackward = v
|
||||
@@ -64,7 +69,12 @@ internal sealed class GeneralTab
|
||||
DrawKeybindModePicker();
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("general.notifications"u8), "Notifications"))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("general.notifications"u8),
|
||||
HellionStrings.Settings_Section_Notifications
|
||||
)
|
||||
)
|
||||
{
|
||||
// The game reports a failed tell in the log only, where a player who
|
||||
// is typing does not see it. On by default and never reachable.
|
||||
@@ -110,7 +120,7 @@ internal sealed class GeneralTab
|
||||
_w.Row(
|
||||
ImGui.GetID("general.behaviour.language"u8),
|
||||
Language.Options_Language_Name,
|
||||
"Switching rebuilds the font atlas, so the chat goes blank for a moment.",
|
||||
HellionStrings.Settings_General_Language_Description,
|
||||
ctx =>
|
||||
{
|
||||
ImGui.SetNextItemWidth(ctx.ControlWidth);
|
||||
|
||||
@@ -18,7 +18,15 @@ internal sealed class WindowTab
|
||||
MainWindowLayoutMode.Sidebar,
|
||||
MainWindowLayoutMode.TopTabs,
|
||||
];
|
||||
private static readonly string[] LayoutLabels = ["Sidebar", "Top tabs"];
|
||||
|
||||
// Built per call rather than cached: a runtime language switch has to reach
|
||||
// these, and a static array would keep whichever language the plugin
|
||||
// happened to start in.
|
||||
private static string[] LayoutLabels =>
|
||||
[
|
||||
HellionStrings.Settings_Window_LayoutSidebar,
|
||||
HellionStrings.Settings_Window_LayoutTopTabs,
|
||||
];
|
||||
|
||||
public WindowTab(Plugin plugin, TokenResolver resolver)
|
||||
{
|
||||
@@ -29,12 +37,12 @@ internal sealed class WindowTab
|
||||
{
|
||||
// ASCII literals, not the visible titles: the keys have to survive a
|
||||
// language change, and u8 literals cost no allocation.
|
||||
if (_w.Section(ImGui.GetID("window.layout"u8), "Layout mode"))
|
||||
if (_w.Section(ImGui.GetID("window.layout"u8), HellionStrings.Settings_Section_LayoutMode))
|
||||
{
|
||||
_w.SegmentRow(
|
||||
ImGui.GetID("window.layout.mode"u8),
|
||||
"Tab placement",
|
||||
"Where the tab list sits in the main window.",
|
||||
HellionStrings.Settings_Window_TabPlacement_Name,
|
||||
HellionStrings.Settings_Window_TabPlacement_Description,
|
||||
LayoutValues,
|
||||
LayoutLabels,
|
||||
() => Plugin.Config.MainWindowLayoutMode,
|
||||
@@ -51,14 +59,14 @@ internal sealed class WindowTab
|
||||
{
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("window.style.titlebar"u8),
|
||||
"Show title bar",
|
||||
HellionStrings.Settings_Window_TitleBar_Name,
|
||||
null,
|
||||
() => Plugin.Config.ShowTitleBar,
|
||||
v => Plugin.Config.ShowTitleBar = v
|
||||
);
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("window.style.popouttitlebar"u8),
|
||||
"Show title bar for pop-outs",
|
||||
HellionStrings.Settings_Window_PopoutTitleBar_Name,
|
||||
null,
|
||||
() => Plugin.Config.ShowPopOutTitleBar,
|
||||
v => Plugin.Config.ShowPopOutTitleBar = v
|
||||
@@ -72,7 +80,7 @@ internal sealed class WindowTab
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("window.opacity"u8), "Opacity"))
|
||||
if (_w.Section(ImGui.GetID("window.opacity"u8), HellionStrings.Settings_Section_Opacity))
|
||||
{
|
||||
_w.SliderFloatRow(
|
||||
ImGui.GetID("window.opacity.active"u8),
|
||||
@@ -85,8 +93,8 @@ internal sealed class WindowTab
|
||||
);
|
||||
_w.SliderFloatRow(
|
||||
ImGui.GetID("window.opacity.inactive"u8),
|
||||
"Inactive opacity",
|
||||
"Applies while another window has focus.",
|
||||
HellionStrings.Settings_Window_InactiveOpacity_Name,
|
||||
HellionStrings.Settings_Window_InactiveOpacity_Description,
|
||||
() => Plugin.Config.WindowOpacityInactive,
|
||||
v => Plugin.Config.WindowOpacityInactive = v,
|
||||
0.1f,
|
||||
@@ -94,26 +102,31 @@ internal sealed class WindowTab
|
||||
);
|
||||
}
|
||||
|
||||
if (_w.Section(ImGui.GetID("window.resize"u8), "Resize behaviour"))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("window.resize"u8),
|
||||
HellionStrings.Settings_Section_ResizeBehaviour
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("window.resize.move"u8),
|
||||
"Allow movement",
|
||||
HellionStrings.Settings_Window_AllowMove_Name,
|
||||
null,
|
||||
() => Plugin.Config.CanMove,
|
||||
v => Plugin.Config.CanMove = v
|
||||
);
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("window.resize.resize"u8),
|
||||
"Allow resize",
|
||||
HellionStrings.Settings_Window_AllowResize_Name,
|
||||
null,
|
||||
() => Plugin.Config.CanResize,
|
||||
v => Plugin.Config.CanResize = v
|
||||
);
|
||||
_w.SliderIntRow(
|
||||
ImGui.GetID("window.resize.threshold"u8),
|
||||
"Sidebar auto-switch threshold",
|
||||
"Below this width the sidebar folds into top tabs, in pixels.",
|
||||
HellionStrings.Settings_Window_SidebarThreshold_Name,
|
||||
HellionStrings.Settings_Window_SidebarThreshold_Description,
|
||||
() => Plugin.Config.SidebarAutoSwitchThresholdPx,
|
||||
v => Plugin.Config.SidebarAutoSwitchThresholdPx = v,
|
||||
200,
|
||||
@@ -131,7 +144,7 @@ internal sealed class WindowTab
|
||||
{
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("window.preview.position"u8),
|
||||
"Preview position",
|
||||
HellionStrings.Settings_Window_PreviewPosition_Name,
|
||||
null,
|
||||
() => Plugin.Config.PreviewPosition,
|
||||
v => Plugin.Config.PreviewPosition = v,
|
||||
@@ -139,7 +152,7 @@ internal sealed class WindowTab
|
||||
);
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("window.preview.onlyif"u8),
|
||||
"Only show preview when typing",
|
||||
HellionStrings.Settings_Window_PreviewOnlyTyping_Name,
|
||||
null,
|
||||
() => Plugin.Config.OnlyPreviewIf,
|
||||
v => Plugin.Config.OnlyPreviewIf = v
|
||||
|
||||
Reference in New Issue
Block a user