feat(window): restore the title-bar, hide-button, and 24-hour-clock toggles
Re-wires four 1.5.6 settings that survived the v1.6.0 rewrite as dormant config fields but lost their UI + consumers: - ShowTitleBar / ShowPopOutTitleBar: gate ImGuiWindowFlags.NoTitleBar on the main window (ResolveFlags) and pop-out windows (new PreDraw). Inverted logic matches 1.5.6 (flag set only when the toggle is off). - ShowHideButton: gate the input-bar hide button on the toggle. - Use24HourClock: add the toggle (MessageList already consumes the field). New 'Window style' section in WindowTab; Use24HourClock in ChatTab display modes. MainWindowFlagsStep extended with the NoTitleBar fresh-base contract.
This commit is contained in:
@@ -34,7 +34,11 @@ internal sealed class MainWindowFlagsStep : ISelfTestStep
|
|||||||
// value for the live config. No state mutation needed.
|
// value for the live config. No state mutation needed.
|
||||||
var savedFlags = window.Flags;
|
var savedFlags = window.Flags;
|
||||||
window.PreDraw();
|
window.PreDraw();
|
||||||
var expected = MainWindow.ResolveFlags(Plugin.Config.CanMove, Plugin.Config.CanResize);
|
var expected = MainWindow.ResolveFlags(
|
||||||
|
Plugin.Config.CanMove,
|
||||||
|
Plugin.Config.CanResize,
|
||||||
|
Plugin.Config.ShowTitleBar
|
||||||
|
);
|
||||||
if (window.Flags != expected)
|
if (window.Flags != expected)
|
||||||
{
|
{
|
||||||
ImGui.Text($"PreDraw set Flags {window.Flags}, expected ResolveFlags = {expected}");
|
ImGui.Text($"PreDraw set Flags {window.Flags}, expected ResolveFlags = {expected}");
|
||||||
@@ -43,7 +47,7 @@ internal sealed class MainWindowFlagsStep : ISelfTestStep
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fresh-base contract: locked window carries NoMove|NoResize ...
|
// Fresh-base contract: locked window carries NoMove|NoResize ...
|
||||||
var locked = MainWindow.ResolveFlags(false, false);
|
var locked = MainWindow.ResolveFlags(false, false, true);
|
||||||
if (
|
if (
|
||||||
!locked.HasFlag(ImGuiWindowFlags.NoMove)
|
!locked.HasFlag(ImGuiWindowFlags.NoMove)
|
||||||
|| !locked.HasFlag(ImGuiWindowFlags.NoResize)
|
|| !locked.HasFlag(ImGuiWindowFlags.NoResize)
|
||||||
@@ -51,17 +55,35 @@ internal sealed class MainWindowFlagsStep : ISelfTestStep
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
ImGui.Text(
|
ImGui.Text(
|
||||||
$"ResolveFlags(false,false) = {locked}, missing NoMove/NoResize/NoScrollbar"
|
$"ResolveFlags(false,false,true) = {locked}, missing NoMove/NoResize/NoScrollbar"
|
||||||
);
|
);
|
||||||
window.Flags = savedFlags;
|
window.Flags = savedFlags;
|
||||||
return SelfTestStepResult.Fail;
|
return SelfTestStepResult.Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and re-enabling both CLEARS NoMove|NoResize (no accumulation).
|
// ... and re-enabling both CLEARS NoMove|NoResize (no accumulation).
|
||||||
var free = MainWindow.ResolveFlags(true, true);
|
var free = MainWindow.ResolveFlags(true, true, true);
|
||||||
if (free.HasFlag(ImGuiWindowFlags.NoMove) || free.HasFlag(ImGuiWindowFlags.NoResize))
|
if (free.HasFlag(ImGuiWindowFlags.NoMove) || free.HasFlag(ImGuiWindowFlags.NoResize))
|
||||||
{
|
{
|
||||||
ImGui.Text($"ResolveFlags(true,true) = {free}, NoMove/NoResize stuck after re-enable");
|
ImGui.Text(
|
||||||
|
$"ResolveFlags(true,true,true) = {free}, NoMove/NoResize stuck after re-enable"
|
||||||
|
);
|
||||||
|
window.Flags = savedFlags;
|
||||||
|
return SelfTestStepResult.Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// P7 title-bar contract: ShowTitleBar=false adds NoTitleBar from the
|
||||||
|
// fresh base, true clears it (same no-accumulation guarantee).
|
||||||
|
var barHidden = MainWindow.ResolveFlags(true, true, false);
|
||||||
|
var barShown = MainWindow.ResolveFlags(true, true, true);
|
||||||
|
if (
|
||||||
|
!barHidden.HasFlag(ImGuiWindowFlags.NoTitleBar)
|
||||||
|
|| barShown.HasFlag(ImGuiWindowFlags.NoTitleBar)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ImGui.Text(
|
||||||
|
$"NoTitleBar wiring wrong: hidden={barHidden} (want NoTitleBar), shown={barShown} (want none)"
|
||||||
|
);
|
||||||
window.Flags = savedFlags;
|
window.Flags = savedFlags;
|
||||||
return SelfTestStepResult.Fail;
|
return SelfTestStepResult.Fail;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -540,6 +540,11 @@ internal sealed class InputBar
|
|||||||
ImGui.SetTooltip("Settings");
|
ImGui.SetTooltip("Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide button gated on ShowHideButton (1.5.6 parity). It is the last
|
||||||
|
// button in the row, so skipping it (with its leading SameLine) leaves
|
||||||
|
// no dangling SameLine. Shared by main + pop-out InputBars.
|
||||||
|
if (Plugin.Config.ShowHideButton)
|
||||||
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var hidden = Plugin.Config.HideChat;
|
var hidden = Plugin.Config.HideChat;
|
||||||
var visIcon = hidden ? FontAwesomeIcon.EyeSlash : FontAwesomeIcon.Eye;
|
var visIcon = hidden ? FontAwesomeIcon.EyeSlash : FontAwesomeIcon.Eye;
|
||||||
@@ -552,6 +557,7 @@ internal sealed class InputBar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test-only hook; do not call from production code.
|
// Test-only hook; do not call from production code.
|
||||||
internal void TestSetPendingMessageForSelfTest(string value) => _pendingMessage = value;
|
internal void TestSetPendingMessageForSelfTest(string value) => _pendingMessage = value;
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ internal sealed class ChatTab
|
|||||||
() => Plugin.Config.HideSameTimestamps,
|
() => Plugin.Config.HideSameTimestamps,
|
||||||
v => Plugin.Config.HideSameTimestamps = v
|
v => Plugin.Config.HideSameTimestamps = v
|
||||||
);
|
);
|
||||||
|
DrawToggle(
|
||||||
|
"24-hour clock",
|
||||||
|
() => Plugin.Config.Use24HourClock,
|
||||||
|
v => Plugin.Config.Use24HourClock = v
|
||||||
|
);
|
||||||
DrawWorldSuffixCombo();
|
DrawWorldSuffixCombo();
|
||||||
DrawNameFormCombo();
|
DrawNameFormCombo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,25 @@ internal sealed class WindowTab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader("Window style", ImGuiTreeNodeFlags.DefaultOpen))
|
||||||
|
{
|
||||||
|
DrawToggle(
|
||||||
|
"Show title bar",
|
||||||
|
() => Plugin.Config.ShowTitleBar,
|
||||||
|
v => Plugin.Config.ShowTitleBar = v
|
||||||
|
);
|
||||||
|
DrawToggle(
|
||||||
|
"Show title bar for pop-outs",
|
||||||
|
() => Plugin.Config.ShowPopOutTitleBar,
|
||||||
|
v => Plugin.Config.ShowPopOutTitleBar = v
|
||||||
|
);
|
||||||
|
DrawToggle(
|
||||||
|
"Show hide button",
|
||||||
|
() => Plugin.Config.ShowHideButton,
|
||||||
|
v => Plugin.Config.ShowHideButton = v
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Opacity", ImGuiTreeNodeFlags.DefaultOpen))
|
if (ImGui.CollapsingHeader("Opacity", ImGuiTreeNodeFlags.DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawSlider(
|
DrawSlider(
|
||||||
|
|||||||
@@ -75,6 +75,17 @@ internal sealed class ChannelPopoutWindow : Window
|
|||||||
IsOpen = false;
|
IsOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void PreDraw()
|
||||||
|
{
|
||||||
|
// Gate the native title bar on the user toggle (1.5.6 parity). DrawHeader
|
||||||
|
// carries the close button in-body regardless, so hiding the title bar
|
||||||
|
// never strands the pop-out. Reset from a fresh base each frame so
|
||||||
|
// toggling the bar back on clears NoTitleBar.
|
||||||
|
Flags = Plugin.Config.ShowPopOutTitleBar
|
||||||
|
? ImGuiWindowFlags.None
|
||||||
|
: ImGuiWindowFlags.NoTitleBar;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
if (Bound is null)
|
if (Bound is null)
|
||||||
|
|||||||
@@ -77,19 +77,21 @@ internal sealed class MainWindow : Window
|
|||||||
internal float ResolveBgAlpha(bool isFocused) =>
|
internal float ResolveBgAlpha(bool isFocused) =>
|
||||||
isFocused ? Plugin.Config.WindowOpacity : Plugin.Config.WindowOpacityInactive;
|
isFocused ? Plugin.Config.WindowOpacity : Plugin.Config.WindowOpacityInactive;
|
||||||
|
|
||||||
// B1-2: rebuild flags from a fresh base every frame so toggling CanMove/
|
// B1-2 / P7: rebuild flags from a fresh base every frame so toggling
|
||||||
// CanResize back on actually CLEARS NoMove/NoResize (not accumulating).
|
// CanMove/CanResize/ShowTitleBar back on actually CLEARS NoMove/NoResize/
|
||||||
// Move/resize toggle logic as 1.5.6 (ChatLogWindow.PreOpenCheck
|
// NoTitleBar (not accumulating). Move/resize/title-bar logic as 1.5.6
|
||||||
// 1d3b429:703-707); base flags = today's MainWindow set (NoScrollbar|
|
// (ChatLogWindow.PreOpenCheck 1d3b429:703-710); base flags = today's
|
||||||
// NoScrollWithMouse — the message list owns its own scroll; 1.5.6's
|
// MainWindow set (NoScrollbar|NoScrollWithMouse — the message list owns its
|
||||||
// NoFocusOnAppearing/NoTitleBar are deliberately not restored).
|
// own scroll; 1.5.6's NoFocusOnAppearing is deliberately not restored).
|
||||||
internal static ImGuiWindowFlags ResolveFlags(bool canMove, bool canResize)
|
internal static ImGuiWindowFlags ResolveFlags(bool canMove, bool canResize, bool showTitleBar)
|
||||||
{
|
{
|
||||||
var flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
|
var flags = ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse;
|
||||||
if (!canMove)
|
if (!canMove)
|
||||||
flags |= ImGuiWindowFlags.NoMove;
|
flags |= ImGuiWindowFlags.NoMove;
|
||||||
if (!canResize)
|
if (!canResize)
|
||||||
flags |= ImGuiWindowFlags.NoResize;
|
flags |= ImGuiWindowFlags.NoResize;
|
||||||
|
if (!showTitleBar)
|
||||||
|
flags |= ImGuiWindowFlags.NoTitleBar;
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +116,11 @@ internal sealed class MainWindow : Window
|
|||||||
BgAlpha = null;
|
BgAlpha = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Flags = ResolveFlags(Plugin.Config.CanMove, Plugin.Config.CanResize);
|
Flags = ResolveFlags(
|
||||||
|
Plugin.Config.CanMove,
|
||||||
|
Plugin.Config.CanResize,
|
||||||
|
Plugin.Config.ShowTitleBar
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tab? ActiveTab => _activeTab;
|
public Tab? ActiveTab => _activeTab;
|
||||||
|
|||||||
Reference in New Issue
Block a user