void HandleEditorDragging(Editor[] editors, int editorIndex, Rect targetRect, float markerY, bool bottomTarget) { var evt = Event.current; switch (evt.type) { case EventType.DragUpdated: if (targetRect.Contains(evt.mousePosition)) { var draggingMode = DragAndDrop.GetGenericData(k_DraggingModeKey) as DraggingMode ? ; if (!draggingMode.HasValue) { var draggedObjects = DragAndDrop.objectReferences; if (draggedObjects.Length == 0) { draggingMode = DraggingMode.NotApplicable; } else if (draggedObjects.All(o => o is Component && !(o is Transform))) { draggingMode = DraggingMode.Component; } else if (draggedObjects.All(o => o is MonoScript)) { draggingMode = DraggingMode.Script; } else { draggingMode = DraggingMode.NotApplicable; } DragAndDrop.SetGenericData(k_DraggingModeKey, draggingMode); } if (draggingMode.Value != DraggingMode.NotApplicable) { if (bottomTarget) { m_TargetAbove = false; m_TargetIndex = m_LastIndex; } else { m_TargetAbove = evt.mousePosition.y < targetRect.y + targetRect.height / 2f; m_TargetIndex = editorIndex; if (m_TargetAbove) { m_TargetIndex++; while (m_TargetIndex < editors.Length && m_InspectorWindow.ShouldCullEditor(editors, m_TargetIndex)) { m_TargetIndex++; } if (m_TargetIndex == editors.Length) { m_TargetIndex = -1; return; } } } if (m_TargetAbove && m_InspectorWindow.EditorHasLargeHeader(m_TargetIndex, editors)) { m_TargetIndex--; while (m_TargetIndex >= 0 && m_InspectorWindow.ShouldCullEditor(editors, m_TargetIndex)) { m_TargetIndex--; } if (m_TargetIndex == -1) { return; } m_TargetAbove = false; } if (draggingMode.Value == DraggingMode.Script) { // Validate dragging scripts // Always allow script dragging, instead fail during DragPerform with a dialog box DragAndDrop.visualMode = DragAndDropVisualMode.Link; } else { // Validate dragging components var valid = false; if (editors[m_TargetIndex].targets.All(t => t is Component)) { var targetComponents = editors[m_TargetIndex].targets.Cast <Component>().ToArray(); var sourceComponents = DragAndDrop.objectReferences.Cast <Component>().ToArray(); valid = MoveOrCopyComponents(sourceComponents, targetComponents, EditorUtility.EventHasDragCopyModifierPressed(evt), true); } if (valid) { DragAndDrop.visualMode = EditorUtility.EventHasDragCopyModifierPressed(evt) ? DragAndDropVisualMode.Copy : DragAndDropVisualMode.Move; } else { DragAndDrop.visualMode = DragAndDropVisualMode.None; m_TargetIndex = -1; return; } } evt.Use(); } } else { m_TargetIndex = -1; } break; case EventType.DragPerform: if (m_TargetIndex != -1) { var draggingMode = DragAndDrop.GetGenericData(k_DraggingModeKey) as DraggingMode ? ; if (!draggingMode.HasValue || draggingMode.Value == DraggingMode.NotApplicable) { m_TargetIndex = -1; return; } if (!editors[m_TargetIndex].targets.All(t => t is Component)) { return; } var targetComponents = editors[m_TargetIndex].targets.Cast <Component>().ToArray(); if (draggingMode.Value == DraggingMode.Script) { var scripts = DragAndDrop.objectReferences.Cast <MonoScript>(); // Ensure all script components can be added var valid = true; foreach (var targetComponent in targetComponents) { var gameObject = targetComponent.gameObject; if (scripts.Any(s => !ComponentUtility.WarnCanAddScriptComponent(targetComponent.gameObject, s))) { valid = false; break; } } if (valid) { Undo.IncrementCurrentGroup(); var undoGroup = Undo.GetCurrentGroup(); // Add script components var index = 0; var addedComponents = new Component[targetComponents.Length * scripts.Count()]; for (int i = 0; i < targetComponents.Length; i++) { var targetComponent = targetComponents[i]; var gameObject = targetComponent.gameObject; bool targetIsTransform = targetComponent is Transform; foreach (var script in scripts) { addedComponents[index++] = ObjectFactory.AddComponent(gameObject, script.GetClass()); } // If the target is a Transform, the AddComponent might have replaced it with a RectTransform. // Handle this possibility by updating the target component. if (targetIsTransform) { targetComponents[i] = gameObject.transform; } } // Move added components relative to target components if (!ComponentUtility.MoveComponentsRelativeToComponents(addedComponents, targetComponents, m_TargetAbove)) { // Revert added components if move operation fails (e.g. user aborts when asked to break prefab instance) Undo.RevertAllDownToGroup(undoGroup); } } } else { // Handle dragging components var sourceComponents = DragAndDrop.objectReferences.Cast <Component>().ToArray(); if (sourceComponents.Length == 0 || targetComponents.Length == 0) { return; } MoveOrCopyComponents(sourceComponents, targetComponents, EditorUtility.EventHasDragCopyModifierPressed(evt), false); } m_TargetIndex = -1; DragAndDrop.AcceptDrag(); evt.Use(); EditorGUIUtility.ExitGUI(); } break; case EventType.DragExited: m_TargetIndex = -1; break; case EventType.Repaint: if (m_TargetIndex != -1 && targetRect.Contains(evt.mousePosition)) { Styles.insertionMarker.Draw(GetMarkerRect(targetRect, markerY, m_TargetAbove), false, false, false, false); } break; } }
void HandleEditorDragging(Editor[] editors, int editorIndex, Rect targetRect, float markerY, bool bottomTarget) { var evt = Event.current; switch (evt.type) { case EventType.DragUpdated: if (targetRect.Contains(evt.mousePosition)) { var draggingMode = DragAndDrop.GetGenericData(k_DraggingModeKey) as DraggingMode ? ; if (!draggingMode.HasValue) { var draggedObjects = DragAndDrop.objectReferences; if (draggedObjects.Length == 0) { draggingMode = DraggingMode.NotApplicable; } else if (draggedObjects.All(o => o is Component && !(o is Transform))) { draggingMode = DraggingMode.Component; } else if (draggedObjects.All(o => o is MonoScript)) { draggingMode = DraggingMode.Script; } else { draggingMode = DraggingMode.NotApplicable; } DragAndDrop.SetGenericData(k_DraggingModeKey, draggingMode); } if (draggingMode.Value != DraggingMode.NotApplicable) { if (bottomTarget) { m_TargetAbove = false; m_TargetIndex = m_LastIndex; } else { m_TargetAbove = evt.mousePosition.y < targetRect.y + targetRect.height / 2f; m_TargetIndex = editorIndex; if (m_TargetAbove) { m_TargetIndex++; while (m_TargetIndex < editors.Length && m_InspectorWindow.ShouldCullEditor(editors, m_TargetIndex)) { m_TargetIndex++; } if (m_TargetIndex == editors.Length) { m_TargetIndex = -1; return; } } } if (m_TargetAbove && InspectorWindow.EditorHasLargeHeader(m_TargetIndex, editors)) { m_TargetIndex--; while (m_TargetIndex >= 0 && m_InspectorWindow.ShouldCullEditor(editors, m_TargetIndex)) { m_TargetIndex--; } if (m_TargetIndex == -1) { return; } m_TargetAbove = false; } if (draggingMode.Value == DraggingMode.Script) { // Validate dragging scripts // Always allow script dragging, instead fail during DragPerform with a dialog box DragAndDrop.visualMode = DragAndDropVisualMode.Link; } else { // Validate dragging components var valid = false; if (editors[m_TargetIndex].targets.All(t => t is Component)) { var targetComponents = editors[m_TargetIndex].targets.Cast <Component>().ToArray(); var sourceComponents = DragAndDrop.objectReferences.Cast <Component>().ToArray(); valid = MoveOrCopyComponents(sourceComponents, targetComponents, EditorUtility.EventHasDragCopyModifierPressed(evt), true); } if (valid) { DragAndDrop.visualMode = EditorUtility.EventHasDragCopyModifierPressed(evt) ? DragAndDropVisualMode.Copy : DragAndDropVisualMode.Move; } else { DragAndDrop.visualMode = DragAndDropVisualMode.None; m_TargetIndex = -1; return; } } evt.Use(); } } else { m_TargetIndex = -1; } break; case EventType.DragPerform: if (m_TargetIndex != -1) { HandleDragPerformEvent(editors, evt, ref m_TargetIndex); } break; case EventType.DragExited: m_TargetIndex = -1; break; case EventType.Repaint: if (m_TargetIndex != -1 && editorIndex == m_TargetIndex && (targetRect.Contains(evt.mousePosition) || m_BottomArea.Contains(GUIClip.UnclipToWindow(evt.mousePosition)) && m_BottomAreaDropIndex == editors.Length - 1)) { Styles.insertionMarker.Draw(GetMarkerRect(targetRect, markerY, m_TargetAbove), false, false, false, false); } break; } }