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.
218 lines
8.0 KiB
C#
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
|
|
);
|
|
}
|
|
}
|
|
}
|