diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index 30b5c10..758b965 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -1627,15 +1627,19 @@ public sealed class ChatLogWindow : Window var maxLines = Plugin.Config.MaxLinesToRender; var startLine = messages.Count > maxLines ? messages.Count - maxLines : 0; - // Card-mode pre-loop: theme/drawList/winLeft/winRight/border are invariant - // per DrawMessages call; only cursorY moves per row. + // Card-mode pre-loop: theme/drawList/winLeft/winRight are + // 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 drawList = ImGui.GetWindowDrawList(); var winLeft = ImGui.GetWindowPos().X; var winRight = winLeft + ImGui.GetWindowSize().X; - var borderColorAbgr = ColourUtil.RgbaToAbgr( - (theme.Colors.Border & 0xFFFFFF00u) | 0x33u - ); + var baseBorderRgba = (theme.Colors.Border & 0xFFFFFF00u) | 0x33u; + var anyCardHovered = false; for (var i = startLine; i < messages.Count; i++) { @@ -1791,6 +1795,8 @@ public sealed class ChatLogWindow : Window var useCard = !Plugin.Config.UseCompactDensity; if (useCard) { + var rowStartY = ImGui.GetCursorScreenPos().Y; + if (message.Sender.Count > 0) { var senderColor = @@ -1814,9 +1820,18 @@ public sealed class ChatLogWindow : Window else 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 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( new Vector2(winLeft + 4, rowEndY - 1), new Vector2(winRight - 4, rowEndY - 1), @@ -1824,6 +1839,17 @@ public sealed class ChatLogWindow : Window 1f ); 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 @@ -1848,6 +1874,20 @@ public sealed class ChatLogWindow : Window 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) { @@ -2098,7 +2138,19 @@ public sealed class ChatLogWindow : Window 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()) { // 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) { // Vertical accent pill on the left window edge, 3px wide, half tab height,