Initial commit: AetherBags + KamiToolKit for FC Gitea
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using KamiToolKit.Classes;
|
||||
using KamiToolKit.Timelines;
|
||||
using Lumina.Text.ReadOnly;
|
||||
|
||||
namespace KamiToolKit.Nodes;
|
||||
|
||||
public unsafe class TreeListCategoryNode : ResNode {
|
||||
|
||||
public readonly NineGridNode BackgroundNode;
|
||||
public readonly SimpleComponentNode ChildContainer;
|
||||
public readonly ImageNode CollapseArrowNode;
|
||||
public readonly CollisionNode CollisionNode;
|
||||
public readonly TextNode LabelNode;
|
||||
|
||||
private readonly List<NodeBase> children = [];
|
||||
|
||||
public IReadOnlyCollection<TreeListHeaderNode> HeaderNodes => children.OfType<TreeListHeaderNode>().ToList();
|
||||
public IReadOnlyCollection<NodeBase> Children => children.AsReadOnly();
|
||||
public IEnumerable<T> GetNodes<T>() where T : NodeBase => children.OfType<T>();
|
||||
|
||||
public Action<bool>? OnToggle;
|
||||
|
||||
public TreeListCategoryNode() {
|
||||
CollisionNode = new CollisionNode {
|
||||
Height = 28.0f,
|
||||
};
|
||||
CollisionNode.AttachNode(this);
|
||||
|
||||
BackgroundNode = new SimpleNineGridNode {
|
||||
TexturePath = "ui/uld/ListItemB.tex",
|
||||
TextureSize = new Vector2(48.0f, 28.0f),
|
||||
TextureCoordinates = new Vector2(0.0f, 24.0f),
|
||||
Height = 28.0f,
|
||||
TopOffset = 10.0f,
|
||||
LeftOffset = 12.0f,
|
||||
RightOffset = 12.0f,
|
||||
BottomOffset = 12.0f,
|
||||
};
|
||||
BackgroundNode.AttachNode(this);
|
||||
|
||||
CollapseArrowNode = new ImageNode {
|
||||
Position = new Vector2(0.0f, 1.0f),
|
||||
Size = new Vector2(24.0f, 24.0f),
|
||||
PartId = 1,
|
||||
};
|
||||
|
||||
CollapseArrowNode.AddPart(new Part {
|
||||
TexturePath = "ui/uld/ListItemB.tex",
|
||||
TextureCoordinates = new Vector2(0.0f, 0.0f),
|
||||
Size = new Vector2(24.0f, 24.0f),
|
||||
Id = 0,
|
||||
});
|
||||
|
||||
CollapseArrowNode.AddPart(new Part {
|
||||
TexturePath = "ui/uld/ListItemB.tex",
|
||||
TextureCoordinates = new Vector2(24.0f, 0.0f),
|
||||
Size = new Vector2(24.0f, 24.0f),
|
||||
Id = 1,
|
||||
});
|
||||
CollapseArrowNode.AttachNode(this);
|
||||
|
||||
LabelNode = new TextNode {
|
||||
Position = new Vector2(23.0f, 0.0f),
|
||||
FontType = FontType.Axis,
|
||||
FontSize = 14,
|
||||
Height = 28.0f,
|
||||
AlignmentType = AlignmentType.Left,
|
||||
TextColor = ColorHelper.GetColor(50),
|
||||
TextOutlineColor = ColorHelper.GetColor(7),
|
||||
};
|
||||
LabelNode.AttachNode(this);
|
||||
|
||||
ChildContainer = new SimpleComponentNode {
|
||||
Position = new Vector2(0.0f, 24.0f + VerticalPadding),
|
||||
};
|
||||
ChildContainer.AttachNode(this);
|
||||
|
||||
BuildTimelines();
|
||||
|
||||
CollisionNode.ShowClickableCursor = true;
|
||||
CollisionNode.AddEvent(AtkEventType.MouseOver, () => Timeline?.PlayAnimation(IsCollapsed ? 2 : 9));
|
||||
CollisionNode.AddEvent(AtkEventType.MouseOut, () => Timeline?.PlayAnimation(IsCollapsed ? 1 : 8));
|
||||
CollisionNode.AddEvent(AtkEventType.MouseClick, () => {
|
||||
IsCollapsed = !IsCollapsed;
|
||||
UpdateCollapsed();
|
||||
OnToggle?.Invoke(!IsCollapsed);
|
||||
});
|
||||
}
|
||||
|
||||
public TreeListNode? ParentTreeListNode { get; set; }
|
||||
|
||||
private bool InternalIsCollapsed { get; set; }
|
||||
|
||||
public bool IsCollapsed {
|
||||
get => InternalIsCollapsed;
|
||||
set {
|
||||
InternalIsCollapsed = value;
|
||||
UpdateCollapsed();
|
||||
Timeline?.PlayAnimation(IsCollapsed ? 1 : 8);
|
||||
}
|
||||
}
|
||||
|
||||
public float VerticalPadding { get; set; } = 4.0f;
|
||||
|
||||
public ReadOnlySeString String {
|
||||
get => LabelNode.String;
|
||||
set => LabelNode.String = value;
|
||||
}
|
||||
|
||||
private void UpdateCollapsed() {
|
||||
Timeline?.PlayAnimation(IsCollapsed ? 1 : 8);
|
||||
ChildContainer.IsVisible = !IsCollapsed;
|
||||
Height = IsCollapsed ? BackgroundNode.Height : ChildContainer.Height + BackgroundNode.Height;
|
||||
ParentTreeListNode?.RefreshLayout();
|
||||
}
|
||||
|
||||
public void RecalculateLayout() {
|
||||
ChildContainer.Height = 0.0f;
|
||||
|
||||
foreach (var child in children) {
|
||||
if (!child.IsVisible) continue;
|
||||
|
||||
child.Y = ChildContainer.Height;
|
||||
child.Width = ChildContainer.Width;
|
||||
|
||||
ChildContainer.Height += child.Height + VerticalPadding;
|
||||
Height = ChildContainer.Height + BackgroundNode.Height;
|
||||
}
|
||||
|
||||
UpdateCollapsed();
|
||||
}
|
||||
|
||||
public void AddHeader(ReadOnlySeString label) {
|
||||
var newHeaderNode = new TreeListHeaderNode {
|
||||
Size = new Vector2(Width, 24.0f),
|
||||
String = label,
|
||||
};
|
||||
|
||||
AddNode(newHeaderNode);
|
||||
}
|
||||
|
||||
public void AddNode(NodeBase node) {
|
||||
node.Y = ChildContainer.Height;
|
||||
node.Width = ChildContainer.Width;
|
||||
node.NodeId = (uint)children.Count + 2;
|
||||
|
||||
ChildContainer.Height += node.Height + VerticalPadding;
|
||||
Height = ChildContainer.Height + BackgroundNode.Height;
|
||||
|
||||
children.Add(node);
|
||||
node.AttachNode(ChildContainer);
|
||||
UpdateCollapsed();
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged() {
|
||||
base.OnSizeChanged();
|
||||
|
||||
BackgroundNode.Width = Width;
|
||||
CollapseArrowNode.Width = 24.0f;
|
||||
LabelNode.Width = Width - 23.0f;
|
||||
ChildContainer.Width = Width;
|
||||
CollisionNode.Width = Width;
|
||||
|
||||
foreach (var node in children) {
|
||||
node.Width = Width;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateChildrenNodeId() {
|
||||
CollisionNode.NodeId = NodeId * 10000 + 1;
|
||||
BackgroundNode.NodeId = NodeId * 10000 + 2;
|
||||
CollapseArrowNode.NodeId = NodeId * 10000 + 3;
|
||||
LabelNode.NodeId = NodeId * 10000 + 4;
|
||||
ChildContainer.NodeId = NodeId * 10000 + 5;
|
||||
}
|
||||
|
||||
private void BuildTimelines() {
|
||||
AddTimeline(new TimelineBuilder()
|
||||
.BeginFrameSet(1, 119)
|
||||
.AddLabel(1, 1, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(9, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(10, 2, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(19, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(20, 3, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(29, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(30, 7, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(39, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(40, 6, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(49, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(50, 4, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(59, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(60, 8, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(69, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(70, 9, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(79, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(80, 10, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(89, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(90, 14, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(99, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(100, 13, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(109, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.AddLabel(110, 11, AtkTimelineJumpBehavior.Start, 0)
|
||||
.AddLabel(119, 0, AtkTimelineJumpBehavior.PlayOnce, 0)
|
||||
.EndFrameSet()
|
||||
.Build()
|
||||
);
|
||||
|
||||
CollapseArrowNode.AddTimeline(new TimelineBuilder()
|
||||
.BeginFrameSet(1, 9)
|
||||
.AddFrame(1, alpha: 255)
|
||||
.AddFrame(1, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(1, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(10, 19)
|
||||
.AddFrame(10, alpha: 255)
|
||||
.AddFrame(12, alpha: 255)
|
||||
.AddFrame(10, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(12, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(10, partId: 0)
|
||||
.AddFrame(12, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(20, 29)
|
||||
.AddFrame(20, alpha: 255)
|
||||
.AddFrame(20, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(20, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(30, 39)
|
||||
.AddFrame(30, alpha: 178)
|
||||
.AddFrame(30, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(50, 50, 50))
|
||||
.AddFrame(30, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(40, 49)
|
||||
.AddFrame(40, alpha: 255)
|
||||
.AddFrame(40, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(40, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(50, 59)
|
||||
.AddFrame(50, alpha: 255)
|
||||
.AddFrame(52, alpha: 255)
|
||||
.AddFrame(50, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(52, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(50, partId: 0)
|
||||
.AddFrame(52, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(60, 69)
|
||||
.AddFrame(60, alpha: 255)
|
||||
.AddFrame(60, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(60, partId: 1)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(70, 79)
|
||||
.AddFrame(70, alpha: 255)
|
||||
.AddFrame(72, alpha: 255)
|
||||
.AddFrame(70, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(72, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(70, partId: 1)
|
||||
.AddFrame(72, partId: 1)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(80, 89)
|
||||
.AddFrame(80, alpha: 255)
|
||||
.AddFrame(80, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(80, partId: 0)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(90, 99)
|
||||
.AddFrame(90, alpha: 178)
|
||||
.AddFrame(90, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(50, 50, 50))
|
||||
.AddFrame(90, partId: 1)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(100, 109)
|
||||
.AddFrame(100, alpha: 255)
|
||||
.AddFrame(100, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(100, partId: 1)
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(110, 119)
|
||||
.AddFrame(110, alpha: 255)
|
||||
.AddFrame(112, alpha: 255)
|
||||
.AddFrame(110, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(112, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(110, partId: 1)
|
||||
.AddFrame(112, partId: 1)
|
||||
.EndFrameSet()
|
||||
.Build()
|
||||
);
|
||||
|
||||
LabelNode.AddTimeline(new TimelineBuilder()
|
||||
.BeginFrameSet(1, 9)
|
||||
.AddFrame(1, alpha: 229)
|
||||
.AddFrame(1, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(10, 19)
|
||||
.AddFrame(10, alpha: 229)
|
||||
.AddFrame(10, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(20, 29)
|
||||
.AddFrame(20, alpha: 229)
|
||||
.AddFrame(20, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(30, 39)
|
||||
.AddFrame(30, alpha: 153)
|
||||
.AddFrame(30, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(80, 80, 80))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(40, 49)
|
||||
.AddFrame(40, alpha: 229)
|
||||
.AddFrame(40, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(50, 59)
|
||||
.AddFrame(50, alpha: 229)
|
||||
.AddFrame(50, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(60, 69)
|
||||
.AddFrame(60, alpha: 229)
|
||||
.AddFrame(60, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(70, 79)
|
||||
.AddFrame(70, alpha: 229)
|
||||
.AddFrame(70, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(80, 89)
|
||||
.AddFrame(80, alpha: 229)
|
||||
.AddFrame(80, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(90, 99)
|
||||
.AddFrame(90, alpha: 153)
|
||||
.AddFrame(90, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(80, 80, 80))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(100, 109)
|
||||
.AddFrame(100, alpha: 229)
|
||||
.AddFrame(100, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(110, 119)
|
||||
.AddFrame(110, alpha: 229)
|
||||
.AddFrame(110, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.Build()
|
||||
);
|
||||
|
||||
BackgroundNode.AddTimeline(new TimelineBuilder()
|
||||
.BeginFrameSet(1, 9)
|
||||
.AddFrame(1, alpha: 255)
|
||||
.AddFrame(1, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(10, 19)
|
||||
.AddFrame(10, alpha: 255)
|
||||
.AddFrame(12, alpha: 255)
|
||||
.AddFrame(10, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(12, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(20, 29)
|
||||
.AddFrame(20, alpha: 255)
|
||||
.AddFrame(20, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(30, 39)
|
||||
.AddFrame(30, alpha: 178)
|
||||
.AddFrame(30, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(50, 50, 50))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(40, 49)
|
||||
.AddFrame(40, alpha: 255)
|
||||
.AddFrame(40, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(50, 59)
|
||||
.AddFrame(50, alpha: 255)
|
||||
.AddFrame(52, alpha: 255)
|
||||
.AddFrame(50, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(52, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(60, 69)
|
||||
.AddFrame(60, alpha: 255)
|
||||
.AddFrame(60, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(70, 79)
|
||||
.AddFrame(70, alpha: 255)
|
||||
.AddFrame(72, alpha: 255)
|
||||
.AddFrame(70, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(72, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(80, 89)
|
||||
.AddFrame(80, alpha: 255)
|
||||
.AddFrame(80, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(90, 99)
|
||||
.AddFrame(90, alpha: 178)
|
||||
.AddFrame(90, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(50, 50, 50))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(100, 109)
|
||||
.AddFrame(100, alpha: 255)
|
||||
.AddFrame(100, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.BeginFrameSet(110, 119)
|
||||
.AddFrame(110, alpha: 255)
|
||||
.AddFrame(112, alpha: 255)
|
||||
.AddFrame(110, addColor: new Vector3(16, 16, 16), multiplyColor: new Vector3(100, 100, 100))
|
||||
.AddFrame(112, addColor: new Vector3(0, 0, 0), multiplyColor: new Vector3(100, 100, 100))
|
||||
.EndFrameSet()
|
||||
.Build()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user