From 1c1fd5d6d5b4a639568c2f29401033436cc2573d Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 15 Feb 2022 18:36:16 -0500 Subject: [PATCH] feat: add jank hover highlight for links --- ChatTwo/Ui/ChatLog.cs | 4 ++-- ChatTwo/Util/ColourUtil.cs | 9 +++++++++ ChatTwo/Util/ImGuiUtil.cs | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ChatTwo/Ui/ChatLog.cs b/ChatTwo/Ui/ChatLog.cs index 980d22c..6270872 100755 --- a/ChatTwo/Ui/ChatLog.cs +++ b/ChatTwo/Ui/ChatLog.cs @@ -164,7 +164,7 @@ internal sealed class ChatLog : IUiComponent { if (parts.Length < 2 || parts[0] != "chat") { return; } - + switch (parts[1]) { case "hide": this._hideState = HideState.User; @@ -988,7 +988,7 @@ internal sealed class ChatLog : IUiComponent { } if (wrap) { - ImGuiUtil.WrapText(content, chunk, handler); + ImGuiUtil.WrapText(content, chunk, handler, this.Ui.DefaultText); } else { ImGui.TextUnformatted(content); ImGuiUtil.PostPayload(chunk, handler); diff --git a/ChatTwo/Util/ColourUtil.cs b/ChatTwo/Util/ColourUtil.cs index e524ffa..0887e4c 100755 --- a/ChatTwo/Util/ColourUtil.cs +++ b/ChatTwo/Util/ColourUtil.cs @@ -29,6 +29,15 @@ internal static class ColourUtil { ); } + internal static uint Vector4ToAbgr(Vector4 col) { + return RgbaToAbgr(ComponentsToRgba( + (byte) Math.Round(col.X * 255), + (byte) Math.Round(col.Y * 255), + (byte) Math.Round(col.Z * 255), + (byte) Math.Round(col.W * 255) + )); + } + internal static uint ComponentsToRgba(byte red, byte green, byte blue, byte alpha = 0xFF) => alpha | (uint) (red << 24) | (uint) (green << 16) diff --git a/ChatTwo/Util/ImGuiUtil.cs b/ChatTwo/Util/ImGuiUtil.cs index 18a3cd9..7638740 100755 --- a/ChatTwo/Util/ImGuiUtil.cs +++ b/ChatTwo/Util/ImGuiUtil.cs @@ -1,4 +1,6 @@ +using System.Numerics; using System.Text; +using Dalamud.Game.Text.SeStringHandling; using Dalamud.Interface; using Dalamud.Interface.Style; using ImGuiNET; @@ -12,11 +14,18 @@ internal static class ImGuiUtil { ImGuiMouseButton.Right, }; + private static Payload? _hovered; + private static Payload? _lastLink; + private static readonly List<(Vector2, Vector2)> _payloadBounds = new(); + internal static void PostPayload(Chunk chunk, PayloadHandler? handler) { var payload = chunk.Link; if (payload != null && ImGui.IsItemHovered()) { + _hovered = payload; ImGui.SetMouseCursor(ImGuiMouseCursor.Hand); handler?.Hover(payload); + } else if (!ReferenceEquals(_hovered, payload)) { + _hovered = null; } if (handler == null) { @@ -30,10 +39,34 @@ internal static class ImGuiUtil { } } - internal static unsafe void WrapText(string csText, Chunk chunk, PayloadHandler? handler) { + internal static unsafe void WrapText(string csText, Chunk chunk, PayloadHandler? handler, Vector4 defaultText) { void Text(byte* text, byte* textEnd) { + var oldPos = ImGui.GetCursorScreenPos(); + ImGuiNative.igTextUnformatted(text, textEnd); PostPayload(chunk, handler); + + if (!ReferenceEquals(_lastLink, chunk.Link)) { + _payloadBounds.Clear(); + } + + _lastLink = chunk.Link; + + if (_hovered != null && ReferenceEquals(_hovered, chunk.Link)) { + defaultText.W = 0.25f; + var actualCol = ColourUtil.Vector4ToAbgr(defaultText); + ImGui.GetWindowDrawList().AddRectFilled(oldPos, oldPos + ImGui.GetItemRectSize(), actualCol); + + foreach (var (start, size) in _payloadBounds) { + ImGui.GetWindowDrawList().AddRectFilled(start, start + size, actualCol); + } + + _payloadBounds.Clear(); + } + + if (_hovered == null && chunk.Link != null) { + _payloadBounds.Add((oldPos, ImGui.GetItemRectSize())); + } } if (csText.Length == 0) {