Files
LightlessClient/LightlessSync/UI/Handlers/IdDisplayHandler.cs
2025-10-01 23:25:34 +09:00

359 lines
13 KiB
C#

using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using LightlessSync.API.Dto.Group;
using LightlessSync.LightlessConfiguration;
using LightlessSync.PlayerData.Pairs;
using LightlessSync.Services.Mediator;
using LightlessSync.Services.ServerConfiguration;
using LightlessSync.Utils;
using System;
using System.Numerics;
namespace LightlessSync.UI.Handlers;
public class IdDisplayHandler
{
private readonly LightlessConfigService _lightlessConfigService;
private readonly LightlessMediator _mediator;
private readonly ServerConfigurationManager _serverManager;
private readonly Dictionary<string, bool> _showIdForEntry = new(StringComparer.Ordinal);
private string _editComment = string.Empty;
private string _editEntry = string.Empty;
private bool _editIsUid = false;
private string _lastMouseOverUid = string.Empty;
private bool _popupShown = false;
private DateTime? _popupTime;
public IdDisplayHandler(LightlessMediator mediator, ServerConfigurationManager serverManager, LightlessConfigService lightlessConfigService)
{
_mediator = mediator;
_serverManager = serverManager;
_lightlessConfigService = lightlessConfigService;
}
public void DrawGroupText(string id, GroupFullInfoDto group, float textPosX, Func<float> editBoxWidth)
{
ImGui.SameLine(textPosX);
(bool textIsUid, string playerText) = GetGroupText(group);
if (!string.Equals(_editEntry, group.GID, StringComparison.Ordinal))
{
ImGui.AlignTextToFramePadding();
using (ImRaii.PushFont(UiBuilder.MonoFont, textIsUid))
ImGui.TextUnformatted(playerText);
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
var prevState = textIsUid;
if (_showIdForEntry.TryGetValue(group.GID, out bool value))
{
prevState = value;
}
_showIdForEntry[group.GID] = !prevState;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
if (_editIsUid)
{
_serverManager.SetNoteForUid(_editEntry, _editComment, save: true);
}
else
{
_serverManager.SetNoteForGid(_editEntry, _editComment, save: true);
}
_editComment = _serverManager.GetNoteForGid(group.GID) ?? string.Empty;
_editEntry = group.GID;
_editIsUid = false;
}
}
else
{
ImGui.AlignTextToFramePadding();
ImGui.SetNextItemWidth(editBoxWidth.Invoke());
if (ImGui.InputTextWithHint("", "Name/Notes", ref _editComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
{
_serverManager.SetNoteForGid(group.GID, _editComment, save: true);
_editEntry = string.Empty;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
_editEntry = string.Empty;
}
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
}
public void DrawPairText(string id, Pair pair, float textPosX, Func<float> editBoxWidth)
{
ImGui.SameLine(textPosX);
(bool textIsUid, string playerText) = GetPlayerText(pair);
if (!string.Equals(_editEntry, pair.UserData.UID, StringComparison.Ordinal))
{
ImGui.AlignTextToFramePadding();
var font = UiBuilder.MonoFont;
Vector4? textColor = null;
Vector4? glowColor = null;
if (pair.UserData.HasVanity)
{
if (!string.IsNullOrWhiteSpace(pair.UserData.TextColorHex))
{
textColor = UIColors.HexToRgba(pair.UserData.TextColorHex);
}
if (!string.IsNullOrWhiteSpace(pair.UserData.TextGlowColorHex))
{
glowColor = UIColors.HexToRgba(pair.UserData.TextGlowColorHex);
}
}
var useVanityColors = _lightlessConfigService.Current.useColoredUIDs && (textColor != null || glowColor != null);
var seString = useVanityColors
? SeStringUtils.BuildFormattedPlayerName(playerText, textColor, glowColor)
: SeStringUtils.BuildPlain(playerText);
var rowStart = ImGui.GetCursorScreenPos();
var drawList = ImGui.GetWindowDrawList();
bool useHighlight = false;
float highlightPadX = 0f;
float highlightPadY = 0f;
if (useVanityColors && textColor is Vector4 contrastColor)
{
var brightness = (0.299f * contrastColor.X) + (0.587f * contrastColor.Y) + (0.114f * contrastColor.Z);
if (brightness < 0.35f)
{
var style = ImGui.GetStyle();
useHighlight = true;
highlightPadX = MathF.Max(style.FramePadding.X * 0.6f, 2f * ImGuiHelpers.GlobalScale);
highlightPadY = MathF.Max(style.FramePadding.Y * 0.55f, 1.25f * ImGuiHelpers.GlobalScale);
drawList.ChannelsSplit(2);
drawList.ChannelsSetCurrent(1);
}
}
Vector2 itemMin;
Vector2 itemMax;
Vector2 textSize;
using (ImRaii.PushFont(font, textIsUid))
{
SeStringUtils.RenderSeStringWithHitbox(seString, rowStart, font);
itemMin = ImGui.GetItemRectMin();
itemMax = ImGui.GetItemRectMax();
textSize = itemMax - itemMin;
}
if (useHighlight)
{
var style = ImGui.GetStyle();
var frameHeight = ImGui.GetFrameHeight();
var rowTop = rowStart.Y - style.FramePadding.Y;
var rowBottom = rowTop + frameHeight;
var highlightMin = new Vector2(itemMin.X - highlightPadX, rowTop - highlightPadY);
var highlightMax = new Vector2(itemMax.X + highlightPadX, rowBottom + highlightPadY);
var windowPos = ImGui.GetWindowPos();
var contentMin = windowPos + ImGui.GetWindowContentRegionMin();
var contentMax = windowPos + ImGui.GetWindowContentRegionMax();
highlightMin.X = MathF.Max(highlightMin.X, contentMin.X);
highlightMax.X = MathF.Min(highlightMax.X, contentMax.X);
highlightMin.Y = MathF.Max(highlightMin.Y, contentMin.Y);
highlightMax.Y = MathF.Min(highlightMax.Y, contentMax.Y);
var highlightColor = style.Colors[(int)ImGuiCol.TableRowBgAlt];
highlightColor.X = 0.25f;
highlightColor.Y = 0.25f;
highlightColor.Z = 0.25f;
highlightColor.W = 1f;
float rounding = style.FrameRounding > 0f ? style.FrameRounding : 5f * ImGuiHelpers.GlobalScale;
drawList.ChannelsSetCurrent(0);
drawList.AddRectFilled(highlightMin, highlightMax, ImGui.GetColorU32(highlightColor), rounding);
var borderColor = style.Colors[(int)ImGuiCol.Border];
borderColor.W *= 0.25f;
drawList.AddRect(highlightMin, highlightMax, ImGui.GetColorU32(borderColor), rounding);
drawList.ChannelsMerge();
}
if (ImGui.IsItemHovered())
{
if (!string.Equals(_lastMouseOverUid, id))
{
_popupTime = DateTime.UtcNow.AddSeconds(_lightlessConfigService.Current.ProfileDelay);
}
_lastMouseOverUid = id;
if (_popupTime > DateTime.UtcNow || !_lightlessConfigService.Current.ProfilesShow)
{
ImGui.SetTooltip("Left click to switch between UID display and nick" + Environment.NewLine
+ "Right click to change nick for " + pair.UserData.AliasOrUID + Environment.NewLine
+ "Middle Mouse Button to open their profile in a separate window");
}
else if (_popupTime < DateTime.UtcNow && !_popupShown)
{
_popupShown = true;
_mediator.Publish(new ProfilePopoutToggle(pair));
}
}
else
{
if (string.Equals(_lastMouseOverUid, id))
{
_mediator.Publish(new ProfilePopoutToggle(Pair: null));
_lastMouseOverUid = string.Empty;
_popupShown = false;
}
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
var prevState = textIsUid;
if (_showIdForEntry.ContainsKey(pair.UserData.UID))
{
prevState = _showIdForEntry[pair.UserData.UID];
}
_showIdForEntry[pair.UserData.UID] = !prevState;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
if (_editIsUid)
{
_serverManager.SetNoteForUid(_editEntry, _editComment, save: true);
}
else
{
_serverManager.SetNoteForGid(_editEntry, _editComment, save: true);
}
_editComment = pair.GetNote() ?? string.Empty;
_editEntry = pair.UserData.UID;
_editIsUid = true;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Middle))
{
_mediator.Publish(new ProfileOpenStandaloneMessage(pair));
}
}
else
{
ImGui.AlignTextToFramePadding();
ImGui.SetNextItemWidth(editBoxWidth.Invoke());
if (ImGui.InputTextWithHint("##" + pair.UserData.UID, "Nick/Notes", ref _editComment, 255, ImGuiInputTextFlags.EnterReturnsTrue))
{
_serverManager.SetNoteForUid(pair.UserData.UID, _editComment);
_serverManager.SaveNotes();
_editEntry = string.Empty;
}
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
{
_editEntry = string.Empty;
}
UiSharedService.AttachToolTip("Hit ENTER to save\nRight click to cancel");
}
}
public (bool isGid, string text) GetGroupText(GroupFullInfoDto group)
{
var textIsGid = true;
bool showUidInsteadOfName = ShowGidInsteadOfName(group);
string? groupText = _serverManager.GetNoteForGid(group.GID);
if (!showUidInsteadOfName && groupText != null)
{
if (string.IsNullOrEmpty(groupText))
{
groupText = group.GroupAliasOrGID;
}
else
{
textIsGid = false;
}
}
else
{
groupText = group.GroupAliasOrGID;
}
return (textIsGid, groupText!);
}
public (bool isUid, string text) GetPlayerText(Pair pair)
{
var textIsUid = true;
bool showUidInsteadOfName = ShowUidInsteadOfName(pair);
string? playerText = _serverManager.GetNoteForUid(pair.UserData.UID);
if (!showUidInsteadOfName && playerText != null)
{
if (string.IsNullOrEmpty(playerText))
{
playerText = pair.UserData.AliasOrUID;
}
else
{
textIsUid = false;
}
}
else
{
playerText = pair.UserData.AliasOrUID;
}
if (_lightlessConfigService.Current.ShowCharacterNameInsteadOfNotesForVisible && pair.IsVisible && !showUidInsteadOfName)
{
playerText = pair.PlayerName;
textIsUid = false;
if (_lightlessConfigService.Current.PreferNotesOverNamesForVisible)
{
var note = pair.GetNote();
if (note != null)
{
playerText = note;
}
}
}
return (textIsUid, playerText!);
}
internal void Clear()
{
_editEntry = string.Empty;
_editComment = string.Empty;
}
internal void OpenProfile(Pair entry)
{
_mediator.Publish(new ProfileOpenStandaloneMessage(entry));
}
private bool ShowGidInsteadOfName(GroupFullInfoDto group)
{
_showIdForEntry.TryGetValue(group.GID, out var showidInsteadOfName);
return showidInsteadOfName;
}
private bool ShowUidInsteadOfName(Pair pair)
{
_showIdForEntry.TryGetValue(pair.UserData.UID, out var showidInsteadOfName);
return showidInsteadOfName;
}
}