Beispiel #1
0
        /// <summary>
        /// Determines whether current event is a mouse drag event.
        ///
        /// True if has DragAndDropObjectReferences.
        ///
        /// True if mouse has moved since mouse button was pressed down and last input event type is MouseDrag, DragUpdated, or MouseDown for left mouse button.
        ///
        /// True if mouse has moved since mouse button was pressed down and current input event type is DragPerform, DragExited.
        ///
        /// NOTE: This can return true for the remaining duration of the the frame, even after MouseDownInfo.Clear(true) has been called.
        ///
        /// NOTE: This can return true, even if mouse down event was used.
        /// </summary>
        /// <returns> True if event is a mouse drag event, otherwise returns false. </returns>
        public bool IsDrag()
        {
            //UPDATE: The DragAndDropObjectReferences check is important
            //as without it the check would fail at random times when dragging
            //a MonoScript from the Project view on the custom InspectorWindow
            if (DrawGUI.IsUnityObjectDrag)
            {
                return(true);
            }

            if (isClick)
            {
                return(false);
            }

            switch (DrawGUI.LastInputEventType)
            {
            case EventType.DragPerform:
            case EventType.DragExited:
                return(Event.current != null && Event.current.Equals(DrawGUI.LastInputEvent()));

            case EventType.MouseDrag:
            case EventType.DragUpdated:
                return(true);

            case EventType.MouseDown:
                var lastInputEvent = DrawGUI.LastInputEvent();
                return(lastInputEvent != null && lastInputEvent.button == 0);

            default:
                return(false);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Determines whether current event is a mouse drag event.
        ///
        /// True if has DragAndDropObjectReferences.
        ///
        /// True if mouse has moved since mouse button was pressed down and last input event type is MouseDrag, DragUpdated, or MouseDown for right mouse button.
        ///
        /// True if mouse has moved since mouse button was pressed down and current input event type is DragPerform, DragExited.
        ///
        /// NOTE: This can return true for the remaining duration of the the frame, even after Clear has been called.
        ///
        /// NOTE: This can return true, even if mouse down event was used.
        /// </summary>
        /// <returns> True if event is a mouse drag event, otherwise returns false. </returns>
        public bool IsDrag()
        {
            if (DrawGUI.IsUnityObjectDrag)
            {
                return(true);
            }

            if (isClick)
            {
                return(false);
            }

            switch (DrawGUI.LastInputEventType)
            {
            case EventType.DragPerform:
            case EventType.DragExited:
                return(Event.current != null && Event.current.Equals(DrawGUI.LastInputEvent()));

            case EventType.MouseDrag:
            case EventType.DragUpdated:
                return(true);

            case EventType.ContextClick:
            case EventType.MouseDown:
                var lastInputEvent = DrawGUI.LastInputEvent();
                return(lastInputEvent != null && lastInputEvent.button == 1);

            default:
                return(false);
            }
        }
        private static void BeginEditorOrPropertyDrawer(out bool editingTextFieldWas, out EventType eventType, out KeyCode keyCode)
        {
            editingTextFieldWas = EditorGUIUtility.editingTextField;
            eventType           = DrawGUI.LastInputEventType;
            var lastInputEvent = DrawGUI.LastInputEvent();

            keyCode = lastInputEvent == null ? KeyCode.None : lastInputEvent.keyCode;
        }
        /// <inheritdoc/>
        protected override void OnSelectedInternal(ReasonSelectionChanged reason, IDrawer previous, bool isMultiSelection)
        {
                        #if DEV_MODE && DEBUG_ON_SELECTED
            Debug.Log(ToString() + ".OnSelectedInternal(" + reason + "," + StringUtils.ToString(previous) + ")");
                        #endif

            bool wasUnfolded = false;

            bool isClick = false;
            switch (reason)
            {
            case ReasonSelectionChanged.PrefixClicked:
                isClick = true;
                if (DrawGUI.LastInputEvent().control)
                {
                    ComponentDrawerUtility.singleInspectedInstance = this;
                }
                break;

            case ReasonSelectionChanged.ControlClicked:
                if (DrawGUI.LastInputEvent().control)
                {
                    ComponentDrawerUtility.singleInspectedInstance = this;
                }
                return;

            case ReasonSelectionChanged.ThisClicked:
                isClick = true;
                break;
            }

                        #if UNFOLD_ON_SELECT_IN_SINGLE_ACTIVE_MODE
            if (UserSettings.EditComponentsOneAtATime && !inspector.HasFilter)
            {
                if (ComponentDrawerUtility.singleInspectedInstance != null && ComponentDrawerUtility.singleInspectedInstance != this)
                {
                    ComponentDrawerUtility.singleInspectedInstance.SetUnfolded(false);
                }
                ComponentDrawerUtility.singleInspectedInstance = this;

                // if Component was clicked, let the click event handle the unfolding
                if (!Unfolded && (!isClick || (MouseoveredHeaderPart != HeaderPart.FoldoutArrow && !inspector.Preferences.changeFoldedStateOnFirstClick)))
                {
                    wasUnfolded = true;
                    // allow bypassing EditComponentsOneAtATime functionality by holding down control when clicking the Component header
                    bool collapseAllOthers = !Event.current.control || reason != ReasonSelectionChanged.PrefixClicked;
                    SetUnfolded(true, collapseAllOthers, false);
                }
            }
                        #endif

            base.OnSelectedInternal(reason, previous, isMultiSelection);

            if (wasUnfolded)
            {
                ExitGUIUtility.ExitGUI();
            }
        }
        /// <inheritdoc />
        protected override void OnSelectedInternal(ReasonSelectionChanged reason, IDrawer previous, bool isMultiSelection)
        {
            bool isClick = false;

            switch (reason)
            {
            case ReasonSelectionChanged.PrefixClicked:
                isClick = true;
                if (DrawGUI.LastInputEvent().control)
                {
                    ComponentDrawerUtility.singleInspectedInstance = this;
                }
                break;

            case ReasonSelectionChanged.ControlClicked:
                if (DrawGUI.LastInputEvent().control)
                {
                    ComponentDrawerUtility.singleInspectedInstance = this;
                }
                return;
            }

                        #if UNFOLD_ON_SELECT_IN_SINGLE_ACTIVE_MODE
            if (UserSettings.EditComponentsOneAtATime && !InspectorUtility.ActiveInspector.HasFilter)
            {
                if (ComponentDrawerUtility.singleInspectedInstance != null && ComponentDrawerUtility.singleInspectedInstance != this)
                {
                    ComponentDrawerUtility.singleInspectedInstance.SetUnfolded(false);
                }
                ComponentDrawerUtility.singleInspectedInstance = this;

                // if Component was clicked, let the click event handle the unfolding
                if (!Unfolded && (!isClick || (MouseoveredHeaderPart != HeaderPart.FoldoutArrow && !inspector.Preferences.changeFoldedStateOnFirstClick)))
                {
                    SetUnfolded(true, Event.current.alt);
                }
            }
                        #endif

            base.OnSelectedInternal(reason, previous, isMultiSelection);
        }
        /// <inheritdoc/>
        protected override void OnDeselectedInternal(ReasonSelectionChanged reason, IDrawer losingFocusTo)
        {
                        #if DEV_MODE && DEBUG_ON_DESELECTED
            Debug.Log(ToString() + ".OnDeselectedInternal(" + reason + "," + StringUtils.ToString(losingFocusTo) + ")");
                        #endif

            bool unfoldIfLostFocus = UserSettings.EditComponentsOneAtATime;
            switch (reason)
            {
            case ReasonSelectionChanged.PrefixClicked:
            case ReasonSelectionChanged.ControlClicked:
                if (DrawGUI.LastInputEvent().control)
                {
                    unfoldIfLostFocus = false;
                }
                break;
            }

            if (unfoldIfLostFocus)
            {
                var test = losingFocusTo;
                while (test != null)
                {
                    var component = test as IComponentDrawer;
                    if (component != null)
                    {
                        if (component != this)
                        {
                            SetUnfolded(false, false);
                        }
                        break;
                    }
                    test = test.Parent;
                }
            }

            base.OnDeselectedInternal(reason, losingFocusTo);
        }
        private static void EndEditorOrPropertyDrawer(bool editingTextFieldWas, EventType eventType, KeyCode keyCode)
        {
            if (EditorGUIUtility.editingTextField != editingTextFieldWas)
            {
                if (eventType != EventType.KeyDown && eventType != EventType.KeyUp)
                {
                                        #if DEV_MODE && DEBUG_SET_EDITING_TEXT_FIELD
                    Debug.Log("DrawGUI.EditingTextField = " + StringUtils.ToColorizedString(EditorGUIUtility.editingTextField) + " with eventType=" + StringUtils.ToString(eventType) + ", keyCode=" + keyCode + ", lastInputEvent=" + StringUtils.ToString(DrawGUI.LastInputEvent()));
                                        #endif
                    DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
                }
                else
                {
                    switch (keyCode)
                    {
                    case KeyCode.UpArrow:
                    case KeyCode.DownArrow:
                    case KeyCode.LeftArrow:
                    case KeyCode.RightArrow:
                        if (!EditorGUIUtility.editingTextField)
                        {
                                                                #if DEV_MODE
                            Debug.Log("DrawGUI.EditingTextField = " + StringUtils.ToColorizedString(false) + " with eventType=" + StringUtils.ToString(eventType) + ", keyCode=" + keyCode + ", lastInputEvent=" + StringUtils.ToString(DrawGUI.LastInputEvent()));
                                                                #endif
                            DrawGUI.EditingTextField = false;
                        }
                        else                                 // prevent Unity automatically starting field editing when field focus is changed to a text field, as that is not how Power Inspector functions
                        {
                                                                #if DEV_MODE
                            Debug.LogWarning("EditorGUIUtility.editingTextField = " + StringUtils.ToColorizedString(false) + " with eventType=" + StringUtils.ToString(eventType) + ", keyCode=" + keyCode + ", lastInputEvent=" + StringUtils.ToString(DrawGUI.LastInputEvent()));
                                                                #endif
                            EditorGUIUtility.editingTextField = false;
                        }
                        return;

                    default:
                                                        #if DEV_MODE
                        Debug.Log("DrawGUI.EditingTextField = " + StringUtils.ToColorizedString(false) + " with eventType=" + StringUtils.ToString(eventType) + ", keyCode=" + keyCode + ", lastInputEvent=" + StringUtils.ToString(DrawGUI.LastInputEvent()));
                                                        #endif
                        DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
                        return;
                    }
                }
            }
        }
Beispiel #8
0
        /// <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;
            }
        }
