Use InventoryScrollingNode, fixes #12
This commit is contained in:
@@ -25,7 +25,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
{
|
{
|
||||||
InitializeBackgroundDropTarget();
|
InitializeBackgroundDropTarget();
|
||||||
|
|
||||||
ScrollableCategories = new ScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
ScrollableCategories = new InventoryScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
||||||
{
|
{
|
||||||
Position = ContentStartPosition,
|
Position = ContentStartPosition,
|
||||||
Size = ContentSize,
|
Size = ContentSize,
|
||||||
@@ -179,6 +179,8 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
|
|
||||||
protected override void OnFinalize(AtkUnitBase* addon)
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
|
_lootedCategoryNode?.Dispose();
|
||||||
|
|
||||||
System.LootedItemsTracker.OnLootedItemsChanged -= OnLootedItemsChanged;
|
System.LootedItemsTracker.OnLootedItemsChanged -= OnLootedItemsChanged;
|
||||||
|
|
||||||
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
|
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
|
||||||
@@ -189,8 +191,6 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
|
|
||||||
addon->UnsubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
addon->UnsubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
||||||
|
|
||||||
_lootedCategoryNode?.Dispose();
|
|
||||||
|
|
||||||
IsSetupComplete = false;
|
IsSetupComplete = false;
|
||||||
base.OnFinalize(addon);
|
base.OnFinalize(addon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
|||||||
|
|
||||||
WindowNode?.AddColor = _tintColor;
|
WindowNode?.AddColor = _tintColor;
|
||||||
|
|
||||||
ScrollableCategories = new ScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
ScrollableCategories = new InventoryScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
||||||
{
|
{
|
||||||
Position = ContentStartPosition,
|
Position = ContentStartPosition,
|
||||||
Size = ContentSize,
|
Size = ContentSize,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
|||||||
|
|
||||||
WindowNode?.AddColor = _tintColor;
|
WindowNode?.AddColor = _tintColor;
|
||||||
|
|
||||||
ScrollableCategories = new ScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
ScrollableCategories = new InventoryScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>>
|
||||||
{
|
{
|
||||||
Position = ContentStartPosition,
|
Position = ContentStartPosition,
|
||||||
Size = ContentSize,
|
Size = ContentSize,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
protected readonly HashSet<InventoryCategoryNode> HoverSubscribed = new();
|
protected readonly HashSet<InventoryCategoryNode> HoverSubscribed = new();
|
||||||
|
|
||||||
protected DragDropNode BackgroundDropTarget = null!;
|
protected DragDropNode BackgroundDropTarget = null!;
|
||||||
protected ScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>> ScrollableCategories = null!;
|
protected InventoryScrollingAreaNode<WrappingGridNode<InventoryCategoryNodeBase>> ScrollableCategories = null!;
|
||||||
protected WrappingGridNode<InventoryCategoryNodeBase> CategoriesNode = null!;
|
protected WrappingGridNode<InventoryCategoryNodeBase> CategoriesNode = null!;
|
||||||
protected TextInputWithButtonNode SearchInputNode = null!;
|
protected TextInputWithButtonNode SearchInputNode = null!;
|
||||||
protected InventoryFooterNode FooterNode = null!;
|
protected InventoryFooterNode FooterNode = null!;
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using KamiToolKit;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
|
namespace AetherBags.Nodes.Layout;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A copy of KamiToolKit's ScrollingAreaNode with ContentAreaClipNode changed from
|
||||||
|
/// SimpleComponentNode to ResNode, to prevent the native AtkDragDropManager from
|
||||||
|
/// treating the clip boundary as a component node (which blocks drag-to-hotbar).
|
||||||
|
/// According to Kami it is possible that this may or may not leak.
|
||||||
|
/// We will eventually change this later.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class InventoryScrollingAreaNode<T> : SimpleComponentNode where T : NodeBase, new() {
|
||||||
|
|
||||||
|
public readonly ResNode ContentAreaClipNode;
|
||||||
|
public readonly T ContentAreaNode;
|
||||||
|
public readonly ScrollBarNode ScrollBarNode;
|
||||||
|
public readonly CollisionNode ScrollingCollisionNode;
|
||||||
|
|
||||||
|
public InventoryScrollingAreaNode() {
|
||||||
|
ScrollingCollisionNode = new CollisionNode();
|
||||||
|
ScrollingCollisionNode.AttachNode(this);
|
||||||
|
|
||||||
|
ContentAreaClipNode = new ResNode {
|
||||||
|
NodeFlags = NodeFlags.Clip | NodeFlags.EmitsEvents | NodeFlags.Visible,
|
||||||
|
};
|
||||||
|
ContentAreaClipNode.AttachNode(this);
|
||||||
|
|
||||||
|
ContentAreaNode = new T();
|
||||||
|
ContentAreaNode.AttachNode(ContentAreaClipNode);
|
||||||
|
|
||||||
|
ScrollBarNode = new ScrollBarNode {
|
||||||
|
ContentNode = ContentAreaNode,
|
||||||
|
ContentCollisionNode = ScrollingCollisionNode,
|
||||||
|
HideWhenDisabled = true,
|
||||||
|
};
|
||||||
|
ScrollBarNode.AttachNode(this);
|
||||||
|
|
||||||
|
AtkResNode* clipNode = ContentAreaClipNode;
|
||||||
|
AtkResNode* contentNode = ContentAreaNode;
|
||||||
|
|
||||||
|
clipNode->AtkEventManager.RegisterEvent(
|
||||||
|
AtkEventType.MouseWheel,
|
||||||
|
5,
|
||||||
|
null,
|
||||||
|
ScrollingCollisionNode,
|
||||||
|
ScrollBarNode,
|
||||||
|
false);
|
||||||
|
|
||||||
|
ScrollingCollisionNode.Node->AtkEventManager.RegisterEvent(
|
||||||
|
AtkEventType.MouseWheel,
|
||||||
|
5,
|
||||||
|
null,
|
||||||
|
ScrollingCollisionNode,
|
||||||
|
ScrollBarNode,
|
||||||
|
false);
|
||||||
|
|
||||||
|
contentNode->AtkEventManager.RegisterEvent(
|
||||||
|
AtkEventType.MouseWheel,
|
||||||
|
5,
|
||||||
|
null,
|
||||||
|
ScrollingCollisionNode,
|
||||||
|
ScrollBarNode,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual T ContentNode => ContentAreaNode;
|
||||||
|
|
||||||
|
public int ScrollPosition {
|
||||||
|
get => ScrollBarNode.ScrollPosition;
|
||||||
|
set => ScrollBarNode.ScrollPosition = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ScrollSpeed {
|
||||||
|
get => ScrollBarNode.ScrollSpeed;
|
||||||
|
set => ScrollBarNode.ScrollSpeed = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public required float ContentHeight {
|
||||||
|
get => ContentAreaNode.Height;
|
||||||
|
set {
|
||||||
|
ContentAreaNode.Height = value;
|
||||||
|
ScrollBarNode.UpdateScrollParams();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AutoHideScrollBar {
|
||||||
|
get => ScrollBarNode.HideWhenDisabled;
|
||||||
|
set => ScrollBarNode.HideWhenDisabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSizeChanged() {
|
||||||
|
base.OnSizeChanged();
|
||||||
|
|
||||||
|
ContentAreaNode.Width = Width - 16.0f;
|
||||||
|
ScrollingCollisionNode.Size = new Vector2(Width - 16.0f, Height);
|
||||||
|
ContentAreaClipNode.Size = new Vector2(Width - 16.0f, Height);
|
||||||
|
ScrollBarNode.Size = new Vector2(8.0f, Height);
|
||||||
|
ScrollBarNode.UpdateScrollParams();
|
||||||
|
|
||||||
|
ScrollBarNode.X = Width - 8.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FitToContentHeight() {
|
||||||
|
if (ContentNode is LayoutListNode layoutNode) {
|
||||||
|
ContentHeight = layoutNode.Nodes.Sum(node => node.IsVisible ? node.Height + layoutNode.ItemSpacing : 0.0f) + layoutNode.FirstItemSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user