DragAndDrop EditorGUILayout.Box ?

is it possible to somehow make DragAndDrop functionality for boxes in EditorGUI ? i’d like to make nodes but i can’t figure the dragndrop part

Here, I use these everywhere.

public static void DragDropArea<T>(string label, Action<T> onDrop, Action onMouseUp, float h = 25) where T : Object
{
	HorizontalBlock(() =>
	{
		// draw a box area for our drag-drop
		GUILayout.Space(15f);
		Rect dropArea = GUILayoutUtility.GetRect(0, h);
		GUI.Box(dropArea, label);

		// cache the current event
		Event currentEvent = Event.current;

		// if our mouse isn't contained within that box area, exit out
		if (!dropArea.Contains(currentEvent.mousePosition)) return;

		if (onMouseUp != null)
			if (currentEvent.type == EventType.MouseUp)
				onMouseUp();

		if (onDrop != null) {
			if (currentEvent.type == EventType.DragUpdated ||
				currentEvent.type == EventType.DragPerform) {

				// set the visual mode to copy
				DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

				// if we dropped something
				if (currentEvent.type == EventType.DragPerform) {

					// register that this drag-drop event has been handled by this control
					DragAndDrop.AcceptDrag();

					// loop over the dropped items
					foreach (var item in DragAndDrop.objectReferences) {
						onDrop(item as T);
					}
				}
				// since we've used the DragPerform event, we'll mark it as used
				// (its type will change to EventType.Used)
				// so that other controls ignore it
				Event.current.Use();
			}
		}
	});
}

Use these if you want manually register drag/drop for a custom field (Have a read at the DragAndDrop class to see what the methods do)

/// <summary>
/// Registers fieldRect for drop operations.
/// sets the fieldValue to whatever that's been dropped, returns fieldValue in either cases.
/// (could have used a ref parameter instead of returning the field)
/// </summary>
public static T RegisterFieldForDrop<T>(Rect fieldRect, T fieldValue, Func<Object[], Object> getDroppedObject) where T : Object
{
	Event e = Event.current;
	EventType eType = e.type;
	if (fieldRect.Contains(e.mousePosition) && eType == EventType.DragUpdated || eType == EventType.DragPerform) {
		DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
		if (eType == EventType.DragPerform) {
			DragAndDrop.AcceptDrag();
			fieldValue = getDroppedObject(DragAndDrop.objectReferences) as T;
			Event.current.Use();
		}
	}
	return fieldValue;
}

/// <summary>
/// Registers fieldRect for drag operations. dragObject is what's being dragged out of that field.
/// </summary>
public static void RegisterFieldForDrag(Rect fieldRect, Object dragObject)
{
	if (dragObject == null) return; // can't drag a null wtf!
	Event e = Event.current;
	if (fieldRect.Contains(e.mousePosition) && e.type == EventType.MouseDrag) {
		DragAndDrop.PrepareStartDrag();
		DragAndDrop.objectReferences = new[] { dragObject };
		DragAndDrop.StartDrag("drag");
		Event.current.Use();
	}
}

public static void HorizontalBlock(Action block)
{
	GUILayout.BeginHorizontal();
	block();
	GUILayout.EndHorizontal();
}

See this video of mine to see what I mean by “registering for a drag”