Beispiel #9
0
        /// <summary>
        /// This is called every frame after cursor has left the bounds of the Inspector window during a drag-n-drop event.
        /// Each frame we try and firure out whether or not a drag n drop is still happening, and once we know it,
        /// adjust MouseDownInfo state accordingly.
        /// </summary>
        /// <param name="newPosition"> The new position. </param>
        private void HandleDragAfterCursorEnteredInspector(Vector2 newPosition)
        {
            var e = Event.current;

            if (e == null)
            {
                                #if DEV_MODE
                Debug.LogWarning("HandleDragAfterCursorEnteredInspector - ignoring because not mouse event: " + StringUtils.ToString(e));
                                #endif
                return;
            }

            switch (e.type)
            {
            case EventType.DragUpdated:
            case EventType.MouseDrag:
                // it's a drag!

                                        #if DEV_MODE
                Debug.LogWarning("HandleDragAfterCursorEnteredInspector - restoring Drag because event=" + StringUtils.ToString(e));
                                        #endif

                                        #if DEV_MODE
                Debug.LogError("STOPPED LISTENING - IS DRAG!!!");
                                        #endif

                Cursor.OnPositionChanged          -= HandleDragAfterCursorEnteredInspector;
                mouseoveredInspectorLeftDuringDrag = false;
                MouseButtonIsDown = true;
                IsClick           = false;
                var draggedObjects = DrawGUI.Active.DragAndDropObjectReferences;
                if (draggedObjects != null)
                {
                    MouseButtonIsDown = true;
                    IsClick           = false;
                    OnDragStarted(inspector, draggedObjects);
                }
                break;

            //case EventType.Layout: //I think that DragUpdated should always get called instead of Layout during Drags. UPDATE: Noup. At least gets called during frame that cursor enters a new inspector during a drag.
            case EventType.MouseMove:
            case EventType.MouseDown:
            case EventType.MouseUp:
                                        #if DEV_MODE
                Debug.LogError("STOPPED LISTENING - NOT DRAG!!!");
                                        #endif

                // it's no longer a drag...
                Cursor.OnPositionChanged -= HandleDragAfterCursorEnteredInspector;

                                        #if DEV_MODE
                Debug.LogWarning("HandleDragAfterCursorEnteredInspector - discarding Drag because event=" + StringUtils.ToString(e));
                                        #endif

                var lastInputEvent = DrawGUI.LastInputEvent();
                if (lastInputEvent != null)
                {
                    var type = lastInputEvent.type;
                    if (type != EventType.DragExited && type != EventType.MouseUp)
                    {
                        var setLastInputEvent = new Event(lastInputEvent);
                        setLastInputEvent.type = mouseoveredInspectorLeftDuringDrag || DrawGUI.IsUnityObjectDrag ? EventType.DragExited : EventType.MouseUp;
                        DrawGUI.Use(setLastInputEvent);
                    }
                }

                Clear(true);

                mouseoveredInspectorLeftDuringDrag = false;

                                        #if DEV_MODE && PI_ASSERTATIONS
                Debug.Assert(!IsClick, "IsClick was true after MouseDownInfo.Clear was called during event " + StringUtils.ToString(e));
                Debug.Assert(!MouseButtonIsDown, "MouseButtonIsDown was true after MouseDownInfo.Clear was called during event " + StringUtils.ToString(e));
                Debug.Assert(!IsDrag(), "IsDrag was true after MouseDownInfo.Clear was called during event " + StringUtils.ToString(e));
                                        #endif

                break;
            }
        }
