Add Color options

This commit is contained in:
Zeffuro
2025-12-23 07:40:53 +01:00
parent 5381c1f794
commit aedcc7953c
15 changed files with 404 additions and 18 deletions
+6 -1
View File
@@ -117,12 +117,17 @@ public class AddonInventoryWindow : NativeAddon
base.OnUpdate(addon); base.OnUpdate(addon);
} }
public void ManualRefresh() public void ManualInventoryRefresh()
{ {
InventoryState.RefreshFromGame(); InventoryState.RefreshFromGame();
RefreshCategoriesCore(true); RefreshCategoriesCore(true);
} }
public void ManualCurrencyRefresh()
{
_footerNode.RefreshCurrencies();
}
private void OnInventoryUpdate(AddonEvent type, AddonArgs args) private void OnInventoryUpdate(AddonEvent type, AddonArgs args)
{ {
InventoryState.RefreshFromGame(); InventoryState.RefreshFromGame();
+1
View File
@@ -28,5 +28,6 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>false</Visible> <Visible>false</Visible>
</Content> </Content>
<Content Include="Media\Textures\*.*" />
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -1,10 +1,14 @@
using System.Numerics; using System.Numerics;
using KamiToolKit.Classes; using KamiToolKit.Classes;
using SixLabors.ImageSharp.PixelFormats;
namespace AetherBags.Configuration; namespace AetherBags.Configuration;
public class CurrencySettings public class CurrencySettings
{ {
public bool Enabled { get; set; } = true;
public bool ColorWhenCapped { get; set; } = true;
public bool ColorWhenLimited { get; set; } = true;
public Vector4 DefaultColor { get; set; } = ColorHelper.GetColor(8); public Vector4 DefaultColor { get; set; } = ColorHelper.GetColor(8);
public Vector4 CappedColor { get; set; } = ColorHelper.GetColor(43); public Vector4 CappedColor { get; set; } = ColorHelper.GetColor(43);
public Vector4 LimitColor { get; set; } = ColorHelper.GetColor(17); public Vector4 LimitColor { get; set; } = ColorHelper.GetColor(17);
Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

+92
View File
@@ -0,0 +1,92 @@
using System;
using System.Numerics;
using KamiToolKit.Nodes;
using KamiToolKit.Premade.Addons;
namespace AetherBags.Nodes.Color;
public class ColorInputRow : HorizontalListNode
{
private readonly GridNode _gridNode;
private ColorPickerAddon? _colorPickerAddon;
private readonly LabelTextNode _labelTextNode;
private ColorPreviewButtonNode _colorPreview;
private Vector4 _initialColor;
public ColorInputRow()
{
InitializeColorPicker();
_initialColor = CurrentColor;
_colorPreview = new ColorPreviewButtonNode
{
Size = new Vector2(28),
Color = CurrentColor,
OnClick = () =>
{
_colorPickerAddon?.InitialColor = CurrentColor;
_colorPickerAddon?.DefaultColor = DefaultColor;
_colorPickerAddon?.Toggle();
_colorPickerAddon?.OnColorConfirmed = color =>
{
CurrentColor = color;
_colorPreview?.Color = color;
_initialColor = color;
OnColorConfirmed?.Invoke(color);
};
_colorPickerAddon?.OnColorCancelled = () => OnColorCanceled?.Invoke(_initialColor);
}
};
_colorPreview.AttachNode(this);
_labelTextNode = new LabelTextNode
{
Position = new Vector2(28, 0),
Size = Size with { Y = 24 },
String = Label ?? string.Empty,
};
_labelTextNode.AttachNode(this);
}
private void InitializeColorPicker() {
if (_colorPickerAddon is not null) return;
_colorPickerAddon = new ColorPickerAddon {
InternalName = "ColorPicker",
Title = "ColorPicker_AetherBags",
};
}
protected override void Dispose(bool disposing, bool isNativeDestructor) {
base.Dispose();
_colorPickerAddon?.Dispose();
_colorPickerAddon = null;
}
public required string Label
{
get;
set
{
field = value;
_labelTextNode.String = value;
}
}
public required Vector4 CurrentColor
{
get;
set
{
field = value;
_colorPreview.Color = value;
}
}
public required Vector4 DefaultColor { get; set; }
public Action<Vector4>? OnColorConfirmed { get; set; }
public Action<Vector4>? OnColorCanceled { get; set; }
public Action<Vector4>? OnColorChange { get; set; }
}
@@ -0,0 +1,43 @@
using System.Numerics;
using Dalamud.Game.Addon.Events.EventDataTypes;
using KamiToolKit.Nodes;
using ColorPreviewNode = AetherBags.Nodes.Color.ColorPreviewNode;
namespace AetherBags.Nodes.Color;
public class ColorPreviewButtonNode : ButtonBase {
private readonly ColorPreviewNode _colorPreview;
public ColorPreviewButtonNode() {
_colorPreview = new ColorPreviewNode {
IsVisible = true,
Position = Vector2.Zero,
Size = base.Size,
};
_colorPreview.AttachNode(this);
LoadTimelines();
InitializeComponentEvents();
}
public override Vector4 Color
{
get => _colorPreview.Color;
set => _colorPreview.Color = value;
}
public override Vector2 Size
{
get => base.Size;
set
{
base.Size = value;
_colorPreview.Size = value;
}
}
private void LoadTimelines()
=> LoadTwoPartTimelines(this, _colorPreview);
}
+112
View File
@@ -0,0 +1,112 @@
using System.Drawing;
using System.IO;
using System.Numerics;
using Dalamud.Interface;
using KamiToolKit.Classes;
using KamiToolKit.Nodes;
namespace AetherBags.Nodes.Color;
public class ColorPreviewNode : ResNode
{
private readonly BackgroundImageNode _colorBackground;
private readonly ImGuiImageNode _alphaLayer;
private readonly BackgroundImageNode _colorForeground;
private bool _isDisposed;
public ColorPreviewNode()
{
base.Size = new Vector2(64, 64);
_colorBackground = new BackgroundImageNode
{
IsVisible = true,
Color = KnownColor.Black.Vector(),
FitTexture = true,
};
_colorBackground.AttachNode(this);
_alphaLayer = new ImGuiImageNode
{
IsVisible = true,
TexturePath = GetAlphaTexturePath(),
WrapMode = WrapMode.Tile,
};
_alphaLayer.AttachNode(this);
_colorForeground = new BackgroundImageNode
{
IsVisible = true,
Color = KnownColor.White.Vector(),
FitTexture = true,
};
_colorForeground.AttachNode(this);
UpdateLayout();
}
public override Vector4 Color
{
get => _colorForeground.Color;
set => _colorForeground.Color = value;
}
public override Vector2 Size
{
get => base.Size;
set
{
base.Size = value;
UpdateLayout();
}
}
public BackgroundImageNode BackgroundNode => _colorBackground;
public BackgroundImageNode ForegroundNode => _colorForeground;
private void UpdateLayout()
{
const float backgroundPadding = 6f;
const float alphaPadding = 8f;
const float foregroundPadding = 8f;
var bgSize = base.Size - new Vector2(backgroundPadding * 2f);
var alphaSize = base.Size - new Vector2(alphaPadding * 2f);
var fgSize = base.Size - new Vector2(foregroundPadding * 2f);
_colorBackground.Size = bgSize;
_colorBackground.Position = new Vector2(backgroundPadding, backgroundPadding);
_alphaLayer.Size = alphaSize;
_alphaLayer.Position = new Vector2(alphaPadding, alphaPadding);
_colorForeground.Size = fgSize;
_colorForeground.Position = new Vector2(foregroundPadding, foregroundPadding);
}
private static string GetAlphaTexturePath()
{
var baseDir = Services.PluginInterface.AssemblyLocation.Directory!.FullName;
return Path.Combine(baseDir, "Media", "Textures", "alpha_background.png");
}
protected override void Dispose(bool disposing, bool isNativeDestructor)
{
if (_isDisposed)
{
base.Dispose(disposing, isNativeDestructor);
return;
}
_isDisposed = true;
if (disposing)
{
_colorBackground.Dispose();
_alphaLayer.Dispose();
_colorForeground.Dispose();
}
base.Dispose(disposing, isNativeDestructor);
}
}
@@ -0,0 +1,126 @@
using System.Drawing;
using System.Numerics;
using AetherBags.Configuration;
using AetherBags.Nodes.Color;
using Dalamud.Interface;
using KamiToolKit.Classes;
using KamiToolKit.Nodes;
using KamiToolKit.Premade.Addons;
using KamiToolKit.Premade.Nodes;
namespace AetherBags.Nodes.Configuration.Currency;
public sealed class CurrencyConfigurationNode : TabbedVerticalListNode
{
public CurrencyConfigurationNode()
{
CurrencySettings config = System.Config.Currency;
LabelTextNode titleNode = new LabelTextNode
{
Size = Size with { Y = 18 },
String = "Currency Configuration",
TextColor = ColorHelper.GetColor(2),
TextOutlineColor = ColorHelper.GetColor(0),
};
AddNode(titleNode);
AddTab(1);
CheckboxNode currencyEnabledCheckbox = new CheckboxNode
{
Size = Size with { Y = 18 },
IsVisible = true,
String = "Show Currency",
IsChecked = config.Enabled,
OnClick = isChecked =>
{
config.Enabled = isChecked;
RefreshCurrency();
}
};
AddNode(currencyEnabledCheckbox);
AddTab(1);
ColorInputRow defaultCurrencyColorNode = new ColorInputRow
{
Label = "Default Currency Color",
Size = new Vector2(300, 24),
CurrentColor = config.DefaultColor,
DefaultColor = new CurrencySettings().DefaultColor,
OnColorConfirmed = color =>
{
config.DefaultColor = color;
RefreshCurrency();
},
};
AddNode(defaultCurrencyColorNode);
AddNode();
CheckboxNode cappedEnabledCheckbox = new CheckboxNode
{
Size = Size with { Y = 18 },
IsVisible = true,
String = "Color When Capped",
IsChecked = config.ColorWhenCapped,
OnClick = isChecked =>
{
config.ColorWhenCapped = isChecked;
RefreshCurrency();
}
};
AddNode(cappedEnabledCheckbox);
AddTab(1);
ColorInputRow cappedCurrencyColorNode = new ColorInputRow
{
Label = "Capped Currency Color",
Size = new Vector2(300, 24),
CurrentColor = config.CappedColor,
DefaultColor = new CurrencySettings().CappedColor,
OnColorConfirmed = color =>
{
config.CappedColor = color;
RefreshCurrency();
},
};
AddNode(cappedCurrencyColorNode);
SubtractTab(1);
CheckboxNode limitedEnabledCheckbox = new CheckboxNode
{
Size = Size with { Y = 18 },
IsVisible = true,
String = "Color Weekly Limit",
IsChecked = config.ColorWhenLimited,
OnClick = isChecked =>
{
config.ColorWhenLimited = isChecked;
RefreshCurrency();
}
};
AddNode(limitedEnabledCheckbox);
AddTab(1);
ColorInputRow limitCurrencyColorNode = new ColorInputRow
{
Label = "Limit Currency Color",
Size = new Vector2(300, 24),
CurrentColor = config.LimitColor,
DefaultColor = new CurrencySettings().LimitColor,
OnColorConfirmed = color =>
{
config.LimitColor = color;
RefreshCurrency();
},
};
AddNode(limitCurrencyColorNode);
}
private void RefreshCurrency() => System.AddonInventoryWindow.ManualCurrencyRefresh();
}
@@ -1,8 +1,15 @@
using AetherBags.Nodes.Configuration.Currency;
using KamiToolKit.Nodes; using KamiToolKit.Nodes;
namespace AetherBags.Nodes.Configuration; namespace AetherBags.Nodes.Configuration;
public class CurrencyScrollingAreaNode : ScrollingAreaNode<VerticalListNode> public sealed class CurrencyScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
{ {
public CurrencyScrollingAreaNode()
{
ContentNode.AddNode(new CurrencyConfigurationNode
{
Size = Size
});
}
} }
@@ -46,5 +46,5 @@ public sealed class GeneralScrollingAreaNode : ScrollingAreaNode<VerticalListNod
ContentNode.AddNode(_debugCheckboxNode); ContentNode.AddNode(_debugCheckboxNode);
} }
private void RefreshInventory() => System.AddonInventoryWindow.ManualRefresh(); private void RefreshInventory() => System.AddonInventoryWindow.ManualInventoryRefresh();
} }
@@ -32,7 +32,7 @@ internal sealed class CompactLookaheadNode : SimpleComponentNode
OnValueUpdate = value => OnValueUpdate = value =>
{ {
config.CompactLookahead = value; config.CompactLookahead = value;
System.AddonInventoryWindow.ManualRefresh(); System.AddonInventoryWindow.ManualInventoryRefresh();
} }
}; };
CompactLookahead.ComponentBase->SetEnabledState(config.CompactPackingEnabled); CompactLookahead.ComponentBase->SetEnabledState(config.CompactPackingEnabled);
@@ -38,7 +38,7 @@ internal class LayoutConfigurationNode : TabbedVerticalListNode
_preferLargestFitCheckboxNode.IsEnabled = isChecked; _preferLargestFitCheckboxNode.IsEnabled = isChecked;
_useStableInsertCheckboxNode.IsEnabled = isChecked; _useStableInsertCheckboxNode.IsEnabled = isChecked;
_compactLookaheadNode.CompactLookahead.ComponentBase->SetEnabledState(isChecked); _compactLookaheadNode.CompactLookahead.ComponentBase->SetEnabledState(isChecked);
System.AddonInventoryWindow.ManualRefresh(); System.AddonInventoryWindow.ManualInventoryRefresh();
} }
}; };
AddNode(compactPackingCheckboxNode); AddNode(compactPackingCheckboxNode);
@@ -54,7 +54,7 @@ internal class LayoutConfigurationNode : TabbedVerticalListNode
OnClick = isChecked => OnClick = isChecked =>
{ {
config.CompactPreferLargestFit = isChecked; config.CompactPreferLargestFit = isChecked;
System.AddonInventoryWindow.ManualRefresh(); System.AddonInventoryWindow.ManualInventoryRefresh();
} }
}; };
AddNode(_preferLargestFitCheckboxNode); AddNode(_preferLargestFitCheckboxNode);
@@ -69,7 +69,7 @@ internal class LayoutConfigurationNode : TabbedVerticalListNode
OnClick = isChecked => OnClick = isChecked =>
{ {
config.CompactStableInsert = isChecked; config.CompactStableInsert = isChecked;
System.AddonInventoryWindow.ManualRefresh(); System.AddonInventoryWindow.ManualInventoryRefresh();
} }
}; };
AddNode(_useStableInsertCheckboxNode); AddNode(_useStableInsertCheckboxNode);
+3
View File
@@ -34,6 +34,7 @@ public sealed class InventoryFooterNode : SimpleComponentNode
{ {
Position = new Vector2(0, 0), Position = new Vector2(0, 0),
Size = new Vector2(120, 28), Size = new Vector2(120, 28),
IsVisible = System.Config.Currency.Enabled
}; };
_currencyListNode.AttachNode(this); _currencyListNode.AttachNode(this);
@@ -42,6 +43,8 @@ public sealed class InventoryFooterNode : SimpleComponentNode
public void RefreshCurrencies() public void RefreshCurrencies()
{ {
_currencyListNode.IsVisible = System.Config.Currency.Enabled;
IReadOnlyList<CurrencyInfo> currencyInfoList = InventoryState.GetCurrencyInfoList([1, 28, 0xFFFF_FFFE, 0xFFFF_FFFD]); IReadOnlyList<CurrencyInfo> currencyInfoList = InventoryState.GetCurrencyInfoList([1, 28, 0xFFFF_FFFE, 0xFFFF_FFFD]);
_currencyListNode.SyncWithListDataByKey<CurrencyInfo, CurrencyNode, uint>( _currencyListNode.SyncWithListDataByKey<CurrencyInfo, CurrencyNode, uint>(
dataList: currencyInfoList, dataList: currencyInfoList,
+2 -9
View File
@@ -17,15 +17,8 @@ public class LabeledDropdownNode : SimpleComponentNode {
}; };
_gridNode.AttachNode(this); _gridNode.AttachNode(this);
_labelNode = new TextNode { _labelNode = new LabelTextNode {
AlignmentType = AlignmentType.Bottom, String = String.Empty,
FontType = FontType.Axis,
FontSize = 14,
LineSpacing = 14,
TextColor = ColorHelper.GetColor(8),
TextOutlineColor = ColorHelper.GetColor(7),
TextFlags = TextFlags.Edge | TextFlags.AutoAdjustNodeSize,
String = string.Empty,
}; };
_labelNode.AttachNode(_gridNode[0, 0]); _labelNode.AttachNode(_gridNode[0, 0]);
+1 -1
View File
@@ -88,7 +88,7 @@ public class Plugin : IDalamudPlugin
{ {
// Manually import from SortaKinda for testing until we have a proper config window // Manually import from SortaKinda for testing until we have a proper config window
ImportExportResetHelper.TryImportSortaKindaFromClipboard(true); ImportExportResetHelper.TryImportSortaKindaFromClipboard(true);
System.AddonInventoryWindow.ManualRefresh(); System.AddonInventoryWindow.ManualInventoryRefresh();
} }
break; break;
} }