/// <summary> /// This should be called at the beginning of OnGUI of every instance of classes that implement IInspectorDrawer. /// /// SEE ALSO: DrawGUI.BeginOnGUI and InspectorUtility.BeginInspector. /// </summary> /// <param name="inspectorDrawer"> The inspector drawer instance. </param> /// <param name="splittable"> The inspector drawer if it implements ISplittableInspectorDrawer, otherwise null. </param> public static void BeginInspectorDrawer([NotNull] IInspectorDrawer inspectorDrawer, [CanBeNull] ISplittableInspectorDrawer splittable) { #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(inspectorDrawer != null); #endif var manager = inspectorDrawer.Manager; activeInspectorDrawer = inspectorDrawer; ActiveManager = manager; activeManager.ActiveInspector = inspectorDrawer.MainView; var e = Event.current; #if DEV_MODE && PI_ASSERTATIONS Debug.Assert(e != null); #endif var mouseDownInfo = activeManager.MouseDownInfo; // Events like MouseUp, DragUpdated and DragPerformed are normally ignored when the cursor is outside EditorWindow bounds // but when a field is being dragged we still need those events (especially important for the MouseUp event!) var type = mouseDownInfo.GetEventTypeForMouseUpDetection(e); if (mouseDownInfo.NowReordering) { var reordering = mouseDownInfo.Reordering; var dropTarget = reordering.MouseoveredDropTarget; // When reordering and cursor is not above a valid drop target, set DragAndDropVisualMode to rejected, // unless dragging Object references outside window bounds, where want to allow dragging into other // EditorWindows. // UPDATE: This broke drag n drop e.g. from Component header to object reference field inside a custom editor. //if(dropTarget.Parent == null && ((DrawGUI.Active.DragAndDropObjectReferences.Length == 0 || activeManager.MouseoveredInspector != null))) if (dropTarget.Parent == null && DrawGUI.Active.DragAndDropObjectReferences.Length == 0) { #if DEV_MODE Debug.LogWarning("Reordering Rejected because dropTarget.Parent=null && DrawGUI.Active.DragAndDropObjectReferences=" + StringUtils.ToString(DrawGUI.Active.DragAndDropObjectReferences) + ", activeManager.MouseoveredInspector=" + StringUtils.ToString(activeManager.MouseoveredInspector)); #endif // Update: only do this once cursor has moved, otherwise it can look strange during simple click events if (mouseDownInfo.CursorMovedAfterMouseDown) { DrawGUI.Active.DragAndDropVisualMode = DragAndDropVisualMode.Rejected; } } DrawGUI.Active.AddCursorRect(new Rect(0f, 0f, 100000f, 100000f), MouseCursor.MoveArrow); } else if (mouseDownInfo.NowDraggingPrefix) { DrawGUI.Active.SetCursor(MouseCursor.SlideArrow); } switch (type) { case EventType.Repaint: if (inspectorDrawer.MainView.RequiresConstantRepaint() || (splittable != null && splittable.ViewIsSplit && splittable.SplitView.RequiresConstantRepaint())) { inspectorDrawer.Repaint(); } break; case EventType.Layout: activeManager.OnLayout(); UpdateDimensions(inspectorDrawer, splittable); break; case EventType.ValidateCommand: inspectorDrawer.OnValidateCommand(e); break; case EventType.ExecuteCommand: if (OnExecuteCommand != null) { if (inspectorDrawer == manager.FirstInspectorDrawer) { #if DEV_MODE && DEBUG_EXECUTE_COMMAND Debug.Log("ExecuteCommand(" + e.commandName + ")"); #endif OnExecuteCommand(ActiveManager.LastSelectedActiveOrDefaultInspector(), e.commandName); } #if DEV_MODE && DEBUG_EXECUTE_COMMAND else { Debug.Log("ExecuteCommand(" + e.commandName + ") not sent with e=" + StringUtils.ToString(e) + ", OnExecuteCommand=" + StringUtils.ToString(OnExecuteCommand)); } #endif } inspectorDrawer.OnExecuteCommand(e); break; case EventType.MouseUp: case EventType.DragPerform: #if DEV_MODE && (DEBUG_MOUSE_UP || DEBUG_DRAG_N_DROP) Debug.Log(type + " with IsUnityObjectDrag=" + StringUtils.True + ", MouseDownInfo.Inspector=" + activeManager.MouseDownInfo.Inspector + ", activeInspectorDrawer.MouseIsOver=" + (inspectorDrawer == null ? StringUtils.Null : StringUtils.ToColorizedString(inspectorDrawer.MouseIsOver))); #endif inspectorDrawer.Repaint(); mouseDownInfo.OnMouseUp(activeManager); break; case EventType.DragExited: //IMPORTANT NOTE: DragExited gets called when during DragNDrop cursor leaves EditorWindow bounds! #if DEV_MODE && UNITY_EDITOR Debug.Log(type + " with LastInputEvent().type=" + DrawGUI.LastInputEvent().type + ", IsUnityObjectDrag=" + StringUtils.ToColorizedString(DrawGUI.IsUnityObjectDrag) + ", EditorWindow.focusedWindow=" + UnityEditor.EditorWindow.focusedWindow + ", activeManager.MouseoveredInspector=" + activeManager.MouseoveredInspector + ", mouseoveredDrawer.position=" + (activeManager.MouseoveredInspector == null || activeManager.MouseoveredInspector.InspectorDrawer == null ? StringUtils.Null : activeManager.MouseoveredInspector.InspectorDrawer.position.ToString()) + ", MouseDownInfo.Inspector=" + activeManager.MouseDownInfo.Inspector + ", Drawer.MouseIsOver=" + (activeInspectorDrawer == null ? StringUtils.Null : StringUtils.ToColorizedString(activeInspectorDrawer.MouseIsOver))); #endif if (mouseDownInfo.IsDragExitedReallyMouseLeaveWindowEvent()) { #if DEV_MODE Debug.LogWarning("Ignoring DragExited call because IsDragExitedReallyMouseLeaveWindowEvent=" + StringUtils.True + " - cursor probably just left EditorWindow bounds."); #endif break; } inspectorDrawer.Repaint(); mouseDownInfo.OnMouseUp(activeManager); break; case EventType.MouseDown: ActiveManager.MouseDownInfo.OnMouseDown(); #if DEV_MODE && DEBUG_ON_MOUSE_DOWN Debug.Log("MouseDown with button=" + e.button + ", keyCode=" + e.keyCode + ", MouseoveredSelectable=" + StringUtils.ToString(ActiveManager.MouseoveredSelectable)); #endif break; case EventType.KeyDown: inspectorDrawer.OnKeyDown(e); break; case EventType.KeyUp: inspectorDrawer.Manager.OnKeyUp(e); break; } }