Initial commit: AetherBags + KamiToolKit for FC Gitea
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Dalamud.Game.Addon.Events;
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using KamiToolKit.Classes;
|
||||
using KamiToolKit.Enums;
|
||||
using KamiToolKit.Nodes;
|
||||
|
||||
namespace KamiToolKit;
|
||||
|
||||
public abstract unsafe partial class NodeBase {
|
||||
|
||||
private Vector2 clickStartPosition = Vector2.Zero;
|
||||
private NodeEditMode currentEditMode = 0;
|
||||
|
||||
private ViewportEventListener? editEventListener;
|
||||
|
||||
private bool isCursorSet;
|
||||
|
||||
private bool isMoving;
|
||||
private bool isResizing;
|
||||
|
||||
private NodeEditOverlayNode? overlayNode;
|
||||
|
||||
public Action<NodeBase>? OnResizeComplete { get; set; }
|
||||
public Action<NodeBase>? OnMoveComplete { get; set; }
|
||||
public Action<NodeBase>? OnEditComplete { get; set; }
|
||||
|
||||
public bool EnableMoving {
|
||||
get;
|
||||
set {
|
||||
field = value;
|
||||
if (value) {
|
||||
EnableEditMode(NodeEditMode.Move);
|
||||
}
|
||||
else {
|
||||
DisableEditMode(NodeEditMode.Move);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnableResizing {
|
||||
get;
|
||||
set {
|
||||
field = value;
|
||||
if (value) {
|
||||
EnableEditMode(NodeEditMode.Resize);
|
||||
}
|
||||
else {
|
||||
DisableEditMode(NodeEditMode.Resize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EnableEditMode(NodeEditMode mode) {
|
||||
|
||||
currentEditMode |= mode;
|
||||
|
||||
if (overlayNode is null) {
|
||||
overlayNode = new NodeEditOverlayNode {
|
||||
Position = new Vector2(-16.0f, -16.0f),
|
||||
Size = Size + new Vector2(32.0f, 32.0f),
|
||||
};
|
||||
overlayNode.AttachNode(this);
|
||||
ChildNodes.Add(overlayNode);
|
||||
}
|
||||
|
||||
overlayNode.ShowParts = currentEditMode.HasFlag(NodeEditMode.Resize);
|
||||
|
||||
if (editEventListener is null) {
|
||||
editEventListener = new ViewportEventListener(OnEditEvent);
|
||||
editEventListener.AddEvent(AtkEventType.MouseMove, overlayNode);
|
||||
editEventListener.AddEvent(AtkEventType.MouseDown, overlayNode);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableEditMode(NodeEditMode mode) {
|
||||
|
||||
currentEditMode &= ~mode;
|
||||
|
||||
if (currentEditMode.HasFlag(NodeEditMode.Resize) || currentEditMode.HasFlag(NodeEditMode.Move)) return;
|
||||
|
||||
if (editEventListener is not null) {
|
||||
editEventListener.RemoveEvent(AtkEventType.MouseMove);
|
||||
editEventListener.RemoveEvent(AtkEventType.MouseDown);
|
||||
editEventListener.Dispose();
|
||||
editEventListener = null;
|
||||
}
|
||||
|
||||
if (overlayNode is not null) {
|
||||
ChildNodes.Remove(overlayNode);
|
||||
overlayNode.DetachNode();
|
||||
overlayNode.Dispose();
|
||||
overlayNode = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEditEvent(AtkEventListener* thisPtr, AtkEventType eventType, int eventParam, AtkEvent* atkEvent, AtkEventData* atkEventData) {
|
||||
if (overlayNode is null) return;
|
||||
if (editEventListener is null) return;
|
||||
|
||||
ref var mouseData = ref atkEventData->MouseData;
|
||||
var mousePosition = new Vector2(mouseData.PosX, mouseData.PosY);
|
||||
var mouseDelta = mousePosition - clickStartPosition;
|
||||
|
||||
switch (eventType) {
|
||||
// Move Logic
|
||||
case AtkEventType.MouseMove when isMoving: {
|
||||
Position += mouseDelta;
|
||||
clickStartPosition = mousePosition;
|
||||
|
||||
atkEvent->SetEventIsHandled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Update hover state when not resizing, as we latch that for the behavior
|
||||
case AtkEventType.MouseMove when !isResizing: {
|
||||
overlayNode.UpdateHover(atkEventData);
|
||||
}
|
||||
break;
|
||||
|
||||
// Resize Logic
|
||||
case AtkEventType.MouseMove when isResizing: {
|
||||
Position += overlayNode.GetPositionDelta(mouseDelta);
|
||||
Size += overlayNode.GetSizeDelta(mouseDelta);
|
||||
|
||||
overlayNode.Size = Size + new Vector2(32.0f, 32.0f);
|
||||
|
||||
clickStartPosition = mousePosition;
|
||||
|
||||
atkEvent->SetEventIsHandled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Begin Resize Event
|
||||
case AtkEventType.MouseDown when !isResizing && overlayNode.AnyHovered() && currentEditMode.HasFlag(NodeEditMode.Resize): {
|
||||
editEventListener.AddEvent(AtkEventType.MouseUp, overlayNode);
|
||||
|
||||
isResizing = true;
|
||||
clickStartPosition = mousePosition;
|
||||
|
||||
atkEvent->SetEventIsHandled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
// End Resize Event
|
||||
case AtkEventType.MouseUp when isResizing: {
|
||||
OnResizeComplete?.Invoke(this);
|
||||
OnEditComplete?.Invoke(this);
|
||||
|
||||
isResizing = false;
|
||||
editEventListener.RemoveEvent(AtkEventType.MouseUp);
|
||||
}
|
||||
break;
|
||||
|
||||
// Begin Move Event
|
||||
case AtkEventType.MouseDown when !overlayNode.AnyHovered() && overlayNode.CheckCollision(atkEventData) && !isMoving && currentEditMode.HasFlag(NodeEditMode.Move): {
|
||||
editEventListener.AddEvent(AtkEventType.MouseUp, overlayNode);
|
||||
|
||||
isMoving = true;
|
||||
clickStartPosition = mousePosition;
|
||||
|
||||
atkEvent->SetEventIsHandled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
// End Move Event
|
||||
case AtkEventType.MouseUp when isMoving: {
|
||||
OnMoveComplete?.Invoke(this);
|
||||
OnEditComplete?.Invoke(this);
|
||||
|
||||
isMoving = false;
|
||||
editEventListener.RemoveEvent(AtkEventType.MouseUp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCursorSet) {
|
||||
ResetCursor();
|
||||
isCursorSet = false;
|
||||
}
|
||||
|
||||
if (currentEditMode.HasFlag(NodeEditMode.Move)) {
|
||||
if (isMoving) {
|
||||
SetCursor(AddonCursorType.Grab);
|
||||
isCursorSet = true;
|
||||
}
|
||||
else if (CheckCollision(atkEventData)) {
|
||||
SetCursor(AddonCursorType.Hand);
|
||||
isCursorSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (overlayNode.AnyHovered() && currentEditMode.HasFlag(NodeEditMode.Resize)) {
|
||||
overlayNode.SetCursor();
|
||||
isCursorSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCursor(AddonCursorType cursor)
|
||||
=> DalamudInterface.Instance.AddonEventManager.SetCursor(cursor);
|
||||
|
||||
private static void ResetCursor()
|
||||
=> DalamudInterface.Instance.AddonEventManager.ResetCursor();
|
||||
}
|
||||
Reference in New Issue
Block a user