mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +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 Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game.Addon;
|
||||
using Dalamud.Game.Addon.Events;
|
||||
using Dalamud.Game.Addon.Lifecycle;
|
||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
||||
|
|
@ -46,22 +45,26 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
|||
|
||||
private readonly AddonLifecycleEventListener dtrPostDrawListener;
|
||||
private readonly AddonLifecycleEventListener dtrPostRequestedUpdateListener;
|
||||
|
||||
private readonly AddonLifecycleEventListener dtrPreFinalizeListener;
|
||||
|
||||
private readonly ConcurrentBag<DtrBarEntry> newEntries = new();
|
||||
private readonly List<DtrBarEntry> entries = new();
|
||||
|
||||
private readonly Dictionary<uint, List<IAddonEventHandle>> eventHandles = new();
|
||||
|
||||
private uint runningNodeIds = BaseNodeId;
|
||||
private float entryStartPos = float.NaN;
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private DtrBar()
|
||||
{
|
||||
this.dtrPostDrawListener = new AddonLifecycleEventListener(AddonEvent.PostDraw, "_DTR", this.OnDtrPostDraw);
|
||||
this.dtrPostRequestedUpdateListener = new AddonLifecycleEventListener(AddonEvent.PostRequestedUpdate, "_DTR", this.OnAddonRequestedUpdateDetour);
|
||||
this.dtrPostDrawListener = new AddonLifecycleEventListener(AddonEvent.PostDraw, "_DTR", this.FixCollision);
|
||||
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.dtrPostRequestedUpdateListener);
|
||||
this.addonLifecycle.RegisterListener(this.dtrPreFinalizeListener);
|
||||
|
||||
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.dtrPostRequestedUpdateListener);
|
||||
this.addonLifecycle.UnregisterListener(this.dtrPreFinalizeListener);
|
||||
|
||||
foreach (var entry in this.entries)
|
||||
this.RemoveNode(entry.TextNode);
|
||||
|
|
@ -185,11 +189,10 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
|||
var collisionNode = dtr->GetNodeById(17);
|
||||
if (collisionNode == null) return;
|
||||
|
||||
// If we are drawing backwards, we should start from the right side of the collision node. That is,
|
||||
// collisionNode->X + collisionNode->Width.
|
||||
var runningXPos = this.configuration.DtrSwapDirection
|
||||
? collisionNode->X + collisionNode->Width
|
||||
: collisionNode->X;
|
||||
// We haven't calculated the native size yet, so we don't know where to start positioning.
|
||||
if (float.IsNaN(this.entryStartPos)) return;
|
||||
|
||||
var runningXPos = this.entryStartPos;
|
||||
|
||||
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;
|
||||
if (addon->RootNode is null || addon->UldManager.NodeList is null) return;
|
||||
|
||||
this.UpdateNodePositions(addon);
|
||||
|
||||
if (!this.configuration.DtrSwapDirection)
|
||||
float minX = addon->RootNode->Width;
|
||||
var additionalWidth = 0;
|
||||
AtkResNode* collisionNode = null;
|
||||
|
||||
foreach (var index in Enumerable.Range(0, addon->UldManager.NodeListCount))
|
||||
{
|
||||
var targetSize = (ushort)this.CalculateTotalSize();
|
||||
var sizeDelta = MathF.Round((targetSize - addon->RootNode->Width) * addon->RootNode->ScaleX);
|
||||
|
||||
if (addon->RootNode->Width != targetSize)
|
||||
var node = addon->UldManager.NodeList[index];
|
||||
if (node->IsVisible)
|
||||
{
|
||||
addon->RootNode->SetWidth(targetSize);
|
||||
addon->SetX((short)(addon->GetX() - sizeDelta));
|
||||
|
||||
// force a RequestedUpdate immediately to force the game to right-justify it immediately.
|
||||
addon->OnUpdate(AtkStage.GetSingleton()->GetNumberArrayData(), AtkStage.GetSingleton()->GetStringArrayData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateNodePositions(AtkUnitBase* addon)
|
||||
{
|
||||
// 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;
|
||||
while (node is not null)
|
||||
{
|
||||
if (node->NodeID < 1000 && node->IsVisible)
|
||||
var nodeId = node->NodeID;
|
||||
var nodeType = node->Type;
|
||||
|
||||
if (nodeType == NodeType.Collision)
|
||||
{
|
||||
node->SetX(node->GetX() - sizeOffset);
|
||||
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);
|
||||
}
|
||||
|
||||
node = node->PrevSiblingNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (collisionNode == null) return;
|
||||
|
||||
var nativeWidth = addon->RootNode->Width - (int)minX;
|
||||
var targetX = minX - (this.configuration.DtrSwapDirection ? 0 : additionalWidth);
|
||||
var targetWidth = (ushort)(nativeWidth + additionalWidth);
|
||||
|
||||
if (collisionNode->Width != targetWidth || collisionNode->X != targetX)
|
||||
{
|
||||
collisionNode->SetWidth(targetWidth);
|
||||
collisionNode->SetX(targetX);
|
||||
}
|
||||
|
||||
// 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.UpdateNodePositions(addon);
|
||||
this.entryStartPos = float.NaN;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -332,7 +340,7 @@ internal sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
|
|||
{
|
||||
this.eventHandles.Clear();
|
||||
}
|
||||
|
||||
|
||||
foreach (var entry in this.entries)
|
||||
{
|
||||
entry.TextNode = this.MakeNode(++this.runningNodeIds);
|
||||
|
|
@ -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)
|
||||
{
|
||||
var dtr = this.GetDtr();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue