mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
Resize collision node instead of root node in DtrBar (#1494)
This commit is contained in:
parent
3fb5bcc348
commit
6ba31d2752
1 changed files with 56 additions and 70 deletions
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Dalamud.Configuration.Internal;
|
using Dalamud.Configuration.Internal;
|
||||||
using Dalamud.Game.Addon;
|
|
||||||
using Dalamud.Game.Addon.Events;
|
using Dalamud.Game.Addon.Events;
|
||||||
using Dalamud.Game.Addon.Lifecycle;
|
using Dalamud.Game.Addon.Lifecycle;
|
||||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||||
|
|
@ -46,6 +45,7 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
|
|
||||||
private readonly AddonLifecycleEventListener dtrPostDrawListener;
|
private readonly AddonLifecycleEventListener dtrPostDrawListener;
|
||||||
private readonly AddonLifecycleEventListener dtrPostRequestedUpdateListener;
|
private readonly AddonLifecycleEventListener dtrPostRequestedUpdateListener;
|
||||||
|
private readonly AddonLifecycleEventListener dtrPreFinalizeListener;
|
||||||
|
|
||||||
private readonly ConcurrentBag<DtrBarEntry> newEntries = new();
|
private readonly ConcurrentBag<DtrBarEntry> newEntries = new();
|
||||||
private readonly List<DtrBarEntry> entries = new();
|
private readonly List<DtrBarEntry> entries = new();
|
||||||
|
|
@ -53,15 +53,18 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
private readonly Dictionary<uint, List<IAddonEventHandle>> eventHandles = new();
|
private readonly Dictionary<uint, List<IAddonEventHandle>> eventHandles = new();
|
||||||
|
|
||||||
private uint runningNodeIds = BaseNodeId;
|
private uint runningNodeIds = BaseNodeId;
|
||||||
|
private float entryStartPos = float.NaN;
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
private DtrBar()
|
private DtrBar()
|
||||||
{
|
{
|
||||||
this.dtrPostDrawListener = new AddonLifecycleEventListener(AddonEvent.PostDraw, "_DTR", this.OnDtrPostDraw);
|
this.dtrPostDrawListener = new AddonLifecycleEventListener(AddonEvent.PostDraw, "_DTR", this.FixCollision);
|
||||||
this.dtrPostRequestedUpdateListener = new AddonLifecycleEventListener(AddonEvent.PostRequestedUpdate, "_DTR", this.OnAddonRequestedUpdateDetour);
|
this.dtrPostRequestedUpdateListener = new AddonLifecycleEventListener(AddonEvent.PostRequestedUpdate, "_DTR", this.FixCollision);
|
||||||
|
this.dtrPreFinalizeListener = new AddonLifecycleEventListener(AddonEvent.PreFinalize, "_DTR", this.PreFinalize);
|
||||||
|
|
||||||
this.addonLifecycle.RegisterListener(this.dtrPostDrawListener);
|
this.addonLifecycle.RegisterListener(this.dtrPostDrawListener);
|
||||||
this.addonLifecycle.RegisterListener(this.dtrPostRequestedUpdateListener);
|
this.addonLifecycle.RegisterListener(this.dtrPostRequestedUpdateListener);
|
||||||
|
this.addonLifecycle.RegisterListener(this.dtrPreFinalizeListener);
|
||||||
|
|
||||||
this.framework.Update += this.Update;
|
this.framework.Update += this.Update;
|
||||||
|
|
||||||
|
|
@ -102,6 +105,7 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
{
|
{
|
||||||
this.addonLifecycle.UnregisterListener(this.dtrPostDrawListener);
|
this.addonLifecycle.UnregisterListener(this.dtrPostDrawListener);
|
||||||
this.addonLifecycle.UnregisterListener(this.dtrPostRequestedUpdateListener);
|
this.addonLifecycle.UnregisterListener(this.dtrPostRequestedUpdateListener);
|
||||||
|
this.addonLifecycle.UnregisterListener(this.dtrPreFinalizeListener);
|
||||||
|
|
||||||
foreach (var entry in this.entries)
|
foreach (var entry in this.entries)
|
||||||
this.RemoveNode(entry.TextNode);
|
this.RemoveNode(entry.TextNode);
|
||||||
|
|
@ -185,11 +189,10 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
var collisionNode = dtr->GetNodeById(17);
|
var collisionNode = dtr->GetNodeById(17);
|
||||||
if (collisionNode == null) return;
|
if (collisionNode == null) return;
|
||||||
|
|
||||||
// If we are drawing backwards, we should start from the right side of the collision node. That is,
|
// We haven't calculated the native size yet, so we don't know where to start positioning.
|
||||||
// collisionNode->X + collisionNode->Width.
|
if (float.IsNaN(this.entryStartPos)) return;
|
||||||
var runningXPos = this.configuration.DtrSwapDirection
|
|
||||||
? collisionNode->X + collisionNode->Width
|
var runningXPos = this.entryStartPos;
|
||||||
: collisionNode->X;
|
|
||||||
|
|
||||||
foreach (var data in this.entries)
|
foreach (var data in this.entries)
|
||||||
{
|
{
|
||||||
|
|
@ -255,56 +258,61 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDtrPostDraw(AddonEvent eventType, AddonArgs addonInfo)
|
private void FixCollision(AddonEvent eventType, AddonArgs addonInfo)
|
||||||
{
|
{
|
||||||
var addon = (AtkUnitBase*)addonInfo.Addon;
|
var addon = (AtkUnitBase*)addonInfo.Addon;
|
||||||
|
if (addon->RootNode is null || addon->UldManager.NodeList is null) return;
|
||||||
|
|
||||||
this.UpdateNodePositions(addon);
|
float minX = addon->RootNode->Width;
|
||||||
|
var additionalWidth = 0;
|
||||||
|
AtkResNode* collisionNode = null;
|
||||||
|
|
||||||
if (!this.configuration.DtrSwapDirection)
|
foreach (var index in Enumerable.Range(0, addon->UldManager.NodeListCount))
|
||||||
{
|
{
|
||||||
var targetSize = (ushort)this.CalculateTotalSize();
|
var node = addon->UldManager.NodeList[index];
|
||||||
var sizeDelta = MathF.Round((targetSize - addon->RootNode->Width) * addon->RootNode->ScaleX);
|
if (node->IsVisible)
|
||||||
|
|
||||||
if (addon->RootNode->Width != targetSize)
|
|
||||||
{
|
{
|
||||||
addon->RootNode->SetWidth(targetSize);
|
var nodeId = node->NodeID;
|
||||||
addon->SetX((short)(addon->GetX() - sizeDelta));
|
var nodeType = node->Type;
|
||||||
|
|
||||||
// force a RequestedUpdate immediately to force the game to right-justify it immediately.
|
if (nodeType == NodeType.Collision)
|
||||||
addon->OnUpdate(AtkStage.GetSingleton()->GetNumberArrayData(), AtkStage.GetSingleton()->GetStringArrayData());
|
{
|
||||||
|
collisionNode = node;
|
||||||
|
}
|
||||||
|
else if (nodeId >= BaseNodeId)
|
||||||
|
{
|
||||||
|
// Dalamud-created node
|
||||||
|
additionalWidth += node->Width + this.configuration.DtrSpacing;
|
||||||
|
}
|
||||||
|
else if ((nodeType == NodeType.Res || (ushort)nodeType >= 1000) &&
|
||||||
|
(node->ChildNode == null || node->ChildNode->IsVisible))
|
||||||
|
{
|
||||||
|
// Native top-level node. These are are either res nodes or button components.
|
||||||
|
// Both the node and its child (if it has one) must be visible for the node to be counted.
|
||||||
|
minX = MathF.Min(minX, node->X);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateNodePositions(AtkUnitBase* addon)
|
if (collisionNode == null) return;
|
||||||
{
|
|
||||||
// If we grow to the right, we need to left-justify the original elements.
|
|
||||||
// else if we grow to the left, the game right-justifies it for us.
|
|
||||||
if (this.configuration.DtrSwapDirection)
|
|
||||||
{
|
|
||||||
var targetSize = (ushort)this.CalculateTotalSize();
|
|
||||||
addon->RootNode->SetWidth(targetSize);
|
|
||||||
var sizeOffset = addon->GetNodeById(17)->GetX();
|
|
||||||
|
|
||||||
var node = addon->RootNode->ChildNode;
|
var nativeWidth = addon->RootNode->Width - (int)minX;
|
||||||
while (node is not null)
|
var targetX = minX - (this.configuration.DtrSwapDirection ? 0 : additionalWidth);
|
||||||
|
var targetWidth = (ushort)(nativeWidth + additionalWidth);
|
||||||
|
|
||||||
|
if (collisionNode->Width != targetWidth || collisionNode->X != targetX)
|
||||||
{
|
{
|
||||||
if (node->NodeID < 1000 && node->IsVisible)
|
collisionNode->SetWidth(targetWidth);
|
||||||
{
|
collisionNode->SetX(targetX);
|
||||||
node->SetX(node->GetX() - sizeOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node = node->PrevSiblingNode;
|
// If we are drawing backwards, we should start from the right side of the native nodes.
|
||||||
}
|
this.entryStartPos = this.configuration.DtrSwapDirection ? minX + nativeWidth : minX;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAddonRequestedUpdateDetour(AddonEvent eventType, AddonArgs addonInfo)
|
private void PreFinalize(AddonEvent type, AddonArgs args)
|
||||||
{
|
{
|
||||||
var addon = (AtkUnitBase*)addonInfo.Addon;
|
this.entryStartPos = float.NaN;
|
||||||
|
|
||||||
this.UpdateNodePositions(addon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -340,28 +348,6 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the total width the dtr bar should be
|
|
||||||
private float CalculateTotalSize()
|
|
||||||
{
|
|
||||||
var addon = this.GetDtr();
|
|
||||||
if (addon is null || addon->RootNode is null || addon->UldManager.NodeList is null) return 0;
|
|
||||||
|
|
||||||
var totalSize = 0.0f;
|
|
||||||
|
|
||||||
foreach (var index in Enumerable.Range(0, addon->UldManager.NodeListCount))
|
|
||||||
{
|
|
||||||
var node = addon->UldManager.NodeList[index];
|
|
||||||
|
|
||||||
// Node 17 is the default CollisionNode that fits over the existing elements
|
|
||||||
if (node->NodeID is 17) totalSize += node->Width;
|
|
||||||
|
|
||||||
// Node > 1000, are our custom nodes
|
|
||||||
if (node->NodeID is > 1000 && node->IsVisible) totalSize += node->Width + this.configuration.DtrSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool AddNode(AtkTextNode* node)
|
private bool AddNode(AtkTextNode* node)
|
||||||
{
|
{
|
||||||
var dtr = this.GetDtr();
|
var dtr = this.GetDtr();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue