/// <summary>
        /// Draws the Odin Editor Window.
        /// </summary>
        protected virtual void OnGUI()
        {
            EditorTimeHelper prevTimeHelper = EditorTimeHelper.Time;

            EditorTimeHelper.Time = this.timeHelper;
            EditorTimeHelper.Time.Update();
            try
            {
                bool messureArea = this.preventContentFromExpanding;
                if (messureArea)
                {
                    GUILayout.BeginArea(new Rect(0, 0, this.position.width, this.wrappedAreaMaxHeight));
                }

                if (this.OnBeginGUI != null)
                {
                    this.OnBeginGUI();
                }

                // Editor windows, can be created before Odin assigns OdinEditors to all relevent types via reflection.
                // This ensures that that happens before we render anything.
                if (!hasUpdatedOdinEditors)
                {
                    InspectorConfig.Instance.EnsureEditorsHaveBeenUpdated();
                    hasUpdatedOdinEditors = true;
                }

                this.InitializeIfNeeded();

                this.marginStyle = this.marginStyle ?? new GUIStyle()
                {
                    padding = new RectOffset()
                };

                if (Event.current.type == EventType.Layout)
                {
                    this.marginStyle.padding.left   = (int)this.WindowPadding.x;
                    this.marginStyle.padding.right  = (int)this.WindowPadding.y;
                    this.marginStyle.padding.top    = (int)this.WindowPadding.z;
                    this.marginStyle.padding.bottom = (int)this.WindowPadding.w;

                    // Creates the editors.
                    UpdateEditors();
                }

                // Removes focus from text-fields when clicking on an empty area.
                var prevType = Event.current.type;
                if (Event.current.type == EventType.MouseDown)
                {
                    this.mouseDownId = GUIUtility.hotControl;
                    this.mouseDownKeyboardControl = GUIUtility.keyboardControl;
                    this.mouseDownWindow          = focusedWindow;
                }

                // Draws the editors.
                bool useScrollWheel = this.UseScrollView;
                if (useScrollWheel)
                {
                    this.scrollPos = EditorGUILayout.BeginScrollView(this.scrollPos);
                }

                // Draw the GUI
                //var r = EditorGUILayout.BeginVertical();
                //{
                // Update the content rect
                Vector2 size;
                if (this.preventContentFromExpanding)
                {
                    size = EditorGUILayout.BeginVertical(GUILayoutOptions.ExpandHeight(false)).size;
                }
                else
                {
                    size = EditorGUILayout.BeginVertical().size;
                }

                if (this.contenSize == Vector2.zero || Event.current.type == EventType.Repaint)
                {
                    this.contenSize = size;
                }

                GUIHelper.PushHierarchyMode(false);
                float labelWidth;
                if (this.DefaultLabelWidth < 1)
                {
                    labelWidth = this.contenSize.x * this.DefaultLabelWidth;
                }
                else
                {
                    labelWidth = this.DefaultLabelWidth;
                }

                GUIHelper.PushLabelWidth(labelWidth);
                this.OnBeginDrawEditors();
                GUILayout.BeginVertical(this.marginStyle);

                DrawEditors();

                GUILayout.EndVertical();
                this.OnEndDrawEditors();
                GUIHelper.PopLabelWidth();
                GUIHelper.PopHierarchyMode();

                EditorGUILayout.EndVertical();

                if (useScrollWheel)
                {
                    EditorGUILayout.EndScrollView();
                }

                if (this.OnEndGUI != null)
                {
                    this.OnEndGUI();
                }

                // This removes focus from text-fields when clicking on an empty area.
                if (Event.current.type != prevType)
                {
                    this.mouseDownId = -2;
                }
                if (Event.current.type == EventType.MouseUp && GUIUtility.hotControl == this.mouseDownId && focusedWindow == this.mouseDownWindow && GUIUtility.keyboardControl == this.mouseDownKeyboardControl)
                {
                    GUIHelper.RemoveFocusControl();
                    GUI.FocusControl(null);
                }

                if (this.drawCountWarmup < 10)
                {
                    this.Repaint();

                    if (Event.current.type == EventType.Repaint)
                    {
                        this.drawCountWarmup++;
                    }
                }


                // TODO: Find out why the window doesn't repaint properly when this is 0. And then remove this if statement.
                // Try navigating a menu tree with the keyboard filled menu items with nothing to inspect.
                // It only updates when you start moving the mouse.
                if (Event.current.isMouse || Event.current.type == EventType.Used || this.currentTargets == null || this.currentTargets.Length == 0 || GUIHelper.CurrentWindowHasFocus)
                {
                    this.Repaint();
                }

                this.RepaintIfRequested();

                if (messureArea)
                {
                    GUILayout.EndArea();
                }
            }
            finally
            {
                EditorTimeHelper.Time = prevTimeHelper;
            }
        }
