diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs
index ee79764de..4f7e02062 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/AtkArrayDataBrowserWidget.cs
@@ -1,8 +1,14 @@
-using System.Numerics;
+using System.Numerics;
+
+using Dalamud.Interface.Utility.Raii;
+
+using FFXIVClientStructs.FFXIV.Client.UI;
+using FFXIVClientStructs.FFXIV.Component.GUI;
-using Dalamud.Memory;
using ImGuiNET;
+using Lumina.Text.ReadOnly;
+
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
///
@@ -10,6 +16,18 @@ namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
///
internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget
{
+ private readonly Type numberType = typeof(NumberArrayType);
+ private readonly Type stringType = typeof(StringArrayType);
+ private readonly Type extendType = typeof(ExtendArrayType);
+
+ private int selectedNumberArray;
+ private int selectedStringArray;
+ private int selectedExtendArray;
+
+ private string searchTerm = string.Empty;
+ private bool hideUnsetStringArrayEntries = false;
+ private bool hideUnsetExtendArrayEntries = false;
+
///
public bool Ready { get; set; }
@@ -17,7 +35,7 @@ internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget
public string[]? CommandShortcuts { get; init; } = { "atkarray" };
///
- public string DisplayName { get; init; } = "Atk Array Data";
+ public string DisplayName { get; init; } = "Atk Array Data";
///
public void Load()
@@ -28,148 +46,354 @@ internal unsafe class AtkArrayDataBrowserWidget : IDataWindowWidget
///
public void Draw()
{
- var fontWidth = ImGui.CalcTextSize("A").X;
- var fontHeight = ImGui.GetTextLineHeightWithSpacing();
- var uiModule = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance()->GetUIModule();
+ using var tabs = ImRaii.TabBar("AtkArrayDataTabs");
+ if (!tabs) return;
- if (uiModule == null)
+ this.DrawNumberArrayTab();
+ this.DrawStringArrayTab();
+ this.DrawExtendArrayTab();
+ }
+
+ private static void DrawCopyableText(string text, string tooltipText)
+ {
+ ImGui.TextUnformatted(text);
+
+ if (ImGui.IsItemHovered())
{
- ImGui.Text("UIModule unavailable.");
- return;
+ ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
+ ImGui.BeginTooltip();
+ ImGui.TextUnformatted(tooltipText);
+ ImGui.EndTooltip();
}
- var atkArrayDataHolder = &uiModule->GetRaptureAtkModule()->AtkModule.AtkArrayDataHolder;
-
- if (ImGui.BeginTabBar("AtkArrayDataBrowserTabBar"))
+ if (ImGui.IsItemClicked())
{
- if (ImGui.BeginTabItem($"NumberArrayData [{atkArrayDataHolder->NumberArrayCount}]"))
+ ImGui.SetClipboardText(text);
+ }
+ }
+
+ private void DrawArrayList(Type? arrayType, int arrayCount, short* arrayKeys, AtkArrayData** arrays, ref int selectedIndex)
+ {
+ using var table = ImRaii.Table("ArkArrayTable", 3, ImGuiTableFlags.ScrollY | ImGuiTableFlags.Borders, new Vector2(300, -1));
+ if (!table) return;
+
+ ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, 30);
+ ImGui.TableSetupColumn("Type", ImGuiTableColumnFlags.WidthStretch);
+ ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, 40);
+ ImGui.TableSetupScrollFreeze(3, 1);
+ ImGui.TableHeadersRow();
+
+ var hasSearchTerm = !string.IsNullOrEmpty(this.searchTerm);
+
+ for (var arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++)
+ {
+ var inUse = arrayKeys[arrayIndex] != -1;
+
+ var rowsFound = 0;
+
+ if (hasSearchTerm && arrayType == typeof(StringArrayType))
{
- if (ImGui.BeginTable("NumberArrayDataTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY))
+ if (!inUse)
+ continue;
+
+ var stringArrayData = (StringArrayData*)arrays[arrayIndex];
+ for (var rowIndex = 0; rowIndex < arrays[arrayIndex]->Size; rowIndex++)
{
- ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
- ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
- ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableHeadersRow();
- for (var numberArrayIndex = 0; numberArrayIndex < atkArrayDataHolder->NumberArrayCount; numberArrayIndex++)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.Text($"{numberArrayIndex} [{numberArrayIndex * 8:X}]");
- ImGui.TableNextColumn();
- var numberArrayData = atkArrayDataHolder->NumberArrays[numberArrayIndex];
- if (numberArrayData != null)
- {
- ImGui.Text($"{numberArrayData->AtkArrayData.Size}");
- ImGui.TableNextColumn();
- if (ImGui.TreeNodeEx($"{(long)numberArrayData:X}###{numberArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
- {
- ImGui.NewLine();
- var tableHeight = Math.Min(40, numberArrayData->AtkArrayData.Size + 4);
- if (ImGui.BeginTable($"NumberArrayDataTable", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
- {
- ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
- ImGui.TableSetupColumn("Hex", ImGuiTableColumnFlags.WidthFixed, fontWidth * 9);
- ImGui.TableSetupColumn("Integer", ImGuiTableColumnFlags.WidthFixed, fontWidth * 12);
- ImGui.TableSetupColumn("Float", ImGuiTableColumnFlags.WidthFixed, fontWidth * 20);
- ImGui.TableHeadersRow();
- for (var numberIndex = 0; numberIndex < numberArrayData->AtkArrayData.Size; numberIndex++)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.Text($"{numberIndex}");
- ImGui.TableNextColumn();
- ImGui.Text($"{numberArrayData->IntArray[numberIndex]:X}");
- ImGui.TableNextColumn();
- ImGui.Text($"{numberArrayData->IntArray[numberIndex]}");
- ImGui.TableNextColumn();
- ImGui.Text($"{*(float*)&numberArrayData->IntArray[numberIndex]}");
- }
+ var isNull = (nint)stringArrayData->StringArray[rowIndex] == 0;
+ if (isNull)
+ continue;
- ImGui.EndTable();
- }
-
- ImGui.TreePop();
- }
- }
- else
- {
- ImGui.TextDisabled("--");
- ImGui.TableNextColumn();
- ImGui.TextDisabled("--");
- }
- }
-
- ImGui.EndTable();
+ if (new ReadOnlySeStringSpan(stringArrayData->StringArray[rowIndex]).ExtractText().Contains(this.searchTerm, StringComparison.InvariantCultureIgnoreCase))
+ rowsFound++;
}
- ImGui.EndTabItem();
+ if (rowsFound == 0)
+ continue;
}
- if (ImGui.BeginTabItem($"StringArrayData [{atkArrayDataHolder->StringArrayCount}]"))
+ using var disabled = ImRaii.Disabled(!inUse);
+ ImGui.TableNextRow();
+
+ ImGui.TableNextColumn(); // Index
+ if (ImGui.Selectable($"#{arrayIndex}", selectedIndex == arrayIndex, ImGuiSelectableFlags.SpanAllColumns))
+ selectedIndex = arrayIndex;
+
+ ImGui.TableNextColumn(); // Type
+ if (arrayType != null && Enum.IsDefined(arrayType, arrayIndex))
{
- if (ImGui.BeginTable("StringArrayDataTable", 3, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY))
+ ImGui.TextUnformatted(Enum.GetName(arrayType, arrayIndex));
+ }
+ else if (inUse && arrays[arrayIndex]->SubscribedAddonsCount > 0)
+ {
+ var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
+
+ for (var j = 0; j < arrays[arrayIndex]->SubscribedAddonsCount; j++)
{
- ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
- ImGui.TableSetupColumn("Size", ImGuiTableColumnFlags.WidthFixed, fontWidth * 10);
- ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableHeadersRow();
- for (var stringArrayIndex = 0; stringArrayIndex < atkArrayDataHolder->StringArrayCount; stringArrayIndex++)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.Text($"{stringArrayIndex} [{stringArrayIndex * 8:X}]");
- ImGui.TableNextColumn();
- var stringArrayData = atkArrayDataHolder->StringArrays[stringArrayIndex];
- if (stringArrayData != null)
- {
- ImGui.Text($"{stringArrayData->AtkArrayData.Size}");
- ImGui.TableNextColumn();
- if (ImGui.TreeNodeEx($"{(long)stringArrayData:X}###{stringArrayIndex}", ImGuiTreeNodeFlags.SpanFullWidth))
- {
- ImGui.NewLine();
- var tableHeight = Math.Min(40, stringArrayData->AtkArrayData.Size + 4);
- if (ImGui.BeginTable($"StringArrayDataTable", 2, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, new Vector2(0.0F, fontHeight * tableHeight)))
- {
- ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, fontWidth * 6);
- ImGui.TableSetupColumn("String", ImGuiTableColumnFlags.WidthStretch);
- ImGui.TableHeadersRow();
- for (var stringIndex = 0; stringIndex < stringArrayData->AtkArrayData.Size; stringIndex++)
- {
- ImGui.TableNextRow();
- ImGui.TableNextColumn();
- ImGui.Text($"{stringIndex}");
- ImGui.TableNextColumn();
- if (stringArrayData->StringArray[stringIndex] != null)
- {
- ImGui.Text($"{MemoryHelper.ReadSeStringNullTerminated(new IntPtr(stringArrayData->StringArray[stringIndex]))}");
- }
- else
- {
- ImGui.TextDisabled("--");
- }
- }
+ if (arrays[arrayIndex]->SubscribedAddons[j] == 0)
+ continue;
- ImGui.EndTable();
- }
-
- ImGui.TreePop();
- }
- }
- else
- {
- ImGui.TextDisabled("--");
- ImGui.TableNextColumn();
- ImGui.TextDisabled("--");
- }
- }
-
- ImGui.EndTable();
+ using (ImRaii.PushColor(ImGuiCol.Text, 0xFF00FFFF))
+ ImGui.TextUnformatted(raptureAtkUnitManager->GetAddonById(arrays[arrayIndex]->SubscribedAddons[j])->NameString);
+ break;
}
-
- ImGui.EndTabItem();
}
- ImGui.EndTabBar();
+ ImGui.TableNextColumn(); // Size
+ if (inUse)
+ ImGui.TextUnformatted((rowsFound > 0 ? rowsFound : arrays[arrayIndex]->Size).ToString());
+ }
+ }
+
+ private void DrawArrayHeader(Type? arrayType, string type, int index, AtkArrayData* array)
+ {
+ ImGui.TextUnformatted($"{type} Array #{index}");
+
+ if (arrayType != null && Enum.IsDefined(arrayType, index))
+ {
+ ImGui.SameLine(0, 0);
+ ImGui.TextUnformatted($" ({Enum.GetName(arrayType, index)})");
+ }
+
+ ImGui.SameLine();
+ ImGui.TextUnformatted("–");
+ ImGui.SameLine();
+ ImGui.TextUnformatted("Address: ");
+ ImGui.SameLine(0, 0);
+ DrawCopyableText($"0x{(nint)array:X}", "Copy address");
+
+ if (array->SubscribedAddonsCount > 0)
+ {
+ ImGui.SameLine();
+ ImGui.TextUnformatted("–");
+ ImGui.SameLine();
+ using (ImRaii.PushColor(ImGuiCol.Text, 0xFF00FFFF))
+ ImGui.TextUnformatted($"{array->SubscribedAddonsCount} Subscribed Addon" + (array->SubscribedAddonsCount > 1 ? 's' : string.Empty));
+
+ if (ImGui.IsItemHovered())
+ {
+ using var tooltip = ImRaii.Tooltip();
+ if (tooltip)
+ {
+ var raptureAtkUnitManager = RaptureAtkUnitManager.Instance();
+
+ for (var j = 0; j < array->SubscribedAddonsCount; j++)
+ {
+ if (array->SubscribedAddons[j] == 0)
+ continue;
+
+ ImGui.TextUnformatted(raptureAtkUnitManager->GetAddonById(array->SubscribedAddons[j])->NameString);
+ }
+ }
+ }
+ }
+ }
+
+ private void DrawNumberArrayTab()
+ {
+ var atkArrayDataHolder = RaptureAtkModule.Instance()->AtkArrayDataHolder;
+
+ using var tab = ImRaii.TabItem("Number Arrays");
+ if (!tab) return;
+
+ this.DrawArrayList(
+ this.numberType,
+ atkArrayDataHolder.NumberArrayCount,
+ atkArrayDataHolder.NumberArrayKeys,
+ (AtkArrayData**)atkArrayDataHolder.NumberArrays,
+ ref this.selectedNumberArray);
+
+ if (this.selectedNumberArray >= atkArrayDataHolder.NumberArrayCount || atkArrayDataHolder.NumberArrayKeys[this.selectedNumberArray] == -1)
+ this.selectedNumberArray = 0;
+
+ ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
+
+ using var child = ImRaii.Child("AtkArrayContent", new Vector2(-1), true, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoSavedSettings);
+ if (!child) return;
+
+ var array = atkArrayDataHolder.NumberArrays[this.selectedNumberArray];
+ this.DrawArrayHeader(this.numberType, "Number", this.selectedNumberArray, (AtkArrayData*)array);
+
+ using var table = ImRaii.Table("NumberArrayDataTable", 7, ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg | ImGuiTableFlags.Borders);
+ if (!table) return;
+
+ ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, 40);
+ ImGui.TableSetupColumn("Entry Address", ImGuiTableColumnFlags.WidthFixed, 120);
+ ImGui.TableSetupColumn("Integer", ImGuiTableColumnFlags.WidthFixed, 100);
+ ImGui.TableSetupColumn("Short", ImGuiTableColumnFlags.WidthFixed, 100);
+ ImGui.TableSetupColumn("Byte", ImGuiTableColumnFlags.WidthFixed, 100);
+ ImGui.TableSetupColumn("Float", ImGuiTableColumnFlags.WidthFixed, 100);
+ ImGui.TableSetupColumn("Hex", ImGuiTableColumnFlags.WidthFixed, 100);
+ ImGui.TableSetupScrollFreeze(7, 1);
+ ImGui.TableHeadersRow();
+
+ for (var i = 0; i < array->Size; i++)
+ {
+ ImGui.TableNextRow();
+ ImGui.TableNextColumn(); // Index
+ ImGui.TextUnformatted($"#{i}");
+
+ var ptr = &array->IntArray[i];
+
+ ImGui.TableNextColumn(); // Address
+ DrawCopyableText($"0x{(nint)ptr:X}", "Copy entry address");
+
+ ImGui.TableNextColumn(); // Integer
+ DrawCopyableText((*ptr).ToString(), "Copy value");
+
+ ImGui.TableNextColumn(); // Short
+ DrawCopyableText((*(short*)ptr).ToString(), "Copy as short");
+
+ ImGui.TableNextColumn(); // Byte
+ DrawCopyableText((*(byte*)ptr).ToString(), "Copy as byte");
+
+ ImGui.TableNextColumn(); // Float
+ DrawCopyableText((*(float*)ptr).ToString(), "Copy as float");
+
+ ImGui.TableNextColumn(); // Hex
+ DrawCopyableText($"0x{array->IntArray[i]:X2}", "Copy Hex");
+ }
+ }
+
+ private void DrawStringArrayTab()
+ {
+ using var tab = ImRaii.TabItem("String Arrays");
+ if (!tab) return;
+
+ var atkArrayDataHolder = RaptureAtkModule.Instance()->AtkArrayDataHolder;
+
+ using (var sidebarchild = ImRaii.Child("StringArraySidebar", new Vector2(300, -1), false, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoSavedSettings))
+ {
+ if (sidebarchild)
+ {
+ ImGui.SetNextItemWidth(-1);
+ ImGui.InputTextWithHint("##TextSearch", "Search...", ref this.searchTerm, 256, ImGuiInputTextFlags.AutoSelectAll);
+
+ this.DrawArrayList(
+ this.stringType,
+ atkArrayDataHolder.StringArrayCount,
+ atkArrayDataHolder.StringArrayKeys,
+ (AtkArrayData**)atkArrayDataHolder.StringArrays,
+ ref this.selectedStringArray);
+ }
+ }
+
+ if (this.selectedStringArray >= atkArrayDataHolder.StringArrayCount || atkArrayDataHolder.StringArrayKeys[this.selectedStringArray] == -1)
+ this.selectedStringArray = 0;
+
+ ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
+
+ using var child = ImRaii.Child("AtkArrayContent", new Vector2(-1), true, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoSavedSettings);
+ if (!child) return;
+
+ var array = atkArrayDataHolder.StringArrays[this.selectedStringArray];
+ this.DrawArrayHeader(this.stringType, "String", this.selectedStringArray, (AtkArrayData*)array);
+ ImGui.Checkbox("Hide unset entries##HideUnsetStringArrayEntriesCheckbox", ref this.hideUnsetStringArrayEntries);
+
+ using var table = ImRaii.Table("StringArrayDataTable", 4, ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg | ImGuiTableFlags.Borders);
+ if (!table) return;
+
+ ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, 40);
+ ImGui.TableSetupColumn(ImGui.IsKeyDown(ImGuiKey.LeftShift) ? "Entry Address" : "Text Address", ImGuiTableColumnFlags.WidthFixed, 120);
+ ImGui.TableSetupColumn("Managed", ImGuiTableColumnFlags.WidthFixed, 60);
+ ImGui.TableSetupColumn("Text", ImGuiTableColumnFlags.WidthStretch);
+ ImGui.TableSetupScrollFreeze(4, 1);
+ ImGui.TableHeadersRow();
+
+ var hasSearchTerm = !string.IsNullOrEmpty(this.searchTerm);
+
+ for (var i = 0; i < array->Size; i++)
+ {
+ var isNull = (nint)array->StringArray[i] == 0;
+ if (isNull && this.hideUnsetStringArrayEntries)
+ continue;
+
+ if (hasSearchTerm)
+ {
+ if (isNull)
+ continue;
+
+ if (!new ReadOnlySeStringSpan(array->StringArray[i]).ExtractText().Contains(this.searchTerm, StringComparison.InvariantCultureIgnoreCase))
+ continue;
+ }
+
+ using var disabledColor = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), isNull);
+
+ ImGui.TableNextRow();
+ ImGui.TableNextColumn(); // Index
+ ImGui.TextUnformatted($"#{i}");
+
+ ImGui.TableNextColumn(); // Address
+ if (ImGui.IsKeyDown(ImGuiKey.LeftShift))
+ {
+ DrawCopyableText($"0x{(nint)(&array->StringArray[i]):X}", "Copy entry address");
+ }
+ else if (!isNull)
+ {
+ DrawCopyableText($"0x{(nint)array->StringArray[i]:X}", "Copy text address");
+ }
+
+ ImGui.TableNextColumn(); // Managed
+ if (!isNull)
+ ImGui.TextUnformatted(((nint)array->StringArray[i] != 0 && array->ManagedStringArray[i] == array->StringArray[i]).ToString());
+
+ ImGui.TableNextColumn(); // Text
+ if (!isNull)
+ DrawCopyableText(new ReadOnlySeStringSpan(array->StringArray[i]).ToString(), "Copy text");
+ }
+ }
+
+ private void DrawExtendArrayTab()
+ {
+ using var tab = ImRaii.TabItem("Extend Arrays");
+ if (!tab) return;
+
+ var atkArrayDataHolder = RaptureAtkModule.Instance()->AtkArrayDataHolder;
+
+ this.DrawArrayList(
+ this.extendType,
+ atkArrayDataHolder.ExtendArrayCount,
+ atkArrayDataHolder.ExtendArrayKeys,
+ (AtkArrayData**)atkArrayDataHolder.ExtendArrays,
+ ref this.selectedExtendArray);
+
+ if (this.selectedExtendArray >= atkArrayDataHolder.ExtendArrayCount || atkArrayDataHolder.ExtendArrayKeys[this.selectedExtendArray] == -1)
+ this.selectedExtendArray = 0;
+
+ ImGui.SameLine(0, ImGui.GetStyle().ItemInnerSpacing.X);
+
+ using var child = ImRaii.Child("AtkArrayContent", new Vector2(-1), true, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoSavedSettings);
+
+ var array = atkArrayDataHolder.ExtendArrays[this.selectedExtendArray];
+ this.DrawArrayHeader(null, "Extend", this.selectedExtendArray, (AtkArrayData*)array);
+ ImGui.Checkbox("Hide unset entries##HideUnsetExtendArrayEntriesCheckbox", ref this.hideUnsetExtendArrayEntries);
+
+ using var table = ImRaii.Table("ExtendArrayDataTable", 3, ImGuiTableFlags.ScrollY | ImGuiTableFlags.RowBg | ImGuiTableFlags.Borders);
+ if (!table) return;
+
+ ImGui.TableSetupColumn("Index", ImGuiTableColumnFlags.WidthFixed, 40);
+ ImGui.TableSetupColumn("Entry Address", ImGuiTableColumnFlags.WidthFixed, 120);
+ ImGui.TableSetupColumn("Pointer", ImGuiTableColumnFlags.WidthStretch);
+ ImGui.TableSetupScrollFreeze(3, 1);
+ ImGui.TableHeadersRow();
+
+ for (var i = 0; i < array->Size; i++)
+ {
+ var isNull = (nint)array->DataArray[i] == 0;
+ if (isNull && this.hideUnsetExtendArrayEntries)
+ continue;
+
+ using var disabledColor = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetColorU32(ImGuiCol.TextDisabled), isNull);
+
+ ImGui.TableNextRow();
+ ImGui.TableNextColumn(); // Index
+ ImGui.TextUnformatted($"#{i}");
+
+ ImGui.TableNextColumn(); // Address
+ DrawCopyableText($"0x{(nint)(&array->DataArray[i]):X}", "Copy entry address");
+
+ ImGui.TableNextColumn(); // Pointer
+ if (!isNull)
+ DrawCopyableText($"0x{(nint)array->DataArray[i]:X}", "Copy address");
}
}
}