Fixes category nodes going beyond the grid
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using AetherBags.AddonLifecycles;
|
|
||||||
using AetherBags.Configuration;
|
using AetherBags.Configuration;
|
||||||
using AetherBags.Helpers;
|
using AetherBags.Helpers;
|
||||||
using AetherBags.Inventory;
|
using AetherBags.Inventory;
|
||||||
@@ -43,8 +42,8 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
protected virtual float MaxWindowHeight => 1000;
|
protected virtual float MaxWindowHeight => 1000;
|
||||||
|
|
||||||
protected const float CategorySpacing = 12;
|
protected const float CategorySpacing = 12;
|
||||||
protected const float ItemSize = 40;
|
protected const float ItemSize = 42;
|
||||||
protected const float ItemPadding = 4;
|
protected const float ItemPadding = 5;
|
||||||
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 const float SettingsButtonOffset = 48f;
|
||||||
@@ -172,7 +171,7 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
string dataFilter = config.SearchMode == SearchMode.Filter ? searchText : string.Empty;
|
string dataFilter = config.SearchMode == SearchMode.Filter ? searchText : string.Empty;
|
||||||
var categories = InventoryState.GetCategories(dataFilter);
|
var categories = InventoryState.GetCategories(dataFilter);
|
||||||
|
|
||||||
float maxContentWidth = MaxWindowWidth - (ContentStartPosition.X * 2);
|
float maxContentWidth = CategoriesNode.Width > 0 ? CategoriesNode.Width : ContentSize.X;
|
||||||
int maxItemsPerLine = CalculateOptimalItemsPerLine(maxContentWidth);
|
int maxItemsPerLine = CalculateOptimalItemsPerLine(maxContentWidth);
|
||||||
|
|
||||||
CategoriesNode.SyncWithListDataByKey<CategorizedInventory, InventoryCategoryNode, uint>(
|
CategoriesNode.SyncWithListDataByKey<CategorizedInventory, InventoryCategoryNode, uint>(
|
||||||
@@ -181,10 +180,11 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
getKeyFromNode: node => node.CategorizedInventory.Key,
|
getKeyFromNode: node => node.CategorizedInventory.Key,
|
||||||
updateNode: (node, data) =>
|
updateNode: (node, data) =>
|
||||||
{
|
{
|
||||||
|
node.MaxWidth = maxContentWidth;
|
||||||
node.SetCategoryData(data, Math.Min(data.Items.Count, maxItemsPerLine));
|
node.SetCategoryData(data, Math.Min(data.Items.Count, maxItemsPerLine));
|
||||||
node.RefreshNodeVisuals();
|
node.RefreshNodeVisuals();
|
||||||
},
|
},
|
||||||
createNodeMethod: _ => CreateCategoryNode());
|
createNodeMethod: _ => CreateCategoryNode(maxContentWidth));
|
||||||
|
|
||||||
if (HasPinning)
|
if (HasPinning)
|
||||||
{
|
{
|
||||||
@@ -254,11 +254,12 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
BackgroundDropTarget.AttachNode(this);
|
BackgroundDropTarget.AttachNode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual InventoryCategoryNode CreateCategoryNode()
|
protected virtual InventoryCategoryNode CreateCategoryNode(float? maxWidth = null)
|
||||||
{
|
{
|
||||||
return new InventoryCategoryNode
|
return new InventoryCategoryNode
|
||||||
{
|
{
|
||||||
Size = ContentSize with { Y = 120 },
|
Size = ContentSize with { Y = 120 },
|
||||||
|
MaxWidth = maxWidth,
|
||||||
OnRefreshRequested = ManualRefresh,
|
OnRefreshRequested = ManualRefresh,
|
||||||
OnDragEnd = () => InventoryOrchestrator.RefreshAll(updateMaps: true),
|
OnDragEnd = () => InventoryOrchestrator.RefreshAll(updateMaps: true),
|
||||||
};
|
};
|
||||||
@@ -340,6 +341,20 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
|
|
||||||
CategoriesNode.Position = contentPos;
|
CategoriesNode.Position = contentPos;
|
||||||
CategoriesNode.Size = new Vector2(contentSize.X, gridH);
|
CategoriesNode.Size = new Vector2(contentSize.X, gridH);
|
||||||
|
|
||||||
|
UpdateCategoryMaxWidths(contentSize.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCategoryMaxWidths(float maxWidth)
|
||||||
|
{
|
||||||
|
foreach (var node in CategoriesNode.Nodes)
|
||||||
|
{
|
||||||
|
if (node is InventoryCategoryNode categoryNode && categoryNode.MaxWidth != maxWidth)
|
||||||
|
{
|
||||||
|
categoryNode.MaxWidth = maxWidth;
|
||||||
|
categoryNode.RecalculateSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AutoSizeWindow()
|
protected virtual void AutoSizeWindow()
|
||||||
@@ -376,6 +391,8 @@ public abstract unsafe class InventoryAddonBase : NativeAddon, IInventoryWindow
|
|||||||
CategoriesNode.Position = ContentStartPosition;
|
CategoriesNode.Position = ContentStartPosition;
|
||||||
CategoriesNode.Size = new Vector2(contentWidth, gridBudget);
|
CategoriesNode.Size = new Vector2(contentWidth, gridBudget);
|
||||||
|
|
||||||
|
UpdateCategoryMaxWidths(contentWidth);
|
||||||
|
|
||||||
CategoriesNode.RecalculateLayout();
|
CategoriesNode.RecalculateLayout();
|
||||||
|
|
||||||
float requiredGridHeight = CategoriesNode.GetRequiredHeight();
|
float requiredGridHeight = CategoriesNode.GetRequiredHeight();
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
private const float MinWidth = 40;
|
private const float MinWidth = 40;
|
||||||
|
|
||||||
private float? _fixedWidth;
|
private float? _fixedWidth;
|
||||||
|
private float? _maxWidth;
|
||||||
private int _hoverRefs;
|
private int _hoverRefs;
|
||||||
private bool _headerSuppressed;
|
private bool _headerSuppressed;
|
||||||
private bool _headerExpanded;
|
private bool _headerExpanded;
|
||||||
@@ -40,6 +41,7 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
private int _lastItemCount;
|
private int _lastItemCount;
|
||||||
private ulong _lastItemsHash;
|
private ulong _lastItemsHash;
|
||||||
private int _lastItemsPerLine;
|
private int _lastItemsPerLine;
|
||||||
|
private float? _lastMaxWidth;
|
||||||
|
|
||||||
public event Action<InventoryCategoryNode, bool>? HeaderHoverChanged;
|
public event Action<InventoryCategoryNode, bool>? HeaderHoverChanged;
|
||||||
public Action? OnRefreshRequested { get; set; }
|
public Action? OnRefreshRequested { get; set; }
|
||||||
@@ -88,6 +90,7 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
{
|
{
|
||||||
bool categoryChanged = data.Key != _lastCategoryKey;
|
bool categoryChanged = data.Key != _lastCategoryKey;
|
||||||
bool itemsPerLineChanged = itemsPerLine != _lastItemsPerLine;
|
bool itemsPerLineChanged = itemsPerLine != _lastItemsPerLine;
|
||||||
|
bool maxWidthChanged = _maxWidth != _lastMaxWidth;
|
||||||
|
|
||||||
ulong itemsHash = ComputeItemsHash(CollectionsMarshal.AsSpan(data.Items));
|
ulong itemsHash = ComputeItemsHash(CollectionsMarshal.AsSpan(data.Items));
|
||||||
bool itemsChanged = data.Items.Count != _lastItemCount || itemsHash != _lastItemsHash;
|
bool itemsChanged = data.Items.Count != _lastItemCount || itemsHash != _lastItemsHash;
|
||||||
@@ -96,6 +99,7 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
_lastItemCount = data.Items.Count;
|
_lastItemCount = data.Items.Count;
|
||||||
_lastItemsHash = itemsHash;
|
_lastItemsHash = itemsHash;
|
||||||
_lastItemsPerLine = itemsPerLine;
|
_lastItemsPerLine = itemsPerLine;
|
||||||
|
_lastMaxWidth = _maxWidth;
|
||||||
|
|
||||||
_categorizedInventory = data;
|
_categorizedInventory = data;
|
||||||
|
|
||||||
@@ -120,7 +124,7 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
_itemGridNode.ItemsPerLine = itemsPerLine;
|
_itemGridNode.ItemsPerLine = itemsPerLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (categoryChanged || itemsChanged || itemsPerLineChanged)
|
if (categoryChanged || itemsChanged || itemsPerLineChanged || maxWidthChanged)
|
||||||
{
|
{
|
||||||
RecalculateSize();
|
RecalculateSize();
|
||||||
}
|
}
|
||||||
@@ -160,6 +164,12 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float? MaxWidth
|
||||||
|
{
|
||||||
|
get => _maxWidth;
|
||||||
|
set => _maxWidth = value;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool IsPinnedInConfig => CategorizedInventory.Category?.IsPinned ?? false;
|
public override bool IsPinnedInConfig => CategorizedInventory.Category?.IsPinned ?? false;
|
||||||
|
|
||||||
public void BeginHeaderHover()
|
public void BeginHeaderHover()
|
||||||
@@ -224,13 +234,19 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecalculateSize()
|
public void RecalculateSize()
|
||||||
{
|
{
|
||||||
int itemCount = CategorizedInventory.Items.Count;
|
int itemCount = CategorizedInventory.Items.Count;
|
||||||
|
|
||||||
|
float cellW = _itemGridNode.Nodes.Count > 0 ? _itemGridNode.Nodes[0].Width : FallbackItemSize;
|
||||||
|
float cellH = _itemGridNode.Nodes.Count > 0 ? _itemGridNode.Nodes[0].Height : FallbackItemSize;
|
||||||
|
float hPad = _itemGridNode.HorizontalPadding;
|
||||||
|
float vPad = _itemGridNode.VerticalPadding;
|
||||||
|
|
||||||
if (itemCount == 0)
|
if (itemCount == 0)
|
||||||
{
|
{
|
||||||
float width = _fixedWidth ?? MinWidth;
|
float width = _fixedWidth ?? MinWidth;
|
||||||
|
if (_maxWidth.HasValue) width = Math.Min(width, _maxWidth.Value);
|
||||||
Size = new Vector2(width, HeaderHeight);
|
Size = new Vector2(width, HeaderHeight);
|
||||||
_baseHeaderWidth = width;
|
_baseHeaderWidth = width;
|
||||||
_itemGridNode.Position = new Vector2(0, HeaderHeight);
|
_itemGridNode.Position = new Vector2(0, HeaderHeight);
|
||||||
@@ -240,21 +256,36 @@ public class InventoryCategoryNode : InventoryCategoryNodeBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
int itemsPerLine = Math.Max(1, _itemGridNode.ItemsPerLine);
|
int itemsPerLine = Math.Max(1, _itemGridNode.ItemsPerLine);
|
||||||
|
|
||||||
|
float minUsableWidth = cellW;
|
||||||
|
if (_maxWidth.HasValue && _fixedWidth is null && _maxWidth.Value >= minUsableWidth)
|
||||||
|
{
|
||||||
|
int maxColumns = (int)MathF.Floor((_maxWidth.Value + hPad) / (cellW + hPad));
|
||||||
|
maxColumns = Math.Max(1, maxColumns);
|
||||||
|
|
||||||
|
float widthNeeded = maxColumns * cellW + (maxColumns - 1) * hPad;
|
||||||
|
if (widthNeeded > _maxWidth.Value && maxColumns > 1)
|
||||||
|
maxColumns--;
|
||||||
|
|
||||||
|
itemsPerLine = Math.Min(itemsPerLine, maxColumns);
|
||||||
|
}
|
||||||
|
|
||||||
int rows = (itemCount + itemsPerLine - 1) / itemsPerLine;
|
int rows = (itemCount + itemsPerLine - 1) / itemsPerLine;
|
||||||
int actualColumns = Math.Min(itemCount, itemsPerLine);
|
int actualColumns = Math.Min(itemCount, itemsPerLine);
|
||||||
|
|
||||||
float cellW = _itemGridNode.Nodes.Count > 0 ? _itemGridNode.Nodes[0].Width : FallbackItemSize;
|
|
||||||
float cellH = _itemGridNode.Nodes.Count > 0 ? _itemGridNode.Nodes[0].Height : FallbackItemSize;
|
|
||||||
|
|
||||||
float hPad = _itemGridNode.HorizontalPadding;
|
|
||||||
float vPad = _itemGridNode.VerticalPadding;
|
|
||||||
|
|
||||||
float calculatedWidth = _fixedWidth ?? Math.Max(MinWidth, actualColumns * cellW + (actualColumns - 1) * hPad);
|
float calculatedWidth = _fixedWidth ?? Math.Max(MinWidth, actualColumns * cellW + (actualColumns - 1) * hPad);
|
||||||
|
|
||||||
|
if (_maxWidth.HasValue && _fixedWidth is null && _maxWidth.Value >= minUsableWidth)
|
||||||
|
calculatedWidth = Math.Min(calculatedWidth, _maxWidth.Value);
|
||||||
|
|
||||||
float height = HeaderHeight + rows * cellH + (rows - 1) * vPad;
|
float height = HeaderHeight + rows * cellH + (rows - 1) * vPad;
|
||||||
|
|
||||||
Size = new Vector2(calculatedWidth, height);
|
Size = new Vector2(calculatedWidth, height);
|
||||||
_itemGridNode.Position = new Vector2(0, HeaderHeight);
|
_itemGridNode.Position = new Vector2(0, HeaderHeight);
|
||||||
_itemGridNode.Size = new Vector2(calculatedWidth, height - HeaderHeight);
|
_itemGridNode.Size = new Vector2(calculatedWidth, height - HeaderHeight);
|
||||||
|
|
||||||
|
if (_itemGridNode.ItemsPerLine != itemsPerLine)
|
||||||
|
_itemGridNode.ItemsPerLine = itemsPerLine;
|
||||||
_baseHeaderWidth = calculatedWidth;
|
_baseHeaderWidth = calculatedWidth;
|
||||||
|
|
||||||
ApplyHeaderVisualStateAndSize();
|
ApplyHeaderVisualStateAndSize();
|
||||||
|
|||||||
Reference in New Issue
Block a user