This lets you drag a view of visual elements in an editor window.
Idea is:
- Create a visual element on the root that fills the view and interprets mouse events to drag the view.
- Add a dummy element to the root, and add your elements on to that.
- The first element adds the mouse delta of the drag event to the dummy element.
Problems:
- Haven’t worked on how to capture the event yet so if the mouse goes over one of the visual elements the drag stops
have put the code all in one script for now as i’m just jamming stuff out
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Experimental.UIElements;
using UnityEditor.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleEnums;
public class DraggerWindow : EditorWindow {
[MenuItem("UIElement examples/Draggable view")]
public static void OpenWindow()
{
var window = GetWindow<DraggerWindow>();
window.minSize = new Vector2(700, 700);
window.titleContent = new GUIContent("Draggable view example");
}
float zoom = 1;
void OnEnable()
{
// UIElement set up.
var root = this.GetRootVisualContainer();
VisualElement dummy = new VisualElement()
{
style ={
width=0,
height=0
}
};
dummy.clippingOptions = VisualElement.ClippingOptions.NoClipping;
VisualElement panel = new VisualElement()
{
style ={
// stretch to fit whole display
flex = 1,
alignSelf = Align.Stretch,
flexDirection = FlexDirection.Row,
backgroundColor = Color.black
}
};
panel.style.backgroundColor = Color.grey;
root.Add(panel);
DragManipulator dm = new DragManipulator(dummy);
panel.AddManipulator(dm);
root.Add(dummy);
root.style.backgroundColor = Color.black;
for (int i = 0; i < 10; i++)
{
VisualElement box = new VisualElement()
{
style ={
width = 50,
height=50,
backgroundColor = Random.ColorHSV()
}
};
dummy.Add(box);
box.transform.position = new Vector3(Random.Range(100, 600),-Random.Range(100, 600), 0);
}
}
}
class DragManipulator : Manipulator
{
VisualElement passTo;
bool dragging = false;
public DragManipulator(VisualElement passTo)
{
this.passTo = passTo;
}
protected override void RegisterCallbacksOnTarget()
{
target.RegisterCallback<MouseEnterEvent>(OnMouseEnterEvent);
target.RegisterCallback<MouseLeaveEvent>(OnMouseLeaveEvent);
target.RegisterCallback<MouseDownEvent>(OnMouseDownEvent);
target.RegisterCallback<MouseUpEvent>(OnMouseUpEvent);
target.RegisterCallback<MouseMoveEvent>(OnMouseMoveEvent);
}
protected override void UnregisterCallbacksFromTarget()
{
target.UnregisterCallback<MouseEnterEvent>(OnMouseEnterEvent);
target.UnregisterCallback<MouseLeaveEvent>(OnMouseLeaveEvent);
target.UnregisterCallback<MouseDownEvent>(OnMouseDownEvent);
target.UnregisterCallback<MouseUpEvent>(OnMouseUpEvent);
target.UnregisterCallback<MouseMoveEvent>(OnMouseMoveEvent);
}
protected virtual void OnMouseEnterEvent(MouseEventBase<MouseEnterEvent> evt)
{
}
protected virtual void OnMouseLeaveEvent(MouseEventBase<MouseLeaveEvent> evt)
{
// this hack gets around the fact I don't know how to capture events at the moment.
// if removed and the mouse leaves the element while dragging, the element gets stuck in drag mode.
dragging = false;
}
protected virtual void OnMouseDownEvent(MouseEventBase<MouseDownEvent> evt)
{
//target.TakeMouseCapture()
evt.StopPropagation();
// start the drag
dragging = true;
}
protected virtual void OnMouseUpEvent(MouseEventBase<MouseUpEvent> evt)
{
evt.StopPropagation();
// stop the drag
dragging = false;
}
protected virtual void OnMouseMoveEvent(MouseEventBase<MouseMoveEvent> evt)
{
if (dragging)
{
evt.StopPropagation();
OnDrag(evt);
}
}
protected virtual void OnDrag(MouseEventBase<MouseMoveEvent> evt)
{
passTo.transform.position += new Vector3(evt.mouseDelta.x, evt.mouseDelta.y, 0);
}
}