private static void SaveLog(object obj)
        {
            string filePath = UnityDebugViewerWindowUtility.GetSelectedFilePath();

            if (string.IsNullOrEmpty(filePath))
            {
                return;
            }

            var editor = UnityDebugViewerEditorManager.GetActiveEditor();

            if (editor == null)
            {
                return;
            }

            bool saveFileterLog = (bool)obj;

            GUI.enabled = false;
            if (editor.SaveLogToFile(filePath, saveFileterLog))
            {
                EditorUtility.DisplayDialog("UnityDebugViewer", string.Format("Save Log to {0} sucecessfully", filePath), "OK", "");
            }
            GUI.enabled = true;
        }
        private void DrawStackBox(LogStackData stack, int index, ref Vector2 drawPos)
        {
            if (string.IsNullOrEmpty(stack.sourceContent))
            {
                stack.sourceContent = UnityDebugViewerEditorUtility.GetSourceContent(stack.filePath, stack.lineNumber);
            }

            var stackBoxGUIContent = new GUIContent(string.Format("\n{0}\n{1}", stack.fullStackMessage, stack.sourceContent));

            if (this.selectedStackIndex == index)
            {
                stackBoxStyle = UnityDebugViewerWindowUtility.activeControlID == this.stackBoxControlID ? stackBoxStyle = UnityDebugViewerWindowStyleUtility.selectedStackBoxStyle : UnityDebugViewerWindowStyleUtility.inactiveStackBoxStyle;
            }
            else
            {
                stackBoxStyle = index % 2 == 0 ? UnityDebugViewerWindowStyleUtility.oddStackBoxStyle : UnityDebugViewerWindowStyleUtility.evenStackBoxStyle;
            }

            var height       = stackBoxStyle.CalcHeight(stackBoxGUIContent, this.lowerPanelRect.width);
            var stackBoxRect = new Rect(drawPos.x, drawPos.y, this.lowerPanelRect.width, height);

            EditorGUI.LabelField(stackBoxRect, stackBoxGUIContent, stackBoxStyle);
            EditorGUILayout.GetControlRect(false, height);

            this.stackRectList[index] = stackBoxRect;
            drawPos.y += height;

            if (stackBoxRect.Contains(Event.current.mousePosition))
            {
                EventType eventType = Event.current.GetTypeForControl(this.stackBoxControlID);
#if UNITY_5 || UNITY_5_3_OR_NEWER
                if (eventType == EventType.MouseDown)
#else
                if (eventType == EventType.mouseDown)
#endif
                {
                    if (Event.current.button == 0 && Event.current.clickCount == 2)
                    {
                        UnityDebugViewerWindowUtility.JumpToSource(stack);
                    }

                    this.selectedStackIndex = index;

                    UnityDebugViewerWindowUtility.activeControlID = this.stackBoxControlID;
                    Event.current.Use();
                }
#if UNITY_5 || UNITY_5_3_OR_NEWER
                if (eventType == EventType.MouseUp && Event.current.button == 1)
#else
                if (eventType == EventType.mouseUp && Event.current.button == 1)
#endif
                {
                    ShowCopyMenu(stack.fullStackMessage);

                    UnityDebugViewerWindowUtility.activeControlID = this.stackBoxControlID;
                    Event.current.Use();
                }
            }
        }
        private void MoveToSpecificLogBox(int logIndex)
        {
            float rectTop    = (logIndex + 1) * logBoxHeight;
            float rectBottom = logIndex * logBoxHeight;

            float showTop    = this.logBoxControlRect.y + this.upperPanelScrollPos.y + this.upperPanelRect.height;
            float showBottom = this.logBoxControlRect.y + this.upperPanelScrollPos.y;

            UnityDebugViewerWindowUtility.MoveToSpecificRect(showTop, showBottom, rectTop, rectBottom, ref this.upperPanelScrollPos);
        }
        private bool ShouldLogBoxShow(int logIndex)
        {
            float rectTop    = (logIndex + 1) * logBoxHeight;
            float rectBottom = logIndex * logBoxHeight;

            float showTop    = this.logBoxControlRect.y + this.upperPanelScrollPos.y + this.upperPanelRect.height;
            float showBottom = this.logBoxControlRect.y + this.upperPanelScrollPos.y;

            return(UnityDebugViewerWindowUtility.ShouldRectShow(showTop, showBottom, rectTop, rectBottom, false));
        }
        private void StopADBForward()
        {
            string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();

            UnityDebugViewerADBUtility.StopForwardProcess(adbPath);
            startForwardProcess = false;

            /// will abort process, should excute at last
            UnityDebugViewerTransferUtility.Clear();
        }
        private void DrawAnalysisMessage()
        {
            if (analysisDataTreeView == null)
            {
                return;
            }

            Rect analysisMenuBarRect = new Rect(lowerPanelRect.x, lowerPanelRect.y, lowerPanelRect.width, menuBarHeight);
            Rect titleRect           = new Rect(lowerPanelRect.x, analysisMenuBarRect.y + analysisMenuBarRect.height, lowerPanelRect.width, 1.5f * EditorGUIUtility.singleLineHeight);
            Rect analysisRect        = new Rect(lowerPanelRect.x, titleRect.y + titleRect.height, lowerPanelRect.width, lowerPanelRect.height - titleRect.height - analysisMenuBarRect.height);

            GUILayout.BeginArea(analysisMenuBarRect, EditorStyles.toolbar);
            {
                GUILayout.BeginHorizontal();
                {
                    EditorGUI.BeginChangeCheck();
                    GUILayout.Label(new GUIContent("Sort Type: "), EditorStyles.toolbarButton);
                    analysisDataSortType = (AnalysisDataSortType)EditorGUILayout.EnumPopup(analysisDataSortType, EditorStyles.toolbarPopup);
                    if (EditorGUI.EndChangeCheck())
                    {
                        this.editorManager.activeEditor.analysisDataManager.Sort(analysisDataSortType);
                    }

                    GUILayout.FlexibleSpace();

                    string tempSearchText = UnityDebugViewerWindowUtility.CopyPasteTextField(this.analysisSearchText, UnityDebugViewerWindowStyleUtility.toolbarSearchTextStyle, GUILayout.MinWidth(180f), GUILayout.MaxWidth(300f));
                    if (tempSearchText.Equals(this.analysisSearchText) == false)
                    {
                        /// update search result first
                        this.editorManager.activeEditor.analysisDataManager.Search(tempSearchText);

                        if (string.IsNullOrEmpty(tempSearchText) && string.IsNullOrEmpty(this.analysisSearchText) == false)
                        {
                            analysisDataTreeView.MoveToSelectedNode(analysisRect, ref this.analysisPanelScrollPos);
                        }
                        this.analysisSearchText = tempSearchText;
                    }
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.EndArea();

            GUILayout.BeginArea(analysisRect);
            {
                this.analysisPanelScrollPos = GUILayout.BeginScrollView(this.analysisPanelScrollPos);
                {
                    analysisDataTreeView.DrawTreeLayout(analysisRect, ref this.analysisPanelScrollPos);
                }
                GUILayout.EndScrollView();
            }
            GUILayout.EndArea();

            /// draw title at last to make sure title is always on the top
            analysisDataTreeView.DrawColumnTitle(titleRect);
        }
        private void StartADBLogcat()
        {
            if (UnityDebugViewerWindowUtility.CheckADBStatus() == false)
            {
                return;
            }

            string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();

            startLogcatProcess = UnityDebugViewerADBUtility.StartLogcatProcess(LogcatDataHandler, logcatTagFilterStr, adbPath);
        }
        private void DisconnectToServerHandler()
        {
            string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();

            if (UnityDebugViewerADBUtility.CheckDevice(adbPath) == false)
            {
                UnityDebugViewerLogger.LogError("No devices connect, adb forward process should be restart!", UnityDebugViewerDefaultMode.ADBForward);

                StopADBForward();
            }
        }
        private void StartADBForward()
        {
            if (UnityDebugViewerWindowUtility.CheckADBStatus() == false)
            {
                return;
            }

            string adbPath = UnityDebugViewerWindowUtility.GetAdbPath();

            startForwardProcess = UnityDebugViewerADBUtility.StartForwardProcess(pcPort, phonePort, adbPath);
            if (startForwardProcess)
            {
                int port = 0;
                if (int.TryParse(pcPort, out port))
                {
                    UnityDebugViewerTransferUtility.ConnectToServer("127.0.0.1", port);
                }
            }
        }
        private void DrawStackMessage()
        {
            GUILayout.BeginArea(this.lowerPanelRect);
            {
                this.stackBoxControlID = GUIUtility.GetControlID(FocusType.Passive, lowerPanelRect);

                this.stackPanelScrollPos = GUILayout.BeginScrollView(this.stackPanelScrollPos);
                {
                    var log = this.editorManager.activeEditor.selectedLog;
                    if (log != null && this.logFilter.ShouldDisplay(log))
                    {
                        string logFullMessage = string.Format("{0}\n{1}", log.info, log.extraInfo);
                        var    logFullMessageAreaGUIContent = new GUIContent(logFullMessage);
                        this.logFullMessageAreaHeight = UnityDebugViewerWindowStyleUtility.logFullMessageAreaStyle.CalcHeight(logFullMessageAreaGUIContent, this.lowerPanelRect.width);

                        EditorGUILayout.SelectableLabel(logFullMessage, UnityDebugViewerWindowStyleUtility.logFullMessageAreaStyle, GUILayout.ExpandWidth(true), GUILayout.Height(this.logFullMessageAreaHeight));

                        GUILayout.Label(GUIContent.none, GUI.skin.GetStyle("Wizard Box"), GUILayout.Height(this.splitHeight), GUILayout.ExpandWidth(true));

                        if (this.stackRectList == null)
                        {
                            this.stackRectList = new List <Rect>();
                        }
                        if (this.stackRectList.Count < log.stackList.Count)
                        {
                            this.stackRectList.Clear();
                            for (int i = 0; i < log.stackList.Count; i++)
                            {
                                this.stackRectList.Add(Rect.zero);
                            }
                        }


                        Vector2 startPos = new Vector2(0, this.logFullMessageAreaHeight + this.splitHeight);

                        for (int i = 0; i < log.stackList.Count; i++)
                        {
                            var stack = log.stackList[i];
                            if (stack == null)
                            {
                                continue;
                            }

                            DrawStackBox(stack, i, ref startPos);
                        }

                        EventType eventType = Event.current.GetTypeForControl(this.stackBoxControlID);
#if UNITY_5 || UNITY_5_3_OR_NEWER
                        if (eventType == EventType.KeyUp)
#else
                        if (eventType == EventType.keyUp)
#endif
                        {
                            if (this.stackBoxControlID == UnityDebugViewerWindowUtility.activeControlID)
                            {
                                bool changeSeletedStack = false;

                                if (Event.current.keyCode == KeyCode.UpArrow)
                                {
                                    this.selectedStackIndex--;
                                    if (this.selectedStackIndex < 0)
                                    {
                                        this.selectedStackIndex    = 0;
                                        this.stackPanelScrollPos.y = 0;
                                    }
                                    changeSeletedStack = true;
                                }
                                else if (Event.current.keyCode == KeyCode.DownArrow)
                                {
                                    this.selectedStackIndex++;
                                    if (this.selectedStackIndex > log.stackList.Count - 1)
                                    {
                                        this.selectedStackIndex = log.stackList.Count - 1;
                                    }
                                    changeSeletedStack = true;
                                }

                                if (changeSeletedStack)
                                {
                                    float showRectTop    = this.stackPanelScrollPos.y + this.lowerPanelRect.height;
                                    float showRectBottom = this.stackPanelScrollPos.y;
                                    float rectTop        = stackRectList[this.selectedStackIndex].y + stackRectList[this.selectedStackIndex].height;
                                    float rectBottom     = stackRectList[this.selectedStackIndex].y;

                                    UnityDebugViewerWindowUtility.MoveToSpecificRect(showRectTop, showRectBottom, rectTop, rectBottom, ref this.stackPanelScrollPos);

                                    GUI.changed = true;
                                    Event.current.Use();
                                }
                            }
                        }
                    }
                }
                GUILayout.EndScrollView();
            }
            GUILayout.EndArea();
        }
        private void DrawLogBox(LogData log, Rect logBoxRect, int index, bool isCollapsed = false)
        {
            GUIStyle iconStyle;

            switch (log.type)
            {
            case LogType.Error:
            case LogType.Exception:
            case LogType.Assert:
                iconStyle = UnityDebugViewerWindowStyleUtility.errorIconStyle;
                break;

            case LogType.Warning:
                iconStyle = UnityDebugViewerWindowStyleUtility.warningIconStyle;
                break;

            case LogType.Log:
                iconStyle = UnityDebugViewerWindowStyleUtility.infoIconStyle;
                break;

            default:
                iconStyle = null;
                break;
            }
            if (iconStyle == null)
            {
                return;
            }


            if (index == this.editorManager.activeEditor.selectedLogIndex)
            {
                logBoxStyle = UnityDebugViewerWindowUtility.activeControlID == this.logBoxControlID ? logBoxStyle = UnityDebugViewerWindowStyleUtility.selectedLogBoxStyle : UnityDebugViewerWindowStyleUtility.inactiveLogBoxStyle;
            }
            else
            {
                logBoxStyle = index % 2 == 0 ? UnityDebugViewerWindowStyleUtility.oddLogBoxtyle : UnityDebugViewerWindowStyleUtility.evenLogBoxtyle;
            }
            GUI.DrawTexture(logBoxRect, logBoxStyle.normal.background);


            string logContent       = log.GetContent(showTime);
            var    logBoxGUIContent = new GUIContent(logContent);
            var    logContentHeight = logBoxStyle.CalcHeight(logBoxGUIContent, logBoxRect.width);

            logBoxStyle.alignment = logContentHeight > logBoxHeight ? TextAnchor.UpperLeft : TextAnchor.MiddleLeft;
            EditorGUI.LabelField(logBoxRect, logBoxGUIContent, logBoxStyle);

            var logBoxMidHeight = logBoxRect.y + logBoxRect.height / 2;
            var iconSize        = iconStyle.CalcSize(GUIContent.none);
            var iconRect        = new Rect(5, logBoxMidHeight - iconSize.y / 2, iconSize.x, iconSize.y);

            EditorGUI.LabelField(iconRect, GUIContent.none, iconStyle);

            if (collapse)
            {
                /// make sure the number label display in a fixed relative position of the window
                int        num             = this.editorManager.activeEditor.GetLogNum(log);
                GUIContent labelGUIContent = new GUIContent(num.ToString());
                var        labelSize       = UnityDebugViewerWindowStyleUtility.collapsedNumLabelStyle.CalcSize(labelGUIContent);
                Rect       labelRect       = new Rect(position.width - labelSize.x - 20, logBoxRect.y + logBoxRect.height / 2 - labelSize.y / 2, labelSize.x, labelSize.y);

                EditorGUI.LabelField(labelRect, labelGUIContent, UnityDebugViewerWindowStyleUtility.collapsedNumLabelStyle);
            }

            EventType eventType = Event.current.GetTypeForControl(this.logBoxControlID);

#if UNITY_5 || UNITY_5_3_OR_NEWER
            if (eventType == EventType.MouseDown)
#else
            if (eventType == EventType.mouseDown)
#endif
            {
                /// process event
                if (logBoxRect.Contains(Event.current.mousePosition))
                {
                    this.editorManager.activeEditor.selectedLogIndex = index;

                    if (Event.current.button == 0 && Event.current.clickCount == 2)
                    {
                        UnityDebugViewerWindowUtility.JumpToSource(log);
                    }

                    UnityDebugViewerWindowUtility.activeControlID = this.logBoxControlID;
                    Event.current.Use();
                }

                if (Event.current.button == 2)
                {
                    MoveToSpecificLogBox(this.editorManager.activeEditor.selectedLogIndex);

                    Event.current.Use();
                }
            }
#if UNITY_5 || UNITY_5_3_OR_NEWER
            else if (eventType == EventType.MouseUp)
#else
            else if (eventType == EventType.mouseUp)
#endif
            {
                if (logBoxRect.Contains(Event.current.mousePosition) && Event.current.button == 1)
                {
                    ShowCopyMenu(logContent);

                    UnityDebugViewerWindowUtility.activeControlID = this.logBoxControlID;
                    Event.current.Use();
                }
            }
#if UNITY_5 || UNITY_5_3_OR_NEWER
            else if (eventType == EventType.KeyUp)
#else
            else if (eventType == EventType.keyUp)
#endif
            {
                if (this.logBoxControlID == UnityDebugViewerWindowUtility.activeControlID)
                {
                    bool changeSelectedLog = false;
                    int  selectedIndex     = this.editorManager.activeEditor.selectedLogIndex;
                    if (Event.current.keyCode == KeyCode.UpArrow)
                    {
                        selectedIndex--;
                        changeSelectedLog = true;
                    }
                    else if (Event.current.keyCode == KeyCode.DownArrow)
                    {
                        selectedIndex++;
                        changeSelectedLog = true;
                    }

                    if (changeSelectedLog)
                    {
                        this.editorManager.activeEditor.selectedLogIndex = Mathf.Clamp(selectedIndex, 0, this.logList.Count - 1);

                        MoveToSpecificLogBox(this.editorManager.activeEditor.selectedLogIndex);

                        Event.current.Use();
                    }
                }
            }
        }
        private void DrawMenuBar()
        {
            menuBarRect = new Rect(0, 0, position.width, menuBarHeight);

            GUILayout.BeginArea(menuBarRect, EditorStyles.toolbar);
            {
                GUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button(new GUIContent("Clear"), EditorStyles.toolbarButton, GUILayout.Width(40)))
                    {
                        this.editorManager.activeEditor.Clear();
                    }

                    GUILayout.Space(5);

                    EditorGUI.BeginChangeCheck();
                    collapse = GUILayout.Toggle(collapse, new GUIContent("Collapse"), EditorStyles.toolbarButton);
                    if (EditorGUI.EndChangeCheck())
                    {
                        this.logFilter.collapse    = collapse;
                        this.shouldUpdateLogFilter = true;
                        PlayerPrefs.SetInt(CollapsePref, collapse ? 1 : 0);
                    }

                    EditorGUI.BeginChangeCheck();
                    clearOnPlay = GUILayout.Toggle(clearOnPlay, new GUIContent("Clear On Play"), EditorStyles.toolbarButton);
                    errorPause  = GUILayout.Toggle(errorPause, new GUIContent("Error Pause"), EditorStyles.toolbarButton);
                    autoScroll  = GUILayout.Toggle(autoScroll, new GUIContent("Auto Scroll"), EditorStyles.toolbarButton);

                    GUILayout.Space(5);

                    showlogAnalysis = GUILayout.Toggle(showlogAnalysis, new GUIContent("Show Analysis"), EditorStyles.toolbarButton);

                    if (EditorGUI.EndChangeCheck())
                    {
                        PlayerPrefs.SetInt(ClearOnPlayPref, clearOnPlay ? 1 : 0);
                        PlayerPrefs.SetInt(ErrorPausePref, errorPause ? 1 : 0);
                        PlayerPrefs.SetInt(AutoScrollPref, autoScroll ? 1 : 0);
                        PlayerPrefs.SetInt(ShowAnalysisPref, showlogAnalysis ? 1 : 0);
                    }

                    GUILayout.Space(5);

                    Vector2 size = EditorStyles.toolbarPopup.CalcSize(new GUIContent(this.editorManager.activeMode));
                    EditorGUI.BeginChangeCheck();
                    this.editorManager.activeModeIndex = EditorGUILayout.Popup(this.editorManager.activeModeIndex, this.editorManager.modeArray, EditorStyles.toolbarPopup, GUILayout.Width(size.x));
                    if (EditorGUI.EndChangeCheck())
                    {
                        this.analysisDataTreeView  = new UnityDebugViewerAnalysisDataTreeView(this.editorManager.activeEditor.analysisDataManager.root);
                        this.shouldUpdateLogFilter = true;
                    }

                    this.editorManager.activeEditor.OnGUI();

                    GUILayout.FlexibleSpace();


                    string tempSearchText = UnityDebugViewerWindowUtility.CopyPasteTextField(this.searchText, UnityDebugViewerWindowStyleUtility.toolbarSearchTextStyle, GUILayout.MinWidth(180f), GUILayout.MaxWidth(300f));
                    if (tempSearchText.Equals(this.searchText) == false)
                    {
                        this.clearSearchText = string.IsNullOrEmpty(tempSearchText) && string.IsNullOrEmpty(this.searchText) == false;

                        this.searchText            = tempSearchText;
                        this.logFilter.searchText  = this.searchText;
                        this.shouldUpdateLogFilter = true;
                    }

                    string logNum     = this.editorManager.activeEditor.logNum.ToString();
                    string warningNum = this.editorManager.activeEditor.warningNum.ToString();
                    string errorNum   = this.editorManager.activeEditor.errorNum.ToString();

                    EditorGUI.BeginChangeCheck();
                    searchWithRegex = GUILayout.Toggle(searchWithRegex, new GUIContent("Regex"), EditorStyles.toolbarButton);
                    showTime        = GUILayout.Toggle(showTime, new GUIContent("Time"), EditorStyles.toolbarButton);
                    showLog         = GUILayout.Toggle(showLog, new GUIContent(logNum, UnityDebugViewerWindowStyleUtility.infoIconSmallTexture), EditorStyles.toolbarButton);
                    showWarning     = GUILayout.Toggle(showWarning, new GUIContent(warningNum, UnityDebugViewerWindowStyleUtility.warningIconSmallTexture), EditorStyles.toolbarButton);
                    showError       = GUILayout.Toggle(showError, new GUIContent(errorNum, UnityDebugViewerWindowStyleUtility.errorIconSmallTexture), EditorStyles.toolbarButton);
                    if (EditorGUI.EndChangeCheck())
                    {
                        PlayerPrefs.SetInt(SearchWithRegexPref, searchWithRegex ? 1 : 0);
                        PlayerPrefs.SetInt(ShowTimePref, showTime ? 1 : 0);
                        PlayerPrefs.SetInt(ShowLogPref, showLog ? 1 : 0);
                        PlayerPrefs.SetInt(ShowWarningPref, showWarning ? 1 : 0);
                        PlayerPrefs.SetInt(ShowErrorPref, showError ? 1 : 0);

                        this.logFilter.searchWithRegex = searchWithRegex;
                        this.logFilter.showTime        = showTime;
                        this.logFilter.showLog         = showLog;
                        this.logFilter.showWarning     = showWarning;
                        this.logFilter.showError       = showError;
                        this.shouldUpdateLogFilter     = true;
                    }
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.EndArea();
        }
 public override void Clear()
 {
     UnityDebugViewerWindowUtility.ClearNativeConsoleWindow();
 }
Пример #14
0
        protected virtual bool OnDrawRow(UnityDebugViewerAnalysisDataTreeItem node)
        {
            if (UnityDebugViewerAnalysisData.IsNullOrEmpty(node.Data) || node.Data.isVisible == false)
            {
                return(true);
            }

            float rowHeight = GetRowHeight(node);

            Rect rowRect = new Rect(0, _controlRect.y + _drawY, _controlRect.width, rowHeight);

            node.Row = (int)(_drawY / rowHeight);
            if (_changeSelectedRow && _selectedRow == node.Row)
            {
                _selectedNode      = node;
                _changeSelectedRow = false;
                float showTop    = _controlRect.y + _scrollPos.y + _panelRect.height;
                float showBottom = _controlRect.y + _scrollPos.y;
                float rectTop    = rowRect.y + rowRect.height;
                float rectBottom = rowRect.y;
                UnityDebugViewerWindowUtility.MoveToSpecificRect(showTop, showBottom, rectTop, rectBottom, ref _scrollPos);
            }

            OnDrawTreeNode(rowRect, node, _selectedNode == node, false);

            EventType eventType = Event.current.GetTypeForControl(_controlID);

#if UNITY_5 || UNITY_5_3_OR_NEWER
            if (eventType == EventType.MouseDown)
#else
            if (eventType == EventType.mouseDown)
#endif
            {
                if (rowRect.Contains(Event.current.mousePosition))
                {
                    _selectedNode = node;
                    _selectedRow  = node.Row;

                    GUI.changed = true;

                    UnityDebugViewerWindowUtility.activeControlID = _controlID;
                    Event.current.Use();
                }
            }
#if UNITY_5 || UNITY_5_3_OR_NEWER
            else if (eventType == EventType.KeyUp)
#else
            else if (eventType == EventType.keyUp)
#endif
            {
                if (_controlID == UnityDebugViewerWindowUtility.activeControlID)
                {
                    if (Event.current.keyCode == KeyCode.UpArrow)
                    {
                        _selectedRow = _selectedNode.Row - 1;
                        if (_selectedRow < 0)
                        {
                            _selectedRow = 0;
                        }
                        _changeSelectedRow = true;
                    }
                    else if (Event.current.keyCode == KeyCode.DownArrow)
                    {
                        _selectedRow = _selectedNode.Row + 1;
                        int maxRow = (int)(_controlRect.height / rowHeight) - 1;
                        if (_selectedRow > maxRow)
                        {
                            _selectedRow = maxRow;
                        }
                        _changeSelectedRow = true;
                    }

                    if (_changeSelectedRow)
                    {
                        GUI.changed = true;
                        Event.current.Use();
                    }
                }
            }

            _drawY += rowHeight;

            return(node.Data.isExpanded);
        }