feat(ui): lerp sidebar-icon and card-mode-border hover alphas
Sidebar icons ease from 40% to 100% alpha on hover-in via FrameLerp plus ApplyAlpha. Card-mode borders aggregate row-hover per tab and lift the border alpha by up to ~+0x70 across every row in that tab. borderColorAbgr moves into the loop so the per-iteration boost can apply. ReduceMotion snaps both paths instantly. Card-hover detection uses IsMouseHoveringRect over the row bounds -- IsItemHovered would only see the 2px spacer dummy below each row.
This commit is contained in:
@@ -1627,15 +1627,19 @@ public sealed class ChatLogWindow : Window
|
|||||||
var maxLines = Plugin.Config.MaxLinesToRender;
|
var maxLines = Plugin.Config.MaxLinesToRender;
|
||||||
var startLine = messages.Count > maxLines ? messages.Count - maxLines : 0;
|
var startLine = messages.Count > maxLines ? messages.Count - maxLines : 0;
|
||||||
|
|
||||||
// Card-mode pre-loop: theme/drawList/winLeft/winRight/border are invariant
|
// Card-mode pre-loop: theme/drawList/winLeft/winRight are
|
||||||
// per DrawMessages call; only cursorY moves per row.
|
// invariant per DrawMessages call. borderColorAbgr used to be
|
||||||
|
// hoisted here too, but PM-3d (v1.5.4) modulates it by
|
||||||
|
// tab._cardHoverAlpha per row, so it moves into the AddLine
|
||||||
|
// call below. anyCardHovered aggregates the row-hover state
|
||||||
|
// across all card-rows; the lerp runs once at the loop end so
|
||||||
|
// the next frame paints with the updated alpha.
|
||||||
var theme = Plugin.ThemeRegistry.Active;
|
var theme = Plugin.ThemeRegistry.Active;
|
||||||
var drawList = ImGui.GetWindowDrawList();
|
var drawList = ImGui.GetWindowDrawList();
|
||||||
var winLeft = ImGui.GetWindowPos().X;
|
var winLeft = ImGui.GetWindowPos().X;
|
||||||
var winRight = winLeft + ImGui.GetWindowSize().X;
|
var winRight = winLeft + ImGui.GetWindowSize().X;
|
||||||
var borderColorAbgr = ColourUtil.RgbaToAbgr(
|
var baseBorderRgba = (theme.Colors.Border & 0xFFFFFF00u) | 0x33u;
|
||||||
(theme.Colors.Border & 0xFFFFFF00u) | 0x33u
|
var anyCardHovered = false;
|
||||||
);
|
|
||||||
|
|
||||||
for (var i = startLine; i < messages.Count; i++)
|
for (var i = startLine; i < messages.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -1791,6 +1795,8 @@ public sealed class ChatLogWindow : Window
|
|||||||
var useCard = !Plugin.Config.UseCompactDensity;
|
var useCard = !Plugin.Config.UseCompactDensity;
|
||||||
if (useCard)
|
if (useCard)
|
||||||
{
|
{
|
||||||
|
var rowStartY = ImGui.GetCursorScreenPos().Y;
|
||||||
|
|
||||||
if (message.Sender.Count > 0)
|
if (message.Sender.Count > 0)
|
||||||
{
|
{
|
||||||
var senderColor =
|
var senderColor =
|
||||||
@@ -1814,9 +1820,18 @@ public sealed class ChatLogWindow : Window
|
|||||||
else
|
else
|
||||||
DrawChunks(message.Content, true, handler, lineWidth);
|
DrawChunks(message.Content, true, handler, lineWidth);
|
||||||
|
|
||||||
// Border bottom as card separator. Alpha reduced to 0x33 for subtlety.
|
// Border bottom as card separator. Base alpha 0x33;
|
||||||
|
// PM-3d lifts it by up to ~+0x70 while any row in this
|
||||||
|
// tab is hovered. _cardHoverAlpha lerps at the loop
|
||||||
|
// end, so the one-frame lag is invisible at 10f speed.
|
||||||
{
|
{
|
||||||
var rowEndY = ImGui.GetCursorScreenPos().Y;
|
var rowEndY = ImGui.GetCursorScreenPos().Y;
|
||||||
|
var hoverBoost = 0.45f * tab._cardHoverAlpha;
|
||||||
|
var alphaByte = (uint)
|
||||||
|
Math.Clamp((int)(0x33u + hoverBoost * 255f), 0x33, 0xCC);
|
||||||
|
var borderColorAbgr = ColourUtil.RgbaToAbgr(
|
||||||
|
(baseBorderRgba & 0xFFFFFF00u) | alphaByte
|
||||||
|
);
|
||||||
drawList.AddLine(
|
drawList.AddLine(
|
||||||
new Vector2(winLeft + 4, rowEndY - 1),
|
new Vector2(winLeft + 4, rowEndY - 1),
|
||||||
new Vector2(winRight - 4, rowEndY - 1),
|
new Vector2(winRight - 4, rowEndY - 1),
|
||||||
@@ -1824,6 +1839,17 @@ public sealed class ChatLogWindow : Window
|
|||||||
1f
|
1f
|
||||||
);
|
);
|
||||||
ImGui.Dummy(new Vector2(0, 2));
|
ImGui.Dummy(new Vector2(0, 2));
|
||||||
|
|
||||||
|
// Whole-row hover test. IsItemHovered would only see
|
||||||
|
// the 2px Dummy above, so hit-test the row rect from
|
||||||
|
// its start Y down to the separator line instead.
|
||||||
|
if (
|
||||||
|
ImGui.IsMouseHoveringRect(
|
||||||
|
new Vector2(winLeft, rowStartY),
|
||||||
|
new Vector2(winRight, rowEndY)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
anyCardHovered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1848,6 +1874,20 @@ public sealed class ChatLogWindow : Window
|
|||||||
|
|
||||||
message.IsVisible[tab.Identifier] = ImGui.IsItemVisible();
|
message.IsVisible[tab.Identifier] = ImGui.IsItemVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PM-3d: update the per-tab card-hover lerp once per
|
||||||
|
// DrawMessages call. ReduceMotion snaps to the target;
|
||||||
|
// otherwise the border alpha eases toward it over a few
|
||||||
|
// frames the next time the rows paint.
|
||||||
|
var cardTarget = anyCardHovered ? 1f : 0f;
|
||||||
|
tab._cardHoverAlpha = Plugin.Config.ReduceMotion
|
||||||
|
? cardTarget
|
||||||
|
: FrameLerp.Smooth(
|
||||||
|
tab._cardHoverAlpha,
|
||||||
|
cardTarget,
|
||||||
|
speed: 10f,
|
||||||
|
deltaTime: ImGui.GetIO().DeltaTime
|
||||||
|
);
|
||||||
}
|
}
|
||||||
catch (ApplicationException)
|
catch (ApplicationException)
|
||||||
{
|
{
|
||||||
@@ -2098,7 +2138,19 @@ public sealed class ChatLogWindow : Window
|
|||||||
ColourUtil.RgbaToAbgr(theme.Colors.Surface)
|
ColourUtil.RgbaToAbgr(theme.Colors.Surface)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(iconColor)))
|
// PM-3c: icon alpha eases from 40% (dim) to 100% on
|
||||||
|
// hover. _hoverAlpha lerps at the end of this block,
|
||||||
|
// so the colour for frame N uses frame N-1's value --
|
||||||
|
// a sub-frame lag that is invisible at 10f speed.
|
||||||
|
using (
|
||||||
|
ImRaii.PushColor(
|
||||||
|
ImGuiCol.Text,
|
||||||
|
ColourUtil.ApplyAlpha(
|
||||||
|
ColourUtil.RgbaToAbgr(iconColor),
|
||||||
|
0.4f + 0.6f * tab._hoverAlpha
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
using (Plugin.FontManager.FontAwesome.Push())
|
using (Plugin.FontManager.FontAwesome.Push())
|
||||||
{
|
{
|
||||||
// Button stretches with the configured sidebar width so a
|
// Button stretches with the configured sidebar width so a
|
||||||
@@ -2110,6 +2162,19 @@ public sealed class ChatLogWindow : Window
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PM-3c hover-lerp: ramp _hoverAlpha toward 1 while the
|
||||||
|
// icon button is hovered, back to 0 otherwise.
|
||||||
|
// ReduceMotion snaps so the dim/full states stay binary.
|
||||||
|
var hoverTarget = ImGui.IsItemHovered() ? 1f : 0f;
|
||||||
|
tab._hoverAlpha = Plugin.Config.ReduceMotion
|
||||||
|
? hoverTarget
|
||||||
|
: FrameLerp.Smooth(
|
||||||
|
tab._hoverAlpha,
|
||||||
|
hoverTarget,
|
||||||
|
speed: 10f,
|
||||||
|
deltaTime: ImGui.GetIO().DeltaTime
|
||||||
|
);
|
||||||
|
|
||||||
if (isCurrentTab)
|
if (isCurrentTab)
|
||||||
{
|
{
|
||||||
// Vertical accent pill on the left window edge, 3px wide, half tab height,
|
// Vertical accent pill on the left window edge, 3px wide, half tab height,
|
||||||
|
|||||||
Reference in New Issue
Block a user