mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-15 13:14:17 +01:00
Misc UiDebug2 Fixes
- The widget will now only check the `FFXIVClientStructs` assembly for addon type information. - Updated ImRaii usage - Clarified suppression in `NodeTree.Text.cs` - Restored the original Addon Inspector in the Data window, so that both versions can coexist for the time being
This commit is contained in:
parent
e19f9284e5
commit
552aafd70d
17 changed files with 379 additions and 347 deletions
|
|
@ -16,8 +16,10 @@ public unsafe partial class AddonTree
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<string, Type?> AddonTypeDict = [];
|
private static readonly Dictionary<string, Type?> AddonTypeDict = [];
|
||||||
|
|
||||||
|
private static readonly Assembly? ClientStructs = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(static a => a.GetName().Name == "FFXIVClientStructs");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a collection of names corresponding to pointers documented within the addon struct.
|
/// Gets or sets a collection of names for field offsets that have been documented in FFXIVClientStructs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Dictionary<nint, List<string>> FieldNames { get; set; } = [];
|
internal Dictionary<nint, List<string>> FieldNames { get; set; } = [];
|
||||||
|
|
||||||
|
|
@ -28,28 +30,25 @@ public unsafe partial class AddonTree
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddonTypeDict.TryAdd(this.AddonName, null))
|
if (AddonTypeDict.TryAdd(this.AddonName, null) && ClientStructs != null)
|
||||||
{
|
{
|
||||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
try
|
||||||
{
|
{
|
||||||
try
|
foreach (var t in from t in ClientStructs.GetTypes()
|
||||||
|
where t.IsPublic
|
||||||
|
let xivAddonAttr = (Addon?)t.GetCustomAttribute(typeof(Addon), false)
|
||||||
|
where xivAddonAttr != null
|
||||||
|
where xivAddonAttr.AddonIdentifiers.Contains(this.AddonName)
|
||||||
|
select t)
|
||||||
{
|
{
|
||||||
foreach (var t in from t in a.GetTypes()
|
AddonTypeDict[this.AddonName] = t;
|
||||||
where t.IsPublic
|
break;
|
||||||
let xivAddonAttr = (Addon?)t.GetCustomAttribute(typeof(Addon), false)
|
|
||||||
where xivAddonAttr != null
|
|
||||||
where xivAddonAttr.AddonIdentifiers.Contains(this.AddonName)
|
|
||||||
select t)
|
|
||||||
{
|
|
||||||
AddonTypeDict[this.AddonName] = t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddonTypeDict.TryGetValue(this.AddonName, out var result) && result != null ? Marshal.PtrToStructure(new(addon), result) : *addon;
|
return AddonTypeDict.TryGetValue(this.AddonName, out var result) && result != null ? Marshal.PtrToStructure(new(addon), result) : *addon;
|
||||||
|
|
@ -108,7 +107,7 @@ public unsafe partial class AddonTree
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (this.FieldNames.TryAdd(fieldAddr, [..path!, name]) && fieldType.DeclaringType == baseType)
|
if (this.FieldNames.TryAdd(fieldAddr, [..path, name]) && fieldType.DeclaringType == baseType)
|
||||||
{
|
{
|
||||||
this.PopulateFieldNames(field.GetValue(obj), fieldAddr, [..path, name]);
|
this.PopulateFieldNames(field.GetValue(obj), fieldAddr, [..path, name]);
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +139,7 @@ public unsafe partial class AddonTree
|
||||||
var itemAddr = fieldAddr + (size * i);
|
var itemAddr = fieldAddr + (size * i);
|
||||||
var itemName = $"{name}[{i}]";
|
var itemName = $"{name}[{i}]";
|
||||||
|
|
||||||
this.FieldNames.TryAdd(itemAddr, [..path!, itemName]);
|
this.FieldNames.TryAdd(itemAddr, [..path, itemName]);
|
||||||
|
|
||||||
var item = Marshal.PtrToStructure(itemAddr, itemType);
|
var item = Marshal.PtrToStructure(itemAddr, itemType);
|
||||||
if (itemType.DeclaringType == baseType)
|
if (itemType.DeclaringType == baseType)
|
||||||
|
|
@ -176,10 +175,10 @@ public unsafe partial class AddonTree
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.FieldNames.TryAdd(fieldAddr, [..path!, name]);
|
this.FieldNames.TryAdd(fieldAddr, [..path, name]);
|
||||||
this.FieldNames.TryAdd(pointer, [..path, name]);
|
this.FieldNames.TryAdd(pointer, [..path, name]);
|
||||||
|
|
||||||
if (itemType?.DeclaringType != baseType || itemType!.IsPointer)
|
if (itemType?.DeclaringType != baseType || itemType.IsPointer)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,44 +26,41 @@ public static class Events
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tree = ImRaii.TreeNode($"Events##{(nint)node:X}eventTree");
|
using var tree = ImRaii.TreeNode($"Events##{(nint)node:X}eventTree");
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
var tab = ImRaii.Table($"##{(nint)node:X}eventTable", 7, Resizable | SizingFixedFit | Borders | RowBg);
|
using (ImRaii.Table($"##{(nint)node:X}eventTable", 7, Resizable | SizingFixedFit | Borders | RowBg))
|
||||||
|
|
||||||
ImGui.TableSetupColumn("#", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Type", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Param", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Flags", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Unk29", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Target", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Listener", WidthFixed);
|
|
||||||
|
|
||||||
ImGui.TableHeadersRow();
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
while (evt != null)
|
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableSetupColumn("#", WidthFixed);
|
||||||
ImGui.Text($"{i++}");
|
ImGui.TableSetupColumn("Type", WidthFixed);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableSetupColumn("Param", WidthFixed);
|
||||||
ImGui.Text($"{evt->Type}");
|
ImGui.TableSetupColumn("Flags", WidthFixed);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableSetupColumn("Unk29", WidthFixed);
|
||||||
ImGui.Text($"{evt->Param}");
|
ImGui.TableSetupColumn("Target", WidthFixed);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableSetupColumn("Listener", WidthFixed);
|
||||||
ImGui.Text($"{evt->Flags}");
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableHeadersRow();
|
||||||
ImGui.Text($"{evt->Unk29}");
|
|
||||||
ImGui.TableNextColumn();
|
var i = 0;
|
||||||
Gui.ClickToCopyText($"{(nint)evt->Target:X}");
|
while (evt != null)
|
||||||
ImGui.TableNextColumn();
|
{
|
||||||
Gui.ClickToCopyText($"{(nint)evt->Listener:X}");
|
ImGui.TableNextColumn();
|
||||||
evt = evt->NextEvent;
|
ImGui.Text($"{i++}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text($"{evt->Type}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text($"{evt->Param}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text($"{evt->Flags}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text($"{evt->Unk29}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
Gui.ClickToCopyText($"{(nint)evt->Target:X}");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
Gui.ClickToCopyText($"{(nint)evt->Listener:X}");
|
||||||
|
evt = evt->NextEvent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tab.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,10 @@ internal unsafe partial class ResNodeTree
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private protected void DrawNodeEditorTable()
|
private protected void DrawNodeEditorTable()
|
||||||
{
|
{
|
||||||
var tab = ImRaii.Table($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX);
|
using (ImRaii.Table($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX))
|
||||||
|
{
|
||||||
this.DrawEditorRows();
|
this.DrawEditorRows();
|
||||||
|
}
|
||||||
tab.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Draws the texture inside the window, in either of two styles.<br/><br/>
|
/// Draws the texture inside the window, in either of two styles.<br/><br/>
|
||||||
/// <term>Full Image</term>presents the texture in full as a spritesheet.<br/>
|
/// <term>Full Image (0)</term>presents the texture in full as a spritesheet.<br/>
|
||||||
/// <term>Parts List</term>presents the individual parts as rows in a table.
|
/// <term>Parts List (1)</term>presents the individual parts as rows in a table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private protected void DrawTextureAndParts()
|
private protected void DrawTextureAndParts()
|
||||||
{
|
{
|
||||||
|
|
@ -63,7 +63,7 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tree = ImRaii.TreeNode($"Texture##texture{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", SpanFullWidth);
|
using var tree = ImRaii.TreeNode($"Texture##texture{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", SpanFullWidth);
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
|
|
@ -99,8 +99,6 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
|
||||||
this.DrawFullTexture();
|
this.DrawFullTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -191,58 +189,62 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
|
||||||
|
|
||||||
private void PrintPartsTable()
|
private void PrintPartsTable()
|
||||||
{
|
{
|
||||||
var tab = ImRaii.Table($"partsTable##{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", 3, Borders | RowBg | Reorderable);
|
using (ImRaii.Table($"partsTable##{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", 3, Borders | RowBg | Reorderable))
|
||||||
ImGui.TableSetupColumn("Part ID", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Part Texture", WidthFixed);
|
|
||||||
ImGui.TableSetupColumn("Coordinates", WidthFixed);
|
|
||||||
|
|
||||||
ImGui.TableHeadersRow();
|
|
||||||
|
|
||||||
var tWidth = this.TexData.Texture->Width;
|
|
||||||
var tHeight = this.TexData.Texture->Height;
|
|
||||||
var textureSize = new Vector2(tWidth, tHeight);
|
|
||||||
|
|
||||||
for (ushort i = 0; i < this.TexData.PartCount; i++)
|
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableSetupColumn("Part ID", WidthFixed);
|
||||||
|
ImGui.TableSetupColumn("Part Texture", WidthFixed);
|
||||||
|
ImGui.TableSetupColumn("Coordinates", WidthFixed);
|
||||||
|
|
||||||
var col = i == this.TexData.PartId ? new Vector4(0, 0.85F, 1, 1) : new(1);
|
ImGui.TableHeadersRow();
|
||||||
ImGui.TextColored(col, $"#{i.ToString().PadLeft(this.TexData.PartCount.ToString().Length, '0')}");
|
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
var tWidth = this.TexData.Texture->Width;
|
||||||
|
var tHeight = this.TexData.Texture->Height;
|
||||||
|
var textureSize = new Vector2(tWidth, tHeight);
|
||||||
|
|
||||||
var part = this.TexData.PartsList->Parts[i];
|
for (ushort i = 0; i < this.TexData.PartCount; i++)
|
||||||
var hiRes = this.TexData.HiRes;
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
var u = hiRes ? part.U * 2f : part.U;
|
var col = i == this.TexData.PartId ? new Vector4(0, 0.85F, 1, 1) : new(1);
|
||||||
var v = hiRes ? part.V * 2f : part.V;
|
ImGui.TextColored(col, $"#{i.ToString().PadLeft(this.TexData.PartCount.ToString().Length, '0')}");
|
||||||
var width = hiRes ? part.Width * 2f : part.Width;
|
|
||||||
var height = hiRes ? part.Height * 2f : part.Height;
|
|
||||||
|
|
||||||
ImGui.Image(new(this.TexData.Texture->D3D11ShaderResourceView), new(width, height), new Vector2(u, v) / textureSize, new Vector2(u + width, v + height) / textureSize);
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
var part = this.TexData.PartsList->Parts[i];
|
||||||
|
var hiRes = this.TexData.HiRes;
|
||||||
|
|
||||||
ImGui.TextColored(!hiRes ? new(1) : new(0.6f, 0.6f, 0.6f, 1), "Standard:\t");
|
var u = hiRes ? part.U * 2f : part.U;
|
||||||
ImGui.SameLine();
|
var v = hiRes ? part.V * 2f : part.V;
|
||||||
var cursX = ImGui.GetCursorPosX();
|
var width = hiRes ? part.Width * 2f : part.Width;
|
||||||
|
var height = hiRes ? part.Height * 2f : part.Height;
|
||||||
|
|
||||||
PrintPartCoords(u / 2f, v / 2f, width / 2f, height / 2f);
|
ImGui.Image(
|
||||||
|
new(this.TexData.Texture->D3D11ShaderResourceView),
|
||||||
|
new(width, height),
|
||||||
|
new Vector2(u, v) / textureSize,
|
||||||
|
new Vector2(u + width, v + height) / textureSize);
|
||||||
|
|
||||||
ImGui.TextColored(hiRes ? new(1) : new(0.6f, 0.6f, 0.6f, 1), "Hi-Res:\t");
|
ImGui.TableNextColumn();
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetCursorPosX(cursX);
|
|
||||||
|
|
||||||
PrintPartCoords(u, v, width, height);
|
ImGui.TextColored(!hiRes ? new(1) : new(0.6f, 0.6f, 0.6f, 1), "Standard:\t");
|
||||||
|
ImGui.SameLine();
|
||||||
|
var cursX = ImGui.GetCursorPosX();
|
||||||
|
|
||||||
ImGui.Text("UV:\t");
|
PrintPartCoords(u / 2f, v / 2f, width / 2f, height / 2f);
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetCursorPosX(cursX);
|
|
||||||
|
|
||||||
PrintPartCoords(u / tWidth, v / tWidth, (u + width) / tWidth, (v + height) / tHeight, true, true);
|
ImGui.TextColored(hiRes ? new(1) : new(0.6f, 0.6f, 0.6f, 1), "Hi-Res:\t");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.SetCursorPosX(cursX);
|
||||||
|
|
||||||
|
PrintPartCoords(u, v, width, height);
|
||||||
|
|
||||||
|
ImGui.Text("UV:\t");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.SetCursorPosX(cursX);
|
||||||
|
|
||||||
|
PrintPartCoords(u / tWidth, v / tWidth, (u + width) / tWidth, (v + height) / tHeight, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tab.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,11 @@ internal unsafe partial class ResNodeTree : IDisposable
|
||||||
NodeType.ClippingMask => new ClippingMaskNodeTree(node, addonTree),
|
NodeType.ClippingMask => new ClippingMaskNodeTree(node, addonTree),
|
||||||
NodeType.Counter => new CounterNodeTree(node, addonTree),
|
NodeType.Counter => new CounterNodeTree(node, addonTree),
|
||||||
NodeType.Collision => new CollisionNodeTree(node, addonTree),
|
NodeType.Collision => new CollisionNodeTree(node, addonTree),
|
||||||
_ => new ResNodeTree(node, addonTree),
|
_ => new ResNodeTree(node, addonTree)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints a list of NodeTree for a given list of nodes.
|
/// Prints a list of NodeTrees for a given list of nodes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nodeList">The address of the start of the list.</param>
|
/// <param name="nodeList">The address of the start of the list.</param>
|
||||||
/// <param name="count">The number of nodes in the list.</param>
|
/// <param name="count">The number of nodes in the list.</param>
|
||||||
|
|
@ -122,8 +122,8 @@ internal unsafe partial class ResNodeTree : IDisposable
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var c = ImRaii.PushColor(Text, color);
|
using var c = ImRaii.PushColor(Text, color);
|
||||||
var tree = ImRaii.TreeNode($"{label}##{(nint)nodeList:X}", SpanFullWidth);
|
using var tree = ImRaii.TreeNode($"{label}##{(nint)nodeList:X}", SpanFullWidth);
|
||||||
c.Pop();
|
c.Pop();
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
|
|
@ -139,8 +139,6 @@ internal unsafe partial class ResNodeTree : IDisposable
|
||||||
ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(color), 1);
|
ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(color), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -275,8 +273,8 @@ internal unsafe partial class ResNodeTree : IDisposable
|
||||||
ImGui.SetNextItemOpen(true, ImGuiCond.Always);
|
ImGui.SetNextItemOpen(true, ImGuiCond.Always);
|
||||||
}
|
}
|
||||||
|
|
||||||
var col = ImRaii.PushColor(Text, displayColor);
|
using var col = ImRaii.PushColor(Text, displayColor);
|
||||||
var tree = ImRaii.TreeNode(label, SpanFullWidth);
|
using var tree = ImRaii.TreeNode(label, SpanFullWidth);
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
|
|
@ -331,8 +329,6 @@ internal unsafe partial class ResNodeTree : IDisposable
|
||||||
ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(displayColor), 1);
|
ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(displayColor), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawBasicControls()
|
private void DrawBasicControls()
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ internal unsafe partial class TextNodeTree : ResNodeTree
|
||||||
ImGui.TextColored(new(1), "Text:");
|
ImGui.TextColored(new(1), "Text:");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
#pragma warning disable
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var style = new SeStringDrawParams
|
var style = new SeStringDrawParams
|
||||||
|
|
@ -61,13 +60,14 @@ internal unsafe partial class TextNodeTree : ResNodeTree
|
||||||
EdgeStrength = 1f
|
EdgeStrength = 1f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma warning disable SeStringRenderer
|
||||||
ImGuiHelpers.SeStringWrapped(this.NodeText.AsSpan(), style);
|
ImGuiHelpers.SeStringWrapped(this.NodeText.AsSpan(), style);
|
||||||
|
#pragma warning restore SeStringRenderer
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
ImGui.Text(Marshal.PtrToStringAnsi(new(this.NodeText.StringPtr)) ?? "");
|
ImGui.Text(Marshal.PtrToStringAnsi(new(this.NodeText.StringPtr)) ?? "");
|
||||||
}
|
}
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
PrintFieldValuePairs(
|
PrintFieldValuePairs(
|
||||||
("Font", $"{this.TxtNode->FontType}"),
|
("Font", $"{this.TxtNode->FontType}"),
|
||||||
|
|
@ -83,7 +83,7 @@ internal unsafe partial class TextNodeTree : ResNodeTree
|
||||||
|
|
||||||
private void PrintPayloads()
|
private void PrintPayloads()
|
||||||
{
|
{
|
||||||
var tree = ImRaii.TreeNode($"Text Payloads##{(nint)this.Node:X}");
|
using var tree = ImRaii.TreeNode($"Text Payloads##{(nint)this.Node:X}");
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
|
|
@ -116,7 +116,5 @@ internal unsafe partial class TextNodeTree : ResNodeTree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public readonly unsafe partial struct TimelineTree
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
var tree = ImRaii.TreeNode($"Timeline##{(nint)this.node:X}timeline", SpanFullWidth);
|
using var tree = ImRaii.TreeNode($"Timeline##{(nint)this.node:X}timeline", SpanFullWidth);
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
|
|
@ -81,8 +81,6 @@ public readonly unsafe partial struct TimelineTree
|
||||||
this.PrintAnimation(animation, a, isActive, (nint)(this.NodeTimeline->Resource->Animations + (a * sizeof(AtkTimelineAnimation))));
|
this.PrintAnimation(animation, a, isActive, (nint)(this.NodeTimeline->Resource->Animations + (a * sizeof(AtkTimelineAnimation))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -310,45 +308,46 @@ public readonly unsafe partial struct TimelineTree
|
||||||
{
|
{
|
||||||
var columns = this.BuildColumns(animation);
|
var columns = this.BuildColumns(animation);
|
||||||
|
|
||||||
var col = ImRaii.PushColor(ImGuiCol.Text, isActive ? new Vector4(1, 0.65F, 0.4F, 1) : new(1));
|
using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(1, 0.65F, 0.4F, 1), isActive))
|
||||||
var tree = ImRaii.TreeNode($"[#{a}] [Frames {animation.StartFrameIdx}-{animation.EndFrameIdx}] {(isActive ? " (Active)" : string.Empty)}###{(nint)this.node}animTree{a}");
|
|
||||||
col.Dispose();
|
|
||||||
|
|
||||||
if (tree)
|
|
||||||
{
|
{
|
||||||
PrintFieldValuePair("Animation", $"{address:X}");
|
using var tree = ImRaii.TreeNode($"[#{a}] [Frames {animation.StartFrameIdx}-{animation.EndFrameIdx}] {(isActive ? " (Active)" : string.Empty)}###{(nint)this.node}animTree{a}");
|
||||||
|
|
||||||
ShowStruct((AtkTimelineAnimation*)address);
|
if (tree)
|
||||||
|
|
||||||
if (columns.Count > 0)
|
|
||||||
{
|
{
|
||||||
var table = ImRaii.Table($"##{(nint)this.node}animTable{a}", columns.Count, Borders | SizingFixedFit | RowBg | NoHostExtendX);
|
PrintFieldValuePair("Animation", $"{address:X}");
|
||||||
|
|
||||||
foreach (var c in columns)
|
ShowStruct((AtkTimelineAnimation*)address);
|
||||||
|
|
||||||
|
if (columns.Count > 0)
|
||||||
{
|
{
|
||||||
ImGui.TableSetupColumn(c.Name, WidthFixed, c.Width);
|
using (ImRaii.Table(
|
||||||
}
|
$"##{(nint)this.node}animTable{a}",
|
||||||
|
columns.Count,
|
||||||
ImGui.TableHeadersRow();
|
Borders | SizingFixedFit | RowBg | NoHostExtendX))
|
||||||
|
|
||||||
var rows = columns.Select(static c => c.Count).Max();
|
|
||||||
|
|
||||||
for (var i = 0; i < rows; i++)
|
|
||||||
{
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
|
|
||||||
foreach (var c in columns)
|
|
||||||
{
|
{
|
||||||
ImGui.TableNextColumn();
|
foreach (var c in columns)
|
||||||
c.PrintValueAt(i);
|
{
|
||||||
|
ImGui.TableSetupColumn(c.Name, WidthFixed, c.Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
|
var rows = columns.Select(static c => c.Count).Max();
|
||||||
|
|
||||||
|
for (var i = 0; i < rows; i++)
|
||||||
|
{
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
|
foreach (var c in columns)
|
||||||
|
{
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
c.PrintValueAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IKeyGroupColumn> BuildColumns(AtkTimelineAnimation animation)
|
private List<IKeyGroupColumn> BuildColumns(AtkTimelineAnimation animation)
|
||||||
|
|
|
||||||
|
|
@ -79,43 +79,53 @@ internal unsafe class ElementSelector : IDisposable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void DrawInterface()
|
internal void DrawInterface()
|
||||||
{
|
{
|
||||||
var ch = ImRaii.Child("###sidebar_elementSelector", new(250, 0), true);
|
using (ImRaii.Child("###sidebar_elementSelector", new(250, 0), true))
|
||||||
|
|
||||||
var f = ImRaii.PushFont(IconFont);
|
|
||||||
var col = ImRaii.PushColor(Text, this.Active ? new Vector4(1, 1, 0.2f, 1) : new(1));
|
|
||||||
if (ImGui.Button($"{(char)ObjectUngroup}"))
|
|
||||||
{
|
{
|
||||||
this.Active = !this.Active;
|
using var f = ImRaii.PushFont(IconFont);
|
||||||
}
|
using var col = ImRaii.PushColor(Text, new Vector4(1, 1, 0.2f, 1), this.Active);
|
||||||
|
|
||||||
if (Countdown > 0)
|
if (ImGui.Button($"{(char)ObjectUngroup}"))
|
||||||
{
|
|
||||||
Countdown -= 1;
|
|
||||||
if (Countdown < 0)
|
|
||||||
{
|
{
|
||||||
Countdown = 0;
|
this.Active = !this.Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Countdown > 0)
|
||||||
|
{
|
||||||
|
Countdown -= 1;
|
||||||
|
if (Countdown < 0)
|
||||||
|
{
|
||||||
|
Countdown = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
col.Pop();
|
||||||
|
f.Pop();
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui.SetTooltip("Element Selector");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 32);
|
||||||
|
ImGui.InputTextWithHint(
|
||||||
|
"###addressSearchInput",
|
||||||
|
"Address Search",
|
||||||
|
ref this.addressSearchInput,
|
||||||
|
18,
|
||||||
|
ImGuiInputTextFlags.AutoSelectAll);
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGuiComponents.IconButton("###elemSelectorAddrSearch", Search) && nint.TryParse(
|
||||||
|
this.addressSearchInput,
|
||||||
|
NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier,
|
||||||
|
InvariantInfo,
|
||||||
|
out var address))
|
||||||
|
{
|
||||||
|
this.PerformSearch(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
col.Pop();
|
|
||||||
f.Pop();
|
|
||||||
if (ImGui.IsItemHovered())
|
|
||||||
{
|
|
||||||
ImGui.SetTooltip("Element Selector");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X - 32);
|
|
||||||
ImGui.InputTextWithHint("###addressSearchInput", "Address Search", ref this.addressSearchInput, 18, ImGuiInputTextFlags.AutoSelectAll);
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGuiComponents.IconButton("###elemSelectorAddrSearch", Search) && nint.TryParse(this.addressSearchInput, NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier, InvariantInfo, out var address))
|
|
||||||
{
|
|
||||||
this.PerformSearch(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
ch.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -141,72 +151,71 @@ internal unsafe class ElementSelector : IDisposable
|
||||||
var mousePos = ImGui.GetMousePos() - MainViewport.Pos;
|
var mousePos = ImGui.GetMousePos() - MainViewport.Pos;
|
||||||
var addonResults = GetAtkUnitBaseAtPosition(mousePos);
|
var addonResults = GetAtkUnitBaseAtPosition(mousePos);
|
||||||
|
|
||||||
var col = ImRaii.PushColor(WindowBg, new Vector4(0.5f));
|
using var col = ImRaii.PushColor(WindowBg, new Vector4(0.5f));
|
||||||
var ch = ImRaii.Child("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse);
|
using (ImRaii.Child("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse))
|
||||||
var g = ImRaii.Group();
|
|
||||||
|
|
||||||
Gui.PrintFieldValuePair("Mouse Position", $"{mousePos.X}, {mousePos.Y}");
|
|
||||||
ImGui.Spacing();
|
|
||||||
ImGui.Text("RESULTS:\n");
|
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
foreach (var a in addonResults)
|
|
||||||
{
|
{
|
||||||
var name = a.Addon->NameString;
|
using (ImRaii.Group())
|
||||||
ImGui.Text($"[Addon] {name}");
|
|
||||||
ImGui.Indent(15);
|
|
||||||
foreach (var n in a.Nodes)
|
|
||||||
{
|
{
|
||||||
var nSelected = i++ == this.index;
|
Gui.PrintFieldValuePair("Mouse Position", $"{mousePos.X}, {mousePos.Y}");
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Text("RESULTS:\n");
|
||||||
|
|
||||||
PrintNodeHeaderOnly(n.Node, nSelected, a.Addon);
|
var i = 0;
|
||||||
|
foreach (var a in addonResults)
|
||||||
if (nSelected && ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
|
||||||
{
|
{
|
||||||
this.Active = false;
|
var name = a.Addon->NameString;
|
||||||
|
ImGui.Text($"[Addon] {name}");
|
||||||
this.uiDebug2.SelectedAddonName = a.Addon->NameString;
|
ImGui.Indent(15);
|
||||||
|
foreach (var n in a.Nodes)
|
||||||
var ptrList = new List<nint> { (nint)n.Node };
|
|
||||||
|
|
||||||
var nextNode = n.Node->ParentNode;
|
|
||||||
while (nextNode != null)
|
|
||||||
{
|
{
|
||||||
ptrList.Add((nint)nextNode);
|
var nSelected = i++ == this.index;
|
||||||
nextNode = nextNode->ParentNode;
|
|
||||||
|
PrintNodeHeaderOnly(n.Node, nSelected, a.Addon);
|
||||||
|
|
||||||
|
if (nSelected && ImGui.IsMouseClicked(ImGuiMouseButton.Left))
|
||||||
|
{
|
||||||
|
this.Active = false;
|
||||||
|
|
||||||
|
this.uiDebug2.SelectedAddonName = a.Addon->NameString;
|
||||||
|
|
||||||
|
var ptrList = new List<nint> { (nint)n.Node };
|
||||||
|
|
||||||
|
var nextNode = n.Node->ParentNode;
|
||||||
|
while (nextNode != null)
|
||||||
|
{
|
||||||
|
ptrList.Add((nint)nextNode);
|
||||||
|
nextNode = nextNode->ParentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResults = [.. ptrList];
|
||||||
|
Countdown = 100;
|
||||||
|
Scrolled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nSelected)
|
||||||
|
{
|
||||||
|
n.NodeBounds.DrawFilled(new(1, 1, 0.2f, 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SearchResults = [.. ptrList];
|
ImGui.Indent(-15);
|
||||||
Countdown = 100;
|
|
||||||
Scrolled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nSelected)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
n.NodeBounds.DrawFilled(new(1, 1, 0.2f, 1));
|
this.index -= (int)ImGui.GetIO().MouseWheel;
|
||||||
|
while (this.index < 0)
|
||||||
|
{
|
||||||
|
this.index += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (this.index >= i)
|
||||||
|
{
|
||||||
|
this.index -= i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Indent(-15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != 0)
|
|
||||||
{
|
|
||||||
this.index -= (int)ImGui.GetIO().MouseWheel;
|
|
||||||
while (this.index < 0)
|
|
||||||
{
|
|
||||||
this.index += i;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (this.index >= i)
|
|
||||||
{
|
|
||||||
this.index -= i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g.Dispose();
|
|
||||||
ch.Dispose();
|
|
||||||
col.Pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<AddonResult> GetAtkUnitBaseAtPosition(Vector2 position)
|
private static List<AddonResult> GetAtkUnitBaseAtPosition(Vector2 position)
|
||||||
|
|
@ -384,9 +393,8 @@ internal unsafe class ElementSelector : IDisposable
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var col = ImRaii.PushColor(Text, selected ? new Vector4(1, 1, 0.2f, 1) : new(0.6f, 0.6f, 0.6f, 1));
|
using var col = ImRaii.PushColor(Text, selected ? new Vector4(1, 1, 0.2f, 1) : new(0.6f, 0.6f, 0.6f, 1));
|
||||||
ResNodeTree.GetOrCreate(node, tree).WriteTreeHeading();
|
ResNodeTree.GetOrCreate(node, tree).WriteTreeHeading();
|
||||||
col.Pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PerformSearch(nint address)
|
private void PerformSearch(nint address)
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,10 @@ internal class AddonPopoutWindow : Window, IDisposable
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
var ch = ImRaii.Child($"{this.WindowName}child", new(-1, -1), true);
|
using (ImRaii.Child($"{this.WindowName}child", new(-1, -1), true))
|
||||||
this.addonTree.Draw();
|
{
|
||||||
ch.Dispose();
|
this.addonTree.Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,11 @@ internal unsafe class NodePopoutWindow : Window, IDisposable
|
||||||
{
|
{
|
||||||
if (this.Node != null && this.AddonTree.ContainsNode(this.Node))
|
if (this.Node != null && this.AddonTree.ContainsNode(this.Node))
|
||||||
{
|
{
|
||||||
var ch = ImRaii.Child($"{(nint)this.Node:X}popoutChild", new(-1, -1), true);
|
using (ImRaii.Child($"{(nint)this.Node:X}popoutChild", new(-1, -1), true))
|
||||||
ResNodeTree.GetOrCreate(this.Node, this.AddonTree).Print(null, this.firstDraw);
|
{
|
||||||
ch.Dispose();
|
ResNodeTree.GetOrCreate(this.Node, this.AddonTree).Print(null, this.firstDraw);
|
||||||
this.firstDraw = false;
|
this.firstDraw = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace Dalamud.Interface.Internal.UiDebug2;
|
||||||
/// <inheritdoc cref="UiDebug2"/>
|
/// <inheritdoc cref="UiDebug2"/>
|
||||||
internal unsafe partial class UiDebug2
|
internal unsafe partial class UiDebug2
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All unit lists to check for addons.
|
/// All unit lists to check for addons.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static readonly List<UnitListOption> UnitListOptions =
|
internal static readonly List<UnitListOption> UnitListOptions =
|
||||||
|
|
@ -38,7 +38,7 @@ internal unsafe partial class UiDebug2
|
||||||
new(12, "Depth Layer 13"),
|
new(12, "Depth Layer 13"),
|
||||||
new(15, "Units 16"),
|
new(15, "Units 16"),
|
||||||
new(16, "Units 17"),
|
new(16, "Units 17"),
|
||||||
new(17, "Units 18"),
|
new(17, "Units 18")
|
||||||
];
|
];
|
||||||
|
|
||||||
private string addonNameSearch = string.Empty;
|
private string addonNameSearch = string.Empty;
|
||||||
|
|
@ -53,54 +53,54 @@ internal unsafe partial class UiDebug2
|
||||||
|
|
||||||
private void DrawSidebar()
|
private void DrawSidebar()
|
||||||
{
|
{
|
||||||
var g = ImRaii.Group();
|
using (ImRaii.Group())
|
||||||
|
{
|
||||||
this.DrawNameSearch();
|
this.DrawNameSearch();
|
||||||
this.DrawAddonSelectionList();
|
this.DrawAddonSelectionList();
|
||||||
this.elementSelector.DrawInterface();
|
this.elementSelector.DrawInterface();
|
||||||
|
}
|
||||||
g.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawNameSearch()
|
private void DrawNameSearch()
|
||||||
{
|
{
|
||||||
var ch = ImRaii.Child("###sidebar_nameSearch", new(250, 40), true);
|
using (ImRaii.Child("###sidebar_nameSearch", new(250, 40), true))
|
||||||
var atkUnitBaseSearch = this.addonNameSearch;
|
|
||||||
|
|
||||||
Vector4? defaultColor = this.visFilter ? new(0.0f, 0.8f, 0.2f, 1f) : new Vector4(0.6f, 0.6f, 0.6f, 1);
|
|
||||||
if (ImGuiComponents.IconButton("filter", LowVision, defaultColor))
|
|
||||||
{
|
{
|
||||||
this.visFilter = !this.visFilter;
|
var atkUnitBaseSearch = this.addonNameSearch;
|
||||||
|
|
||||||
|
Vector4? defaultColor = this.visFilter ? new(0.0f, 0.8f, 0.2f, 1f) : new Vector4(0.6f, 0.6f, 0.6f, 1);
|
||||||
|
if (ImGuiComponents.IconButton("filter", LowVision, defaultColor))
|
||||||
|
{
|
||||||
|
this.visFilter = !this.visFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui.SetTooltip("Filter by visibility");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
||||||
|
if (ImGui.InputTextWithHint("###atkUnitBaseSearch", "Filter by name", ref atkUnitBaseSearch, 0x20))
|
||||||
|
{
|
||||||
|
this.addonNameSearch = atkUnitBaseSearch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
|
||||||
{
|
|
||||||
ImGui.SetTooltip("Filter by visibility");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
|
|
||||||
if (ImGui.InputTextWithHint("###atkUnitBaseSearch", "Filter by name", ref atkUnitBaseSearch, 0x20))
|
|
||||||
{
|
|
||||||
this.addonNameSearch = atkUnitBaseSearch;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawAddonSelectionList()
|
private void DrawAddonSelectionList()
|
||||||
{
|
{
|
||||||
var ch = ImRaii.Child("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar);
|
using (ImRaii.Child("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar))
|
||||||
|
|
||||||
var unitListBaseAddr = GetUnitListBaseAddr();
|
|
||||||
|
|
||||||
foreach (var unit in UnitListOptions)
|
|
||||||
{
|
{
|
||||||
this.DrawUnitListOption(unitListBaseAddr, unit);
|
var unitListBaseAddr = GetUnitListBaseAddr();
|
||||||
}
|
|
||||||
|
|
||||||
ch.Dispose();
|
foreach (var unit in UnitListOptions)
|
||||||
|
{
|
||||||
|
this.DrawUnitListOption(unitListBaseAddr, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawUnitListOption(AtkUnitList* unitListBaseAddr, UnitListOption unit)
|
private void DrawUnitListOption(AtkUnitList* unitListBaseAddr, UnitListOption unit)
|
||||||
|
|
@ -148,25 +148,23 @@ internal unsafe partial class UiDebug2
|
||||||
|
|
||||||
var countStr = $"{(usingFilter ? $"{matchCount}/" : string.Empty)}{totalCount}";
|
var countStr = $"{(usingFilter ? $"{matchCount}/" : string.Empty)}{totalCount}";
|
||||||
|
|
||||||
var col1 = ImRaii.PushColor(ImGuiCol.Text, anyVisible ? new Vector4(1) : new Vector4(0.6f, 0.6f, 0.6f, 1));
|
using var col1 = ImRaii.PushColor(ImGuiCol.Text, anyVisible ? new Vector4(1) : new Vector4(0.6f, 0.6f, 0.6f, 1));
|
||||||
var tree = ImRaii.TreeNode($"{unit.Name} [{countStr}]###unitListTree{unit.Index}");
|
using var tree = ImRaii.TreeNode($"{unit.Name} [{countStr}]###unitListTree{unit.Index}");
|
||||||
col1.Pop();
|
col1.Pop();
|
||||||
|
|
||||||
if (tree)
|
if (tree)
|
||||||
{
|
{
|
||||||
foreach (var option in options)
|
foreach (var option in options)
|
||||||
{
|
{
|
||||||
var col2 = ImRaii.PushColor(ImGuiCol.Text, option.Visible ? new Vector4(0.1f, 1f, 0.1f, 1f) : new Vector4(0.6f, 0.6f, 0.6f, 1));
|
using (ImRaii.PushColor(ImGuiCol.Text, option.Visible ? new Vector4(0.1f, 1f, 0.1f, 1f) : new Vector4(0.6f, 0.6f, 0.6f, 1)))
|
||||||
if (ImGui.Selectable($"{option.Name}##select{option.Name}", this.SelectedAddonName == option.Name))
|
|
||||||
{
|
{
|
||||||
this.SelectedAddonName = option.Name;
|
if (ImGui.Selectable($"{option.Name}##select{option.Name}", this.SelectedAddonName == option.Name))
|
||||||
|
{
|
||||||
|
this.SelectedAddonName = option.Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
col2.Pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,13 @@ internal partial class UiDebug2 : IDisposable
|
||||||
internal UiDebug2()
|
internal UiDebug2()
|
||||||
{
|
{
|
||||||
this.elementSelector = new(this);
|
this.elementSelector = new(this);
|
||||||
|
|
||||||
GameGui = Service<GameGui>.Get();
|
|
||||||
|
|
||||||
Log = new ModuleLog("UiDebug2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ModuleLog"/>
|
/// <inheritdoc cref="ModuleLog"/>
|
||||||
internal static ModuleLog Log { get; set; } = null!;
|
internal static ModuleLog Log { get; set; } = new("UiDebug2");
|
||||||
|
|
||||||
/// <inheritdoc cref="IGameGui"/>
|
/// <inheritdoc cref="IGameGui"/>
|
||||||
internal static IGameGui GameGui { get; set; } = null!;
|
internal static IGameGui GameGui { get; set; } = Service<GameGui>.Get();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a collection of <see cref="AddonTree"/> instances, each representing an <see cref="FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase"/>.
|
/// Gets a collection of <see cref="AddonTree"/> instances, each representing an <see cref="FFXIVClientStructs.FFXIV.Component.GUI.AtkUnitBase"/>.
|
||||||
|
|
@ -86,28 +82,28 @@ internal partial class UiDebug2 : IDisposable
|
||||||
private void DrawMainPanel()
|
private void DrawMainPanel()
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var ch = ImRaii.Child("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar);
|
|
||||||
|
|
||||||
if (this.elementSelector.Active)
|
using (ImRaii.Child("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar))
|
||||||
{
|
{
|
||||||
this.elementSelector.DrawSelectorOutput();
|
if (this.elementSelector.Active)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this.SelectedAddonName != null)
|
|
||||||
{
|
{
|
||||||
var addonTree = AddonTree.GetOrCreate(this.SelectedAddonName);
|
this.elementSelector.DrawSelectorOutput();
|
||||||
|
}
|
||||||
if (addonTree == null)
|
else
|
||||||
|
{
|
||||||
|
if (this.SelectedAddonName != null)
|
||||||
{
|
{
|
||||||
this.SelectedAddonName = null;
|
var addonTree = AddonTree.GetOrCreate(this.SelectedAddonName);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addonTree.Draw();
|
if (addonTree == null)
|
||||||
|
{
|
||||||
|
this.SelectedAddonName = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addonTree.Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ch.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ internal static class Gui
|
||||||
/// <typeparam name="T">The type of value being set.</typeparam>
|
/// <typeparam name="T">The type of value being set.</typeparam>
|
||||||
/// <param name="label">The label for the inputs.</param>
|
/// <param name="label">The label for the inputs.</param>
|
||||||
/// <param name="val">The value being set.</param>
|
/// <param name="val">The value being set.</param>
|
||||||
/// <param name="options">A list of all options to create buttons for.</param>
|
/// <param name="options">A list of all options.</param>
|
||||||
/// <param name="icons">A list of the icons to use for each option.</param>
|
/// <param name="icons">A list of icons corresponding to the options.</param>
|
||||||
/// <returns>true if a button is clicked.</returns>
|
/// <returns>true if a button is clicked.</returns>
|
||||||
internal static unsafe bool IconSelectInput<T>(string label, ref T val, List<T> options, List<FontAwesomeIcon> icons)
|
internal static unsafe bool IconSelectInput<T>(string label, ref T val, List<T> options, List<FontAwesomeIcon> icons)
|
||||||
{
|
{
|
||||||
|
|
@ -104,14 +104,11 @@ internal static class Gui
|
||||||
/// <remarks>Colors the text itself either white or black, depending on the luminosity of the background color.</remarks>
|
/// <remarks>Colors the text itself either white or black, depending on the luminosity of the background color.</remarks>
|
||||||
internal static void PrintColor(Vector4 color, string fmt)
|
internal static void PrintColor(Vector4 color, string fmt)
|
||||||
{
|
{
|
||||||
var c = new ImRaii.Color().Push(Text, Luminosity(color) < 0.5f ? new Vector4(1) : new(0, 0, 0, 1))
|
using (new ImRaii.Color().Push(Text, Luminosity(color) < 0.5f ? new Vector4(1) : new(0, 0, 0, 1)).Push(Button, color).Push(ButtonActive, color).Push(ButtonHovered, color))
|
||||||
.Push(Button, color)
|
{
|
||||||
.Push(ButtonActive, color)
|
ImGui.SmallButton(fmt);
|
||||||
.Push(ButtonHovered, color);
|
}
|
||||||
|
|
||||||
ImGui.SmallButton(fmt);
|
|
||||||
|
|
||||||
c.Pop(4);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static double Luminosity(Vector4 vector4) =>
|
static double Luminosity(Vector4 vector4) =>
|
||||||
|
|
@ -125,20 +122,21 @@ internal static class Gui
|
||||||
/// <inheritdoc cref="ImGuiHelpers.ClickToCopyText"/>
|
/// <inheritdoc cref="ImGuiHelpers.ClickToCopyText"/>
|
||||||
internal static void ClickToCopyText(string text, string? textCopy = null)
|
internal static void ClickToCopyText(string text, string? textCopy = null)
|
||||||
{
|
{
|
||||||
var c = ImRaii.PushColor(Text, new Vector4(0.6f, 0.6f, 0.6f, 1));
|
using (ImRaii.PushColor(Text, new Vector4(0.6f, 0.6f, 0.6f, 1)))
|
||||||
ImGuiHelpers.ClickToCopyText(text, textCopy);
|
{
|
||||||
c.Pop();
|
ImGuiHelpers.ClickToCopyText(text, textCopy);
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
{
|
{
|
||||||
var t = ImRaii.Tooltip();
|
using (ImRaii.Tooltip())
|
||||||
var f = ImRaii.PushFont(UiBuilder.IconFont);
|
{
|
||||||
ImGui.Text(FontAwesomeIcon.Copy.ToIconString());
|
using var f = ImRaii.PushFont(UiBuilder.IconFont);
|
||||||
f.Pop();
|
ImGui.Text(FontAwesomeIcon.Copy.ToIconString());
|
||||||
ImGui.SameLine();
|
f.Pop();
|
||||||
ImGui.Text($"{textCopy ?? text}");
|
ImGui.SameLine();
|
||||||
|
ImGui.Text($"{textCopy ?? text}");
|
||||||
t.Dispose();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,9 +159,10 @@ internal static class Gui
|
||||||
|
|
||||||
var index = (int)Math.Floor(prog * tooltips.Length);
|
var index = (int)Math.Floor(prog * tooltips.Length);
|
||||||
|
|
||||||
var t = ImRaii.Tooltip();
|
using (ImRaii.Tooltip())
|
||||||
ImGui.Text(tooltips[index]);
|
{
|
||||||
t.Dispose();
|
ImGui.Text(tooltips[index]);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
using static System.Math;
|
using static System.Math;
|
||||||
|
using static Dalamud.Interface.ColorHelpers;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.UiDebug2.Utility;
|
namespace Dalamud.Interface.Internal.UiDebug2.Utility;
|
||||||
|
|
||||||
|
|
@ -61,8 +62,8 @@ public unsafe struct NodeBounds
|
||||||
|
|
||||||
if (this.Points.Count == 1)
|
if (this.Points.Count == 1)
|
||||||
{
|
{
|
||||||
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], 10, ColorHelpers.RgbaVector4ToUint(col with { W = col.W / 2 }), 12, thickness);
|
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], 10, RgbaVector4ToUint(col with { W = col.W / 2 }), 12, thickness);
|
||||||
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], thickness, ColorHelpers.RgbaVector4ToUint(col), 12, thickness + 1);
|
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], thickness, RgbaVector4ToUint(col), 12, thickness + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -73,7 +74,7 @@ public unsafe struct NodeBounds
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.GetBackgroundDrawList()
|
ImGui.GetBackgroundDrawList()
|
||||||
.AddPolyline(ref path[0], path.Length, ColorHelpers.RgbaVector4ToUint(col), ImDrawFlags.Closed, thickness);
|
.AddPolyline(ref path[0], path.Length, RgbaVector4ToUint(col), ImDrawFlags.Closed, thickness);
|
||||||
|
|
||||||
path.Dispose();
|
path.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -94,8 +95,8 @@ public unsafe struct NodeBounds
|
||||||
if (this.Points.Count == 1)
|
if (this.Points.Count == 1)
|
||||||
{
|
{
|
||||||
ImGui.GetBackgroundDrawList()
|
ImGui.GetBackgroundDrawList()
|
||||||
.AddCircleFilled(this.Points[0], 10, ColorHelpers.RgbaVector4ToUint(col with { W = col.W / 2 }), 12);
|
.AddCircleFilled(this.Points[0], 10, RgbaVector4ToUint(col with { W = col.W / 2 }), 12);
|
||||||
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], 10, ColorHelpers.RgbaVector4ToUint(col), 12, thickness);
|
ImGui.GetBackgroundDrawList().AddCircle(this.Points[0], 10, RgbaVector4ToUint(col), 12, thickness);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -106,9 +107,9 @@ public unsafe struct NodeBounds
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.GetBackgroundDrawList()
|
ImGui.GetBackgroundDrawList()
|
||||||
.AddConvexPolyFilled(ref path[0], path.Length, ColorHelpers.RgbaVector4ToUint(col with { W = col.W / 2 }));
|
.AddConvexPolyFilled(ref path[0], path.Length, RgbaVector4ToUint(col with { W = col.W / 2 }));
|
||||||
ImGui.GetBackgroundDrawList()
|
ImGui.GetBackgroundDrawList()
|
||||||
.AddPolyline(ref path[0], path.Length, ColorHelpers.RgbaVector4ToUint(col), ImDrawFlags.Closed, thickness);
|
.AddPolyline(ref path[0], path.Length, RgbaVector4ToUint(col), ImDrawFlags.Closed, thickness);
|
||||||
|
|
||||||
path.Dispose();
|
path.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +148,9 @@ public unsafe struct NodeBounds
|
||||||
var sinR = (float)Sin(r);
|
var sinR = (float)Sin(r);
|
||||||
var d = (p - o) * s;
|
var d = (p - o) * s;
|
||||||
|
|
||||||
return new(o.X + (d.X * cosR) - (d.Y * sinR), o.Y + (d.X * sinR) + (d.Y * cosR));
|
return new(
|
||||||
|
o.X + (d.X * cosR) - (d.Y * sinR),
|
||||||
|
o.Y + (d.X * sinR) + (d.Y * cosR));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TransformPoints(AtkResNode* transformNode)
|
private void TransformPoints(AtkResNode* transformNode)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ internal class DataWindow : Window, IDisposable
|
||||||
private readonly IDataWindowWidget[] modules =
|
private readonly IDataWindowWidget[] modules =
|
||||||
{
|
{
|
||||||
new AddonInspectorWidget(),
|
new AddonInspectorWidget(),
|
||||||
|
new AddonInspectorWidget2(),
|
||||||
new AddonLifecycleWidget(),
|
new AddonLifecycleWidget(),
|
||||||
new AddonWidget(),
|
new AddonWidget(),
|
||||||
new AddressesWidget(),
|
new AddressesWidget(),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class AddonInspectorWidget : IDataWindowWidget
|
internal class AddonInspectorWidget : IDataWindowWidget
|
||||||
{
|
{
|
||||||
private UiDebug2.UiDebug2? addonInspector;
|
private UiDebug? addonInspector;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string[]? CommandShortcuts { get; init; } = { "ai", "addoninspector" };
|
public string[]? CommandShortcuts { get; init; } = { "ai", "addoninspector" };
|
||||||
|
|
@ -19,7 +19,7 @@ internal class AddonInspectorWidget : IDataWindowWidget
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
this.addonInspector = new UiDebug2.UiDebug2();
|
this.addonInspector = new UiDebug();
|
||||||
|
|
||||||
if (this.addonInspector is not null)
|
if (this.addonInspector is not null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Widget for displaying addon inspector.
|
||||||
|
/// </summary>
|
||||||
|
internal class AddonInspectorWidget2 : IDataWindowWidget
|
||||||
|
{
|
||||||
|
private UiDebug2.UiDebug2? addonInspector2;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string[]? CommandShortcuts { get; init; } = ["ai2", "addoninspector2"];
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string DisplayName { get; init; } = "Addon Inspector v2 (Testing)";
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Ready { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
this.addonInspector2 = new UiDebug2.UiDebug2();
|
||||||
|
|
||||||
|
if (this.addonInspector2 is not null)
|
||||||
|
{
|
||||||
|
this.Ready = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Draw()
|
||||||
|
{
|
||||||
|
this.addonInspector2?.Draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue