Files
HellionChat/HellionChat/Ui/Components/Settings/Tabs/WindowTab.cs
T
JonKazama-Hellion 75c4acd19a feat(settings): make eleven settings reachable again
Every field here has a reader in the running plugin and had no control
in the window. The config file was the only way to any of them.

HideChat is the one that mattered. It defaults to on, it suppresses the
game's own chat window, and the only other path to it is a right-click
item that sets it to true and can never set it back. Anyone who used
that item once had to edit JSON to get their chat back. The new toggle
reads and writes the same field, so the two agree instead of fighting.

The rest, by tab:

- Window: the three remaining hide conditions, the preview minimum that
  belongs to a toggle already on screen, native item tooltips and their
  offset.
- Chat: an emotes section holding the BetterTTV switch, the cache state,
  and an editor for the blocked-code list that has been in the config
  since v1.0 with nowhere to edit it. Blocking one code is a finer
  instrument than switching emotes off wholesale. Plus auto-translate
  sorting.
- General: the failed-tell warning. The game reports a failed tell in
  the log only, where somebody who is typing does not see it.
- Data & Privacy: battle messages. It decides whether battle lines are
  persisted at all, which makes it a storage decision rather than a chat
  one, and it sits in front of the whitelist rather than inside it.

MaxParallelPopouts stays out. It is read once in the pool's constructor,
the windows are registered once, and registering at runtime is
explicitly forbidden -- a slider would do nothing until a reload, which
is exactly the kind of decoration this cycle exists to remove.

Four new strings in all 25 languages; the other fifteen labels were
already translated and waiting.
2026-08-18 22:40:54 +02:00

218 lines
8.0 KiB
C#

