Initial commit: AetherBags + KamiToolKit for FC Gitea
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
|
||||
namespace KamiToolKit.Nodes;
|
||||
|
||||
public unsafe class ScrollBarNode : ComponentNode<AtkComponentScrollBar, AtkUldComponentDataScrollBar> {
|
||||
|
||||
public readonly ScrollBarBackgroundButtonNode BackgroundButtonNode;
|
||||
public readonly ScrollBarForegroundButtonNode ForegroundButtonNode;
|
||||
|
||||
public ScrollBarNode() {
|
||||
SetInternalComponentType(ComponentType.ScrollBar);
|
||||
|
||||
BackgroundButtonNode = new ScrollBarBackgroundButtonNode {
|
||||
Size = new Vector2(8.0f, 306.0f),
|
||||
};
|
||||
BackgroundButtonNode.AttachNode(this);
|
||||
|
||||
ForegroundButtonNode = new ScrollBarForegroundButtonNode {
|
||||
Size = new Vector2(8.0f, 306.0f),
|
||||
};
|
||||
ForegroundButtonNode.AttachNode(this);
|
||||
|
||||
Data->Nodes[0] = ForegroundButtonNode.NodeId;
|
||||
Data->Nodes[1] = 0; // Arrow Up Button
|
||||
Data->Nodes[2] = 0; // Arrow Down Button
|
||||
Data->Nodes[3] = BackgroundButtonNode.NodeId;
|
||||
|
||||
Data->Vertical = 1;
|
||||
Data->Margin = 0;
|
||||
|
||||
InitializeComponentEvents();
|
||||
|
||||
Component->MouseDownScreenPos = 0;
|
||||
Component->MouseWheelSpeed = 24;
|
||||
|
||||
AddEvent(AtkEventType.ValueUpdate, UpdateHandler);
|
||||
}
|
||||
|
||||
public Action<int>? OnValueChanged { get; set; }
|
||||
|
||||
public NodeBase? ContentNode {
|
||||
get;
|
||||
set {
|
||||
field = value;
|
||||
|
||||
if (value is not null) {
|
||||
Component->ContentNode = value;
|
||||
UpdateScrollParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CollisionNode? ContentCollisionNode {
|
||||
get;
|
||||
set {
|
||||
field = value;
|
||||
Component->ContentCollisionNode = value is null ? null : value.Node;
|
||||
UpdateScrollParams();
|
||||
}
|
||||
}
|
||||
|
||||
public int ScrollPosition {
|
||||
get => Component->ScrollPosition;
|
||||
set => Component->SetScrollPosition(value);
|
||||
}
|
||||
|
||||
public int ScrollSpeed {
|
||||
get => Component->MouseWheelSpeed;
|
||||
set => Component->MouseWheelSpeed = (short)value;
|
||||
}
|
||||
|
||||
public bool HideWhenDisabled { get; set; }
|
||||
|
||||
private void UpdateHandler() {
|
||||
OnValueChanged?.Invoke(Component->PendingScrollPosition);
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged() {
|
||||
base.OnSizeChanged();
|
||||
|
||||
BackgroundButtonNode.Size = Size;
|
||||
ForegroundButtonNode.Size = Size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates from attached Content and Collision nodes
|
||||
/// </summary>
|
||||
public void UpdateScrollParams() {
|
||||
if (Component->ContentNode is null) return;
|
||||
if (Component->ContentCollisionNode is null) return;
|
||||
|
||||
var content = Component->ContentNode;
|
||||
var collision = Component->ContentCollisionNode;
|
||||
|
||||
UpdateScrollParams(collision->Height, content->Height);
|
||||
}
|
||||
|
||||
public void UpdateScrollParams(int barHeight, int offScreenHeight) {
|
||||
var distance = offScreenHeight - barHeight;
|
||||
|
||||
Component->ScrollbarLength = (short)barHeight;
|
||||
Component->ScrollMaxPosition = Math.Max(distance, 0);
|
||||
Component->ContentNodeOffScreenLength = Math.Max((short)distance, (short)0);
|
||||
Component->EmptyLength = Math.Max(barHeight - (int)((float)barHeight / offScreenHeight * barHeight), 0);
|
||||
ForegroundButtonNode.Height = barHeight - Component->EmptyLength;
|
||||
|
||||
if (Component->ScrollPosition > Component->ScrollMaxPosition) {
|
||||
Component->SetScrollPosition(Component->ScrollMaxPosition);
|
||||
}
|
||||
|
||||
if (Component->EmptyLength is 0) {
|
||||
ForegroundButtonNode.Y = 0.0f;
|
||||
|
||||
ContentNode?.Y = 0;
|
||||
}
|
||||
|
||||
var enabledState = Component->EmptyLength is not 0;
|
||||
|
||||
Component->SetEnabledState(enabledState);
|
||||
|
||||
if (HideWhenDisabled) {
|
||||
BackgroundButtonNode.IsVisible = enabledState;
|
||||
ForegroundButtonNode.IsVisible = enabledState;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user