feat(popouts): bring the pop-out windows up to the rest
Three things, all visible in one screenshot. The tab name was drawn twice. The pop-out has a title bar carrying the tab name and a header row underneath repeating it -- the same string, one line apart. The header now only draws when the title bar is off, which is the case it was written for. The close button was ImGui.Button, so it took the theme's button colours. On several themes that is a bright magenta plate sitting next to plain text, making the way out of the window the loudest thing in it. It uses the plugin's own icon button now: glyph contrast-checked against the surface, danger colour on hover only. And the message area gets the same floor as the main log, with the same restraint -- no accent wash, motes at a tenth. Pop-outs were the last surface still sitting on flat background while every other window had depth.
This commit is contained in:
@@ -324,7 +324,10 @@ internal static class PluginHostFactory
|
||||
sp.GetRequiredService<Ui.CommandHelpWindow>()
|
||||
),
|
||||
sp.GetRequiredService<ILogger<Ui.Windows.ChannelPopoutWindow>>(),
|
||||
sp.GetRequiredService<FontManager>()
|
||||
sp.GetRequiredService<FontManager>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.SurfaceBackdrop>(),
|
||||
sp.GetRequiredService<ThemeRegistry>(),
|
||||
sp.GetRequiredService<Ui.StyleEngine.TokenResolver>()
|
||||
)
|
||||
);
|
||||
services.AddSingleton(sp => new Ui.Windows.ChannelPopoutPool(
|
||||
|
||||
@@ -3,7 +3,10 @@ using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using HellionChat.Themes;
|
||||
using HellionChat.Ui.Components;
|
||||
using HellionChat.Ui.StyleEngine.Widgets;
|
||||
using HellionChat.Util;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace HellionChat.Ui.Windows;
|
||||
@@ -20,13 +23,19 @@ internal sealed class ChannelPopoutWindow : Window, IFocusableChatWindow
|
||||
private readonly InputBar _input;
|
||||
private readonly ILogger<ChannelPopoutWindow> _logger;
|
||||
private readonly FontManager _fonts;
|
||||
private readonly Ui.StyleEngine.SurfaceBackdrop _backdrop;
|
||||
private readonly ThemeRegistry _themes;
|
||||
private readonly Ui.StyleEngine.TokenResolver _resolver;
|
||||
|
||||
public ChannelPopoutWindow(
|
||||
int slotIndex,
|
||||
MessageList messages,
|
||||
InputBar input,
|
||||
ILogger<ChannelPopoutWindow> logger,
|
||||
FontManager fonts
|
||||
FontManager fonts,
|
||||
Ui.StyleEngine.SurfaceBackdrop backdrop,
|
||||
ThemeRegistry themes,
|
||||
Ui.StyleEngine.TokenResolver resolver
|
||||
)
|
||||
: base($"{Plugin.PluginName}###hellion_popout_{slotIndex}")
|
||||
{
|
||||
@@ -35,6 +44,9 @@ internal sealed class ChannelPopoutWindow : Window, IFocusableChatWindow
|
||||
_input = input;
|
||||
_logger = logger;
|
||||
_fonts = fonts;
|
||||
_backdrop = backdrop;
|
||||
_themes = themes;
|
||||
_resolver = resolver;
|
||||
IsOpen = false;
|
||||
RespectCloseHotkey = false;
|
||||
ShowCloseButton = false;
|
||||
@@ -103,7 +115,11 @@ internal sealed class ChannelPopoutWindow : Window, IFocusableChatWindow
|
||||
if (Bound is null)
|
||||
return;
|
||||
|
||||
DrawHeader(Bound);
|
||||
// Only when the window has no title bar of its own. With the bar on,
|
||||
// this row repeated the tab name directly underneath it -- the same
|
||||
// string twice, one line apart.
|
||||
if (!Plugin.Config.ShowPopOutTitleBar)
|
||||
DrawHeader(Bound);
|
||||
|
||||
// The header close button can unbind us mid-frame (CloseRequested ->
|
||||
// pool.TryClose -> Unbind nulls Bound). Re-check before the body so we
|
||||
@@ -125,7 +141,13 @@ internal sealed class ChannelPopoutWindow : Window, IFocusableChatWindow
|
||||
)
|
||||
{
|
||||
if (body.Success)
|
||||
{
|
||||
// Same floor as the main window's log, and the same reasoning:
|
||||
// no accent wash and barely any motes, because a chat log is read
|
||||
// line by line.
|
||||
_backdrop.Draw(accentWashHeight: 0f, moteIntensity: 0.10f, strength: 0.45f);
|
||||
_messages.Draw(Bound);
|
||||
}
|
||||
}
|
||||
|
||||
_input.Draw(Bound);
|
||||
@@ -137,18 +159,37 @@ internal sealed class ChannelPopoutWindow : Window, IFocusableChatWindow
|
||||
// close button is the canonical "send the tab back" affordance for v1.8.0.
|
||||
// PartnerHonorific is deferred (HonorificService has no per-target title,
|
||||
// plan §D / Sub-Spec WARN-8) — no honorific row here.
|
||||
var colors = _themes.Active.Colors;
|
||||
var text = ColourUtil.RgbaToAbgr(_resolver.Resolve(Ui.StyleEngine.Token.Text, colors));
|
||||
var surface = ColourUtil.RgbaToAbgr(
|
||||
_resolver.Resolve(Ui.StyleEngine.Token.SurfaceBase, colors)
|
||||
);
|
||||
var danger = ColourUtil.RgbaToAbgr(
|
||||
_resolver.Resolve(Ui.StyleEngine.Token.StatusDanger, colors)
|
||||
);
|
||||
|
||||
ImGui.TextUnformatted(tab.Name);
|
||||
ImGui.SameLine();
|
||||
using (_fonts.FontAwesome.Push())
|
||||
|
||||
// The plugin's own icon button rather than ImGui.Button. The stock one
|
||||
// took the theme's button colours, which on several themes is a bright
|
||||
// magenta plate next to plain text -- the loudest thing in the window
|
||||
// being the way out of it.
|
||||
var size = ImGui.GetFrameHeight();
|
||||
ImGui.SameLine(ImGui.GetContentRegionAvail().X - size);
|
||||
var (clicked, _) = IconButton.Draw(
|
||||
ImGui.GetID($"popout.close.{_slotIndex}"),
|
||||
new Vector2(size, size),
|
||||
FontAwesomeIcon.Times,
|
||||
ColourUtil.EnsureContrast(text, surface, 3f),
|
||||
danger,
|
||||
_fonts.FontAwesome
|
||||
);
|
||||
|
||||
if (clicked)
|
||||
{
|
||||
ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.GetFrameHeight());
|
||||
if (ImGui.Button($"{FontAwesomeIcon.Times.ToIconString()}##popin-{_slotIndex}"))
|
||||
{
|
||||
// Pop-In: release the slot via the pool (not a bare Unbind, which
|
||||
// would orphan the slot — the pool owns the slot bookkeeping).
|
||||
CloseRequested?.Invoke(tab.Identifier);
|
||||
}
|
||||
// Pop-In: release the slot via the pool (not a bare Unbind, which
|
||||
// would orphan the slot — the pool owns the slot bookkeeping).
|
||||
CloseRequested?.Invoke(tab.Identifier);
|
||||
}
|
||||
ImGui.Separator();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user