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); }); } } }