fix(settings): align the theme preview with the real chrome
The preview had been showing surfaces, an accent bar and an unread marker for months while the real sidebar drew none of them. Now that the sidebar has caught up, the preview is the one that is wrong -- in two specific ways. It put the accent bar on row 0 and the raised surface on row 1, so it showed two half-active rows instead of one active row. Both now sit on row 0, and the rows get the separator the real ones have. The unread marker was a 4x4 square. It is a rounded count badge now. The status bar preview was a separate 20px reimplementation with three coloured squares and a hard-coded label. It mirrors the pill layout instead, with the status colours riding along as slot dots so a theme still shows what it does to them.
This commit is contained in:
@@ -181,18 +181,29 @@ internal sealed class LivePreviewPanel : IDisposable
|
||||
var primaryAbgr = ColourUtil.RgbaToAbgr(theme.Colors.Primary);
|
||||
var accentAbgr = ColourUtil.RgbaToAbgr(theme.Colors.Accent);
|
||||
|
||||
// Row 0 is the active one and carries BOTH the raised surface and the
|
||||
// accent bar, the way the real sidebar draws it. Until v1.10.0 those two
|
||||
// sat on different rows here, so the preview promised a layout the
|
||||
// sidebar never delivered -- and then the sidebar caught up.
|
||||
var borderAbgr = ColourUtil.RgbaToAbgr(theme.Colors.Border);
|
||||
ReadOnlySpan<string> labels = ["Linkshell", "Tell", "FC"];
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var rowMin = new Vector2(origin.X, origin.Y + i * rowHeight);
|
||||
var rowMax = new Vector2(origin.X + SidebarWidth, rowMin.Y + rowHeight);
|
||||
var bg = i == 1 ? surfaceHover : surface;
|
||||
draw.AddRectFilled(rowMin, rowMax, bg);
|
||||
var isActive = i == 0;
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
draw.AddRectFilled(rowMin, rowMax, isActive ? surfaceHover : surface);
|
||||
|
||||
if (isActive)
|
||||
draw.AddRectFilled(rowMin, new Vector2(rowMin.X + 2f, rowMax.Y), primaryAbgr);
|
||||
}
|
||||
|
||||
draw.AddLine(
|
||||
new Vector2(rowMin.X, rowMax.Y - 1f),
|
||||
new Vector2(rowMax.X, rowMax.Y - 1f),
|
||||
borderAbgr,
|
||||
1f
|
||||
);
|
||||
|
||||
var labelSize = ImGui.CalcTextSize(labels[i]);
|
||||
var textPos = new Vector2(rowMin.X + 6f, rowMin.Y + (rowHeight - labelSize.Y) * 0.5f);
|
||||
@@ -200,13 +211,21 @@ internal sealed class LivePreviewPanel : IDisposable
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
// Tell row carries an unread-dot in Accent on the right.
|
||||
var dotCenter = new Vector2(rowMax.X - 8f, rowMin.Y + rowHeight * 0.5f);
|
||||
draw.AddRectFilled(
|
||||
new Vector2(dotCenter.X - 2f, dotCenter.Y - 2f),
|
||||
new Vector2(dotCenter.X + 2f, dotCenter.Y + 2f),
|
||||
accentAbgr
|
||||
// Unread marker: a rounded count badge in Accent, not a square.
|
||||
var badgeH = MathF.Min(rowHeight - 4f, 14f);
|
||||
var badgeW = badgeH * 1.4f;
|
||||
var badgeMin = new Vector2(
|
||||
rowMax.X - badgeW - 4f,
|
||||
rowMin.Y + (rowHeight - badgeH) * 0.5f
|
||||
);
|
||||
var badgeMax = badgeMin + new Vector2(badgeW, badgeH);
|
||||
draw.AddRectFilled(
|
||||
badgeMin,
|
||||
badgeMax,
|
||||
(accentAbgr & 0x00FFFFFFu) | 0x38000000u,
|
||||
badgeH * 0.5f
|
||||
);
|
||||
draw.AddRect(badgeMin, badgeMax, accentAbgr, badgeH * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,44 +317,79 @@ internal sealed class LivePreviewPanel : IDisposable
|
||||
ImGui.Dummy(new Vector2(width, height));
|
||||
}
|
||||
|
||||
// Mirrors the real status bar: a top rule, then pill-shaped slots, the last
|
||||
// one right-aligned. The status colours ride along as slot dots so a theme
|
||||
// still shows what it does to them.
|
||||
private static void DrawStatusBar(Theme theme)
|
||||
{
|
||||
const float height = 20f;
|
||||
const float iconSize = 8f;
|
||||
const float iconGap = 6f;
|
||||
const float height = 24f;
|
||||
const float pillH = 18f;
|
||||
const float padX = 6f;
|
||||
const float gap = 6f;
|
||||
var draw = ImGui.GetWindowDrawList();
|
||||
var origin = ImGui.GetCursorScreenPos();
|
||||
var width = ImGui.GetContentRegionAvail().X;
|
||||
var max = new Vector2(origin.X + width, origin.Y + height);
|
||||
|
||||
draw.AddRectFilled(origin, max, ColourUtil.RgbaToAbgr(theme.Colors.ChildBg));
|
||||
draw.AddLine(
|
||||
origin,
|
||||
new Vector2(max.X, origin.Y),
|
||||
ColourUtil.RgbaToAbgr(theme.Colors.Border),
|
||||
1f
|
||||
);
|
||||
|
||||
ReadOnlySpan<uint> statusRgba =
|
||||
var fill = ColourUtil.RgbaToAbgr(theme.Colors.SurfaceHover);
|
||||
var textAbgr = ColourUtil.RgbaToAbgr(theme.Colors.TextPrimary);
|
||||
var pillY = origin.Y + (height - pillH) * 0.5f;
|
||||
|
||||
ReadOnlySpan<string> slots = ["Say", "open", "3 tabs"];
|
||||
ReadOnlySpan<uint> dots =
|
||||
[
|
||||
theme.Colors.StatusSuccess,
|
||||
theme.Colors.StatusDanger,
|
||||
theme.Colors.StatusWarning,
|
||||
theme.Colors.StatusDanger,
|
||||
];
|
||||
|
||||
var iconY = origin.Y + (height - iconSize) * 0.5f;
|
||||
for (var i = 0; i < statusRgba.Length; i++)
|
||||
var x = origin.X + padX;
|
||||
for (var i = 0; i < slots.Length; i++)
|
||||
{
|
||||
var iconX = origin.X + 6f + i * (iconSize + iconGap);
|
||||
draw.AddRectFilled(
|
||||
new Vector2(iconX, iconY),
|
||||
new Vector2(iconX + iconSize, iconY + iconSize),
|
||||
ColourUtil.RgbaToAbgr(statusRgba[i]),
|
||||
2f
|
||||
var labelSize = ImGui.CalcTextSize(slots[i]);
|
||||
var slotW = labelSize.X + padX * 2f + 10f;
|
||||
var slotMin = new Vector2(x, pillY);
|
||||
var slotMax = new Vector2(x + slotW, pillY + pillH);
|
||||
|
||||
draw.AddRectFilled(slotMin, slotMax, fill, pillH * 0.5f);
|
||||
draw.AddCircleFilled(
|
||||
new Vector2(x + padX + 2f, pillY + pillH * 0.5f),
|
||||
2.5f,
|
||||
ColourUtil.RgbaToAbgr(dots[i]),
|
||||
10
|
||||
);
|
||||
draw.AddText(
|
||||
new Vector2(x + padX + 10f, pillY + (pillH - labelSize.Y) * 0.5f),
|
||||
textAbgr,
|
||||
slots[i]
|
||||
);
|
||||
|
||||
x += slotW + gap;
|
||||
}
|
||||
|
||||
var label = "preview";
|
||||
var labelSize = ImGui.CalcTextSize(label);
|
||||
var labelPos = new Vector2(
|
||||
max.X - labelSize.X - 6f,
|
||||
origin.Y + (height - labelSize.Y) * 0.5f
|
||||
var versionSize = ImGui.CalcTextSize(label);
|
||||
var versionW = versionSize.X + padX * 2f;
|
||||
var versionMin = new Vector2(max.X - versionW - padX, pillY);
|
||||
draw.AddRectFilled(
|
||||
versionMin,
|
||||
versionMin + new Vector2(versionW, pillH),
|
||||
fill,
|
||||
pillH * 0.5f
|
||||
);
|
||||
draw.AddText(
|
||||
new Vector2(versionMin.X + padX, pillY + (pillH - versionSize.Y) * 0.5f),
|
||||
ColourUtil.RgbaToAbgr(theme.Colors.TextDim),
|
||||
label
|
||||
);
|
||||
draw.AddText(labelPos, ColourUtil.RgbaToAbgr(theme.Colors.TextDim), label);
|
||||
|
||||
ImGui.Dummy(new Vector2(width, height));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user