using System;
using UnityEngine.UIElements;
namespace UnityEditor.UI
{
///
/// Provides utility methods for creating and manipulating UI Toolkit elements in the Unity Editor.
///
internal static class UIEditorUtility
{
// Unity's internal USS class for the hover state on draggable fields
private const string k_draggerHoverClass = "unity-base-field__label--with-dragger";
///
/// Configures a visual element to act as a drag zone for a value field, allowing users to change the field's
/// value by dragging the mouse.
///
/// The type of the value held by the field.
/// The target field to be updated by dragging. This field must implement IValueField<T>.
/// The visual element that will serve as the interactable drag zone.
/// An optional function to dynamically determine if dragging is currently allowed. If null, dragging is always allowed.
/// Thrown if either the or is null.
/// Thrown if the does not implement IValueField<T>.
public static void SetupDragger(this BaseField field, VisualElement element, Func canDrag = null)
{
if (field == null) throw new ArgumentNullException(nameof(field));
if (element == null) throw new ArgumentNullException(nameof(element));
// Must implement IValueField for FieldMouseDragger to work
if (!(field is IValueField))
throw new ArgumentException($"Field must implement IValueField<{typeof(T).Name}>", nameof(field));
// Initialize dragger (requires casting to IValueField used by UIElements)
var dragger = new FieldMouseDragger((IValueField)field);
dragger.SetDragZone(element);
// Handle mouse over
element.RegisterCallback(_ =>
{
if (canDrag == null || canDrag())
element.AddToClassList(k_draggerHoverClass);
else
element.RemoveFromClassList(k_draggerHoverClass);
});
// Handle mouse leave
element.RegisterCallback(_ =>
element.RemoveFromClassList(k_draggerHoverClass));
// Removal of dragging capabilities if the field gets disabled while the mouse hovers.
field.RegisterCallback(_ =>
{
if (canDrag == null || canDrag())
element.RemoveFromClassList(k_draggerHoverClass);
});
}
}
}