Reviews of blocks C and D found five things a user would see immediately. Row fills ignored the window's own opacity. Theme surfaces are fully opaque, and GlobalStyleScope zeroes ChildBg below full opacity so WindowBg alone carries the coverage -- with the default of 0.85 that made the sidebar a solid block inside a translucent window. Idle rows now draw no fill at all, and the active and hover fills are scaled by the current window opacity. The unread badge landed on the tab icon at the default sidebar width of 44px. Right-aligning it needs roughly 70px for one digit and 90px for three, and the old placement also subtracted the popout column even when there was no popout button. It is only drawn where it clears the icon; below that a plain dot takes over, which is what the sidebar did before this cycle anyway. The same collision existed in the top-tab strip, worse: the badge sat in the trailing padding, which is 10px against a badge at least 14px wide, so it covered the label on every tab that had one. The badge is part of the tab width now, and vertically centred rather than top-aligned. The context menu's spacing guard read the pushed zero back out of GetStyle, so the max never did anything and X stayed at zero -- which is what HelpMarker's SameLine uses, so the "(?)" clung to its label. It sets both axes outright now. Section captions had all their padding above them and one pixel below, so with zero item spacing the next row started immediately under the text. Three smaller items: the tab icon was centred against the text font's line height although FontAwesome is a fixed-width handle that ignores Config.FontSizeV2; IconButton interpolated a label string per button per frame, now a PushID over a u8 literal; and the alpha scaling that had grown four copies now goes through ColourUtil.ApplyAlpha everywhere.
78 lines
2.5 KiB
C#
78 lines
2.5 KiB
C#
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using HellionChat.Util;
|
|
|
|
namespace HellionChat.Ui.StyleEngine.Widgets;
|
|
|
|
// Visual state of a list row. Deliberately carries no Tab: v1.11.0 swaps the
|
|
// sidebar from tab rows to channel rows and should only have to change the
|
|
// caller, not the chrome.
|
|
internal readonly record struct RowVisualState
|
|
{
|
|
public RowVisualState() { }
|
|
|
|
public bool IsActive { get; init; }
|
|
public float HoverAmount { get; init; }
|
|
public uint SurfaceHoverAbgr { get; init; }
|
|
public uint SurfaceActiveAbgr { get; init; }
|
|
public uint AccentAbgr { get; init; }
|
|
public uint BorderAbgr { get; init; }
|
|
}
|
|
|
|
internal readonly record struct RowStyle
|
|
{
|
|
public RowStyle() { }
|
|
|
|
public float AccentBarWidth { get; init; } = 2f;
|
|
public bool DrawSeparator { get; init; } = true;
|
|
}
|
|
|
|
internal static class Row
|
|
{
|
|
// Painted before icon and label, and strictly with draw-list calls only:
|
|
// TabContextMenu binds to the last submitted item, so an interactive widget
|
|
// between the row button and the popup call would steal its right-click.
|
|
internal static void Draw(
|
|
Vector2 origin,
|
|
Vector2 size,
|
|
RowVisualState state,
|
|
RowStyle? styleOverride = null
|
|
)
|
|
{
|
|
if (size.X <= 0f || size.Y <= 0f)
|
|
return;
|
|
|
|
var style = styleOverride ?? new RowStyle();
|
|
var dl = ImGui.GetWindowDrawList();
|
|
var max = origin + size;
|
|
|
|
// Idle rows draw no fill at all. GlobalStyleScope zeroes ChildBg below
|
|
// full window opacity so WindowBg alone carries the coverage, and the
|
|
// default is 0.85 -- an opaque fill per row would make the sidebar a
|
|
// solid block inside a translucent window.
|
|
if (state.IsActive)
|
|
dl.AddRectFilled(origin, max, state.SurfaceActiveAbgr);
|
|
|
|
if (state.HoverAmount > 0f)
|
|
dl.AddRectFilled(
|
|
origin,
|
|
max,
|
|
ColourUtil.ApplyAlpha(state.SurfaceHoverAbgr, state.HoverAmount)
|
|
);
|
|
|
|
if (state.IsActive && style.AccentBarWidth > 0f)
|
|
{
|
|
var barWidth = style.AccentBarWidth * Metrics.Scale;
|
|
dl.AddRectFilled(origin, new Vector2(origin.X + barWidth, max.Y), state.AccentAbgr);
|
|
}
|
|
|
|
if (style.DrawSeparator)
|
|
dl.AddLine(
|
|
new Vector2(origin.X, max.Y - 1f),
|
|
new Vector2(max.X, max.Y - 1f),
|
|
state.BorderAbgr,
|
|
Metrics.Scale
|
|
);
|
|
}
|
|
}
|