Initial window + settings for categories
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using AetherBags.Nodes.Configuration.Category;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using KamiToolKit;
|
||||||
|
using KamiToolKit.Classes;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
using KamiToolKit.Premade.Nodes;
|
||||||
|
|
||||||
|
namespace AetherBags.Addons;
|
||||||
|
|
||||||
|
public class AddonCategoryConfigurationWindow : NativeAddon
|
||||||
|
{
|
||||||
|
private ModifyListNode<CategoryWrapper>? _selectionListNode;
|
||||||
|
private VerticalLineNode? _separatorLine;
|
||||||
|
private CategoryConfigurationNode? _configNode;
|
||||||
|
private TextNode? _nothingSelectedTextNode;
|
||||||
|
|
||||||
|
protected override unsafe void OnSetup(AtkUnitBase* addon)
|
||||||
|
{
|
||||||
|
List<CategoryWrapper> categoryDefinitionsWrappers = System.Config.Categories.UserCategories
|
||||||
|
.Select(categoryDefinition => new CategoryWrapper(categoryDefinition))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
_selectionListNode = new ModifyListNode<CategoryWrapper> {
|
||||||
|
Position = ContentStartPosition,
|
||||||
|
Size = new Vector2(250.0f, ContentSize.Y),
|
||||||
|
SelectionOptions = categoryDefinitionsWrappers,
|
||||||
|
OnOptionChanged = OnOptionChanged,
|
||||||
|
};
|
||||||
|
_selectionListNode.AttachNode(this);
|
||||||
|
|
||||||
|
_separatorLine = new VerticalLineNode {
|
||||||
|
Position = ContentStartPosition + new Vector2(250.0f + 8.0f, 0.0f),
|
||||||
|
Size = new Vector2(4.0f, ContentSize.Y),
|
||||||
|
};
|
||||||
|
_separatorLine.AttachNode(this);
|
||||||
|
|
||||||
|
_nothingSelectedTextNode = new TextNode {
|
||||||
|
Position = ContentStartPosition + new Vector2(250.0f + 16.0f, 0.0f),
|
||||||
|
Size = ContentSize - new Vector2(250.0f + 16.0f, 0.0f),
|
||||||
|
AlignmentType = AlignmentType.Center,
|
||||||
|
TextFlags = TextFlags.WordWrap | TextFlags.MultiLine,
|
||||||
|
FontSize = 14,
|
||||||
|
LineSpacing = 22,
|
||||||
|
FontType = FontType.Axis,
|
||||||
|
String = "Please select a category on the left or add one.",
|
||||||
|
TextColor = ColorHelper.GetColor(1),
|
||||||
|
};
|
||||||
|
_nothingSelectedTextNode.AttachNode(this);
|
||||||
|
|
||||||
|
_configNode = new CategoryConfigurationNode {
|
||||||
|
Position = ContentStartPosition + new Vector2(250.0f + 16.0f, 0.0f),
|
||||||
|
Size = ContentSize - new Vector2(250.0f + 16.0f, 0.0f),
|
||||||
|
IsVisible = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
_configNode.AttachNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOptionChanged(CategoryWrapper? newOption) {
|
||||||
|
if (_configNode is null) return;
|
||||||
|
|
||||||
|
_configNode.IsVisible = newOption is not null;
|
||||||
|
_nothingSelectedTextNode?.IsVisible = newOption is null;
|
||||||
|
|
||||||
|
_configNode.ConfigurationOption = newOption;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using AetherBags.Nodes.Configuration;
|
using AetherBags.Nodes.Configuration;
|
||||||
|
using AetherBags.Nodes.Configuration.Category;
|
||||||
|
using AetherBags.Nodes.Configuration.Currency;
|
||||||
|
using AetherBags.Nodes.Configuration.General;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
using KamiToolKit;
|
using KamiToolKit;
|
||||||
using KamiToolKit.Nodes;
|
using KamiToolKit.Nodes;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using AetherBags.Configuration;
|
||||||
|
using KamiToolKit.Premade;
|
||||||
|
|
||||||
|
namespace AetherBags.Addons;
|
||||||
|
|
||||||
|
public class CategoryWrapper(UserCategoryDefinition categoryDefinition) : IInfoNodeData
|
||||||
|
{
|
||||||
|
public UserCategoryDefinition? CategoryDefinition { get; } = categoryDefinition;
|
||||||
|
|
||||||
|
public string GetLabel() {
|
||||||
|
|
||||||
|
return CategoryDefinition!.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetSubLabel() {
|
||||||
|
return CategoryDefinition!.Enabled ? "Enabled" : "Disabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint? GetId() => null;
|
||||||
|
|
||||||
|
public uint? GetIconId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string? GetTexturePath()
|
||||||
|
=> null;
|
||||||
|
|
||||||
|
public int Compare(IInfoNodeData other, string sortingMode) {
|
||||||
|
if (other is not CategoryWrapper otherWrapper) return 0;
|
||||||
|
|
||||||
|
return CategoryDefinition!.Order.CompareTo(otherWrapper.CategoryDefinition!.Order);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ public class CategorySettings
|
|||||||
|
|
||||||
public class UserCategoryDefinition
|
public class UserCategoryDefinition
|
||||||
{
|
{
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
public string Id { get; set; } = Guid.NewGuid().ToString("N");
|
public string Id { get; set; } = Guid.NewGuid().ToString("N");
|
||||||
public string Name { get; set; } = "New Category";
|
public string Name { get; set; } = "New Category";
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public static unsafe class InventoryState
|
|||||||
InventoryStackMode stackMode = config.General.StackMode;
|
InventoryStackMode stackMode = config.General.StackMode;
|
||||||
bool userCategoriesEnabled = config.Categories.UserCategoriesEnabled;
|
bool userCategoriesEnabled = config.Categories.UserCategoriesEnabled;
|
||||||
bool gameCategoriesEnabled = config.Categories.GameCategoriesEnabled;
|
bool gameCategoriesEnabled = config.Categories.GameCategoriesEnabled;
|
||||||
List<UserCategoryDefinition> userCategories = config.Categories.UserCategories;
|
List<UserCategoryDefinition> userCategories = config.Categories.UserCategories.Where(category => category.Enabled).ToList();
|
||||||
|
|
||||||
Services.Logger.DebugOnly($"RefreshFromGame StackMode={stackMode}");
|
Services.Logger.DebugOnly($"RefreshFromGame StackMode={stackMode}");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
|
using AetherBags.Addons;
|
||||||
|
using AetherBags.Configuration;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
using KamiToolKit.Premade.Nodes;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
|
namespace AetherBags.Nodes.Configuration.Category;
|
||||||
|
|
||||||
|
public class CategoryConfigurationNode : ConfigNode<CategoryWrapper> {
|
||||||
|
private readonly ScrollingAreaNode<VerticalListNode> _categoryList;
|
||||||
|
private CategoryDefinitionConfigurationNode? _activeNode;
|
||||||
|
|
||||||
|
public CategoryConfigurationNode() {
|
||||||
|
_categoryList = new ScrollingAreaNode<VerticalListNode> {
|
||||||
|
ContentHeight = 100.0f,
|
||||||
|
AutoHideScrollBar = true,
|
||||||
|
};
|
||||||
|
_categoryList.ContentNode.FitContents = true;
|
||||||
|
_categoryList.AttachNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OptionChanged(CategoryWrapper? option) {
|
||||||
|
if (option?.CategoryDefinition is null) {
|
||||||
|
_categoryList.IsVisible = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_categoryList.IsVisible = true;
|
||||||
|
|
||||||
|
if (_activeNode is null) {
|
||||||
|
_activeNode = new CategoryDefinitionConfigurationNode(option.CategoryDefinition) {
|
||||||
|
Size = new Vector2(_categoryList.ContentNode.Width, 0f),
|
||||||
|
};
|
||||||
|
_categoryList.ContentNode.AddNode(_activeNode);
|
||||||
|
} else {
|
||||||
|
_activeNode.SetCategory(option.CategoryDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
_categoryList.ContentNode.RecalculateLayout();
|
||||||
|
_categoryList.ContentHeight = _categoryList.ContentNode.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnSizeChanged() {
|
||||||
|
base.OnSizeChanged();
|
||||||
|
_categoryList.Size = Size;
|
||||||
|
_categoryList.ContentNode.Width = Width;
|
||||||
|
|
||||||
|
foreach (var node in _categoryList.ContentNode.GetNodes<CategoryDefinitionConfigurationNode>()) {
|
||||||
|
node.Width = Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using AetherBags.Configuration;
|
||||||
|
using AetherBags.Nodes.Color;
|
||||||
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
using Action = Lumina.Excel.Sheets.Action;
|
||||||
|
|
||||||
|
namespace AetherBags.Nodes.Configuration.Category;
|
||||||
|
|
||||||
|
public sealed class CategoryDefinitionConfigurationNode : VerticalListNode {
|
||||||
|
private readonly CheckboxNode enabledCheckbox;
|
||||||
|
private readonly TextInputNode nameInputNode;
|
||||||
|
private readonly TextInputNode descriptionInputNode;
|
||||||
|
private readonly ColorInputRow colorInputNode;
|
||||||
|
|
||||||
|
public UserCategoryDefinition CategoryDefinition { get; private set; }
|
||||||
|
|
||||||
|
public CategoryDefinitionConfigurationNode(UserCategoryDefinition categoryDefinition) {
|
||||||
|
CategoryDefinition = categoryDefinition;
|
||||||
|
|
||||||
|
FirstItemSpacing = 35.0f;
|
||||||
|
ItemSpacing = 5.0f;
|
||||||
|
|
||||||
|
enabledCheckbox = new CheckboxNode {
|
||||||
|
IsChecked = CategoryDefinition.Enabled,
|
||||||
|
OnClick = isChecked => CategoryDefinition.Enabled = isChecked,
|
||||||
|
};
|
||||||
|
AddNode(enabledCheckbox);
|
||||||
|
|
||||||
|
colorInputNode = new ColorInputRow
|
||||||
|
{
|
||||||
|
Label = "Color",
|
||||||
|
CurrentColor = CategoryDefinition.Color,
|
||||||
|
DefaultColor = new UserCategoryDefinition().Color,
|
||||||
|
OnColorConfirmed = color => CategoryDefinition.Color = color,
|
||||||
|
// OnColorChange = color => CategoryDefinition.Color = color,
|
||||||
|
OnColorCanceled = color => CategoryDefinition.Color = color,
|
||||||
|
};
|
||||||
|
AddNode(colorInputNode);
|
||||||
|
|
||||||
|
nameInputNode = new TextInputNode
|
||||||
|
{
|
||||||
|
String = CategoryDefinition.Name,
|
||||||
|
OnInputComplete = name => CategoryDefinition.Name = name.ExtractText()
|
||||||
|
};
|
||||||
|
AddNode(nameInputNode);
|
||||||
|
|
||||||
|
descriptionInputNode = new TextInputNode
|
||||||
|
{
|
||||||
|
String = CategoryDefinition.Description,
|
||||||
|
OnInputComplete = name => CategoryDefinition.Description = name.ExtractText()
|
||||||
|
};
|
||||||
|
AddNode(descriptionInputNode);
|
||||||
|
|
||||||
|
// TODO: Add Rules
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCategory(UserCategoryDefinition newCategory) {
|
||||||
|
CategoryDefinition = newCategory;
|
||||||
|
RefreshValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshValues()
|
||||||
|
{
|
||||||
|
enabledCheckbox.IsChecked = CategoryDefinition.Enabled;
|
||||||
|
colorInputNode.CurrentColor = CategoryDefinition.Color;
|
||||||
|
nameInputNode.String = CategoryDefinition.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using AetherBags.Addons;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
|
namespace AetherBags.Nodes.Configuration.Category;
|
||||||
|
|
||||||
|
public class CategoryScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
||||||
|
{
|
||||||
|
private AddonCategoryConfigurationWindow? _categoryConfigurationAddon;
|
||||||
|
private readonly TextButtonNode _categoryConfigurationButtonNode;
|
||||||
|
|
||||||
|
public CategoryScrollingAreaNode()
|
||||||
|
{
|
||||||
|
InitializeCategoryAddon();
|
||||||
|
|
||||||
|
_categoryConfigurationButtonNode = new TextButtonNode
|
||||||
|
{
|
||||||
|
Size = new Vector2(300, 28),
|
||||||
|
String = "Configure Categories",
|
||||||
|
OnClick = () => _categoryConfigurationAddon?.Toggle(),
|
||||||
|
};
|
||||||
|
_categoryConfigurationButtonNode.AttachNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeCategoryAddon() {
|
||||||
|
if (_categoryConfigurationAddon is not null) return;
|
||||||
|
|
||||||
|
_categoryConfigurationAddon = new AddonCategoryConfigurationWindow {
|
||||||
|
Size = new Vector2(700.0f, 500.0f),
|
||||||
|
InternalName = "AetherBags_CategoryConfig",
|
||||||
|
Title = "Category Configuration Window",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using KamiToolKit.Nodes;
|
|
||||||
|
|
||||||
namespace AetherBags.Nodes.Configuration;
|
|
||||||
|
|
||||||
public class CategoryScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
+2
-2
@@ -6,9 +6,9 @@ using KamiToolKit.Nodes;
|
|||||||
|
|
||||||
namespace AetherBags.Nodes.Configuration.Currency;
|
namespace AetherBags.Nodes.Configuration.Currency;
|
||||||
|
|
||||||
public sealed class CurrencyConfigurationNode : TabbedVerticalListNode
|
public sealed class CurrencyGeneralConfigurationNode : TabbedVerticalListNode
|
||||||
{
|
{
|
||||||
public CurrencyConfigurationNode()
|
public CurrencyGeneralConfigurationNode()
|
||||||
{
|
{
|
||||||
CurrencySettings config = System.Config.Currency;
|
CurrencySettings config = System.Config.Currency;
|
||||||
|
|
||||||
+2
-3
@@ -1,13 +1,12 @@
|
|||||||
using AetherBags.Nodes.Configuration.Currency;
|
|
||||||
using KamiToolKit.Nodes;
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
namespace AetherBags.Nodes.Configuration;
|
namespace AetherBags.Nodes.Configuration.Currency;
|
||||||
|
|
||||||
public sealed class CurrencyScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
public sealed class CurrencyScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
||||||
{
|
{
|
||||||
public CurrencyScrollingAreaNode()
|
public CurrencyScrollingAreaNode()
|
||||||
{
|
{
|
||||||
ContentNode.AddNode(new CurrencyConfigurationNode
|
ContentNode.AddNode(new CurrencyGeneralConfigurationNode
|
||||||
{
|
{
|
||||||
Size = Size
|
Size = Size
|
||||||
});
|
});
|
||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
using AetherBags.Configuration;
|
|
||||||
using AetherBags.Nodes.Configuration.Layout;
|
|
||||||
using KamiToolKit.Nodes;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using AetherBags.Configuration;
|
||||||
|
using AetherBags.Nodes.Configuration.Layout;
|
||||||
|
using KamiToolKit.Nodes;
|
||||||
|
|
||||||
namespace AetherBags.Nodes.Configuration;
|
namespace AetherBags.Nodes.Configuration.General;
|
||||||
|
|
||||||
public sealed class GeneralScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
public sealed class GeneralScrollingAreaNode : ScrollingAreaNode<VerticalListNode>
|
||||||
{
|
{
|
||||||
Reference in New Issue
Block a user