From e19f9284e502cda31bfa7468ff4a5c018d181cb5 Mon Sep 17 00:00:00 2001 From: ItsBexy Date: Tue, 3 Sep 2024 21:23:50 -0600 Subject: [PATCH] Implement ImRaii --- .../UiDebug2/Browsing/AddonTree.FieldNames.cs | 22 ++--- .../Internal/UiDebug2/Browsing/Events.cs | 69 +++++++-------- .../UiDebug2/Browsing/NodeTree.Component.cs | 81 +++++++++--------- .../UiDebug2/Browsing/NodeTree.Editor.cs | 13 +-- .../UiDebug2/Browsing/NodeTree.Image.cs | 31 ++++--- .../UiDebug2/Browsing/NodeTree.NineGrid.cs | 3 +- .../UiDebug2/Browsing/NodeTree.Res.cs | 46 +++++++--- .../UiDebug2/Browsing/NodeTree.Text.cs | 32 ++++--- .../Browsing/TimelineTree.KeyGroupColumn.cs | 2 +- .../UiDebug2/Browsing/TimelineTree.cs | 33 ++++---- .../Internal/UiDebug2/ElementSelector.cs | 31 +++---- .../Internal/UiDebug2/Popout.Addon.cs | 5 +- .../Internal/UiDebug2/Popout.Node.cs | 5 +- .../Internal/UiDebug2/UiDebug2.Sidebar.cs | 33 ++++---- .../Interface/Internal/UiDebug2/UiDebug2.cs | 7 +- .../Internal/UiDebug2/Utility/Gui.cs | 84 ++++++------------- .../Internal/UiDebug2/Utility/NodeBounds.cs | 7 +- 17 files changed, 248 insertions(+), 256 deletions(-) diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.FieldNames.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.FieldNames.cs index e72de2b23..4baad4753 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.FieldNames.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.FieldNames.cs @@ -28,10 +28,8 @@ public unsafe partial class AddonTree return null; } - if (!AddonTypeDict.ContainsKey(this.AddonName)) + if (AddonTypeDict.TryAdd(this.AddonName, null)) { - AddonTypeDict.Add(this.AddonName, null); - foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { try @@ -104,13 +102,15 @@ public unsafe partial class AddonTree } } + return; + void ParseExplicitField(nint fieldAddr, FieldInfo field, MemberInfo fieldType, string name) { try { - if (this.FieldNames.TryAdd(fieldAddr, new List(path!) { name }) && fieldType.DeclaringType == baseType) + if (this.FieldNames.TryAdd(fieldAddr, [..path!, name]) && fieldType.DeclaringType == baseType) { - this.PopulateFieldNames(field.GetValue(obj), fieldAddr, new List(path) { name }); + this.PopulateFieldNames(field.GetValue(obj), fieldAddr, [..path, name]); } } catch (Exception ex) @@ -140,12 +140,12 @@ public unsafe partial class AddonTree var itemAddr = fieldAddr + (size * i); var itemName = $"{name}[{i}]"; - this.FieldNames.TryAdd(itemAddr, new List(path!) { itemName }); + this.FieldNames.TryAdd(itemAddr, [..path!, itemName]); var item = Marshal.PtrToStructure(itemAddr, itemType); if (itemType.DeclaringType == baseType) { - this.PopulateFieldNames(item, itemAddr, new List(path) { name }); + this.PopulateFieldNames(item, itemAddr, [..path, itemName]); } } } @@ -176,16 +176,16 @@ public unsafe partial class AddonTree return; } - this.FieldNames.TryAdd(fieldAddr, new List(path!) { name }); - this.FieldNames.TryAdd(pointer, new List(path) { name }); + this.FieldNames.TryAdd(fieldAddr, [..path!, name]); + this.FieldNames.TryAdd(pointer, [..path, name]); - if (itemType?.DeclaringType != baseType || itemType.IsPointer) + if (itemType?.DeclaringType != baseType || itemType!.IsPointer) { return; } var item = Marshal.PtrToStructure(pointer, itemType); - this.PopulateFieldNames(item, pointer, new List(path) { name }); + this.PopulateFieldNames(item, pointer, [..path, name]); } catch (Exception ex) { diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs index bd1efe6c7..d542f5025 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs @@ -1,4 +1,5 @@ using Dalamud.Interface.Internal.UiDebug2.Utility; +using Dalamud.Interface.Utility.Raii; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -25,44 +26,44 @@ public static class Events return; } - if (ImGui.TreeNode($"Events##{(nint)node:X}eventTree")) + var tree = ImRaii.TreeNode($"Events##{(nint)node:X}eventTree"); + if (tree) { - if (ImGui.BeginTable($"##{(nint)node:X}eventTable", 7, Resizable | SizingFixedFit | Borders | RowBg)) + var tab = 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.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.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; - } - - ImGui.EndTable(); + ImGui.TableNextColumn(); + 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; } - ImGui.TreePop(); + tab.Dispose(); } + + tree.Dispose(); } } diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Component.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Component.cs index 2c95924c5..026933631 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Component.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Component.cs @@ -14,12 +14,8 @@ namespace Dalamud.Interface.Internal.UiDebug2.Browsing; /// internal unsafe class ComponentNodeTree : ResNodeTree { - private readonly AtkUldManager* uldManager; - private readonly ComponentType componentType; - private readonly AtkComponentBase* component; - /// /// Initializes a new instance of the class. /// @@ -28,17 +24,21 @@ internal unsafe class ComponentNodeTree : ResNodeTree internal ComponentNodeTree(AtkResNode* node, AddonTree addonTree) : base(node, addonTree) { - this.component = ((AtkComponentNode*)node)->Component; - this.uldManager = &this.component->UldManager; this.NodeType = 0; - this.componentType = ((AtkUldComponentInfo*)this.uldManager->Objects)->ComponentType; + this.componentType = ((AtkUldComponentInfo*)this.UldManager->Objects)->ComponentType; } + private AtkComponentBase* Component => this.CompNode->Component; + + private AtkComponentNode* CompNode => (AtkComponentNode*)this.Node; + + private AtkUldManager* UldManager => &this.Component->UldManager; + /// private protected override string GetHeaderText() { - var childCount = (int)this.uldManager->NodeListCount; - return $"{this.componentType} Component Node{(childCount > 0 ? $" [+{childCount}]" : string.Empty)} (Node: {(nint)this.Node:X} / Comp: {(nint)this.component:X})"; + var childCount = (int)this.UldManager->NodeListCount; + return $"{this.componentType} Component Node{(childCount > 0 ? $" [+{childCount}]" : string.Empty)} (Node: {(nint)this.Node:X} / Comp: {(nint)this.Component:X})"; } /// @@ -57,29 +57,30 @@ internal unsafe class ComponentNodeTree : ResNodeTree private protected override void PrintChildNodes() { base.PrintChildNodes(); - var count = this.uldManager->NodeListCount; - PrintNodeListAsTree(this.uldManager->NodeList, count, $"Node List [{count}]:", this.AddonTree, new(0f, 0.5f, 0.8f, 1f)); + var count = this.UldManager->NodeListCount; + PrintNodeListAsTree(this.UldManager->NodeList, count, $"Node List [{count}]:", this.AddonTree, new(0f, 0.5f, 0.8f, 1f)); } /// private protected override void PrintFieldNames() { this.PrintFieldName((nint)this.Node, new(0, 0.85F, 1, 1)); - this.PrintFieldName((nint)this.component, new(0f, 0.5f, 0.8f, 1f)); + this.PrintFieldName((nint)this.Component, new(0f, 0.5f, 0.8f, 1f)); } /// private protected override void PrintFieldsForNodeType(bool isEditorOpen = false) { - if (this.component == null) + if (this.Component == null) { return; } + // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault switch (this.componentType) { case TextInput: - var textInputComponent = (AtkComponentTextInput*)this.component; + var textInputComponent = (AtkComponentTextInput*)this.Component; ImGui.Text( $"InputBase Text1: {Marshal.PtrToStringAnsi(new(textInputComponent->AtkComponentInputBase.UnkText1.StringPtr))}"); ImGui.Text( @@ -97,98 +98,96 @@ internal unsafe class ComponentNodeTree : ResNodeTree break; case List: case TreeList: - var l = (AtkComponentList*)this.component; + var l = (AtkComponentList*)this.Component; if (ImGui.SmallButton("Inc.Selected")) { l->SelectedItemIndex++; } - break; - default: break; } } private void PrintComponentObject() { - PrintFieldValuePair("Component", $"{(nint)this.component:X}"); + PrintFieldValuePair("Component", $"{(nint)this.Component:X}"); ImGui.SameLine(); switch (this.componentType) { case Button: - ShowStruct((AtkComponentButton*)this.component); + ShowStruct((AtkComponentButton*)this.Component); break; case Slider: - ShowStruct((AtkComponentSlider*)this.component); + ShowStruct((AtkComponentSlider*)this.Component); break; case Window: - ShowStruct((AtkComponentWindow*)this.component); + ShowStruct((AtkComponentWindow*)this.Component); break; case CheckBox: - ShowStruct((AtkComponentCheckBox*)this.component); + ShowStruct((AtkComponentCheckBox*)this.Component); break; case GaugeBar: - ShowStruct((AtkComponentGaugeBar*)this.component); + ShowStruct((AtkComponentGaugeBar*)this.Component); break; case RadioButton: - ShowStruct((AtkComponentRadioButton*)this.component); + ShowStruct((AtkComponentRadioButton*)this.Component); break; case TextInput: - ShowStruct((AtkComponentTextInput*)this.component); + ShowStruct((AtkComponentTextInput*)this.Component); break; case Icon: - ShowStruct((AtkComponentIcon*)this.component); + ShowStruct((AtkComponentIcon*)this.Component); break; case NumericInput: - ShowStruct((AtkComponentNumericInput*)this.component); + ShowStruct((AtkComponentNumericInput*)this.Component); break; case List: - ShowStruct((AtkComponentList*)this.component); + ShowStruct((AtkComponentList*)this.Component); break; case TreeList: - ShowStruct((AtkComponentTreeList*)this.component); + ShowStruct((AtkComponentTreeList*)this.Component); break; case DropDownList: - ShowStruct((AtkComponentDropDownList*)this.component); + ShowStruct((AtkComponentDropDownList*)this.Component); break; case ScrollBar: - ShowStruct((AtkComponentScrollBar*)this.component); + ShowStruct((AtkComponentScrollBar*)this.Component); break; case ListItemRenderer: - ShowStruct((AtkComponentListItemRenderer*)this.component); + ShowStruct((AtkComponentListItemRenderer*)this.Component); break; case IconText: - ShowStruct((AtkComponentIconText*)this.component); + ShowStruct((AtkComponentIconText*)this.Component); break; case ComponentType.DragDrop: - ShowStruct((AtkComponentDragDrop*)this.component); + ShowStruct((AtkComponentDragDrop*)this.Component); break; case GuildLeveCard: - ShowStruct((AtkComponentGuildLeveCard*)this.component); + ShowStruct((AtkComponentGuildLeveCard*)this.Component); break; case TextNineGrid: - ShowStruct((AtkComponentTextNineGrid*)this.component); + ShowStruct((AtkComponentTextNineGrid*)this.Component); break; case JournalCanvas: - ShowStruct((AtkComponentJournalCanvas*)this.component); + ShowStruct((AtkComponentJournalCanvas*)this.Component); break; case HoldButton: - ShowStruct((AtkComponentHoldButton*)this.component); + ShowStruct((AtkComponentHoldButton*)this.Component); break; case Portrait: - ShowStruct((AtkComponentPortrait*)this.component); + ShowStruct((AtkComponentPortrait*)this.Component); break; default: - ShowStruct(this.component); + ShowStruct(this.Component); break; } } private void PrintComponentDataObject() { - var componentData = this.component->UldManager.ComponentData; + var componentData = this.Component->UldManager.ComponentData; PrintFieldValuePair("Data", $"{(nint)componentData:X}"); if (componentData != null) diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs index ad7c09165..43c85acda 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; -using System.Linq; using System.Numerics; using Dalamud.Interface.Internal.UiDebug2.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -25,11 +26,11 @@ internal unsafe partial class ResNodeTree /// private protected void DrawNodeEditorTable() { - ImGui.BeginTable($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX); + var tab = ImRaii.Table($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX); this.DrawEditorRows(); - ImGui.EndTable(); + tab.Dispose(); } /// @@ -289,7 +290,7 @@ internal unsafe partial class NineGridNodeTree /// internal unsafe partial class TextNodeTree { - private static readonly List FontList = Enum.GetValues().ToList(); + private static readonly List FontList = [.. Enum.GetValues()]; private static readonly string[] FontNames = Enum.GetNames(); @@ -370,8 +371,8 @@ internal unsafe partial class TextNodeTree var hAlign = (int)alignment % 3; var vAlign = ((int)alignment - hAlign) / 3; - var hAlignInput = IconSelectInput($"{label}H", ref hAlign, new() { 0, 1, 2 }, new() { AlignLeft, AlignCenter, AlignRight }); - var vAlignInput = IconSelectInput($"{label}V", ref vAlign, new() { 0, 1, 2 }, new() { ArrowsUpToLine, GripLines, ArrowsDownToLine }); + var hAlignInput = IconSelectInput($"{label}H", ref hAlign, [0, 1, 2], [AlignLeft, AlignCenter, AlignRight]); + var vAlignInput = IconSelectInput($"{label}V", ref vAlign, [0, 1, 2], [ArrowsUpToLine, GripLines, ArrowsDownToLine]); if (hAlignInput || vAlignInput) { diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs index f3cc69618..de0216b05 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs @@ -1,6 +1,8 @@ using System.Numerics; using System.Runtime.InteropServices; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -11,6 +13,7 @@ using static Dalamud.Utility.Util; using static FFXIVClientStructs.FFXIV.Component.GUI.TextureType; using static ImGuiNET.ImGuiTableColumnFlags; using static ImGuiNET.ImGuiTableFlags; +using static ImGuiNET.ImGuiTreeNodeFlags; namespace Dalamud.Interface.Internal.UiDebug2.Browsing; @@ -60,7 +63,9 @@ internal unsafe partial class ImageNodeTree : ResNodeTree return; } - if (NestedTreePush($"Texture##texture{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", out _)) + var tree = ImRaii.TreeNode($"Texture##texture{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", SpanFullWidth); + + if (tree) { PrintFieldValuePairs( ("Texture Type", $"{this.TexData.TexType}"), @@ -93,9 +98,9 @@ internal unsafe partial class ImageNodeTree : ResNodeTree { this.DrawFullTexture(); } - - ImGui.TreePop(); } + + tree.Dispose(); } /// @@ -157,7 +162,8 @@ internal unsafe partial class ImageNodeTree : ResNodeTree if (ImGui.IsItemClicked()) { - ImGui.SetClipboardText(ImGui.IsKeyDown(ImGuiKey.ModShift) + ImGui.SetClipboardText( + ImGui.IsKeyDown(ImGuiKey.ModShift) ? $"new Vector4({u}{suffix}, {v}{suffix}, {w}{suffix}, {h}{suffix})" : $"new Vector2({u}{suffix}, {v}{suffix});\nnew Vector2({w}{suffix}, {h}{suffix})"); } @@ -185,7 +191,7 @@ internal unsafe partial class ImageNodeTree : ResNodeTree private void PrintPartsTable() { - ImGui.BeginTable($"partsTable##{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", 3, Borders | RowBg | Reorderable); + var tab = 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); @@ -200,17 +206,8 @@ internal unsafe partial class ImageNodeTree : ResNodeTree { ImGui.TableNextColumn(); - if (i == this.TexData.PartId) - { - ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0, 0.85F, 1, 1)); - } - - ImGui.Text($"#{i.ToString().PadLeft(this.TexData.PartCount.ToString().Length, '0')}"); - - if (i == this.TexData.PartId) - { - ImGui.PopStyleColor(1); - } + var col = i == this.TexData.PartId ? new Vector4(0, 0.85F, 1, 1) : new(1); + ImGui.TextColored(col, $"#{i.ToString().PadLeft(this.TexData.PartCount.ToString().Length, '0')}"); ImGui.TableNextColumn(); @@ -245,7 +242,7 @@ internal unsafe partial class ImageNodeTree : ResNodeTree PrintPartCoords(u / tWidth, v / tWidth, (u + width) / tWidth, (v + height) / tHeight, true, true); } - ImGui.EndTable(); + tab.Dispose(); } /// diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs index 3c66d44c3..8f4e8c196 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs @@ -35,8 +35,7 @@ internal unsafe partial class NineGridNodeTree : ImageNodeTree private NineGridOffsets Offsets => new(this.NgNode); /// - private protected override void DrawPartOutline( - uint partId, Vector2 cursorScreenPos, Vector2 cursorLocalPos, Vector4 col, bool reqHover = false) + private protected override void DrawPartOutline(uint partId, Vector2 cursorScreenPos, Vector2 cursorLocalPos, Vector4 col, bool reqHover = false) { var part = this.TexData.PartsList->Parts[partId]; diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs index 222ca30d4..efb62dd7a 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs @@ -3,6 +3,8 @@ using System.Numerics; using Dalamud.Interface.Components; using Dalamud.Interface.Internal.UiDebug2.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -15,6 +17,9 @@ using static Dalamud.Interface.Internal.UiDebug2.Utility.Gui; using static Dalamud.Utility.Util; using static FFXIVClientStructs.FFXIV.Component.GUI.NodeFlags; +using static ImGuiNET.ImGuiCol; +using static ImGuiNET.ImGuiTreeNodeFlags; + namespace Dalamud.Interface.Internal.UiDebug2.Browsing; /// @@ -117,15 +122,25 @@ internal unsafe partial class ResNodeTree : IDisposable return; } - ImGui.PushStyleColor(ImGuiCol.Text, color); - var treeOpened = NestedTreePush($"{label}##{(nint)nodeList:X}", color, out var lineStart); - ImGui.PopStyleColor(); + var c = ImRaii.PushColor(Text, color); + var tree = ImRaii.TreeNode($"{label}##{(nint)nodeList:X}", SpanFullWidth); + c.Pop(); - if (treeOpened) + if (tree) { + var lineStart = ImGui.GetCursorScreenPos() + new Vector2(-10, 2); + PrintNodeList(nodeList, count, addonTree); - NestedTreePop(lineStart, color); + + var lineEnd = lineStart with { Y = ImGui.GetCursorScreenPos().Y - 7 }; + + if (lineStart.Y < lineEnd.Y) + { + ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(color), 1); + } } + + tree.Dispose(); } /// @@ -250,7 +265,7 @@ internal unsafe partial class ResNodeTree : IDisposable private void PrintTree(uint? index, bool forceOpen = false) { var visible = this.Node->NodeFlags.HasFlag(Visible); - + var label = $"{(index == null ? string.Empty : $"[{index}] ")}[#{this.Node->NodeId}]###{(nint)this.Node:X}nodeTree"; var displayColor = !visible ? new Vector4(0.8f, 0.8f, 0.8f, 1) : this.Node->Color.A == 0 ? new(0.015f, 0.575f, 0.355f, 1) : new(0.1f, 1f, 0.1f, 1f); @@ -260,9 +275,8 @@ internal unsafe partial class ResNodeTree : IDisposable ImGui.SetNextItemOpen(true, ImGuiCond.Always); } - ImGui.PushStyleColor(ImGuiCol.Text, displayColor); - - var treePush = NestedTreePush($"{(index == null ? string.Empty : $"[{index}] ")}[#{this.Node->NodeId}]###{(nint)this.Node:X}nodeTree", displayColor, out var lineStart); + var col = ImRaii.PushColor(Text, displayColor); + var tree = ImRaii.TreeNode(label, SpanFullWidth); if (ImGui.IsItemHovered()) { @@ -272,10 +286,11 @@ internal unsafe partial class ResNodeTree : IDisposable ImGui.SameLine(); this.WriteTreeHeading(); - ImGui.PopStyleColor(); + col.Pop(); - if (treePush) + if (tree) { + var lineStart = ImGui.GetCursorScreenPos() + new Vector2(-10, 2); try { PrintFieldValuePair("Node", $"{(nint)this.Node:X}"); @@ -309,8 +324,15 @@ internal unsafe partial class ResNodeTree : IDisposable ImGui.TextDisabled($"Couldn't display node!\n\n{ex}"); } - NestedTreePop(lineStart, displayColor); + var lineEnd = lineStart with { Y = ImGui.GetCursorScreenPos().Y - 7 }; + + if (lineStart.Y < lineEnd.Y) + { + ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(displayColor), 1); + } } + + tree.Dispose(); } private void DrawBasicControls() diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs index 8572a5495..b7c01cbc2 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs @@ -1,10 +1,12 @@ -using System.Numerics; using System.Runtime.InteropServices; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Interface.ImGuiSeStringRenderer; +using Dalamud.Interface.Internal.UiDebug2.Utility; using Dalamud.Interface.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Client.System.String; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -51,19 +53,19 @@ internal unsafe partial class TextNodeTree : ResNodeTree #pragma warning disable try { - var style = new SeStringDrawParams() + var style = new SeStringDrawParams { - Color = TxtNode->TextColor.RGBA, - EdgeColor = TxtNode->EdgeColor.RGBA, + Color = this.TxtNode->TextColor.RGBA, + EdgeColor = this.TxtNode->EdgeColor.RGBA, ForceEdgeColor = true, EdgeStrength = 1f }; - ImGuiHelpers.SeStringWrapped(NodeText.AsSpan(), style); + ImGuiHelpers.SeStringWrapped(this.NodeText.AsSpan(), style); } catch { - ImGui.Text(Marshal.PtrToStringAnsi(new(NodeText.StringPtr)) ?? ""); + ImGui.Text(Marshal.PtrToStringAnsi(new(this.NodeText.StringPtr)) ?? ""); } #pragma warning restore @@ -81,7 +83,9 @@ internal unsafe partial class TextNodeTree : ResNodeTree private void PrintPayloads() { - if (ImGui.TreeNode($"Text Payloads##{(nint)this.Node:X}")) + var tree = ImRaii.TreeNode($"Text Payloads##{(nint)this.Node:X}"); + + if (tree) { var utf8String = this.NodeText; var seStringBytes = new byte[utf8String.BufUsed]; @@ -100,15 +104,7 @@ internal unsafe partial class TextNodeTree : ResNodeTree { case PayloadType.RawText when payload is TextPayload tp: { - ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); - ImGui.Text("Raw Text: '"); - ImGui.SameLine(); - ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(0.6f, 0.6f, 0.6f, 1)); - ImGui.Text(tp.Text); - ImGui.PopStyleColor(); - ImGui.SameLine(); - ImGui.PopStyleVar(); - ImGui.Text("'"); + Gui.PrintFieldValuePair("Raw Text", tp.Text ?? string.Empty); break; } @@ -119,8 +115,8 @@ internal unsafe partial class TextNodeTree : ResNodeTree } } } - - ImGui.TreePop(); } + + tree.Dispose(); } } diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.KeyGroupColumn.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.KeyGroupColumn.cs index 179197128..e638cca40 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.KeyGroupColumn.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.KeyGroupColumn.cs @@ -5,7 +5,7 @@ using ImGuiNET; namespace Dalamud.Interface.Internal.UiDebug2.Browsing; /// -public partial struct TimelineTree +public readonly partial struct TimelineTree { /// /// An interface for retrieving and printing the contents of a given column in an animation timeline table. diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs index 22fb61872..d34233b16 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Numerics; using Dalamud.Interface.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Client.Graphics; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -13,6 +15,7 @@ using static Dalamud.Utility.Util; using static FFXIVClientStructs.FFXIV.Component.GUI.NodeType; using static ImGuiNET.ImGuiTableColumnFlags; using static ImGuiNET.ImGuiTableFlags; +using static ImGuiNET.ImGuiTreeNodeFlags; // ReSharper disable SuggestBaseTypeForParameter namespace Dalamud.Interface.Internal.UiDebug2.Browsing; @@ -20,9 +23,9 @@ namespace Dalamud.Interface.Internal.UiDebug2.Browsing; /// /// A struct allowing a node's animation timeline to be printed and browsed. /// -public unsafe partial struct TimelineTree +public readonly unsafe partial struct TimelineTree { - private AtkResNode* node; + private readonly AtkResNode* node; /// /// Initializes a new instance of the struct. @@ -53,7 +56,9 @@ public unsafe partial struct TimelineTree if (count > 0) { - if (NestedTreePush($"Timeline##{(nint)this.node:X}timeline", out _)) + var tree = ImRaii.TreeNode($"Timeline##{(nint)this.node:X}timeline", SpanFullWidth); + + if (tree) { PrintFieldValuePair("Timeline", $"{(nint)this.NodeTimeline:X}"); @@ -72,12 +77,12 @@ public unsafe partial struct TimelineTree for (var a = 0; a < count; a++) { var animation = this.Resource->Animations[a]; - var isActive = this.ActiveAnimation != null && animation.Equals(*this.ActiveAnimation); + var isActive = this.ActiveAnimation != null && &animation == this.ActiveAnimation; this.PrintAnimation(animation, a, isActive, (nint)(this.NodeTimeline->Resource->Animations + (a * sizeof(AtkTimelineAnimation)))); } - - ImGui.TreePop(); } + + tree.Dispose(); } } @@ -305,11 +310,11 @@ public unsafe partial struct TimelineTree { var columns = this.BuildColumns(animation); - ImGui.PushStyleColor(ImGuiCol.Text, isActive ? new Vector4(1, 0.65F, 0.4F, 1) : new(1)); - var treePush = ImGui.TreeNode($"[#{a}] [Frames {animation.StartFrameIdx}-{animation.EndFrameIdx}] {(isActive ? " (Active)" : string.Empty)}###{(nint)this.node}animTree{a}"); - ImGui.PopStyleColor(); + var col = ImRaii.PushColor(ImGuiCol.Text, isActive ? new Vector4(1, 0.65F, 0.4F, 1) : new(1)); + var tree = ImRaii.TreeNode($"[#{a}] [Frames {animation.StartFrameIdx}-{animation.EndFrameIdx}] {(isActive ? " (Active)" : string.Empty)}###{(nint)this.node}animTree{a}"); + col.Dispose(); - if (treePush) + if (tree) { PrintFieldValuePair("Animation", $"{address:X}"); @@ -317,7 +322,7 @@ public unsafe partial struct TimelineTree if (columns.Count > 0) { - ImGui.BeginTable($"##{(nint)this.node}animTable{a}", columns.Count, Borders | SizingFixedFit | RowBg | NoHostExtendX); + var table = ImRaii.Table($"##{(nint)this.node}animTable{a}", columns.Count, Borders | SizingFixedFit | RowBg | NoHostExtendX); foreach (var c in columns) { @@ -339,11 +344,11 @@ public unsafe partial struct TimelineTree } } - ImGui.EndTable(); + table.Dispose(); } - - ImGui.TreePop(); } + + tree.Dispose(); } private List BuildColumns(AtkTimelineAnimation animation) diff --git a/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs b/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs index c6cb99037..d29eb98cf 100644 --- a/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs +++ b/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs @@ -6,6 +6,8 @@ using System.Numerics; using Dalamud.Interface.Components; using Dalamud.Interface.Internal.UiDebug2.Browsing; using Dalamud.Interface.Internal.UiDebug2.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -18,6 +20,7 @@ using static Dalamud.Interface.Utility.ImGuiHelpers; using static FFXIVClientStructs.FFXIV.Component.GUI.NodeFlags; using static ImGuiNET.ImGuiCol; using static ImGuiNET.ImGuiWindowFlags; +// ReSharper disable StructLacksIEquatable.Global #pragma warning disable CS0659 @@ -76,10 +79,10 @@ internal unsafe class ElementSelector : IDisposable /// internal void DrawInterface() { - ImGui.BeginChild("###sidebar_elementSelector", new(250, 0), true); + var ch = ImRaii.Child("###sidebar_elementSelector", new(250, 0), true); - ImGui.PushFont(IconFont); - ImGui.PushStyleColor(Text, this.Active ? new Vector4(1, 1, 0.2f, 1) : new(1)); + 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; @@ -94,8 +97,8 @@ internal unsafe class ElementSelector : IDisposable } } - ImGui.PopStyleColor(); - ImGui.PopFont(); + col.Pop(); + f.Pop(); if (ImGui.IsItemHovered()) { ImGui.SetTooltip("Element Selector"); @@ -112,7 +115,7 @@ internal unsafe class ElementSelector : IDisposable this.PerformSearch(address); } - ImGui.EndChild(); + ch.Dispose(); } /// @@ -138,9 +141,9 @@ internal unsafe class ElementSelector : IDisposable var mousePos = ImGui.GetMousePos() - MainViewport.Pos; var addonResults = GetAtkUnitBaseAtPosition(mousePos); - ImGui.PushStyleColor(WindowBg, new Vector4(0.5f)); - ImGui.BeginChild("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse); - ImGui.BeginGroup(); + var col = ImRaii.PushColor(WindowBg, new Vector4(0.5f)); + var ch = ImRaii.Child("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse); + var g = ImRaii.Group(); Gui.PrintFieldValuePair("Mouse Position", $"{mousePos.X}, {mousePos.Y}"); ImGui.Spacing(); @@ -201,9 +204,9 @@ internal unsafe class ElementSelector : IDisposable } } - ImGui.EndGroup(); - ImGui.EndChild(); - ImGui.PopStyleColor(); + g.Dispose(); + ch.Dispose(); + col.Pop(); } private static List GetAtkUnitBaseAtPosition(Vector2 position) @@ -381,9 +384,9 @@ internal unsafe class ElementSelector : IDisposable return; } - ImGui.PushStyleColor(Text, selected ? new Vector4(1, 1, 0.2f, 1) : new(0.6f, 0.6f, 0.6f, 1)); + 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(); - ImGui.PopStyleColor(); + col.Pop(); } private void PerformSearch(nint address) diff --git a/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs b/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs index 3aef3b6a4..436607261 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs @@ -1,6 +1,7 @@ using System.Numerics; using Dalamud.Interface.Internal.UiDebug2.Browsing; +using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; using ImGuiNET; @@ -38,9 +39,9 @@ internal class AddonPopoutWindow : Window, IDisposable /// public override void Draw() { - ImGui.BeginChild($"{this.WindowName}child", new(-1, -1), true); + var ch = ImRaii.Child($"{this.WindowName}child", new(-1, -1), true); this.addonTree.Draw(); - ImGui.EndChild(); + ch.Dispose(); } /// diff --git a/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs b/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs index b293b734e..d657bbdec 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs @@ -1,6 +1,7 @@ using System.Numerics; using Dalamud.Interface.Internal.UiDebug2.Browsing; +using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -49,9 +50,9 @@ internal unsafe class NodePopoutWindow : Window, IDisposable { if (this.Node != null && this.AddonTree.ContainsNode(this.Node)) { - ImGui.BeginChild($"{(nint)this.Node:X}popoutChild", new(-1, -1), true); + var ch = ImRaii.Child($"{(nint)this.Node:X}popoutChild", new(-1, -1), true); ResNodeTree.GetOrCreate(this.Node, this.AddonTree).Print(null, this.firstDraw); - ImGui.EndChild(); + ch.Dispose(); this.firstDraw = false; } else diff --git a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs index d2510d16b..45ce27a77 100644 --- a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs +++ b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Numerics; using Dalamud.Interface.Components; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Client.UI; using FFXIVClientStructs.FFXIV.Component.GUI; using ImGuiNET; @@ -14,7 +16,7 @@ namespace Dalamud.Interface.Internal.UiDebug2; /// internal unsafe partial class UiDebug2 { - /// + /// /// All unit lists to check for addons. /// internal static readonly List UnitListOptions = @@ -51,18 +53,18 @@ internal unsafe partial class UiDebug2 private void DrawSidebar() { - ImGui.BeginGroup(); + var g = ImRaii.Group(); this.DrawNameSearch(); this.DrawAddonSelectionList(); this.elementSelector.DrawInterface(); - ImGui.EndGroup(); + g.Dispose(); } private void DrawNameSearch() { - ImGui.BeginChild("###sidebar_nameSearch", new(250, 40), true); + var ch = 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); @@ -84,12 +86,12 @@ internal unsafe partial class UiDebug2 this.addonNameSearch = atkUnitBaseSearch; } - ImGui.EndChild(); + ch.Dispose(); } private void DrawAddonSelectionList() { - ImGui.BeginChild("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar); + var ch = ImRaii.Child("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar); var unitListBaseAddr = GetUnitListBaseAddr(); @@ -98,7 +100,7 @@ internal unsafe partial class UiDebug2 this.DrawUnitListOption(unitListBaseAddr, unit); } - ImGui.EndChild(); + ch.Dispose(); } private void DrawUnitListOption(AtkUnitList* unitListBaseAddr, UnitListOption unit) @@ -144,26 +146,27 @@ internal unsafe partial class UiDebug2 return; } - ImGui.PushStyleColor(ImGuiCol.Text, anyVisible ? new Vector4(1) : new Vector4(0.6f, 0.6f, 0.6f, 1)); var countStr = $"{(usingFilter ? $"{matchCount}/" : string.Empty)}{totalCount}"; - var treePush = ImGui.TreeNodeEx($"{unit.Name} [{countStr}]###unitListTree{unit.Index}"); - ImGui.PopStyleColor(); - if (treePush) + 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}"); + col1.Pop(); + + if (tree) { foreach (var option in options) { - ImGui.PushStyleColor(ImGuiCol.Text, option.Visible ? new Vector4(0.1f, 1f, 0.1f, 1f) : new Vector4(0.6f, 0.6f, 0.6f, 1)); + 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)); if (ImGui.Selectable($"{option.Name}##select{option.Name}", this.SelectedAddonName == option.Name)) { this.SelectedAddonName = option.Name; } - ImGui.PopStyleColor(); + col2.Pop(); } - - ImGui.TreePop(); } + + tree.Dispose(); } /// diff --git a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs index 396a84ac9..afb058641 100644 --- a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs +++ b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Dalamud.Game.Gui; using Dalamud.Interface.Internal.UiDebug2.Browsing; +using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Windowing; using Dalamud.Logging.Internal; using Dalamud.Plugin.Services; @@ -43,7 +44,7 @@ internal partial class UiDebug2 : IDisposable internal static IGameGui GameGui { get; set; } = null!; /// - /// Gets a collection of instances, each representing an . + /// Gets a collection of instances, each representing an . /// internal static Dictionary AddonTrees { get; } = []; @@ -85,7 +86,7 @@ internal partial class UiDebug2 : IDisposable private void DrawMainPanel() { ImGui.SameLine(); - ImGui.BeginChild("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar); + var ch = ImRaii.Child("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar); if (this.elementSelector.Active) { @@ -107,6 +108,6 @@ internal partial class UiDebug2 : IDisposable } } - ImGui.EndChild(); + ch.Dispose(); } } diff --git a/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs b/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs index 37b2f92cd..f523bd685 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs @@ -3,6 +3,8 @@ using System.Numerics; using Dalamud.Interface.Components; using Dalamud.Interface.Utility; +using Dalamud.Interface.Utility.Raii; + using FFXIVClientStructs.FFXIV.Client.Graphics; using ImGuiNET; @@ -16,54 +18,6 @@ namespace Dalamud.Interface.Internal.UiDebug2.Utility; /// internal static class Gui { - /// - /// Begins a tree node that also displays a colored line to the left while open. - /// - /// The label of the tree. - /// The color of the heading text. - /// A value representing where to begin drawing the left-side line. - /// Whether this tree should default to being open. - /// true if the tree is open. - internal static bool NestedTreePush(string label, Vector4 color, out Vector2 lineStart, bool defOpen = false) - { - ImGui.PushStyleColor(Text, color); - var result = NestedTreePush(label, out lineStart, defOpen); - ImGui.PopStyleColor(); - return result; - } - - /// - internal static bool NestedTreePush(string label, out Vector2 lineStart, bool defOpen = false) - { - var imGuiTreeNodeFlags = ImGuiTreeNodeFlags.SpanFullWidth; - - if (defOpen) - { - imGuiTreeNodeFlags |= ImGuiTreeNodeFlags.DefaultOpen; - } - - var treeNodeEx = ImGui.TreeNodeEx(label, imGuiTreeNodeFlags); - lineStart = ImGui.GetCursorScreenPos() + new Vector2(-10, 2); - return treeNodeEx; - } - - /// - /// Completes a NestedTree. - /// - /// The starting position calculated when the tree was pushed. - /// The color of the left-side line. - internal static void NestedTreePop(Vector2 lineStart, Vector4? color = null) - { - var lineEnd = lineStart with { Y = ImGui.GetCursorScreenPos().Y - 7 }; - - if (lineStart.Y < lineEnd.Y) - { - ImGui.GetWindowDrawList().AddLine(lineStart, lineEnd, RgbaVector4ToUint(color ?? new(1)), 1); - } - - ImGui.TreePop(); - } - /// /// A radio-button-esque input that uses Fontawesome icon buttons. /// @@ -150,31 +104,41 @@ internal static class Gui /// Colors the text itself either white or black, depending on the luminosity of the background color. 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)) + .Push(Button, color) + .Push(ButtonActive, color) + .Push(ButtonHovered, color); + + ImGui.SmallButton(fmt); + + c.Pop(4); + return; + static double Luminosity(Vector4 vector4) => Math.Pow( (Math.Pow(vector4.X, 2) * 0.299f) + (Math.Pow(vector4.Y, 2) * 0.587f) + (Math.Pow(vector4.Z, 2) * 0.114f), 0.5f) * vector4.W; - - ImGui.PushStyleColor(Text, Luminosity(color) < 0.5f ? new Vector4(1) : new(0, 0, 0, 1)); - ImGui.PushStyleColor(Button, color); - ImGui.PushStyleColor(ButtonActive, color); - ImGui.PushStyleColor(ButtonHovered, color); - ImGui.SmallButton(fmt); - ImGui.PopStyleColor(4); } /// internal static void ClickToCopyText(string text, string? textCopy = null) { - ImGui.PushStyleColor(Text, new Vector4(0.6f, 0.6f, 0.6f, 1)); + var c = ImRaii.PushColor(Text, new Vector4(0.6f, 0.6f, 0.6f, 1)); ImGuiHelpers.ClickToCopyText(text, textCopy); - ImGui.PopStyleColor(); + c.Pop(); if (ImGui.IsItemHovered()) { - ImGui.SetTooltip($"{textCopy ?? text}"); + var t = ImRaii.Tooltip(); + var f = ImRaii.PushFont(UiBuilder.IconFont); + ImGui.Text(FontAwesomeIcon.Copy.ToIconString()); + f.Pop(); + ImGui.SameLine(); + ImGui.Text($"{textCopy ?? text}"); + + t.Dispose(); } } @@ -197,7 +161,9 @@ internal static class Gui var index = (int)Math.Floor(prog * tooltips.Length); - ImGui.SetTooltip(tooltips[index]); + var t = ImRaii.Tooltip(); + ImGui.Text(tooltips[index]); + t.Dispose(); return true; } diff --git a/Dalamud/Interface/Internal/UiDebug2/Utility/NodeBounds.cs b/Dalamud/Interface/Internal/UiDebug2/Utility/NodeBounds.cs index 82bf8f96c..9d2af32e8 100644 --- a/Dalamud/Interface/Internal/UiDebug2/Utility/NodeBounds.cs +++ b/Dalamud/Interface/Internal/UiDebug2/Utility/NodeBounds.cs @@ -28,9 +28,7 @@ public unsafe struct NodeBounds var w = node->Width; var h = node->Height; - this.Points = w == 0 && h == 0 ? - new() { new(0) } : - new() { new(0), new(w, 0), new(w, h), new(0, h) }; + this.Points = w == 0 && h == 0 ? [new(0)] : [new(0), new(w, 0), new(w, h), new(0, h)]; this.TransformPoints(node); } @@ -149,8 +147,7 @@ public unsafe struct NodeBounds var sinR = (float)Sin(r); 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)