feat(settings): convert the remaining four standard tabs
Chat, Channels, General and Data & Privacy now draw the same way Window does. A half-converted window is worse than an unconverted one: before, all seven tabs were consistently dated; after the pilot, one looked current and six looked abandoned, and switching between them made the seam obvious. Descriptions move out of the help markers and onto the rows. Those strings were written to be read, and a (?) the user has to hover is where an explanation goes to be ignored. Several were translated into 25 languages and had never appeared on screen at all. Two settings that could not use the standard helpers -- the language picker, which rebuilds the font atlas, and the keybind mode, whose description depends on the selected value -- go through a plain Row that hands the caller the control column and leaves the save logic alone. Privacy filter labels now come from the resources that already existed for them, same defect as the channels tab last round: strings present, translated, and reachable from no line of code. Four more constructors take a TokenResolver, so this wants the DI smoke pass. Only the appearance tab still draws stock collapsing headers; its four components are their own block.
This commit is contained in:
@@ -208,20 +208,24 @@ internal static class PluginHostFactory
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.GeneralTab(
|
||||
sp.GetRequiredService<Plugin>(),
|
||||
sp.GetRequiredService<FontManager>()
|
||||
sp.GetRequiredService<FontManager>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChatTab(
|
||||
sp.GetRequiredService<Plugin>()
|
||||
sp.GetRequiredService<Plugin>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.WindowTab(
|
||||
sp.GetRequiredService<Plugin>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.ChannelsTab(
|
||||
sp.GetRequiredService<Plugin>()
|
||||
sp.GetRequiredService<Plugin>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
|
||||
sp.GetRequiredService<Plugin>()
|
||||
sp.GetRequiredService<Plugin>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
));
|
||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.AboutTab(
|
||||
sp.GetRequiredService<FontManager>(),
|
||||
|
||||
@@ -71,6 +71,20 @@ internal sealed class SettingsWidgets
|
||||
// The whole row toggles, label included. The switch itself gets its own
|
||||
// invisible button because SettingRow's hit area stops at the label column,
|
||||
// and clicking the control is what a user tries first.
|
||||
// Escape hatch for controls the helpers do not cover -- a keybind capture,
|
||||
// a picker with side effects. The caller draws whatever it likes into the
|
||||
// control column and keeps its own save logic.
|
||||
internal void Row(
|
||||
uint id,
|
||||
string label,
|
||||
string? description,
|
||||
Action<SettingRowContext> drawControl
|
||||
)
|
||||
{
|
||||
EnsureFrame();
|
||||
SettingRow.Draw(id, label, description, _row, drawControl);
|
||||
}
|
||||
|
||||
internal void ToggleRow(
|
||||
uint id,
|
||||
string label,
|
||||
|
||||
@@ -1,111 +1,116 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using HellionChat.Resources;
|
||||
using HellionChat.Util;
|
||||
using HellionChat.Ui.StyleEngine;
|
||||
|
||||
namespace HellionChat.Ui.Components.Settings.Tabs;
|
||||
|
||||
internal sealed class ChannelsTab
|
||||
{
|
||||
private readonly Plugin _plugin;
|
||||
private readonly SettingsWidgets _w;
|
||||
|
||||
public ChannelsTab(Plugin plugin)
|
||||
public ChannelsTab(Plugin plugin, TokenResolver resolver)
|
||||
{
|
||||
_plugin = plugin;
|
||||
_w = new SettingsWidgets(plugin);
|
||||
_w = new SettingsWidgets(plugin, new SettingsPalette(resolver));
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (
|
||||
ImGui.CollapsingHeader(
|
||||
HellionStrings.Settings_Section_AutoTellTabs,
|
||||
ImGuiTreeNodeFlags.DefaultOpen
|
||||
_w.Section(
|
||||
ImGui.GetID("channels.autotell"u8),
|
||||
HellionStrings.Settings_Section_AutoTellTabs
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("channels.autotell.enable"u8),
|
||||
HellionStrings.ChatLog_AutoTellTabs_Enable_Name,
|
||||
HellionStrings.ChatLog_AutoTellTabs_Enable_Description,
|
||||
() => Plugin.Config.EnableAutoTellTabs,
|
||||
v => Plugin.Config.EnableAutoTellTabs = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Enable_Description);
|
||||
|
||||
_w.SliderInt(
|
||||
_w.SliderIntRow(
|
||||
ImGui.GetID("channels.autotell.limit"u8),
|
||||
HellionStrings.ChatLog_AutoTellTabs_Limit_Name,
|
||||
HellionStrings.ChatLog_AutoTellTabs_Limit_Description,
|
||||
() => Plugin.Config.AutoTellTabsLimit,
|
||||
v => Plugin.Config.AutoTellTabsLimit = v,
|
||||
1,
|
||||
50
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Limit_Description);
|
||||
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("channels.autotell.compact"u8),
|
||||
HellionStrings.ChatLog_AutoTellTabs_Compact_Name,
|
||||
HellionStrings.ChatLog_AutoTellTabs_Compact_Description,
|
||||
() => Plugin.Config.AutoTellTabsCompactDisplay,
|
||||
v => Plugin.Config.AutoTellTabsCompactDisplay = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Compact_Description);
|
||||
|
||||
_w.SliderInt(
|
||||
_w.SliderIntRow(
|
||||
ImGui.GetID("channels.autotell.preload"u8),
|
||||
HellionStrings.Privacy_AutoTellTabs_Preload_Name,
|
||||
HellionStrings.Privacy_AutoTellTabs_Preload_Description,
|
||||
() => Plugin.Config.AutoTellTabsHistoryPreload,
|
||||
v => Plugin.Config.AutoTellTabsHistoryPreload = v,
|
||||
0,
|
||||
200
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Privacy_AutoTellTabs_Preload_Description);
|
||||
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("channels.autotell.greeted"u8),
|
||||
HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Name,
|
||||
HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Description,
|
||||
() => Plugin.Config.AutoTellTabsShowGreetedToggle,
|
||||
v => Plugin.Config.AutoTellTabsShowGreetedToggle = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Description);
|
||||
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("channels.autotell.popout"u8),
|
||||
HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Name,
|
||||
HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Description,
|
||||
() => Plugin.Config.AutoTellTabsOpenAsPopout,
|
||||
v => Plugin.Config.AutoTellTabsOpenAsPopout = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Description);
|
||||
|
||||
// Written for this screen and never shown until now. It names the
|
||||
// one setting in a third-party plugin that silently stops auto-tell
|
||||
// tabs from ever opening, which is not something a user guesses.
|
||||
// Written for this screen and never shown until this cycle. It names
|
||||
// the one setting in a third-party plugin that silently stops
|
||||
// auto-tell tabs from ever opening, which is not something a user
|
||||
// works out alone.
|
||||
ImGui.Spacing();
|
||||
ImGui.TextWrapped(HellionStrings.ChatLog_AutoTellTabs_ConflictHint);
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Tell auto-open mode", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("channels.autoopen"u8), "Tell auto-open"))
|
||||
{
|
||||
_w.EnumCombo(
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("channels.autoopen.mode"u8),
|
||||
"Tell auto-open mode",
|
||||
"Where a tell opens when it arrives.",
|
||||
() => Plugin.Config.TellAutoOpenMode,
|
||||
v => Plugin.Config.TellAutoOpenMode = v,
|
||||
v => v.Name()
|
||||
);
|
||||
_w.Toggle(
|
||||
_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.",
|
||||
() => Plugin.Config.TellAutoOpenSwitchAlways,
|
||||
v => Plugin.Config.TellAutoOpenSwitchAlways = v
|
||||
);
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Sidebar"))
|
||||
if (_w.Section(ImGui.GetID("channels.sidebar"u8), "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.
|
||||
// The stored value is unscaled; display scaling is applied where the
|
||||
// sidebar is drawn.
|
||||
_w.SliderInt(
|
||||
_w.SliderIntRow(
|
||||
ImGui.GetID("channels.sidebar.width"u8),
|
||||
HellionStrings.Settings_ThemeAndLayout_SidebarWidth_Name,
|
||||
HellionStrings.Settings_ThemeAndLayout_SidebarWidth_Description,
|
||||
() => Plugin.Config.SidebarWidth,
|
||||
v => Plugin.Config.SidebarWidth = v,
|
||||
(int)Sidebar.MinSidebarWidth,
|
||||
(int)Sidebar.MaxSidebarWidth
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_ThemeAndLayout_SidebarWidth_Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,79 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using HellionChat.Resources;
|
||||
using HellionChat.Util;
|
||||
using HellionChat.Ui.StyleEngine;
|
||||
|
||||
namespace HellionChat.Ui.Components.Settings.Tabs;
|
||||
|
||||
internal sealed class ChatTab
|
||||
{
|
||||
private readonly Plugin _plugin;
|
||||
private readonly SettingsWidgets _w;
|
||||
|
||||
public ChatTab(Plugin plugin)
|
||||
public ChatTab(Plugin plugin, TokenResolver resolver)
|
||||
{
|
||||
_plugin = plugin;
|
||||
_w = new SettingsWidgets(plugin);
|
||||
_w = new SettingsWidgets(plugin, new SettingsPalette(resolver));
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (ImGui.CollapsingHeader("Display modes", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("chat.display"u8), "Display modes"))
|
||||
{
|
||||
_w.Toggle(
|
||||
"Compact density (card vs compact)",
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.display.density"u8),
|
||||
"Compact density",
|
||||
"Trades the card layout for one line per message.",
|
||||
() => Plugin.Config.UseCompactDensity,
|
||||
v => Plugin.Config.UseCompactDensity = v
|
||||
);
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.display.clock"u8),
|
||||
"24-hour clock",
|
||||
null,
|
||||
() => Plugin.Config.Use24HourClock,
|
||||
v => Plugin.Config.Use24HourClock = v
|
||||
);
|
||||
_w.EnumCombo(
|
||||
|
||||
// Descriptions move out of the help markers and onto the row. They
|
||||
// were written to be read; a (?) the user has to hover is where an
|
||||
// explanation goes to be ignored.
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("chat.display.worldsuffix"u8),
|
||||
HellionStrings.Settings_Chat_WorldSuffix_Name,
|
||||
HellionStrings.Settings_Chat_WorldSuffix_Description,
|
||||
() => Plugin.Config.WorldSuffixMode,
|
||||
v => Plugin.Config.WorldSuffixMode = v,
|
||||
v => v.Name()
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_WorldSuffix_Description);
|
||||
_w.EnumCombo(
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("chat.display.nameform"u8),
|
||||
HellionStrings.Settings_Chat_NameForm_Name,
|
||||
HellionStrings.Settings_Chat_NameForm_Description,
|
||||
() => Plugin.Config.NameFormMode,
|
||||
v => Plugin.Config.NameFormMode = v,
|
||||
v => v.Name()
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NameForm_Description);
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Command help"))
|
||||
if (_w.Section(ImGui.GetID("chat.commandhelp"u8), "Command help", open: false))
|
||||
{
|
||||
_w.EnumCombo(
|
||||
_w.EnumComboRow(
|
||||
ImGui.GetID("chat.commandhelp.side"u8),
|
||||
"Command help side",
|
||||
"Which side the command hint list appears on while typing.",
|
||||
() => Plugin.Config.CommandHelpSide,
|
||||
v => Plugin.Config.CommandHelpSide = v,
|
||||
v => v.Name()
|
||||
);
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Plugin disclosure"))
|
||||
if (_w.Section(ImGui.GetID("chat.disclosure"u8), "Plugin disclosure", open: false))
|
||||
{
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("chat.disclosure.notify"u8),
|
||||
HellionStrings.Settings_Chat_NotifyPluginDisclosure_Name,
|
||||
HellionStrings.Settings_Chat_NotifyPluginDisclosure_Description,
|
||||
() => Plugin.Config.NotifyPluginDisclosure,
|
||||
v => Plugin.Config.NotifyPluginDisclosure = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NotifyPluginDisclosure_Description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,35 +10,37 @@ internal sealed class DataPrivacyTab
|
||||
private readonly Plugin _plugin;
|
||||
private readonly SettingsWidgets _w;
|
||||
|
||||
public DataPrivacyTab(Plugin plugin)
|
||||
public DataPrivacyTab(Plugin plugin, Ui.StyleEngine.TokenResolver resolver)
|
||||
{
|
||||
_plugin = plugin;
|
||||
_w = new SettingsWidgets(plugin);
|
||||
_w = new SettingsWidgets(plugin, new SettingsPalette(resolver));
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (ImGui.CollapsingHeader("Logging", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("privacy.logging"u8), HellionStrings.Retention_Heading))
|
||||
{
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("privacy.logging.enabled"u8),
|
||||
HellionStrings.Retention_Enabled_Name,
|
||||
HellionStrings.Retention_Enabled_Description,
|
||||
() => Plugin.Config.RetentionEnabled,
|
||||
v => Plugin.Config.RetentionEnabled = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Retention_Enabled_Description);
|
||||
|
||||
// Down to 0, which DeleteByRetentionPolicy reads as "keep forever"
|
||||
// for channels without an override. The slider started at 1, so the
|
||||
// one value that means "never delete anything" was unreachable
|
||||
// through the UI while the label promised it.
|
||||
_w.SliderInt(
|
||||
_w.SliderIntRow(
|
||||
ImGui.GetID("privacy.logging.default"u8),
|
||||
HellionStrings.Retention_Default_Label,
|
||||
HellionStrings.Retention_Default_Help,
|
||||
() => Plugin.Config.RetentionDefaultDays,
|
||||
v => Plugin.Config.RetentionDefaultDays = v,
|
||||
0,
|
||||
365
|
||||
);
|
||||
ImGuiUtil.HelpMarker(HellionStrings.Retention_Default_Help);
|
||||
|
||||
// RetentionLastRunAt defaults to MinValue on a fresh install, which
|
||||
// would render as "0001-01-01 00:00" and look like a bug; the "Never"
|
||||
@@ -54,22 +56,31 @@ internal sealed class DataPrivacyTab
|
||||
DrawRetentionOverrides();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Privacy filter", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (
|
||||
_w.Section(
|
||||
ImGui.GetID("privacy.filter"u8),
|
||||
HellionStrings.Settings_Section_PrivacyFilter
|
||||
)
|
||||
)
|
||||
{
|
||||
_w.Toggle(
|
||||
"Enable privacy filter",
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("privacy.filter.enabled"u8),
|
||||
HellionStrings.Privacy_FilterEnabled_Name,
|
||||
HellionStrings.Privacy_FilterEnabled_Description,
|
||||
() => Plugin.Config.PrivacyFilterEnabled,
|
||||
v => Plugin.Config.PrivacyFilterEnabled = v
|
||||
);
|
||||
DrawPrivacyPersistChannelsGrid();
|
||||
_w.Toggle(
|
||||
"Persist unknown channels",
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("privacy.filter.unknown"u8),
|
||||
HellionStrings.Privacy_PersistUnknown_Name,
|
||||
null,
|
||||
() => Plugin.Config.PrivacyPersistUnknownChannels,
|
||||
v => Plugin.Config.PrivacyPersistUnknownChannels = v
|
||||
);
|
||||
DrawPrivacyPersistChannelsGrid();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Telemetry"))
|
||||
if (_w.Section(ImGui.GetID("privacy.telemetry"u8), "Telemetry", open: false))
|
||||
{
|
||||
// Read-only placeholder; no telemetry is wired in v1.7.0. Do not
|
||||
// promote this to a toggle without an explicit Sub-Spec change.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using HellionChat.Resources;
|
||||
using HellionChat.Ui.StyleEngine;
|
||||
using HellionChat.Util;
|
||||
|
||||
namespace HellionChat.Ui.Components.Settings.Tabs;
|
||||
@@ -16,10 +17,10 @@ internal sealed class GeneralTab
|
||||
// localised label never affects the ordering.
|
||||
private static readonly LanguageOverride[] LanguageOrder = BuildLanguageOrder();
|
||||
|
||||
public GeneralTab(Plugin plugin, FontManager fonts)
|
||||
public GeneralTab(Plugin plugin, FontManager fonts, TokenResolver resolver)
|
||||
{
|
||||
_plugin = plugin;
|
||||
_w = new SettingsWidgets(plugin);
|
||||
_w = new SettingsWidgets(plugin, new SettingsPalette(resolver));
|
||||
_fonts = fonts;
|
||||
}
|
||||
|
||||
@@ -33,17 +34,19 @@ internal sealed class GeneralTab
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (ImGui.CollapsingHeader("Behavior", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("general.behaviour"u8), "Behaviour"))
|
||||
{
|
||||
_w.Toggle(
|
||||
"Reduce motion (no theme crossfade)",
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("general.behaviour.reducemotion"u8),
|
||||
"Reduce motion",
|
||||
"Turns off theme crossfades, hover fades and the drifting motes.",
|
||||
() => Plugin.Config.ReduceMotion,
|
||||
v => Plugin.Config.ReduceMotion = v
|
||||
);
|
||||
DrawLanguagePicker();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Keybinds", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("general.keybinds"u8), "Keybinds"))
|
||||
{
|
||||
ImGui.TextDisabled("Click a button, then press the key combination. Esc clears.");
|
||||
DrawKeybind(
|
||||
@@ -61,20 +64,19 @@ internal sealed class GeneralTab
|
||||
DrawKeybindModePicker();
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Notifications", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
if (_w.Section(ImGui.GetID("general.notifications"u8), "Notifications"))
|
||||
{
|
||||
_w.Toggle(
|
||||
_w.ToggleRow(
|
||||
ImGui.GetID("general.notifications.sounds"u8),
|
||||
Language.Options_PlaySounds_Name,
|
||||
Language.Options_PlaySounds_Description,
|
||||
() => Plugin.Config.PlaySounds,
|
||||
v => Plugin.Config.PlaySounds = v
|
||||
);
|
||||
ImGuiUtil.HelpMarker(Language.Options_PlaySounds_Description);
|
||||
}
|
||||
|
||||
if (ImGui.CollapsingHeader("Volumes", ImGuiTreeNodeFlags.DefaultOpen))
|
||||
{
|
||||
_w.SliderFloat(
|
||||
_w.SliderFloatRow(
|
||||
ImGui.GetID("general.notifications.volume"u8),
|
||||
"Custom sound volume",
|
||||
null,
|
||||
() => Plugin.Config.CustomSoundVolume,
|
||||
v => Plugin.Config.CustomSoundVolume = v,
|
||||
0f,
|
||||
@@ -95,18 +97,19 @@ internal sealed class GeneralTab
|
||||
for (var i = 0; i < LanguageOrder.Length; i++)
|
||||
labels[i] = LanguageOrder[i].Name();
|
||||
|
||||
ImGui.SetNextItemWidth(200f);
|
||||
if (ImGui.Combo(Language.Options_Language_Name, ref selected, labels, labels.Length))
|
||||
{
|
||||
if (selected >= 0 && selected < LanguageOrder.Length)
|
||||
ApplyLanguage(LanguageOrder[selected]);
|
||||
}
|
||||
|
||||
ImGuiUtil.HelpMarker(
|
||||
string.Format(Language.Options_Language_Description, Plugin.PluginName)
|
||||
+ "\n\nSwitching rebuilds the font atlas, so the chat window goes blank"
|
||||
+ " for a moment. Scripts a language needs stay enabled afterwards;"
|
||||
+ " clear them under Appearance -> Fonts -> Extra glyphs."
|
||||
_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.",
|
||||
ctx =>
|
||||
{
|
||||
ImGui.SetNextItemWidth(ctx.ControlWidth);
|
||||
if (ImGui.Combo("##hc-language", ref selected, labels, labels.Length))
|
||||
{
|
||||
if (selected >= 0 && selected < LanguageOrder.Length)
|
||||
ApplyLanguage(LanguageOrder[selected]);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -155,18 +158,23 @@ internal sealed class GeneralTab
|
||||
for (var i = 0; i < values.Length; i++)
|
||||
labels[i] = values[i].Name();
|
||||
|
||||
ImGui.SetNextItemWidth(200f);
|
||||
if (ImGui.Combo(Language.Options_KeybindMode_Name, ref selected, labels, labels.Length))
|
||||
{
|
||||
if (selected >= 0 && selected < values.Length)
|
||||
_w.Row(
|
||||
ImGui.GetID("general.keybinds.mode"u8),
|
||||
Language.Options_KeybindMode_Name,
|
||||
Plugin.Config.KeybindMode.Tooltip(),
|
||||
ctx =>
|
||||
{
|
||||
Plugin.Config.KeybindMode = values[selected];
|
||||
_plugin.SaveConfig();
|
||||
ImGui.SetNextItemWidth(ctx.ControlWidth);
|
||||
if (ImGui.Combo("##hc-keybindmode", ref selected, labels, labels.Length))
|
||||
{
|
||||
if (selected >= 0 && selected < values.Length)
|
||||
{
|
||||
Plugin.Config.KeybindMode = values[selected];
|
||||
_plugin.SaveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Plugin.Config.KeybindMode.Tooltip() is { } tip)
|
||||
ImGuiUtil.HelpMarker(tip);
|
||||
);
|
||||
}
|
||||
|
||||
// Wires the already-present ImGuiUtil.KeybindInput capture widget (dead/unwired
|
||||
|
||||
Reference in New Issue
Block a user