using Dalamud.Bindings.ImGui;
using HellionChat.Resources;
using HellionChat.Ui.StyleEngine;
namespace HellionChat.Ui.Components.Settings.Tabs;
// First tab converted to the styled widgets. Everything here used to be stock
// ImGui: framed collapsing bars, checkboxes with their label on the right, and
// sliders glued to the left edge with their name trailing behind.
internal sealed class WindowTab
{
private readonly SettingsWidgets _w;
// Held rather than built per frame, and ordered to match the enum values
// passed alongside them.
private static readonly MainWindowLayoutMode[] LayoutValues =
[
MainWindowLayoutMode.Sidebar,
MainWindowLayoutMode.TopTabs,
];
private static readonly string[] LayoutLabels = ["Sidebar", "Top tabs"];
public WindowTab(Plugin plugin, TokenResolver resolver)
{
_w = new SettingsWidgets(plugin, new SettingsPalette(resolver));
}
public void Draw()
{
// 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"))
{
_w.SegmentRow(
ImGui.GetID("window.layout.mode"u8),
"Tab placement",
"Where the tab list sits in the main window.",
LayoutValues,
LayoutLabels,
() => Plugin.Config.MainWindowLayoutMode,
v => Plugin.Config.MainWindowLayoutMode = v
);
}
if (
_w.Section(
ImGui.GetID("window.style"u8),
HellionStrings.Settings_ThemeAndLayout_WindowStyle_Heading
)
)
{
_w.ToggleRow(
ImGui.GetID("window.style.titlebar"u8),
"Show title bar",
null,
() => Plugin.Config.ShowTitleBar,
v => Plugin.Config.ShowTitleBar = v
);
_w.ToggleRow(
ImGui.GetID("window.style.popouttitlebar"u8),
"Show title bar for pop-outs",
null,
() => Plugin.Config.ShowPopOutTitleBar,
v => Plugin.Config.ShowPopOutTitleBar = v
);
_w.ToggleRow(
ImGui.GetID("window.style.hidebutton"u8),
Language.Options_ShowHideButton_Name,
null,
() => Plugin.Config.ShowHideButton,
v => Plugin.Config.ShowHideButton = v
);
}
if (_w.Section(ImGui.GetID("window.opacity"u8), "Opacity"))
{
_w.SliderFloatRow(
ImGui.GetID("window.opacity.active"u8),
HellionStrings.Theme_WindowOpacity_Label,
null,
() => Plugin.Config.WindowOpacity,
v => Plugin.Config.WindowOpacity = v,
0.1f,
1f
);
_w.SliderFloatRow(
ImGui.GetID("window.opacity.inactive"u8),
"Inactive opacity",
"Applies while another window has focus.",
() => Plugin.Config.WindowOpacityInactive,
v => Plugin.Config.WindowOpacityInactive = v,
0.1f,
1f
);
}
if (_w.Section(ImGui.GetID("window.resize"u8), "Resize behaviour"))
{
_w.ToggleRow(
ImGui.GetID("window.resize.move"u8),
"Allow movement",
null,
() => Plugin.Config.CanMove,
v => Plugin.Config.CanMove = v
);
_w.ToggleRow(
ImGui.GetID("window.resize.resize"u8),
"Allow resize",
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.",
() => Plugin.Config.SidebarAutoSwitchThresholdPx,
v => Plugin.Config.SidebarAutoSwitchThresholdPx = v,
200,
800
);
}
if (_w.Section(ImGui.GetID("window.preview"u8), "Input preview", open: false))
{
_w.EnumComboRow(
ImGui.GetID("window.preview.position"u8),
"Preview position",
null,
() => Plugin.Config.PreviewPosition,
v => Plugin.Config.PreviewPosition = v,
v => v.Name()
);
_w.ToggleRow(
ImGui.GetID("window.preview.onlyif"u8),
"Only show preview when typing",
null,
() => Plugin.Config.OnlyPreviewIf,
v => Plugin.Config.OnlyPreviewIf = v
);
// Partner of the toggle above and useless without it: how many
// characters have to be typed before the preview appears.
_w.SliderIntRow(
ImGui.GetID("window.preview.minimum"u8),
Language.Options_PreviewMinimum_Name,
Language.Options_PreviewMinimum_Description,
() => Plugin.Config.PreviewMinimum,
v => Plugin.Config.PreviewMinimum = v,
0,
20
);
}
// HideChat is the one with real bite: it defaults to on, it suppresses
// the game's own chat window, and the only other way to it is a
// right-click item that can turn it on and never off. Somebody who used
// that item once had to edit JSON to get their chat back.
if (_w.Section(ImGui.GetID("window.hide"u8), HellionStrings.Settings_Section_Hide))
{
_w.ToggleRow(
ImGui.GetID("window.hide.chat"u8),
Language.Options_HideChat_Name,
Language.Options_HideChat_Description,
() => Plugin.Config.HideChat,
v => Plugin.Config.HideChat = v
);
_w.ToggleRow(
ImGui.GetID("window.hide.uihidden"u8),
Language.Options_HideWhenUiHidden_Name,
Language.Options_HideWhenUiHidden_Description,
() => Plugin.Config.HideWhenUiHidden,
v => Plugin.Config.HideWhenUiHidden = v
);
_w.ToggleRow(
ImGui.GetID("window.hide.loading"u8),
Language.Options_HideInLoadingScreens_Name,
Language.Options_HideInLoadingScreens_Description,
() => Plugin.Config.HideInLoadingScreens,
v => Plugin.Config.HideInLoadingScreens = v
);
_w.ToggleRow(
ImGui.GetID("window.hide.newgameplus"u8),
Language.Options_HideInNewGamePlusMenu_Name,
Language.Options_HideInNewGamePlusMenu_Description,
() => Plugin.Config.HideInNewGamePlusMenu,
v => Plugin.Config.HideInNewGamePlusMenu = v
);
}
if (
_w.Section(
ImGui.GetID("window.tooltips"u8),
HellionStrings.Settings_Section_LinksTooltips,
open: false
)
)
{
_w.ToggleRow(
ImGui.GetID("window.tooltips.native"u8),
Language.Options_NativeItemTooltips_Name,
Language.Options_NativeItemTooltips_Description,
() => Plugin.Config.NativeItemTooltips,
v => Plugin.Config.NativeItemTooltips = v
);
_w.SliderIntRow(
ImGui.GetID("window.tooltips.offset"u8),
Language.Options_TooltipOffset_Name,
Language.Options_TooltipOffset_Desc,
() => (int)Plugin.Config.TooltipOffset,
v => Plugin.Config.TooltipOffset = v,
0,
200
);
}
}
}