예제 #1
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;
            }
        }
        public static void OnKeyDown(this IInspectorDrawer inspectorDrawer, Event e)
        {
                        #if DEV_MODE && DEBUG_KEYBOARD_INPUT
            Debug.Log(StringUtils.ToColorizedString(inspectorDrawer.ToString(), ".OnKeyDown(", e.keyCode, ") with HasFocus=", inspectorDrawer.HasFocus, ", selectedControl=", StringUtils.ToString(inspectorDrawer.SelectedOrDefaultView().FocusedDrawer), ", SelectedPart=", inspectorDrawer.Manager.SelectedInspectorPart));
                        #endif

            if (!inspectorDrawer.HasFocus)
            {
                return;
            }

            var view = inspectorDrawer.SelectedOrDefaultView();
            var keys = view.Preferences.keyConfigs;

                        #if !POWER_INSPECTOR_LITE
            if (keys.stepBackInSelectionHistory.DetectAndUseInput(e))
            {
                view.StepBackInSelectionHistory();
                return;
            }
            if (keys.stepForwardInSelectionHistory.DetectAndUseInput(e))
            {
                view.StepForwardInSelectionHistory();
                return;
            }
                        #endif

            inspectorDrawer.Repaint();

            DrawGUI.RegisterInputEvent(e);

            var activeView = inspectorDrawer.SelectedOrDefaultView();

            // give controls time to react to selection changes, editing text field changes etc.
            // before cached values are updated. (e.g. unapplied changes in delayed fields are
            // not discarded before they have time to get applied
            activeView.ResetNextUpdateCachedValues();

                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(!inspectorDrawer.HasFocus || activeView.Selected);
                        #endif

                        #if DEV_MODE && DEBUG_KEYBOARD_INPUT
            Debug.Log(StringUtils.ToColorizedString("OnKeyDown activeView.Selected=", activeView.Selected, ", activeView.FocusedDrawer=", activeView.FocusedDrawer + ", Manager.SelectedInspector=", inspectorDrawer.Manager.SelectedInspector, ", inspectorDrawer.HasFocus=", inspectorDrawer.HasFocus));
                        #endif

            if (activeView.Toolbar.OnKeyboardInputGivenWhenNotSelected(e, activeView.Preferences.keyConfigs))
            {
                if (e.type != EventType.Used)
                {
                    DrawGUI.Use(e);
                    ExitGUIUtility.ExitGUI();
                }
            }

            IDrawer selectedControl = null;
            if (activeView.Selected)
            {
                selectedControl = activeView.FocusedDrawer;
                if (selectedControl != null)
                {
                    var onKeyboardInputBeingGiven = selectedControl.OnKeyboardInputBeingGiven;
                    if (onKeyboardInputBeingGiven != null)
                    {
                                                #if DEV_MODE && DEBUG_KEYBOARD_INPUT
                        Debug.Log("onKeyboardInputBeingGiven(" + StringUtils.ToString(e) + "): " + StringUtils.ToString(onKeyboardInputBeingGiven));
                                                #endif
                        if (onKeyboardInputBeingGiven(selectedControl, e, selectedControl.Inspector.Preferences.keyConfigs))
                        {
                            return;
                        }
                    }

                    if (selectedControl.OnKeyboardInputGiven(e, selectedControl.Inspector.Preferences.keyConfigs))
                    {
                        return;
                    }
                }
                else if (inspectorDrawer.Manager.SelectedInspectorPart == InspectorPart.Toolbar)
                {
                    activeView.Toolbar.OnKeyboardInputGiven(e, activeView.Preferences.keyConfigs);
                }
                else if (inspectorDrawer.Manager.SelectedInspectorPart == InspectorPart.Viewport || inspectorDrawer.Manager.SelectedInspectorPart == InspectorPart.None)
                {
                    bool fieldChangeInputGiven;
                    if (keys.DetectNextField(e, true) || keys.DetectPreviousField(e, true) ||
                        keys.nextFieldLeft.DetectAndUseInput(e) || keys.nextFieldRight.DetectAndUseInput(e) ||
                        keys.nextFieldDown.DetectAndUseInput(e) || keys.nextFieldUp.DetectAndUseInput(e))
                    {
                        fieldChangeInputGiven = true;
                    }
                    else if (e.modifiers == EventModifiers.FunctionKey)
                    {
                        switch (e.keyCode)
                        {
                        case KeyCode.DownArrow:
                        case KeyCode.UpArrow:
                        case KeyCode.LeftArrow:
                        case KeyCode.RightArrow:
                            fieldChangeInputGiven = true;
                            break;

                        default:
                            fieldChangeInputGiven = false;
                            break;
                        }
                    }
                    else
                    {
                        fieldChangeInputGiven = false;
                    }

                    if (fieldChangeInputGiven)
                    {
                        var drawers = activeView.State.drawers;
                        if (drawers.Length == 0)
                        {
                            if (activeView.Toolbar != null)
                            {
                                activeView.Toolbar.OnFindCommandGiven();
                            }
                            else
                            {
                                KeyboardControlUtility.SetKeyboardControl(0, 3);
                            }
                        }
                        else
                        {
                            var first  = drawers[0];
                            var select = first.GetNextSelectableDrawerRight(true, null);

                                                        #if DEV_MODE && DEBUG_NEXT_FIELD
                            Debug.Log(first + ".GetNextSelectableDrawerRight: " + StringUtils.ToString(select));
                                                        #endif

                            if (select != null)
                            {
                                activeView.Select(select, ReasonSelectionChanged.SelectNextControl);
                            }
                        }
                    }
                }
            }

            if (DrawGUI.EditingTextField && keys.DetectTextFieldReservedInput(e, TextFieldType.TextRow))
            {
                                #if DEV_MODE && DEBUG_KEYBOARD_INPUT
                Debug.Log(StringUtils.ToColorizedString("OnKeyboardInputGiven( ", StringUtils.ToString(e), ") DetectTextFieldReservedInput: ", true, " with selectedControl=", selectedControl));
                                #endif
                return;
            }

            if (keys.addComponent.DetectInput(e))
            {
                                #if DEV_MODE
                Debug.Log("AddComponent shortcut detected");
                                #endif

                if (AddComponentButtonDrawer.OpenSelectedOrFirstFoundInstance(activeView))
                {
                    DrawGUI.Use(e);
                }
            }

            if (keys.toggleSplitView.DetectInput(e))
            {
                var splittable = inspectorDrawer as ISplittableInspectorDrawer;
                if (splittable != null && splittable.CanSplitView)
                {
                    DrawGUI.Use(e);
                    bool setSplitView = !splittable.ViewIsSplit;
                    splittable.MainView.OnNextLayout(() => splittable.SetSplitView(setSplitView));
                }
            }

            if (keys.refresh.DetectAndUseInput(e))
            {
                var selectedInspector = inspectorDrawer.Manager.SelectedInspector;
                if (selectedInspector != null && selectedInspector.InspectorDrawer == inspectorDrawer)
                {
                    selectedInspector.ForceRebuildDrawers();
                }
                else
                {
                    var mainView = inspectorDrawer.MainView;
                    mainView.ForceRebuildDrawers();
                    var splittable = inspectorDrawer as ISplittableInspectorDrawer;
                    if (splittable != null && splittable.ViewIsSplit)
                    {
                        splittable.SplitView.ForceRebuildDrawers();
                    }
                }
            }

            var keyCode = e.keyCode;
            switch (keyCode)
            {
            case KeyCode.Menu:
                if (selectedControl != null)
                {
                    selectedControl.OpenContextMenu(e, selectedControl.RightClickArea, false, selectedControl.SelectedPart);
                }
                break;

            case KeyCode.Space:
                inspectorDrawer.Manager.RegisterKeyHeldDown(keyCode, "space");
                break;

            case KeyCode.F2:
                inspectorDrawer.Repaint();
                if (!DrawGUI.EditingTextField)
                {
                    DrawGUI.Use(e);
                    DrawGUI.EditingTextField = true;
                }
                break;

            case KeyCode.Escape:

                                        #if DEV_MODE
                Debug.Log("!!! ESCAPE !!!");
                                        #endif

                //when dragging a control, allow aborting using the escape key
                if (inspectorDrawer.Manager.MouseDownInfo.MouseDownOverDrawer != null)
                {
                    inspectorDrawer.Manager.MouseDownInfo.Clear();
                }

                if (DrawGUI.EditingTextField)
                {
                    DrawGUI.Use(e);
                    DrawGUI.EditingTextField = false;
                }
                break;

            case KeyCode.AltGr:
            case KeyCode.RightAlt:
                KeyConfig.OnAltGrDown();
                break;

                                #if DEV_MODE
            case KeyCode.I:
                if (e.control && e.alt)
                {
                    Debug.Log("INFO: FocusedDrawer=" + StringUtils.ToString(inspectorDrawer.SelectedOrDefaultView().FocusedDrawer) + ", EditingTextField=" + DrawGUI.EditingTextField);
                }
                break;
                                #endif
            }
        }