Inherited Improvements
This commit is contained in:
@@ -4,8 +4,6 @@ using AetherBags.Inventory.State;
|
|||||||
using AetherBags.Nodes.Input;
|
using AetherBags.Nodes.Input;
|
||||||
using AetherBags.Nodes.Inventory;
|
using AetherBags.Nodes.Inventory;
|
||||||
using AetherBags.Nodes.Layout;
|
using AetherBags.Nodes.Layout;
|
||||||
using Dalamud.Game.Addon.Lifecycle;
|
|
||||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
@@ -35,36 +33,26 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
};
|
};
|
||||||
CategoriesNode.AttachNode(this);
|
CategoriesNode.AttachNode(this);
|
||||||
|
|
||||||
var size = new Vector2(addon->Size.X / 2.0f, 28.0f);
|
var header = CalculateHeaderLayout(addon);
|
||||||
|
|
||||||
var header = addon->WindowHeaderCollisionNode;
|
|
||||||
|
|
||||||
float headerX = header->X;
|
|
||||||
float headerY = header->Y;
|
|
||||||
float headerW = header->Width;
|
|
||||||
float headerH = header->Height;
|
|
||||||
|
|
||||||
float x = headerX + (headerW - size.X) * 0.5f;
|
|
||||||
float y = headerY + (headerH - size.Y) * 0.5f;
|
|
||||||
|
|
||||||
_notificationNode = new InventoryNotificationNode
|
_notificationNode = new InventoryNotificationNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(WindowNode!.X - 4f, WindowNode!.Y - 32f),
|
Position = new Vector2(WindowNode!.X - 4f, WindowNode!.Y - 32f),
|
||||||
Size = new Vector2(headerW, 28f),
|
Size = new Vector2(header.HeaderWidth, 28f),
|
||||||
};
|
};
|
||||||
_notificationNode.AttachNode(this);
|
_notificationNode.AttachNode(this);
|
||||||
|
|
||||||
SearchInputNode = new TextInputWithHintNode
|
SearchInputNode = new TextInputWithHintNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(x, y),
|
Position = header.SearchPosition,
|
||||||
Size = size,
|
Size = header.SearchSize,
|
||||||
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
||||||
};
|
};
|
||||||
SearchInputNode.AttachNode(this);
|
SearchInputNode.AttachNode(this);
|
||||||
|
|
||||||
SettingsButtonNode = new CircleButtonNode
|
SettingsButtonNode = new CircleButtonNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(headerW - 48f, y),
|
Position = new Vector2(header.HeaderWidth - SettingsButtonOffset, header.HeaderY),
|
||||||
Size = new Vector2(28f),
|
Size = new Vector2(28f),
|
||||||
Icon = ButtonIcon.GearCog,
|
Icon = ButtonIcon.GearCog,
|
||||||
OnClick = System.AddonConfigurationWindow.Toggle
|
OnClick = System.AddonConfigurationWindow.Toggle
|
||||||
@@ -90,34 +78,12 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
base.OnSetup(addon);
|
base.OnSetup(addon);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUpdate(AtkUnitBase* addon)
|
|
||||||
{
|
|
||||||
if (RefreshQueued)
|
|
||||||
{
|
|
||||||
bool doAutosize = RefreshAutosizeQueued;
|
|
||||||
RefreshQueued = false;
|
|
||||||
RefreshAutosizeQueued = false;
|
|
||||||
|
|
||||||
RefreshCategoriesCore(doAutosize);
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnUpdate(addon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ManualCurrencyRefresh()
|
public void ManualCurrencyRefresh()
|
||||||
{
|
{
|
||||||
if (!Services.ClientState.IsLoggedIn) return;
|
if (!Services.ClientState.IsLoggedIn) return;
|
||||||
FooterNode.RefreshCurrencies();
|
FooterNode.RefreshCurrencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
|
||||||
{
|
|
||||||
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
|
||||||
|
|
||||||
_inventoryState.RefreshFromGame();
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetNotification(InventoryNotificationInfo info)
|
public void SetNotification(InventoryNotificationInfo info)
|
||||||
{
|
{
|
||||||
Services.Framework.RunOnTick(() =>
|
Services.Framework.RunOnTick(() =>
|
||||||
@@ -126,15 +92,6 @@ public unsafe class AddonInventoryWindow : InventoryAddonBase
|
|||||||
}, delayTicks: 1);
|
}, delayTicks: 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSearchText(string searchText)
|
|
||||||
{
|
|
||||||
Services.Framework.RunOnTick(() =>
|
|
||||||
{
|
|
||||||
if (IsOpen) SearchInputNode.SearchString = searchText;
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}, delayTicks: 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFinalize(AtkUnitBase* addon)
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
|
ref var blockingAddonId = ref AgentInventoryContext.Instance()->BlockingAddonId;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using AetherBags.Inventory;
|
using AetherBags.Inventory;
|
||||||
using AetherBags.Inventory.State;
|
using AetherBags.Inventory.State;
|
||||||
using AetherBags.Nodes.Input;
|
using AetherBags.Nodes.Input;
|
||||||
using AetherBags.Nodes.Inventory;
|
using AetherBags.Nodes.Inventory;
|
||||||
using AetherBags.Nodes.Layout;
|
using AetherBags.Nodes.Layout;
|
||||||
using Dalamud.Game.Addon.Lifecycle;
|
|
||||||
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
@@ -31,6 +30,8 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
|||||||
protected override float MinWindowWidth => 400;
|
protected override float MinWindowWidth => 400;
|
||||||
protected override float MaxWindowWidth => 700;
|
protected override float MaxWindowWidth => 700;
|
||||||
|
|
||||||
|
private readonly string[] _retainerAddonNames = { "InventoryRetainer", "InventoryRetainerLarge" };
|
||||||
|
|
||||||
protected override void OnSetup(AtkUnitBase* addon)
|
protected override void OnSetup(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
InitializeBackgroundDropTarget();
|
InitializeBackgroundDropTarget();
|
||||||
@@ -48,29 +49,19 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
|||||||
};
|
};
|
||||||
CategoriesNode.AttachNode(this);
|
CategoriesNode.AttachNode(this);
|
||||||
|
|
||||||
var size = new Vector2(addon->Size.X / 2.0f, 28.0f);
|
var header = CalculateHeaderLayout(addon);
|
||||||
|
|
||||||
var header = addon->WindowHeaderCollisionNode;
|
|
||||||
|
|
||||||
float headerX = header->X;
|
|
||||||
float headerY = header->Y;
|
|
||||||
float headerW = header->Width;
|
|
||||||
float headerH = header->Height;
|
|
||||||
|
|
||||||
float x = headerX + (headerW - size.X) * 0.5f;
|
|
||||||
float y = headerY + (headerH - size.Y) * 0.5f;
|
|
||||||
|
|
||||||
SearchInputNode = new TextInputWithHintNode
|
SearchInputNode = new TextInputWithHintNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(x, y),
|
Position = header.SearchPosition,
|
||||||
Size = size,
|
Size = header.SearchSize,
|
||||||
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
||||||
};
|
};
|
||||||
SearchInputNode.AttachNode(this);
|
SearchInputNode.AttachNode(this);
|
||||||
|
|
||||||
SettingsButtonNode = new CircleButtonNode
|
SettingsButtonNode = new CircleButtonNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(headerW - 48f, y),
|
Position = new Vector2(header.HeaderWidth - SettingsButtonOffset, header.HeaderY),
|
||||||
Size = new Vector2(28f),
|
Size = new Vector2(28f),
|
||||||
Icon = ButtonIcon.GearCog,
|
Icon = ButtonIcon.GearCog,
|
||||||
OnClick = System.AddonConfigurationWindow.Toggle
|
OnClick = System.AddonConfigurationWindow.Toggle
|
||||||
@@ -152,18 +143,23 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
|||||||
SlotCounterNode.Position = new Vector2(contentSize.X - 80f, footerY);
|
SlotCounterNode.Position = new Vector2(contentSize.X - 80f, footerY);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUpdate(AtkUnitBase* addon)
|
private void CloseRetainerWindows()
|
||||||
{
|
{
|
||||||
if (RefreshQueued)
|
var manager = RaptureAtkUnitManager.Instance();
|
||||||
|
foreach (var name in _retainerAddonNames)
|
||||||
{
|
{
|
||||||
bool doAutosize = RefreshAutosizeQueued;
|
var addon = manager->GetAddonByName(name);
|
||||||
RefreshQueued = false;
|
if (addon != null)
|
||||||
RefreshAutosizeQueued = false;
|
{
|
||||||
|
addon->IsVisible = true;
|
||||||
RefreshCategoriesCore(doAutosize);
|
addon->Close(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
base.OnUpdate(addon);
|
private bool IsAnyRetainerWindowLoaded()
|
||||||
|
{
|
||||||
|
return _retainerAddonNames.Any(name => RaptureAtkUnitManager.Instance()->GetAddonByName(name) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnShow(AtkUnitBase* addon)
|
protected override void OnShow(AtkUnitBase* addon)
|
||||||
@@ -175,48 +171,16 @@ public unsafe class AddonRetainerWindow : InventoryAddonBase
|
|||||||
|
|
||||||
private void OnEntrustDuplicates()
|
private void OnEntrustDuplicates()
|
||||||
{
|
{
|
||||||
// TODO: Implement checking if the retainer bag is def open
|
if (!IsAnyRetainerWindowLoaded()) return;
|
||||||
var agent = AgentModule.Instance()->GetAgentByInternalId(AgentId.Retainer);
|
var agent = AgentModule.Instance()->GetAgentByInternalId(AgentId.Retainer);
|
||||||
agent->SendCommand(0, [0]);
|
agent->SendCommand(0, [0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
|
||||||
{
|
|
||||||
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
|
||||||
|
|
||||||
_inventoryState.RefreshFromGame();
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetSearchText(string searchText)
|
|
||||||
{
|
|
||||||
Services.Framework.RunOnTick(() =>
|
|
||||||
{
|
|
||||||
if (IsOpen) SearchInputNode.SearchString = searchText;
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}, delayTicks: 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFinalize(AtkUnitBase* addon)
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
_isSetupComplete = false;
|
_isSetupComplete = false;
|
||||||
|
|
||||||
if (System.Config.General.HideGameRetainer)
|
CloseRetainerWindows();
|
||||||
{
|
|
||||||
var retainerAddon = RaptureAtkUnitManager.Instance()->GetAddonByName("InventoryRetainer");
|
|
||||||
if (retainerAddon != null)
|
|
||||||
{
|
|
||||||
retainerAddon->IsVisible = true;
|
|
||||||
retainerAddon->Close(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
retainerAddon = RaptureAtkUnitManager.Instance()->GetAddonByName("InventoryRetainerLarge");
|
|
||||||
if (retainerAddon != null)
|
|
||||||
{
|
|
||||||
retainerAddon->IsVisible = true;
|
|
||||||
retainerAddon->Close(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnFinalize(addon);
|
base.OnFinalize(addon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,29 +42,19 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
|||||||
};
|
};
|
||||||
CategoriesNode.AttachNode(this);
|
CategoriesNode.AttachNode(this);
|
||||||
|
|
||||||
var size = new Vector2(addon->Size.X / 2.0f, 28.0f);
|
var header = CalculateHeaderLayout(addon);
|
||||||
|
|
||||||
var header = addon->WindowHeaderCollisionNode;
|
|
||||||
|
|
||||||
float headerX = header->X;
|
|
||||||
float headerY = header->Y;
|
|
||||||
float headerW = header->Width;
|
|
||||||
float headerH = header->Height;
|
|
||||||
|
|
||||||
float x = headerX + (headerW - size.X) * 0.5f;
|
|
||||||
float y = headerY + (headerH - size.Y) * 0.5f;
|
|
||||||
|
|
||||||
SearchInputNode = new TextInputWithHintNode
|
SearchInputNode = new TextInputWithHintNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(x, y),
|
Position = header.SearchPosition,
|
||||||
Size = size,
|
Size = header.SearchSize,
|
||||||
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
OnInputReceived = _ => RefreshCategoriesCore(autosize: false),
|
||||||
};
|
};
|
||||||
SearchInputNode.AttachNode(this);
|
SearchInputNode.AttachNode(this);
|
||||||
|
|
||||||
SettingsButtonNode = new CircleButtonNode
|
SettingsButtonNode = new CircleButtonNode
|
||||||
{
|
{
|
||||||
Position = new Vector2(headerW - 48f, y),
|
Position = new Vector2(header.HeaderWidth - SettingsButtonOffset, header.HeaderY),
|
||||||
Size = new Vector2(28f),
|
Size = new Vector2(28f),
|
||||||
AddColor = _tintColor,
|
AddColor = _tintColor,
|
||||||
Icon = ButtonIcon.GearCog,
|
Icon = ButtonIcon.GearCog,
|
||||||
@@ -80,7 +70,7 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
|||||||
FontType = FontType.MiedingerMed,
|
FontType = FontType.MiedingerMed,
|
||||||
TextFlags = TextFlags.Glare,
|
TextFlags = TextFlags.Glare,
|
||||||
TextColor = ColorHelper.GetColor(50),
|
TextColor = ColorHelper.GetColor(50),
|
||||||
TextOutlineColor = ColorHelper.GetColor(32) // Could also be Color 65
|
TextOutlineColor = ColorHelper.GetColor(32)
|
||||||
};
|
};
|
||||||
_slotCounterNode.AttachNode(this);
|
_slotCounterNode.AttachNode(this);
|
||||||
SlotCounterNode = _slotCounterNode;
|
SlotCounterNode = _slotCounterNode;
|
||||||
@@ -106,37 +96,6 @@ public unsafe class AddonSaddleBagWindow : InventoryAddonBase
|
|||||||
base.RefreshCategoriesCore(autosize);
|
base.RefreshCategoriesCore(autosize);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnUpdate(AtkUnitBase* addon)
|
|
||||||
{
|
|
||||||
if (RefreshQueued)
|
|
||||||
{
|
|
||||||
bool doAutosize = RefreshAutosizeQueued;
|
|
||||||
RefreshQueued = false;
|
|
||||||
RefreshAutosizeQueued = false;
|
|
||||||
|
|
||||||
RefreshCategoriesCore(doAutosize);
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnUpdate(addon);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
|
||||||
{
|
|
||||||
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
|
||||||
|
|
||||||
_inventoryState.RefreshFromGame();
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetSearchText(string searchText)
|
|
||||||
{
|
|
||||||
Services.Framework.RunOnTick(() =>
|
|
||||||
{
|
|
||||||
if (IsOpen) SearchInputNode.SearchString = searchText;
|
|
||||||
RefreshCategoriesCore(autosize: true);
|
|
||||||
}, delayTicks: 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnFinalize(AtkUnitBase* addon)
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
_isSetupComplete = false;
|
_isSetupComplete = false;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace AetherBags.Addons;
|
||||||
|
|
||||||
|
public interface IInventoryWindow
|
||||||
|
{
|
||||||
|
bool IsOpen { get; }
|
||||||
|
void Toggle();
|
||||||
|
void Close();
|
||||||
|
void ManualRefresh();
|
||||||
|
void SetSearchText(string searchText);
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ using KamiToolKit.Nodes;
|
|||||||
|
|
||||||
namespace AetherBags.Addons;
|
namespace AetherBags.Addons;
|
||||||
|
|
||||||
public abstract unsafe class InventoryAddonBase : NativeAddon
|
public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
||||||
{
|
{
|
||||||
protected readonly InventoryCategoryHoverCoordinator HoverCoordinator = new();
|
protected readonly InventoryCategoryHoverCoordinator HoverCoordinator = new();
|
||||||
protected readonly InventoryCategoryPinCoordinator PinCoordinator = new();
|
protected readonly InventoryCategoryPinCoordinator PinCoordinator = new();
|
||||||
@@ -41,6 +41,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
|||||||
protected const float ItemPadding = 4;
|
protected const float ItemPadding = 4;
|
||||||
protected const float FooterHeight = 28f;
|
protected const float FooterHeight = 28f;
|
||||||
protected const float FooterTopSpacing = 4f;
|
protected const float FooterTopSpacing = 4f;
|
||||||
|
protected const float SettingsButtonOffset = 48f;
|
||||||
|
|
||||||
protected bool RefreshQueued;
|
protected bool RefreshQueued;
|
||||||
protected bool RefreshAutosizeQueued;
|
protected bool RefreshAutosizeQueued;
|
||||||
@@ -72,6 +73,15 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void SetSearchText(string searchText)
|
||||||
|
{
|
||||||
|
Services.Framework.RunOnTick(() =>
|
||||||
|
{
|
||||||
|
if (IsOpen) SearchInputNode.SearchString = searchText;
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
}, delayTicks: 1);
|
||||||
|
}
|
||||||
|
|
||||||
public void RefreshFromLifecycle()
|
public void RefreshFromLifecycle()
|
||||||
{
|
{
|
||||||
if (!_isSetupComplete) return;
|
if (!_isSetupComplete) return;
|
||||||
@@ -135,6 +145,34 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected readonly struct HeaderLayout
|
||||||
|
{
|
||||||
|
public Vector2 SearchPosition { get; init; }
|
||||||
|
public Vector2 SearchSize { get; init; }
|
||||||
|
public float HeaderWidth { get; init; }
|
||||||
|
public float HeaderY { get; init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HeaderLayout CalculateHeaderLayout(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
var size = new Vector2(addon->Size.X / 2.0f, 28.0f);
|
||||||
|
var header = addon->WindowHeaderCollisionNode;
|
||||||
|
|
||||||
|
float headerW = header->Width;
|
||||||
|
float headerH = header->Height;
|
||||||
|
|
||||||
|
float x = header->X + (headerW - size.X) * 0.5f;
|
||||||
|
float y = header->Y + (headerH - size.Y) * 0.5f;
|
||||||
|
|
||||||
|
return new HeaderLayout
|
||||||
|
{
|
||||||
|
SearchPosition = new Vector2(x, y),
|
||||||
|
SearchSize = size,
|
||||||
|
HeaderWidth = headerW,
|
||||||
|
HeaderY = y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
protected void InitializeBackgroundDropTarget()
|
protected void InitializeBackgroundDropTarget()
|
||||||
{
|
{
|
||||||
BackgroundDropTarget = new DragDropNode
|
BackgroundDropTarget = new DragDropNode
|
||||||
@@ -306,6 +344,28 @@ public abstract unsafe class InventoryAddonBase : NativeAddon
|
|||||||
protected void ResizeWindow(float width, float height)
|
protected void ResizeWindow(float width, float height)
|
||||||
=> ResizeWindow(width, height, recalcLayout: true);
|
=> ResizeWindow(width, height, recalcLayout: true);
|
||||||
|
|
||||||
|
protected override void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
||||||
|
{
|
||||||
|
base.OnRequestedUpdate(addon, numberArrayData, stringArrayData);
|
||||||
|
|
||||||
|
InventoryState.RefreshFromGame();
|
||||||
|
RefreshCategoriesCore(autosize: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnUpdate(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
if (RefreshQueued)
|
||||||
|
{
|
||||||
|
bool doAutosize = RefreshAutosizeQueued;
|
||||||
|
RefreshQueued = false;
|
||||||
|
RefreshAutosizeQueued = false;
|
||||||
|
|
||||||
|
RefreshCategoriesCore(doAutosize);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnUpdate(addon);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnFinalize(AtkUnitBase* addon)
|
protected override void OnFinalize(AtkUnitBase* addon)
|
||||||
{
|
{
|
||||||
HoverSubscribed.Clear();
|
HoverSubscribed.Clear();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using AetherBags.Addons;
|
||||||
using AetherBags.Inventory.Context;
|
using AetherBags.Inventory.Context;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
||||||
@@ -9,32 +11,33 @@ public static unsafe class InventoryOrchestrator
|
|||||||
|
|
||||||
public static void RefreshAll(bool updateMaps = true)
|
public static void RefreshAll(bool updateMaps = true)
|
||||||
{
|
{
|
||||||
// 1. Update the mapping data (Context menus / Visual slots)
|
|
||||||
if (updateMaps)
|
if (updateMaps)
|
||||||
{
|
{
|
||||||
InventoryContextState.RefreshMaps();
|
InventoryContextState.RefreshMaps();
|
||||||
InventoryContextState.RefreshBlockedSlots();
|
InventoryContextState.RefreshBlockedSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Fetch the current context (Are we selling? Trading? Talking to a retainer?)
|
|
||||||
var agent = AgentInventory.Instance();
|
var agent = AgentInventory.Instance();
|
||||||
var contextId = agent != null ? agent->OpenTitleId : 0;
|
var contextId = agent != null ? agent->OpenTitleId : 0;
|
||||||
var notification = NotificationState.GetNotificationInfo(contextId);
|
var notification = NotificationState.GetNotificationInfo(contextId);
|
||||||
|
|
||||||
// 3. Trigger UI refreshes
|
|
||||||
Services.Framework.RunOnTick(() =>
|
Services.Framework.RunOnTick(() =>
|
||||||
{
|
{
|
||||||
if (System.AddonInventoryWindow.IsOpen)
|
if (System.AddonInventoryWindow.IsOpen)
|
||||||
{
|
|
||||||
System.AddonInventoryWindow.SetNotification(notification!);
|
System.AddonInventoryWindow.SetNotification(notification!);
|
||||||
System.AddonInventoryWindow.ManualRefresh();
|
|
||||||
|
foreach (var window in GetAllWindows())
|
||||||
|
{
|
||||||
|
if (window.IsOpen)
|
||||||
|
window.ManualRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.AddonSaddleBagWindow.IsOpen)
|
|
||||||
System.AddonSaddleBagWindow.ManualRefresh();
|
|
||||||
|
|
||||||
if (System.AddonRetainerWindow.IsOpen)
|
|
||||||
System.AddonRetainerWindow.ManualRefresh();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<IInventoryWindow> GetAllWindows()
|
||||||
|
{
|
||||||
|
yield return System.AddonInventoryWindow;
|
||||||
|
yield return System.AddonSaddleBagWindow;
|
||||||
|
yield return System.AddonRetainerWindow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ public sealed class InventoryFooterNode : SimpleComponentNode
|
|||||||
FontType = FontType.MiedingerMed,
|
FontType = FontType.MiedingerMed,
|
||||||
TextFlags = TextFlags.Glare,
|
TextFlags = TextFlags.Glare,
|
||||||
TextColor = ColorHelper.GetColor(50),
|
TextColor = ColorHelper.GetColor(50),
|
||||||
TextOutlineColor = ColorHelper.GetColor(32) // Could also be Color 65
|
TextOutlineColor = ColorHelper.GetColor(32)
|
||||||
};
|
};
|
||||||
_slotAmountTextNode.AttachNode(this);
|
_slotAmountTextNode.AttachNode(this);
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ namespace AetherBags;
|
|||||||
|
|
||||||
public unsafe class Plugin : IDalamudPlugin
|
public unsafe class Plugin : IDalamudPlugin
|
||||||
{
|
{
|
||||||
private static string HelpDescription => "Opens your inventory.";
|
|
||||||
|
|
||||||
private readonly CommandHandler _commandHandler;
|
private readonly CommandHandler _commandHandler;
|
||||||
private readonly InventoryHooks _inventoryHooks;
|
private readonly InventoryHooks _inventoryHooks;
|
||||||
private readonly InventoryLifecycles inventoryLifecycles;
|
private readonly InventoryLifecycles _inventoryLifecycles;
|
||||||
|
|
||||||
public Plugin(IDalamudPluginInterface pluginInterface)
|
public Plugin(IDalamudPluginInterface pluginInterface)
|
||||||
{
|
{
|
||||||
@@ -66,8 +64,6 @@ public unsafe class Plugin : IDalamudPlugin
|
|||||||
|
|
||||||
_commandHandler = new CommandHandler();
|
_commandHandler = new CommandHandler();
|
||||||
|
|
||||||
// Services.GameInventory.InventoryChanged += InventoryState.OnRawItemAdded;
|
|
||||||
|
|
||||||
Services.ClientState.Login += OnLogin;
|
Services.ClientState.Login += OnLogin;
|
||||||
Services.ClientState.Logout += OnLogout;
|
Services.ClientState.Logout += OnLogout;
|
||||||
|
|
||||||
@@ -76,7 +72,7 @@ public unsafe class Plugin : IDalamudPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
_inventoryHooks = new InventoryHooks();
|
_inventoryHooks = new InventoryHooks();
|
||||||
inventoryLifecycles = new InventoryLifecycles();
|
_inventoryLifecycles = new InventoryLifecycles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@@ -96,7 +92,7 @@ public unsafe class Plugin : IDalamudPlugin
|
|||||||
KamiToolKitLibrary.Dispose();
|
KamiToolKitLibrary.Dispose();
|
||||||
|
|
||||||
_inventoryHooks.Dispose();
|
_inventoryHooks.Dispose();
|
||||||
inventoryLifecycles.Dispose();
|
_inventoryLifecycles.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLogin()
|
private void OnLogin()
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ public class Services
|
|||||||
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
|
[PluginService] public static IPluginLog Logger { get; private set; } = null!;
|
||||||
[PluginService] public static INotificationManager NotificationManager { get; private set; } = null!;
|
[PluginService] public static INotificationManager NotificationManager { get; private set; } = null!;
|
||||||
[PluginService] public static IObjectTable ObjectTable { get; private set; } = null!;
|
[PluginService] public static IObjectTable ObjectTable { get; private set; } = null!;
|
||||||
// TODO: Remove cause temp
|
|
||||||
[PluginService] public static ISigScanner SigScanner { get; private set; } = null!;
|
[PluginService] public static ISigScanner SigScanner { get; private set; } = null!;
|
||||||
[PluginService] public static IGameInteropProvider GameInteropProvider { get; private set; } = null!;
|
[PluginService] public static IGameInteropProvider GameInteropProvider { get; private set; } = null!;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user