using UnityEngine.Experimental.Perception.Randomization.VisualElements; using UnityEngine.UIElements; namespace UnityEngine.Experimental.Perception.Randomization.Editor { class DragToReorderManipulator : MouseManipulator { bool m_Active; float m_Offset; RandomizerElement m_RandomizerElement; VisualElement m_DragHandle; VisualElement m_DragBar; VisualElement m_ParameterContainer; protected override void RegisterCallbacksOnTarget() { m_RandomizerElement = (RandomizerElement)target; m_DragHandle = m_RandomizerElement.Q("drag-handle"); m_DragHandle.RegisterCallback(OnMouseDown); m_DragHandle.RegisterCallback(OnMouseMove); m_DragHandle.RegisterCallback(OnMouseUp); } protected override void UnregisterCallbacksFromTarget() { m_DragHandle.UnregisterCallback(OnMouseDown); m_DragHandle.UnregisterCallback(OnMouseMove); m_DragHandle.UnregisterCallback(OnMouseUp); } void OnMouseDown(MouseDownEvent evt) { if (m_Active) { evt.StopImmediatePropagation(); return; } m_ParameterContainer = target.parent; m_DragBar = new ParameterDragBar(); m_DragBar.style.width = new StyleLength(m_ParameterContainer.resolvedStyle.width); target.parent.Add(m_DragBar); m_Offset = m_DragHandle.worldBound.position.y - m_ParameterContainer.worldBound.position.y; m_DragBar.style.top = evt.localMousePosition.y + m_Offset; m_Active = true; m_DragHandle.CaptureMouse(); evt.StopPropagation(); } void OnMouseMove(MouseMoveEvent evt) { if (!m_Active || !m_DragHandle.HasMouseCapture()) return; m_DragBar.style.top = evt.localMousePosition.y + m_Offset; evt.StopPropagation(); } void OnMouseUp(MouseUpEvent evt) { if (!m_Active || !m_DragHandle.HasMouseCapture() || !CanStopManipulation(evt)) return; var dragBarY = evt.localMousePosition.y + m_Offset; m_DragBar.RemoveFromHierarchy(); m_Active = false; m_DragHandle.ReleaseMouse(); evt.StopPropagation(); var p = 0; var middlePoints = new float[m_ParameterContainer.childCount]; foreach (var parameterElement in m_ParameterContainer.Children()) { var middleHeight = parameterElement.worldBound.height / 2; var localY = parameterElement.worldBound.y - m_ParameterContainer.worldBound.position.y; middlePoints[p++] = middleHeight + localY; } var randomizerIndex = m_RandomizerElement.parent.IndexOf(m_RandomizerElement); for (var i = 0; i < middlePoints.Length; i++) { if (dragBarY < middlePoints[i]) { ReorderParameter(randomizerIndex, i); return; } } ReorderParameter(randomizerIndex, middlePoints.Length); } void ReorderParameter(int currentIndex, int nextIndex) { m_RandomizerElement.randomizerList.ReorderRandomizer(currentIndex, nextIndex); } } }