Files
SnowcloakClient/MareSynchronos/UI/PopoutProfileUi.cs

185 lines
8.2 KiB
C#
Raw Normal View History

2025-08-22 02:19:48 +01:00
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Interface.Utility;
using MareSynchronos.API.Data.Extensions;
using MareSynchronos.MareConfiguration;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
using Microsoft.Extensions.Logging;
using System.Numerics;
namespace MareSynchronos.UI;
public class PopoutProfileUi : WindowMediatorSubscriberBase
{
private readonly MareProfileManager _mareProfileManager;
private readonly PairManager _pairManager;
private readonly ServerConfigurationManager _serverManager;
private readonly UiSharedService _uiSharedService;
private Vector2 _lastMainPos = Vector2.Zero;
private Vector2 _lastMainSize = Vector2.Zero;
private byte[] _lastProfilePicture = [];
private byte[] _lastSupporterPicture = [];
private Pair? _pair;
private IDalamudTextureWrap? _supporterTextureWrap;
private IDalamudTextureWrap? _textureWrap;
public PopoutProfileUi(ILogger<PopoutProfileUi> logger, MareMediator mediator, UiSharedService uiSharedService,
ServerConfigurationManager serverManager, MareConfigService mareConfigService,
2025-08-22 21:26:51 +01:00
MareProfileManager mareProfileManager, PairManager pairManager, PerformanceCollectorService performanceCollectorService) : base(logger, mediator, "###SnowcloakSyncPopoutProfileUI", performanceCollectorService)
2025-08-22 02:19:48 +01:00
{
_uiSharedService = uiSharedService;
_serverManager = serverManager;
_mareProfileManager = mareProfileManager;
_pairManager = pairManager;
Flags = ImGuiWindowFlags.NoDecoration;
Mediator.Subscribe<ProfilePopoutToggle>(this, (msg) =>
{
IsOpen = msg.Pair != null;
_pair = msg.Pair;
_lastProfilePicture = [];
_lastSupporterPicture = [];
_textureWrap?.Dispose();
_textureWrap = null;
_supporterTextureWrap?.Dispose();
_supporterTextureWrap = null;
});
Mediator.Subscribe<CompactUiChange>(this, (msg) =>
{
if (msg.Size != Vector2.Zero)
{
var border = ImGui.GetStyle().WindowBorderSize;
var padding = ImGui.GetStyle().WindowPadding;
Size = new(256 + (padding.X * 2) + border, msg.Size.Y / ImGuiHelpers.GlobalScale);
_lastMainSize = msg.Size;
}
var mainPos = msg.Position == Vector2.Zero ? _lastMainPos : msg.Position;
if (mareConfigService.Current.ProfilePopoutRight)
{
Position = new(mainPos.X + _lastMainSize.X * ImGuiHelpers.GlobalScale, mainPos.Y);
}
else
{
Position = new(mainPos.X - Size!.Value.X * ImGuiHelpers.GlobalScale, mainPos.Y);
}
if (msg.Position != Vector2.Zero)
{
_lastMainPos = msg.Position;
}
});
IsOpen = false;
}
protected override void DrawInternal()
{
if (_pair == null) return;
try
{
var spacing = ImGui.GetStyle().ItemSpacing;
var mareProfile = _mareProfileManager.GetMareProfile(_pair.UserData);
if (_textureWrap == null || !mareProfile.ImageData.Value.SequenceEqual(_lastProfilePicture))
{
_textureWrap?.Dispose();
_lastProfilePicture = mareProfile.ImageData.Value;
_textureWrap = _uiSharedService.LoadImage(_lastProfilePicture);
}
var drawList = ImGui.GetWindowDrawList();
var rectMin = drawList.GetClipRectMin();
var rectMax = drawList.GetClipRectMax();
using (_uiSharedService.UidFont.Push())
UiSharedService.ColorText(_pair.UserData.AliasOrUID, UiSharedService.AccentColor);
ImGuiHelpers.ScaledDummy(spacing.Y, spacing.Y);
var textPos = ImGui.GetCursorPosY();
ImGui.Separator();
var imagePos = ImGui.GetCursorPos();
ImGuiHelpers.ScaledDummy(256, 256 * ImGuiHelpers.GlobalScale + spacing.Y);
var note = _serverManager.GetNoteForUid(_pair.UserData.UID);
if (!string.IsNullOrEmpty(note))
{
UiSharedService.ColorText(note, ImGuiColors.DalamudGrey);
}
string status = _pair.IsVisible ? "Visible" : (_pair.IsOnline ? "Online" : "Offline");
UiSharedService.ColorText(status, (_pair.IsVisible || _pair.IsOnline) ? ImGuiColors.HealerGreen : ImGuiColors.DalamudRed);
if (_pair.IsVisible)
{
ImGui.SameLine();
ImGui.TextUnformatted($"({_pair.PlayerName})");
}
if (_pair.UserPair != null)
{
ImGui.TextUnformatted("Directly paired");
if (_pair.UserPair.OwnPermissions.IsPaused())
{
ImGui.SameLine();
UiSharedService.ColorText("You: paused", ImGuiColors.DalamudYellow);
}
if (_pair.UserPair.OtherPermissions.IsPaused())
{
ImGui.SameLine();
UiSharedService.ColorText("They: paused", ImGuiColors.DalamudYellow);
}
}
if (_pair.GroupPair.Any())
{
ImGui.TextUnformatted("Paired through Syncshells:");
foreach (var groupPair in _pair.GroupPair.Select(k => k.Key))
{
var groupNote = _serverManager.GetNoteForGid(groupPair.GID);
var groupName = groupPair.GroupAliasOrGID;
var groupString = string.IsNullOrEmpty(groupNote) ? groupName : $"{groupNote} ({groupName})";
ImGui.TextUnformatted("- " + groupString);
}
}
ImGui.Separator();
_uiSharedService.GameFont.Push();
var remaining = ImGui.GetWindowContentRegionMax().Y - ImGui.GetCursorPosY();
var descText = mareProfile.Description;
var textSize = ImGui.CalcTextSize(descText, hideTextAfterDoubleHash: false, 256f * ImGuiHelpers.GlobalScale);
bool trimmed = textSize.Y > remaining;
while (textSize.Y > remaining && descText.Contains(' '))
{
descText = descText[..descText.LastIndexOf(' ')].TrimEnd();
textSize = ImGui.CalcTextSize(descText + $"...{Environment.NewLine}[Open Full Profile for complete description]", hideTextAfterDoubleHash: false, 256f * ImGuiHelpers.GlobalScale);
}
UiSharedService.TextWrapped(trimmed ? descText + $"...{Environment.NewLine}[Open Full Profile for complete description]" : mareProfile.Description);
_uiSharedService.GameFont.Pop();
var padding = ImGui.GetStyle().WindowPadding.X / 2;
bool tallerThanWide = _textureWrap.Height >= _textureWrap.Width;
var stretchFactor = tallerThanWide ? 256f * ImGuiHelpers.GlobalScale / _textureWrap.Height : 256f * ImGuiHelpers.GlobalScale / _textureWrap.Width;
var newWidth = _textureWrap.Width * stretchFactor;
var newHeight = _textureWrap.Height * stretchFactor;
var remainingWidth = (256f * ImGuiHelpers.GlobalScale - newWidth) / 2f;
var remainingHeight = (256f * ImGuiHelpers.GlobalScale - newHeight) / 2f;
drawList.AddImage(_textureWrap.Handle, new Vector2(rectMin.X + padding + remainingWidth, rectMin.Y + spacing.Y + imagePos.Y + remainingHeight),
new Vector2(rectMin.X + padding + remainingWidth + newWidth, rectMin.Y + spacing.Y + imagePos.Y + remainingHeight + newHeight));
if (_supporterTextureWrap != null)
{
const float iconSize = 38;
drawList.AddImage(_supporterTextureWrap.Handle,
new Vector2(rectMax.X - iconSize - spacing.X, rectMin.Y + (textPos / 2) - (iconSize / 2)),
new Vector2(rectMax.X - spacing.X, rectMin.Y + iconSize + (textPos / 2) - (iconSize / 2)));
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Error during draw tooltip");
}
}
}