using System;
using UnityEngine;
using GUIEvent = UnityEngine.Event;
namespace Unity.VisualScripting
{
public sealed class EventWrapper
{
private static GUIEvent e => GUIEvent.current;
public int controlHint { get; private set; }
public int control { get; private set; }
public EventWrapper(int controlHint)
{
this.controlHint = controlHint;
}
public EventWrapper(object controlHint) : this(controlHint?.GetHashCode() ?? 0) { }
public EventWrapper() : this("EventWrapper") { }
public event Action mouseCaptured;
public event Action mouseReleased;
public event Action keyboardCaptured;
public event Action keyboardReleased;
public bool supportsKeyboard { get; private set; }
public void RegisterControl(FocusType focusType)
{
control = GUIUtility.GetControlID(controlHint, focusType);
supportsKeyboard = focusType == FocusType.Keyboard;
}
private bool shouldReleaseMouse;
private bool canCaptureMouse;
private bool canCaptureKeyboard;
public void HandleCapture(bool canCaptureMouse, bool canCaptureKeyboard)
{
this.canCaptureMouse = canCaptureMouse;
this.canCaptureKeyboard = canCaptureKeyboard;
if (e.type == EventType.MouseDown)
{
//Debug.Log($"Clicked on {control}\nHot: {GUIUtility.hotControl}, Can Capture: {canCaptureMouse}");
if (couldControlMouse && this.canCaptureMouse)
{
CaptureMouse();
}
if (supportsKeyboard && this.canCaptureKeyboard)
{
CaptureKeyboard();
}
}
// Cache this here in case the code after HandleCapture uses the MouseUp event.
shouldReleaseMouse = e.rawType == EventType.MouseUp;
}
public void HandleRelease()
{
if (shouldReleaseMouse)
{
ReleaseMouse();
}
}
public bool controlsMouse => GUIUtility.hotControl == control;
public bool controlsKeyboard => GUIUtility.keyboardControl == control;
public static bool couldControlMouse => GUIUtility.hotControl == 0;
public static bool couldControlKeyboard => GUIUtility.keyboardControl == 0;
public EventType freeType => e.type;
public EventType rawType => e.rawType;
public EventType controlType => e.GetTypeForControl(control);
public EventType mouseType => controlsMouse ? controlType : EventType.Ignore;
public EventType keyboardType => controlsKeyboard ? controlType : EventType.Ignore;
public void CaptureMouse()
{
if (controlsMouse)
{
return;
}
GUIUtility.hotControl = control;
mouseCaptured?.Invoke();
}
public void ReleaseMouse()
{
if (!controlsMouse)
{
return;
}
GUIUtility.hotControl = 0;
mouseReleased?.Invoke();
}
public void CaptureKeyboard()
{
if (!supportsKeyboard)
{
throw new NotSupportedException("Use FocusType.Keyboard to enable keyboard control.");
}
if (controlsKeyboard)
{
return;
}
GUIUtility.keyboardControl = control;
keyboardCaptured?.Invoke();
}
public void ReleaseKeyboard()
{
if (!supportsKeyboard)
{
throw new NotSupportedException("Use FocusType.Keyboard to enable keyboard control.");
}
if (!controlsKeyboard)
{
return;
}
GUIUtility.keyboardControl = 0;
keyboardReleased?.Invoke();
}
public bool IsUsed => controlType == EventType.Used;
public bool IsRepaint => controlType == EventType.Repaint;
public bool IsLayout => controlType == EventType.Layout;
public bool IsAnyMouse => controlsMouse && e.isMouse;
public bool IsAnyMouseDown => mouseType == EventType.MouseDown;
public bool IsAnyMouseUp => mouseType == EventType.MouseUp;
public bool IsAnyMouseDrag => mouseType == EventType.MouseDrag;
public bool IsMouseMove => mouseType == EventType.MouseMove;
public bool IsMouseDown(MouseButton button) => IsAnyMouseDown && mouseButton == button;
public bool IsMouseDown(MouseButton button, EventModifiers modifiers) => IsMouseDown(button) && this.modifiers == modifiers;
public bool IsMouseUp(MouseButton button) => IsAnyMouseUp && mouseButton == button;
public bool IsMouseUp(MouseButton button, EventModifiers modifiers) => IsMouseUp(button) && this.modifiers == modifiers;
public bool IsMouseDrag(MouseButton button) => IsAnyMouseDrag && mouseButton == button;
public bool IsMouseDrag(MouseButton button, EventModifiers modifiers) => IsMouseDrag(button) && this.modifiers == modifiers;
public bool IsAnyKeyboard => controlsMouse && e.isKey;
public bool IsAnyKeyDown => keyboardType == EventType.KeyDown;
public bool IsAnyKeyUp => keyboardType == EventType.KeyUp;
public bool IsKeyDown(KeyCode key) => IsAnyKeyDown && keyCode == key;
public bool IsKeyDown(KeyCode key, EventModifiers modifiers) => IsKeyDown(key) && this.modifiers == modifiers;
public bool IsKeyUp(KeyCode key) => IsAnyKeyUp && keyCode == key;
public bool IsKeyUp(KeyCode key, EventModifiers modifiers) => IsKeyUp(key) && this.modifiers == modifiers;
public bool IsContextClick => canCaptureMouse && (controlType == EventType.ContextClick || (IsKeyDown(KeyCode.E) && ctrlOrCmd));
public bool IsValidateCommand(string name) => keyboardType == EventType.ValidateCommand && commandName == name;
public bool IsExecuteCommand(string name) => keyboardType == EventType.ExecuteCommand && commandName == name;
public bool IsFree(EventType type) => freeType == type;
public bool IsRaw(EventType type) => rawType == type;
public void Use()
{
e.Use();
}
public void TryUse()
{
e?.TryUse();
}
public void ValidateCommand()
{
if (controlType != EventType.ValidateCommand)
{
throw new InvalidOperationException();
}
// In Unity, validating a command means using the ValidateCommand event.
Use();
}
public Vector2 mousePosition => e.mousePosition;
public Vector2 mouseDelta => e.delta;
public int clickCount => e.clickCount;
public KeyCode keyCode => e.keyCode;
public string commandName => e.commandName;
public EventModifiers modifiers => e.modifiers;
public bool alt => e.alt;
public bool shift => e.shift;
public bool ctrl => e.control;
public bool cmd => e.command;
public bool ctrlOrCmd => Application.platform == RuntimePlatform.OSXEditor ? cmd : ctrl;
public MouseButton mouseButton
{
get
{
if (Application.platform == RuntimePlatform.OSXEditor && e.control && e.button == (int)MouseButton.Left)
{
return MouseButton.Right;
}
return (MouseButton)e.button;
}
}
}
}