473 lines
13 KiB
C#
473 lines
13 KiB
C#
|
|
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public class UIDragging
|
|
{
|
|
public class MappedEvent
|
|
{
|
|
public MouseButton mouseButton;
|
|
public EditableUIDraggingEvent uiEvent;
|
|
}
|
|
|
|
public class ButtonState
|
|
{
|
|
public MouseButton mouseButton;
|
|
public bool dragging;
|
|
}
|
|
|
|
public class UIDraggingCallbacks: ICustomDisposer
|
|
{
|
|
public UI ui;
|
|
public Control control;
|
|
|
|
public bool wasDisposed = false;
|
|
|
|
public bool notValid =>
|
|
wasDisposed ||
|
|
onMouseClick == null ||
|
|
onDragging == null ||
|
|
onProcess == null ||
|
|
mouseEvents == null || mouseEvents.FilterNulls().Count == 0 ||
|
|
mouseEventsDragging == null || mouseEventsDragging.FilterNulls().Count == 0;
|
|
|
|
public Action<InputEvent> onMouseClick;
|
|
public Callable callable;
|
|
public Action<InputEvent> onDragging;
|
|
public Action<float> onProcess;
|
|
// public Dictionary<MouseButton,EditableUIDraggingEvent> mouseEvents = new Dictionary<MouseButton, EditableUIDraggingEvent>();
|
|
|
|
public List<MappedEvent> mouseEvents = new List<MappedEvent>();
|
|
public List<ButtonState> mouseEventsDragging = new List<ButtonState>();
|
|
// public Dictionary<MouseButton,bool> mouseEventsDragging = new Dictionary<MouseButton, bool>();
|
|
|
|
public string uid = IDGenerator.GenerateID();
|
|
public string GetUID(){ return uid; }
|
|
|
|
string info = "";
|
|
public string GetInfo(){ return info;}
|
|
|
|
public void Set( Control c, Func<UIDraggingEvent,bool> callback )
|
|
{
|
|
var callbacks = this;
|
|
callbacks.control = c;
|
|
callbacks.ui = c.FindParentThatIs<UI>();
|
|
|
|
callbacks.ui.AddForDisposing( callbacks );
|
|
|
|
info = HierarchyName.Of( c );
|
|
|
|
|
|
callbacks.onProcess = (float delta )=>
|
|
{
|
|
callbacks.mouseEvents.ForEach(
|
|
( m )=>
|
|
{
|
|
callback( m.uiEvent );
|
|
}
|
|
);
|
|
// foreach ( var m in callbacks.mouseEvents )
|
|
// {
|
|
// callback( callbacks.mouseEvents[ m.Key ] );
|
|
// }
|
|
};
|
|
|
|
callbacks.onDragging = ( InputEvent ie ) =>
|
|
{
|
|
|
|
if ( ie is InputEventMouseButton mb && ! mb.Pressed )
|
|
{
|
|
var mdIndex = callbacks.mouseEventsDragging.FindIndex( me => me.mouseButton == mb.ButtonIndex );
|
|
var meIndex = callbacks.mouseEvents.FindIndex( md => md.mouseButton == mb.ButtonIndex );
|
|
callbacks.mouseEventsDragging[ mdIndex ].dragging = false;
|
|
|
|
callbacks.mouseEvents[ meIndex ].uiEvent.UpdatePosition( mb.GlobalPosition, true );
|
|
|
|
callback( callbacks.mouseEvents[ meIndex ].uiEvent );
|
|
|
|
if ( ! callbacks.hasAnyMouseDragging )
|
|
{
|
|
callbacks.ui.onInputEvent.RemoveAction( callbacks.onDragging );
|
|
callbacks.ui.onProcess.RemoveAction( callbacks.onProcess );
|
|
callbacks.hasDraggingCallback = false;
|
|
|
|
if ( c is UIStylePropertyContainer sc )
|
|
{
|
|
sc.GetUISelectorFlags().Remove( UISelectorFlag.Dragging );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( ie is InputEventMouseMotion mo )
|
|
{
|
|
var globalPosition = mo.GlobalPosition;
|
|
|
|
// foreach ( var m in callbacks.mouseEvents )
|
|
// {
|
|
// callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
|
|
// // callback( callbacks.mouseEvents[ m.Key ] );
|
|
// }
|
|
|
|
callbacks.mouseEvents.ForEach(
|
|
( m )=>
|
|
{
|
|
m.uiEvent.UpdatePosition( globalPosition );
|
|
}
|
|
);
|
|
}
|
|
|
|
|
|
};
|
|
|
|
callbacks.onMouseClick = ( InputEvent ie )=>
|
|
{
|
|
if ( ! ( ie is InputEventMouseButton b && b.Pressed ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var mb = ie as InputEventMouseButton;
|
|
|
|
var button = mb.ButtonIndex;
|
|
|
|
var draggingEvent = callbacks.GetMouseEvent( button );
|
|
|
|
draggingEvent.SetStart( mb.GlobalPosition );
|
|
var result = callback( draggingEvent );
|
|
|
|
if ( ! result )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( c is UIStylePropertyContainer sc )
|
|
{
|
|
sc.GetUISelectorFlags().AddIfNotPresent( UISelectorFlag.Dragging );
|
|
}
|
|
|
|
var buttonIndex = callbacks.mouseEventsDragging.FindIndex( bs => bs.mouseButton == button );
|
|
|
|
if ( buttonIndex == -1 )
|
|
{
|
|
var bs = new ButtonState();
|
|
bs.mouseButton = button;
|
|
callbacks.mouseEventsDragging.Add( bs );
|
|
buttonIndex = callbacks.mouseEventsDragging.Count - 1;
|
|
|
|
}
|
|
|
|
callbacks.mouseEventsDragging[ buttonIndex ].dragging = true;
|
|
|
|
if ( ! callbacks.hasDraggingCallback )
|
|
{
|
|
callbacks.ui.onInputEvent.AddAction( callbacks.onDragging );
|
|
callbacks.ui.onProcess.AddAction( callbacks.onProcess );
|
|
}
|
|
|
|
};
|
|
|
|
|
|
callbacks.Connect();
|
|
|
|
wasDisposed = false;
|
|
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
wasDisposed = true;
|
|
|
|
if ( control != null && Node.IsInstanceValid( control ) )
|
|
{
|
|
control.Disconnect( "gui_input", callable );
|
|
}
|
|
|
|
|
|
|
|
// ui = null;
|
|
// control = null;
|
|
|
|
|
|
onMouseClick = null;
|
|
onDragging = null;
|
|
onProcess = null;
|
|
|
|
mouseEvents.Clear();
|
|
|
|
mouseEventsDragging.Clear();
|
|
|
|
// mouseEvents = null;
|
|
// mouseEventsDragging = null;
|
|
|
|
}
|
|
|
|
public bool hasAnyMouseDragging
|
|
{
|
|
get
|
|
{
|
|
foreach ( var mb in mouseEventsDragging )
|
|
{
|
|
if ( mb.dragging )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public bool hasDraggingCallback = false;
|
|
|
|
public EditableUIDraggingEvent GetMouseEvent( MouseButton mb )
|
|
{
|
|
var index = mouseEvents.FindIndex( m => m.mouseButton == mb );
|
|
|
|
if ( index == -1)
|
|
{
|
|
var mappedEvent = new MappedEvent();
|
|
mappedEvent.mouseButton = mb;
|
|
mappedEvent.uiEvent = new EditableUIDraggingEvent( mb );
|
|
mouseEvents.Add( mappedEvent );
|
|
index = mouseEvents.Count - 1;
|
|
}
|
|
|
|
mouseEvents[ index ].uiEvent.SetUI( ui );
|
|
|
|
return mouseEvents[ index ].uiEvent;
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
control.Disconnect( "gui_input", callable );
|
|
}
|
|
|
|
public void Connect()
|
|
{
|
|
callable = Callable.From( onMouseClick );
|
|
control.Connect( "gui_input", callable );
|
|
}
|
|
}
|
|
|
|
public class UIDraggingEvent
|
|
{
|
|
public enum Phase
|
|
{
|
|
Start,
|
|
Dragging,
|
|
End
|
|
}
|
|
|
|
protected Phase _phase = Phase.Start;
|
|
|
|
public bool isStart => Phase.Start == _phase;
|
|
public bool isDragging => Phase.Dragging == _phase;
|
|
public bool isEnd => Phase.End == _phase;
|
|
protected UI _ui;
|
|
public UI ui => _ui;
|
|
|
|
protected MouseButton _mouseButton;
|
|
public MouseButton mouseButton => _mouseButton;
|
|
public bool isLeftMouseButton => MouseButton.Left == _mouseButton;
|
|
public bool isMiddleMouseButton => MouseButton.Middle == _mouseButton;
|
|
public bool isRightMouseButton => MouseButton.Right == _mouseButton;
|
|
public Vector2 customOffset;
|
|
|
|
protected int _touchID = -1;
|
|
|
|
protected Vector2 _startPosition;
|
|
protected Vector2 _position;
|
|
protected Vector2 _lastPosition;
|
|
protected Vector2 _furthestPointFromStart;
|
|
protected float _biggestDistance;
|
|
|
|
public Vector2 startPosition => _startPosition;
|
|
public Vector2 position => _position;
|
|
public Vector2 lastPosition => _lastPosition;
|
|
|
|
public Vector2 movementSinceLastFrame => _position - lastPosition;
|
|
public Vector2 distanceToStart => _position - _startPosition;
|
|
|
|
public Vector2 furthestPointToStart => _furthestPointFromStart;
|
|
public float maximumMovement => _biggestDistance;
|
|
|
|
public UIDraggingEvent( MouseButton mb )
|
|
{
|
|
_mouseButton = mb;
|
|
}
|
|
|
|
public UIDraggingEvent( int touchID )
|
|
{
|
|
this._touchID = touchID;
|
|
}
|
|
|
|
}
|
|
|
|
public class EditableUIDraggingEvent:UIDraggingEvent
|
|
{
|
|
|
|
public EditableUIDraggingEvent( MouseButton mb ):base( mb ){}
|
|
public EditableUIDraggingEvent( int touchID ):base( touchID ){}
|
|
|
|
public void SetUI( UI ui )
|
|
{
|
|
_ui = ui;
|
|
}
|
|
|
|
public void SetStart( Vector2 startPosition )
|
|
{
|
|
_startPosition = startPosition;
|
|
_position = startPosition;
|
|
_lastPosition = startPosition;
|
|
_furthestPointFromStart = Vector2.Zero;
|
|
_phase = Phase.Start;
|
|
}
|
|
|
|
public void UpdatePosition( Vector2 position, bool isEnd = false )
|
|
{
|
|
_lastPosition = _position;
|
|
_position = position;
|
|
|
|
var d = position.DistanceTo( _startPosition );
|
|
|
|
if ( d > _biggestDistance )
|
|
{
|
|
_biggestDistance = d;
|
|
_furthestPointFromStart = position;
|
|
}
|
|
|
|
_phase = isEnd ? Phase.End : Phase.Dragging;
|
|
}
|
|
}
|
|
|
|
public static UIDraggingCallbacks OnLeftMouseButton( Control c, Action<UIDraggingEvent> callback )
|
|
{
|
|
return OnOneMouseButton( c, MouseButton.Left, callback );
|
|
}
|
|
|
|
public static UIDraggingCallbacks OnMiddleMouseButton( Control c, Action<UIDraggingEvent> callback )
|
|
{
|
|
return OnOneMouseButton( c, MouseButton.Middle, callback );
|
|
}
|
|
|
|
public static UIDraggingCallbacks OnRightMouseButton( Control c, Action<UIDraggingEvent> callback )
|
|
{
|
|
return OnOneMouseButton( c, MouseButton.Right, callback );
|
|
}
|
|
|
|
public static UIDraggingCallbacks OnOneMouseButton( Control c, MouseButton mouseButton, Action<UIDraggingEvent> callback )
|
|
{
|
|
var oneButtonCallback = ( UIDraggingEvent ev ) =>
|
|
{
|
|
if ( ev.mouseButton != mouseButton )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
callback( ev );
|
|
|
|
return true;
|
|
};
|
|
|
|
return OnAnyMouseButton( c, oneButtonCallback );
|
|
}
|
|
|
|
public static UIDraggingCallbacks OnAnyMouseButton( Control c, Func<UIDraggingEvent,bool> callback )
|
|
{
|
|
|
|
var callbacks = new UIDraggingCallbacks();
|
|
callbacks.Set( c, callback );
|
|
|
|
// callbacks.control = c;
|
|
// callbacks.ui = c.FindParentThatIs<UI>();
|
|
|
|
// callbacks.ui.AddForDisposing( callbacks );
|
|
|
|
|
|
// callbacks.onProcess = (float delta )=>
|
|
// {
|
|
// foreach ( var m in callbacks.mouseEvents )
|
|
// {
|
|
// callback( callbacks.mouseEvents[ m.Key ] );
|
|
// }
|
|
// };
|
|
|
|
// callbacks.onDragging = ( InputEvent ie ) =>
|
|
// {
|
|
|
|
// if ( ie is InputEventMouseButton mb && ! mb.Pressed )
|
|
// {
|
|
// callbacks.mouseEventsDragging[ mb.ButtonIndex ] = false;
|
|
|
|
// callbacks.mouseEvents[ mb.ButtonIndex ].UpdatePosition( mb.GlobalPosition, true );
|
|
|
|
// callback( callbacks.mouseEvents[ mb.ButtonIndex ] );
|
|
|
|
// if ( ! callbacks.hasAnyMouseDragging )
|
|
// {
|
|
// callbacks.ui.onInputEvent.RemoveAction( callbacks.onDragging );
|
|
// callbacks.ui.onProcess.RemoveAction( callbacks.onProcess );
|
|
// callbacks.hasDraggingCallback = false;
|
|
// }
|
|
// }
|
|
|
|
// if ( ie is InputEventMouseMotion mo )
|
|
// {
|
|
// var globalPosition = mo.GlobalPosition;
|
|
|
|
// foreach ( var m in callbacks.mouseEvents )
|
|
// {
|
|
// callbacks.mouseEvents[ m.Key ].UpdatePosition( globalPosition );
|
|
// // callback( callbacks.mouseEvents[ m.Key ] );
|
|
// }
|
|
// }
|
|
|
|
|
|
// };
|
|
|
|
// callbacks.onMouseClick = ( InputEvent ie )=>
|
|
// {
|
|
// if ( ! ( ie is InputEventMouseButton b && b.Pressed ) )
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// var mb = ie as InputEventMouseButton;
|
|
|
|
// var button = mb.ButtonIndex;
|
|
|
|
// var draggingEvent = callbacks.GetMouseEvent( button );
|
|
|
|
// draggingEvent.SetStart( mb.GlobalPosition );
|
|
// var result = callback( draggingEvent );
|
|
|
|
// if ( ! result )
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// callbacks.mouseEventsDragging[ button ] = true;
|
|
|
|
// if ( ! callbacks.hasDraggingCallback )
|
|
// {
|
|
// callbacks.ui.onInputEvent.AddAction( callbacks.onDragging );
|
|
// callbacks.ui.onProcess.AddAction( callbacks.onProcess );
|
|
// }
|
|
|
|
// };
|
|
|
|
|
|
// callbacks.Connect();
|
|
|
|
// c.Connect( "gui_input", Callable.From( callbacks.onMouseClick ) );
|
|
// c.GuiInput += callbacks.onMouseClick;
|
|
|
|
return callbacks;
|
|
}
|
|
}
|
|
} |