Pinning, Hoisting, Recently Lotted
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using AetherBags.Inventory.Context;
|
||||
using AetherBags.Inventory.Items;
|
||||
using AetherBags.Inventory.State;
|
||||
using AetherBags.Nodes.Input;
|
||||
using AetherBags.Nodes.Inventory;
|
||||
@@ -15,6 +17,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
{
|
||||
private readonly MainBagState _inventoryState = new();
|
||||
private InventoryNotificationNode _notificationNode = null!;
|
||||
private LootedItemsCategoryNode _lootedCategoryNode = null!;
|
||||
|
||||
protected override InventoryStateBase InventoryState => _inventoryState;
|
||||
|
||||
@@ -22,7 +25,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
{
|
||||
InitializeBackgroundDropTarget();
|
||||
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
|
||||
{
|
||||
Position = ContentStartPosition,
|
||||
Size = ContentSize,
|
||||
@@ -33,6 +36,13 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
};
|
||||
CategoriesNode.AttachNode(this);
|
||||
|
||||
_lootedCategoryNode = new LootedItemsCategoryNode
|
||||
{
|
||||
ItemsPerLine = 10,
|
||||
OnDismissItem = OnDismissLootedItem,
|
||||
OnClearAll = OnClearAllLootedItems,
|
||||
};
|
||||
|
||||
var header = CalculateHeaderLayout(addon);
|
||||
|
||||
_notificationNode = new InventoryNotificationNode
|
||||
@@ -71,14 +81,69 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
|
||||
addon->SubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
||||
|
||||
_isSetupComplete = true;
|
||||
System.LootedItemsTracker.OnLootedItemsChanged += OnLootedItemsChanged;
|
||||
|
||||
IsSetupComplete = true;
|
||||
|
||||
_inventoryState.RefreshFromGame();
|
||||
|
||||
var existingLoot = System.LootedItemsTracker.LootedItems;
|
||||
if (existingLoot.Count > 0)
|
||||
{
|
||||
UpdateLootedCategory(existingLoot);
|
||||
}
|
||||
|
||||
RefreshCategoriesCore(autosize: true);
|
||||
|
||||
base.OnSetup(addon);
|
||||
}
|
||||
|
||||
private void OnLootedItemsChanged(IReadOnlyList<LootedItemInfo> lootedItems)
|
||||
{
|
||||
if (!IsOpen || !IsSetupComplete) return;
|
||||
|
||||
Services.Framework.RunOnTick(() =>
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
UpdateLootedCategory(lootedItems);
|
||||
}, delayTicks: 1);
|
||||
}
|
||||
|
||||
private void UpdateLootedCategory(IReadOnlyList<LootedItemInfo> lootedItems)
|
||||
{
|
||||
_lootedCategoryNode.UpdateLootedItems(lootedItems);
|
||||
|
||||
if (lootedItems.Count > 0)
|
||||
{
|
||||
if (CategoriesNode.HoistedNode != _lootedCategoryNode)
|
||||
{
|
||||
CategoriesNode.SetHoistedNode(_lootedCategoryNode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (CategoriesNode.DeferRecalculateLayout())
|
||||
{
|
||||
if (CategoriesNode.HoistedNode == _lootedCategoryNode)
|
||||
{
|
||||
CategoriesNode.SetHoistedNode(null);
|
||||
}
|
||||
|
||||
CategoriesNode.RemoveNode(_lootedCategoryNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDismissLootedItem(int index)
|
||||
{
|
||||
System.LootedItemsTracker.RemoveByIndex(index);
|
||||
}
|
||||
|
||||
private void OnClearAllLootedItems()
|
||||
{
|
||||
System.LootedItemsTracker.Clear();
|
||||
}
|
||||
|
||||
public void ManualCurrencyRefresh()
|
||||
{
|
||||
if (!Services.ClientState.IsLoggedIn) return;
|
||||
@@ -95,6 +160,8 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
|
||||
protected override void OnFinalize(AtkUnitBase* addon)
|
||||
{
|
||||
System.LootedItemsTracker.OnLootedItemsChanged -= OnLootedItemsChanged;
|
||||
|
||||
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
|
||||
if (blockingAddonId != 0)
|
||||
{
|
||||
@@ -103,7 +170,7 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
||||
|
||||
addon->UnsubscribeAtkArrayData(1, (int)NumberArrayType.Inventory);
|
||||
|
||||
_isSetupComplete = false;
|
||||
IsSetupComplete = false;
|
||||
base.OnFinalize(addon);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
||||
|
||||
WindowNode?.AddColor = _tintColor;
|
||||
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
|
||||
{
|
||||
Position = ContentStartPosition,
|
||||
Size = ContentSize,
|
||||
@@ -107,7 +107,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
||||
LayoutContent();
|
||||
|
||||
_inventoryState.RefreshFromGame();
|
||||
_isSetupComplete = true;
|
||||
IsSetupComplete = true;
|
||||
|
||||
RefreshCategoriesCore(autosize: true);
|
||||
|
||||
@@ -116,7 +116,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
||||
|
||||
protected override void RefreshCategoriesCore(bool autosize)
|
||||
{
|
||||
if (!_isSetupComplete)
|
||||
if (!IsSetupComplete)
|
||||
return;
|
||||
|
||||
_slotCounterNode.String = _inventoryState.GetEmptySlotsString();
|
||||
@@ -179,7 +179,7 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
||||
|
||||
protected override void OnFinalize(AtkUnitBase* addon)
|
||||
{
|
||||
_isSetupComplete = false;
|
||||
IsSetupComplete = false;
|
||||
|
||||
CloseRetainerWindows();
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
|
||||
WindowNode?.AddColor = _tintColor;
|
||||
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNode>
|
||||
CategoriesNode = new WrappingGridNode<InventoryCategoryNodeBase>
|
||||
{
|
||||
Position = ContentStartPosition,
|
||||
Size = ContentSize,
|
||||
@@ -80,7 +80,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
|
||||
_inventoryState.RefreshFromGame();
|
||||
|
||||
_isSetupComplete = true;
|
||||
IsSetupComplete = true;
|
||||
|
||||
RefreshCategoriesCore(autosize: true);
|
||||
|
||||
@@ -89,7 +89,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
|
||||
protected override void RefreshCategoriesCore(bool autosize)
|
||||
{
|
||||
if (!_isSetupComplete)
|
||||
if (!IsSetupComplete)
|
||||
return;
|
||||
|
||||
_slotCounterNode.String = _inventoryState.GetEmptySlotsString();
|
||||
@@ -99,7 +99,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
||||
|
||||
protected override void OnFinalize(AtkUnitBase* addon)
|
||||
{
|
||||
_isSetupComplete = false;
|
||||
IsSetupComplete = false;
|
||||
|
||||
if (System.Config.General.HideGameSaddleBags)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Inventory;
|
||||
using AetherBags.Inventory.Categories;
|
||||
using KamiToolKit.Premade;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using AetherBags.Inventory.Items;
|
||||
|
||||
namespace AetherBags.Addons;
|
||||
|
||||
public interface IInventoryWindow
|
||||
@@ -8,4 +10,5 @@ public interface IInventoryWindow
|
||||
void ManualRefresh();
|
||||
void ItemRefresh();
|
||||
void SetSearchText(string searchText);
|
||||
InventoryStats GetStats();
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using AetherBags.Helpers;
|
||||
using AetherBags.Inventory;
|
||||
using AetherBags.Inventory.Categories;
|
||||
using AetherBags.Inventory.Context;
|
||||
using AetherBags.Inventory.Items;
|
||||
using AetherBags.Inventory.Scanning;
|
||||
using AetherBags.Inventory.State;
|
||||
using AetherBags.Nodes.Input;
|
||||
@@ -27,7 +28,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
protected readonly HashSet<InventoryCategoryNode> HoverSubscribed = new();
|
||||
|
||||
protected DragDropNode BackgroundDropTarget = null!;
|
||||
protected WrappingGridNode<InventoryCategoryNode> CategoriesNode = null!;
|
||||
protected WrappingGridNode<InventoryCategoryNodeBase> CategoriesNode = null!;
|
||||
protected TextInputWithButtonNode SearchInputNode = null!;
|
||||
protected InventoryFooterNode FooterNode = null!;
|
||||
protected TextNode? SlotCounterNode { get; set; }
|
||||
@@ -49,8 +50,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
|
||||
protected bool RefreshQueued;
|
||||
protected bool RefreshAutosizeQueued;
|
||||
private bool _isRefreshing;
|
||||
protected bool _isSetupComplete;
|
||||
protected bool IsSetupComplete;
|
||||
|
||||
protected abstract InventoryStateBase InventoryState { get; }
|
||||
|
||||
@@ -59,13 +59,14 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
protected virtual bool HasSlotCounter => false;
|
||||
|
||||
private readonly HashSet<uint> _searchMatchScratch = new();
|
||||
private bool _isRefreshing;
|
||||
|
||||
public void ManualRefresh()
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
if (!Services.ClientState.IsLoggedIn) return;
|
||||
if (_isRefreshing) return;
|
||||
if (!_isSetupComplete) return;
|
||||
if (!IsSetupComplete) return;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -82,6 +83,8 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
|
||||
public string GetSearchText() => SearchInputNode?.SearchString.ExtractText() ?? string.Empty;
|
||||
|
||||
public InventoryStats GetStats() => InventoryState.GetStats();
|
||||
|
||||
public virtual void SetSearchText(string searchText)
|
||||
{
|
||||
Services.Framework.RunOnTick(() =>
|
||||
@@ -93,7 +96,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
|
||||
public void RefreshFromLifecycle()
|
||||
{
|
||||
if (!_isSetupComplete) return;
|
||||
if (!IsSetupComplete) return;
|
||||
if (!IsOpen) return;
|
||||
if (_isRefreshing) return;
|
||||
|
||||
@@ -111,7 +114,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
|
||||
protected virtual void RefreshCategoriesCore(bool autosize)
|
||||
{
|
||||
if (!_isSetupComplete)
|
||||
if (!IsSetupComplete)
|
||||
return;
|
||||
|
||||
var config = System.Config.General;
|
||||
@@ -166,7 +169,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
CategoriesNode.SyncWithListDataByKey<CategorizedInventory, InventoryCategoryNode, uint>(
|
||||
dataList: categories,
|
||||
getKeyFromData: categorizedInventory => categorizedInventory.Key,
|
||||
getKeyFromNode: node => node.CategorizedInventory.Key,
|
||||
getKeyFromNode: node => node.Key,
|
||||
updateNode: (node, data) =>
|
||||
{
|
||||
node.CategorizedInventory = data;
|
||||
@@ -394,7 +397,13 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||
protected void ResizeWindow(float width, float height)
|
||||
=> ResizeWindow(width, height, recalcLayout: true);
|
||||
|
||||
public void ItemRefresh() => RefreshCategoriesCore(false);
|
||||
public void ItemRefresh()
|
||||
{
|
||||
if (!IsOpen) return;
|
||||
if (!IsSetupComplete) return;
|
||||
|
||||
RefreshCategoriesCore(false);
|
||||
}
|
||||
|
||||
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using AetherBags.Configuration;
|
||||
using AetherBags.Inventory;
|
||||
using AetherBags.Inventory.Context;
|
||||
|
||||
Reference in New Issue
Block a user