Пример #2
0
        /// <summary>
        /// Draws the menu tree recursively.
        /// </summary>
        public void DrawMenuTree()
        {
            EditorTimeHelper prevTimeHelper = EditorTimeHelper.Time;

            EditorTimeHelper.Time = this.timeHelper;
            EditorTimeHelper.Time.Update();
            try
            {
                timeHelper.Update();
                this.frameCounter.Update();
                var config = this.Config;

                if (this.requestRepaint)
                {
                    GUIHelper.RequestRepaint();
                    this.requestRepaint = false;
                }

                if (config.DrawSearchToolbar)
                {
                    this.DrawSearchToolbar();
                }

                var outerRect = EditorGUILayout.BeginVertical();

                this.HandleActiveMenuTreeState(outerRect);

                if (config.DrawScrollView)
                {
                    if (Event.current.type == EventType.Repaint)
                    {
                        this.outerScrollViewRect = outerRect;
                    }

                    if (this.hideScrollbarsWhileContentIsExpanding > 0)
                    {
                        config.ScrollPos = EditorGUILayout.BeginScrollView(config.ScrollPos, GUIStyle.none, GUIStyle.none, GUILayoutOptions.ExpandHeight(false));
                    }
                    else
                    {
                        config.ScrollPos = EditorGUILayout.BeginScrollView(config.ScrollPos, GUILayoutOptions.ExpandHeight(false));
                    }

                    var size = EditorGUILayout.BeginVertical();

                    // hideScrollbarsWhileContentIsExpanding:
                    // When drawn in confined areas, the scrollbars on the scrollview will flicker in and out while expanding.
                    // The code below ensures we hide the scorllbars remain invisible while the inner and outer scrollview heights are somewhat close to each other.
                    if (this.innerScrollViewRect.height == 0 || Event.current.type == EventType.Repaint)
                    {
                        var chancedSizeDiff = Mathf.Abs(this.innerScrollViewRect.height - size.height);
                        var boxDiff         = Mathf.Abs(this.innerScrollViewRect.height - this.outerScrollViewRect.height);
                        var shouldHaveScrollViewRegardless = this.innerScrollViewRect.height - 40 > this.outerScrollViewRect.height;

                        if (!shouldHaveScrollViewRegardless && chancedSizeDiff > 0)
                        {
                            this.hideScrollbarsWhileContentIsExpanding = 5;
                            GUIHelper.RequestRepaint();
                        }
                        else if (Mathf.Abs(boxDiff) < 1)
                        {
                            this.hideScrollbarsWhileContentIsExpanding = 5;
                        }
                        else
                        {
                            this.hideScrollbarsWhileContentIsExpanding--;
                            if (this.hideScrollbarsWhileContentIsExpanding < 0)
                            {
                                this.hideScrollbarsWhileContentIsExpanding = 0;
                            }
                            else
                            {
                                GUIHelper.RequestRepaint();
                            }
                        }

                        this.innerScrollViewRect = size;
                    }

                    GUILayout.Space(-1);
                }

                if (this.isDirty && Event.current.type == EventType.Layout)
                {
                    this.UpdateMenuTree();
                    this.isDirty = false;
                }

                VisibleRect                      = GUIClipInfo.VisibleRect.Expand(300);
                CurrentEvent                     = Event.current;
                CurrentEventType                 = CurrentEvent.type;
                CurrentEditorTimeHelper          = EditorTimeHelper.Time;
                CurrentEditorTimeHelperDeltaTime = CurrentEditorTimeHelper.DeltaTime;

                var tree  = this.DrawInSearchMode ? this.FlatMenuTree : this.MenuItems;
                var count = tree.Count;

                if (config.EXPERIMENTAL_INTERNAL_DrawFlatTreeFastNoLayout)
                {
                    var itemHeight = this.DefaultMenuStyle.Height;
                    var height     = count * itemHeight;
                    var rect       = GUILayoutUtility.GetRect(0, height);

                    rect.height = itemHeight;

                    for (int i = 0; i < count; i++)
                    {
                        var item = tree[i];

                        item.EXPERIMENTAL_DontAllocateNewRect = true;
                        item.rect = rect;
                        item.DrawMenuItem(0);

                        rect.y += itemHeight;
                    }
                }
                else
                {
                    for (int i = 0; i < count; i++)
                    {
                        tree[i].DrawMenuItems(0);
                    }
                }

                if (config.DrawScrollView)
                {
                    EditorGUILayout.EndVertical();
                    EditorGUILayout.EndScrollView();
                }

                EditorGUILayout.EndVertical();

                if (config.AutoHandleKeyboardNavigation)
                {
                    this.HandleKeybaordMenuNavigation();
                }

                if (this.scrollToWhenReady != null)
                {
                    this.ScrollToMenuItem(this.scrollToWhenReady, this.scollToCenter);
                }

                if (Event.current.type == EventType.Repaint)
                {
                    this.isFirstFrame = false;
                }
            }
            finally
            {
                EditorTimeHelper.Time = prevTimeHelper;
            }
        }
        /// <summary>
        /// Draws the Odin Editor Window.
        /// </summary>
        protected override void OnGUI()
        {
            EditorTimeHelper prevTimeHelper = EditorTimeHelper.Time;

            EditorTimeHelper.Time = this.timeHelper;
            EditorTimeHelper.Time.Update();
            try
            {
                if (Event.current.type == EventType.Layout)
                {
                    bool setActive = this.menuTree == null;
                    if (this.menuTree == null || this.isDirty)
                    {
                        this.ForceMenuTreeRebuild();
                        if (setActive)
                        {
                            OdinMenuTree.ActiveMenuTree = this.menuTree;
                        }

                        if (UnityEditorEventUtility.HasOnProjectChanged)
                        {
                            UnityEditorEventUtility.OnProjectChanged -= ProjectWindowChanged;
                            UnityEditorEventUtility.OnProjectChanged += ProjectWindowChanged;
                        }
                        else
                        {
#pragma warning disable 0618
                            EditorApplication.projectWindowChanged -= ProjectWindowChanged;
                            EditorApplication.projectWindowChanged += ProjectWindowChanged;
#pragma warning restore 0618
                        }

                        this.isDirty = false;
                    }

                    // Try select object.
                    if (this.trySelectObject != null && this.menuTree != null)
                    {
                        var menuItem = this.menuTree.EnumerateTree()
                                       .FirstOrDefault(x => x.Value == this.trySelectObject);

                        if (menuItem != null)
                        {
                            this.menuTree.Selection.Clear();
                            menuItem.Select();
                            this.trySelectObject = null;
                        }
                    }
                }

                Rect menuBorderRect;

                GUILayout.BeginHorizontal();
                GUILayout.BeginVertical(GUILayoutOptions.Width(this.MenuWidth).ExpandHeight());
                {
                    var rect = GUIHelper.GetCurrentLayoutRect();

                    if (this.menuTree != null)
                    {
                        this.menuTree.MenuTreeActivationZone(rect);
                    }

                    EditorGUI.DrawRect(rect, SirenixGUIStyles.MenuBackgroundColor);
                    menuBorderRect       = rect;
                    menuBorderRect.xMin  = rect.xMax - 4;
                    menuBorderRect.xMax += 4;

                    if (this.ResizableMenuWidth)
                    {
                        EditorGUIUtility.AddCursorRect(menuBorderRect, MouseCursor.ResizeHorizontal);
                        this.MenuWidth += SirenixEditorGUI.SlideRect(menuBorderRect).x;
                    }

                    this.DrawMenu();
                }
                GUILayout.EndVertical();
                GUILayout.BeginVertical();
                {
                    var rect = GUIHelper.GetCurrentLayoutRect();
                    EditorGUI.DrawRect(rect, SirenixGUIStyles.DarkEditorBackground);
                    base.OnGUI();
                }
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();

                EditorGUI.DrawRect(menuBorderRect.AlignCenter(1), SirenixGUIStyles.BorderColor);

                if (this.menuTree != null)
                {
                    this.menuTree.HandleKeybaordMenuNavigation();

                    // TODO: Handle scroll to selected menu items...
                    // this.menuTree.Selection.Last() is the latest selected item.
                }
                this.RepaintIfRequested();
            }
            finally
            {
                EditorTimeHelper.Time = prevTimeHelper;
            }
        }