Beispiel #10
0
        /// <summary>
        /// If DrawGUI.EditingTextField and EditorGUIUtility.editingTextField values are not in sync,
        /// then figures out which should take precedence over the other, and syncs their values accordingly.
        /// </summary>
        public static void SyncEditingTextField()
        {
            if (DrawGUI.EditingTextField == EditorGUIUtility.editingTextField)
            {
                return;
            }

            var manager = InspectorUtility.ActiveManager;

            if (manager == null)
            {
                DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
                return;
            }

            var lastInputEvent = DrawGUI.LastInputEvent();

            if (lastInputEvent == null)
            {
                DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
                return;
            }

            if (lastInputEvent.isMouse)
            {
                // something else than Power Inspector was probably clicked
                if (manager.MouseoveredInspector == null)
                {
                                        #if DEV_MODE && DEBUG_SYNC_EDITING_TEXT_FIELD
                    Debug.Log("DrawGUI.editingTextField = " + StringUtils.ToColorizedString(EditorGUIUtility.editingTextField) + " with lastInputEvent=" + StringUtils.ToString(lastInputEvent) + " because MouseoveredInspector=" + StringUtils.Null);
                                        #endif
                    DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
                }
                // editing text fields is not allowed when multiple controls are selected
                else if (manager.HasMultiSelectedControls)
                {
                                        #if DEV_MODE && DEBUG_SYNC_EDITING_TEXT_FIELD
                    Debug.Log("DrawGUI.EditingTextField = " + StringUtils.False + " with lastInputEvent=" + StringUtils.ToString(lastInputEvent) + " because HasMultiSelectedControls=" + StringUtils.True);
                                        #endif
                    DrawGUI.EditingTextField = false;
                }
                else
                {
                                        #if DEV_MODE && DEBUG_SYNC_EDITING_TEXT_FIELD
                    Debug.LogWarning("EditorGUIUtility.editingTextField = " + StringUtils.ToColorizedString(DrawGUI.EditingTextField) + " with lastInputEvent=" + StringUtils.ToString(lastInputEvent));
                                        #endif
                    EditorGUIUtility.editingTextField = DrawGUI.EditingTextField;
                }
            }
            else if (manager.SelectedInspector == null || !manager.SelectedInspector.InspectorDrawer.HasFocus)
            {
                                #if DEV_MODE && DEBUG_SYNC_EDITING_TEXT_FIELD
                Debug.Log("DrawGUI.editingTextField = " + StringUtils.ToColorizedString(EditorGUIUtility.editingTextField) + " with lastInputEvent=" + StringUtils.ToString(lastInputEvent) + " because MouseoveredInspector=" + StringUtils.Null);
                                #endif
                DrawGUI.EditingTextField = EditorGUIUtility.editingTextField;
            }
            else
            {
                                #if DEV_MODE && DEBUG_SYNC_EDITING_TEXT_FIELD
                Debug.LogWarning("EditorGUIUtility.editingTextField = " + StringUtils.ToColorizedString(DrawGUI.EditingTextField) + " with lastInputEvent=" + StringUtils.ToString(lastInputEvent));
                                #endif
                EditorGUIUtility.editingTextField = DrawGUI.EditingTextField;
            }
        }