172 lines
5.0 KiB
C#
172 lines
5.0 KiB
C#
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Game.Text.SeStringHandling;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.ImGuiSeStringRenderer;
|
|
using Dalamud.Interface.Utility;
|
|
using System.Numerics;
|
|
|
|
namespace LightlessSync.Utils;
|
|
|
|
public static class SeStringUtils
|
|
{
|
|
public static SeString BuildFormattedPlayerName(string text, Vector4? textColor, Vector4? glowColor)
|
|
{
|
|
var b = new SeStringBuilder();
|
|
|
|
if (glowColor is Vector4 glow)
|
|
b.Add(new GlowPayload(glow));
|
|
|
|
if (textColor is Vector4 color)
|
|
b.Add(new ColorPayload(color));
|
|
|
|
b.AddText(text ?? string.Empty);
|
|
|
|
if (textColor is not null)
|
|
b.Add(new ColorEndPayload());
|
|
|
|
if (glowColor is not null)
|
|
b.Add(new GlowEndPayload());
|
|
|
|
return b.Build();
|
|
}
|
|
|
|
public static SeString BuildPlain(string text)
|
|
{
|
|
var b = new SeStringBuilder();
|
|
b.AddText(text ?? string.Empty);
|
|
return b.Build();
|
|
}
|
|
|
|
public static void RenderSeString(SeString seString, Vector2 position, ImFontPtr? font = null, ImDrawListPtr? drawList = null)
|
|
{
|
|
drawList ??= ImGui.GetWindowDrawList();
|
|
|
|
var drawParams = new SeStringDrawParams
|
|
{
|
|
Font = font ?? UiBuilder.MonoFont,
|
|
Color = 0xFFFFFFFF,
|
|
WrapWidth = float.MaxValue,
|
|
TargetDrawList = drawList
|
|
};
|
|
|
|
ImGui.SetCursorScreenPos(position);
|
|
ImGuiHelpers.SeStringWrapped(seString.Encode(), drawParams);
|
|
}
|
|
|
|
public static Vector2 RenderSeStringWithHitbox(SeString seString, Vector2 position, ImFontPtr? font = null)
|
|
{
|
|
var drawList = ImGui.GetWindowDrawList();
|
|
|
|
var drawParams = new SeStringDrawParams
|
|
{
|
|
Font = font ?? UiBuilder.MonoFont,
|
|
Color = 0xFFFFFFFF,
|
|
WrapWidth = float.MaxValue,
|
|
TargetDrawList = drawList
|
|
};
|
|
|
|
ImGui.SetCursorScreenPos(position);
|
|
ImGuiHelpers.SeStringWrapped(seString.Encode(), drawParams);
|
|
|
|
var textSize = ImGui.CalcTextSize(seString.TextValue);
|
|
|
|
ImGui.SetCursorScreenPos(position);
|
|
ImGui.InvisibleButton($"##hitbox_{Guid.NewGuid()}", textSize);
|
|
|
|
return textSize;
|
|
}
|
|
|
|
public static Vector2 RenderIconWithHitbox(int iconId, Vector2 position, ImFontPtr? font = null)
|
|
{
|
|
var drawList = ImGui.GetWindowDrawList();
|
|
|
|
var drawParams = new SeStringDrawParams
|
|
{
|
|
Font = font ?? UiBuilder.MonoFont,
|
|
Color = 0xFFFFFFFF,
|
|
WrapWidth = float.MaxValue,
|
|
TargetDrawList = drawList
|
|
};
|
|
|
|
var iconMacro = $"<icon({iconId})>";
|
|
var drawResult = ImGuiHelpers.CompileSeStringWrapped(iconMacro, drawParams);
|
|
|
|
ImGui.SetCursorScreenPos(position);
|
|
ImGui.InvisibleButton($"##iconHitbox_{Guid.NewGuid()}", drawResult.Size);
|
|
|
|
return drawResult.Size;
|
|
}
|
|
|
|
#region Internal Payloads
|
|
|
|
private abstract class AbstractColorPayload : Payload
|
|
{
|
|
protected byte Red { get; init; }
|
|
protected byte Green { get; init; }
|
|
protected byte Blue { get; init; }
|
|
|
|
protected override byte[] EncodeImpl()
|
|
{
|
|
return new byte[] { 0x02, ChunkType, 0x05, 0xF6, Red, Green, Blue, 0x03 };
|
|
}
|
|
|
|
protected override void DecodeImpl(BinaryReader reader, long endOfStream) { }
|
|
|
|
public override PayloadType Type => PayloadType.Unknown;
|
|
protected abstract byte ChunkType { get; }
|
|
}
|
|
|
|
private abstract class AbstractColorEndPayload : Payload
|
|
{
|
|
protected override byte[] EncodeImpl()
|
|
{
|
|
return new byte[] { 0x02, ChunkType, 0x02, 0xEC, 0x03 };
|
|
}
|
|
|
|
protected override void DecodeImpl(BinaryReader reader, long endOfStream) { }
|
|
|
|
public override PayloadType Type => PayloadType.Unknown;
|
|
protected abstract byte ChunkType { get; }
|
|
}
|
|
|
|
private class ColorPayload : AbstractColorPayload
|
|
{
|
|
protected override byte ChunkType => 0x13;
|
|
|
|
public ColorPayload(Vector3 color)
|
|
{
|
|
Red = Math.Max((byte)1, (byte)(color.X * 255f));
|
|
Green = Math.Max((byte)1, (byte)(color.Y * 255f));
|
|
Blue = Math.Max((byte)1, (byte)(color.Z * 255f));
|
|
}
|
|
|
|
public ColorPayload(Vector4 color) : this(new Vector3(color.X, color.Y, color.Z)) { }
|
|
}
|
|
|
|
private class ColorEndPayload : AbstractColorEndPayload
|
|
{
|
|
protected override byte ChunkType => 0x13;
|
|
}
|
|
|
|
private class GlowPayload : AbstractColorPayload
|
|
{
|
|
protected override byte ChunkType => 0x14;
|
|
|
|
public GlowPayload(Vector3 color)
|
|
{
|
|
Red = Math.Max((byte)1, (byte)(color.X * 255f));
|
|
Green = Math.Max((byte)1, (byte)(color.Y * 255f));
|
|
Blue = Math.Max((byte)1, (byte)(color.Z * 255f));
|
|
}
|
|
|
|
public GlowPayload(Vector4 color) : this(new Vector3(color.X, color.Y, color.Z)) { }
|
|
}
|
|
|
|
private class GlowEndPayload : AbstractColorEndPayload
|
|
{
|
|
protected override byte ChunkType => 0x14;
|
|
}
|
|
|
|
#endregion
|
|
}
|