// Draw a list item. A few too many magic numbers in here so will need to tidy this a bit void DrawItem(ListItem item, Rect area, float x, float y, bool focus, bool selected) { bool drag = (item == dragTarget); bool highlight = selected; if (selected && Event.current.type == EventType.Repaint) { Styles.evenBackground.Draw(new Rect(area.x, y, area.width, c_lineHeight), GUIContent.none, false, false, true, false); } else if (drag) { switch (dragAdjust) { case SelectDirection.Up: if (item.PrevOpenVisible != item.Parent && Event.current.type == EventType.Repaint) { Styles.dragBackground.Draw(new Rect(x, y - 1, area.width, 2), GUIContent.none, false, false, true, false); } break; case SelectDirection.Down: if (Event.current.type == EventType.Repaint) { Styles.dragBackground.Draw(new Rect(x, y - 1, area.width, 2), GUIContent.none, false, false, true, false); } break; default: if (item.CanAccept || item.Parent.Change != null) { if (Event.current.type == EventType.Repaint) { Styles.dragBackground.Draw(new Rect(area.x, y, area.width, c_lineHeight), GUIContent.none, false, false, true, false); } highlight = true; } break; } } else if (dragTarget != null && item == dragTarget.Parent && dragAdjust != SelectDirection.Current) { if (Event.current.type == EventType.Repaint) { Styles.dragBackground.Draw(new Rect(area.x, y, area.width, c_lineHeight), GUIContent.none, false, false, true, false); } highlight = true; } if (item.HasActions) { // Draw any actions available for (int i = 0; i < item.Actions.Length; ++i) { calcSizeTmpContent.text = item.Actions[i]; Vector2 sz = GUI.skin.button.CalcSize(calcSizeTmpContent); if (GUI.Button(new Rect(x, y, sz.x, c_lineHeight), item.Actions[i])) { // Action performed. Callback delegate actionDelegate(item, i); } x += sz.x + 4; // offset by 4 px } } if (item.CanExpand) { EditorGUI.Foldout(new Rect(x, y, 16, c_lineHeight), item.Expanded, GUIContent.none); } Texture icon = item.Icon; Color tmpColor = GUI.color; Color tmpContentColor = GUI.contentColor; // This should not be an else statement as the previous if can set icon if (!item.Dummy || item.Change != null) { // If there is no icon set then we look for cached items if (icon == null) { icon = InternalEditorUtility.GetIconForFile(item.Name); // icon = defaultIcon; } var iconRect = new Rect(x + 14, y, 16, c_lineHeight); if (selected) { Texture activeIcon = EditorUtility.GetIconInActiveState(icon); if (activeIcon != null) { icon = activeIcon; } } if (icon != null) { GUI.DrawTexture(iconRect, icon); } if (item.Asset != null) { bool drawOverlay = true; string vcsType = VersionControlSettings.mode; if (vcsType == ExternalVersionControl.Disabled || vcsType == ExternalVersionControl.AutoDetect || vcsType == ExternalVersionControl.Generic) { drawOverlay = false; // no overlays for these version control systems } if (drawOverlay) { Rect overlayRect = iconRect; overlayRect.width += 12; overlayRect.x -= 6; Overlay.DrawOverlay(item.Asset, overlayRect); } } } if (Event.current.type != EventType.Repaint) { return; } GUIStyle label = item.Change != null ? Styles.changeset : Styles.asset; string displayName = DisplayName(item); Vector2 displayNameSize = label.CalcSize(EditorGUIUtility.TempContent(displayName)); float labelOffsetX = x + 32; Rect textRect = new Rect(labelOffsetX, y, area.width - labelOffsetX, c_lineHeight + 2); int startIndex = -1; if (!string.IsNullOrEmpty(filter)) { startIndex = displayName.IndexOf(filter, StringComparison.OrdinalIgnoreCase); } GUIContent content = new GUIContent(displayName); if (item.Dummy) { GUI.Label(textRect, content, Styles.meta); } else if (startIndex == -1 || item.Asset == null || Event.current.type != EventType.Repaint) { label.Draw(textRect, content, false, false, selected, selected); } else { int endIndex = startIndex + filter.Length; label.DrawWithTextSelection(textRect, content, selected, selected, startIndex, endIndex, false, GUI.skin.settings.selectionColor); } float spaceBefore = labelOffsetX + displayNameSize.x + (item.Change != null ? 10 : 2); Rect metaPosition = new Rect(spaceBefore, y, area.width - spaceBefore, c_lineHeight + 2); int visibleChildCount = item.VisibleChildCount; if (HasHiddenMetaFile(item)) { Styles.meta.Draw(metaPosition, GUIContent.Temp("+meta"), false, false, selected, selected); } if (visibleChildCount > 0) { Styles.meta.Draw(metaPosition, GUIContent.Temp($"{visibleChildCount} files"), false, false, selected, selected); } }
internal void OnGUI() { Event e = Event.current; LoadIcons(); if (!m_HasUpdatedGuiStyles) { m_LineHeight = Mathf.RoundToInt(Constants.ErrorStyle.lineHeight); m_BorderHeight = Constants.ErrorStyle.border.top + Constants.ErrorStyle.border.bottom; UpdateListView(); } GUILayout.BeginHorizontal(Constants.Toolbar); // Clear button and clearing options bool clearClicked = false; if (EditorGUILayout.DropDownToggle(ref clearClicked, Constants.Clear, EditorStyles.toolbarDropDownToggle)) { var clearOnPlay = HasFlag(ConsoleFlags.ClearOnPlay); var clearOnBuild = HasFlag(ConsoleFlags.ClearOnBuild); GenericMenu menu = new GenericMenu(); menu.AddItem(Constants.ClearOnPlay, clearOnPlay, () => { SetFlag(ConsoleFlags.ClearOnPlay, !clearOnPlay); }); menu.AddItem(Constants.ClearOnBuild, clearOnBuild, () => { SetFlag(ConsoleFlags.ClearOnBuild, !clearOnBuild); }); var rect = GUILayoutUtility.GetLastRect(); rect.y += EditorGUIUtility.singleLineHeight; menu.DropDown(rect); } if (clearClicked) { LogEntries.Clear(); GUIUtility.keyboardControl = 0; } int currCount = LogEntries.GetCount(); if (m_ListView.totalRows != currCount) { // scroll bar was at the bottom? if (m_ListView.scrollPos.y >= m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight) { m_ListView.scrollPos.y = currCount * RowHeight - ms_LVHeight; } } bool wasCollapsed = HasFlag(ConsoleFlags.Collapse); SetFlag(ConsoleFlags.Collapse, GUILayout.Toggle(wasCollapsed, Constants.Collapse, Constants.MiniButton)); bool collapsedChanged = (wasCollapsed != HasFlag(ConsoleFlags.Collapse)); if (collapsedChanged) { // unselect if collapsed flag changed m_ListView.row = -1; // scroll to bottom m_ListView.scrollPos.y = LogEntries.GetCount() * RowHeight; } if (HasSpaceForExtraButtons()) { SetFlag(ConsoleFlags.ErrorPause, GUILayout.Toggle(HasFlag(ConsoleFlags.ErrorPause), Constants.ErrorPause, Constants.MiniButton)); PlayerConnectionGUILayout.ConnectionTargetSelectionDropdown(m_ConsoleAttachToPlayerState, EditorStyles.toolbarDropDown); } GUILayout.FlexibleSpace(); // Search bar if (HasSpaceForExtraButtons()) { SearchField(e); } // Flags int errorCount = 0, warningCount = 0, logCount = 0; LogEntries.GetCountsByType(ref errorCount, ref warningCount, ref logCount); EditorGUI.BeginChangeCheck(); bool setLogFlag = GUILayout.Toggle(HasFlag(ConsoleFlags.LogLevelLog), new GUIContent((logCount <= 999 ? logCount.ToString() : "999+"), logCount > 0 ? iconInfoSmall : iconInfoMono), Constants.MiniButton); bool setWarningFlag = GUILayout.Toggle(HasFlag(ConsoleFlags.LogLevelWarning), new GUIContent((warningCount <= 999 ? warningCount.ToString() : "999+"), warningCount > 0 ? iconWarnSmall : iconWarnMono), Constants.MiniButton); bool setErrorFlag = GUILayout.Toggle(HasFlag(ConsoleFlags.LogLevelError), new GUIContent((errorCount <= 999 ? errorCount.ToString() : "999+"), errorCount > 0 ? iconErrorSmall : iconErrorMono), Constants.MiniButtonRight); // Active entry index may no longer be valid if (EditorGUI.EndChangeCheck()) { SetActiveEntry(null); } SetFlag(ConsoleFlags.LogLevelLog, setLogFlag); SetFlag(ConsoleFlags.LogLevelWarning, setWarningFlag); SetFlag(ConsoleFlags.LogLevelError, setErrorFlag); GUILayout.EndHorizontal(); // Console entries SplitterGUILayout.BeginVerticalSplit(spl); GUIContent tempContent = new GUIContent(); int id = GUIUtility.GetControlID(0); int rowDoubleClicked = -1; /////@TODO: Make Frame selected work with ListViewState using (new GettingLogEntriesScope(m_ListView)) { int selectedRow = -1; bool openSelectedItem = false; bool collapsed = HasFlag(ConsoleFlags.Collapse); foreach (ListViewElement el in ListViewGUI.ListView(m_ListView, ListViewOptions.wantsRowMultiSelection, Constants.Box)) { if (e.type == EventType.MouseDown && e.button == 0 && el.position.Contains(e.mousePosition)) { selectedRow = m_ListView.row; if (e.clickCount == 2) { openSelectedItem = true; } } else if (e.type == EventType.Repaint) { int mode = 0; string text = null; LogEntries.GetLinesAndModeFromEntryInternal(el.row, Constants.LogStyleLineCount, ref mode, ref text); bool entryIsSelected = m_ListView.selectedItems != null && el.row < m_ListView.selectedItems.Length && m_ListView.selectedItems[el.row]; // offset value in x for icon and text var offset = Constants.LogStyleLineCount == 1 ? 4 : 8; // Draw the background GUIStyle s = el.row % 2 == 0 ? Constants.OddBackground : Constants.EvenBackground; s.Draw(el.position, false, false, entryIsSelected, false); // Draw the icon GUIStyle iconStyle = GetStyleForErrorMode(mode, true, Constants.LogStyleLineCount == 1); Rect iconRect = el.position; iconRect.x += offset; iconRect.y += 2; iconStyle.Draw(iconRect, false, false, entryIsSelected, false); // Draw the text tempContent.text = text; GUIStyle errorModeStyle = GetStyleForErrorMode(mode, false, Constants.LogStyleLineCount == 1); var textRect = el.position; textRect.x += offset; if (string.IsNullOrEmpty(m_SearchText)) { errorModeStyle.Draw(textRect, tempContent, id, m_ListView.row == el.row); } else { //the whole text contains the searchtext, we have to know where it is int startIndex = text.IndexOf(m_SearchText, StringComparison.OrdinalIgnoreCase); if (startIndex == -1) // the searchtext is not in the visible text, we don't show the selection { errorModeStyle.Draw(textRect, tempContent, id, m_ListView.row == el.row); } else // the searchtext is visible, we show the selection { int endIndex = startIndex + m_SearchText.Length; const bool isActive = false; const bool hasKeyboardFocus = true; // This ensure we draw the selection text over the label. const bool drawAsComposition = false; Color selectionColor = GUI.skin.settings.selectionColor; errorModeStyle.DrawWithTextSelection(textRect, tempContent, isActive, hasKeyboardFocus, startIndex, endIndex, drawAsComposition, selectionColor); } } if (collapsed) { Rect badgeRect = el.position; tempContent.text = LogEntries.GetEntryCount(el.row) .ToString(CultureInfo.InvariantCulture); Vector2 badgeSize = Constants.CountBadge.CalcSize(tempContent); if (Constants.CountBadge.fixedHeight > 0) { badgeSize.y = Constants.CountBadge.fixedHeight; } badgeRect.xMin = badgeRect.xMax - badgeSize.x; badgeRect.yMin += ((badgeRect.yMax - badgeRect.yMin) - badgeSize.y) * 0.5f; badgeRect.x -= 5f; GUI.Label(badgeRect, tempContent, Constants.CountBadge); } } } if (selectedRow != -1) { if (m_ListView.scrollPos.y >= m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight) { m_ListView.scrollPos.y = m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight - 1; } } // Make sure the selected entry is up to date if (m_ListView.totalRows == 0 || m_ListView.row >= m_ListView.totalRows || m_ListView.row < 0) { if (m_ActiveText.Length != 0) { SetActiveEntry(null); } } else { LogEntry entry = new LogEntry(); LogEntries.GetEntryInternal(m_ListView.row, entry); SetActiveEntry(entry); // see if selected entry changed. if so - clear additional info LogEntries.GetEntryInternal(m_ListView.row, entry); if (m_ListView.selectionChanged || !m_ActiveText.Equals(entry.message)) { SetActiveEntry(entry); } // If copy, get the messages from selected rows if (e.type == EventType.ExecuteCommand && e.commandName == EventCommandNames.Copy && m_ListView.selectedItems != null) { m_CopyString.Clear(); for (int rowIndex = 0; rowIndex < m_ListView.selectedItems.Length; rowIndex++) { if (m_ListView.selectedItems[rowIndex]) { LogEntries.GetEntryInternal(rowIndex, entry); m_CopyString.AppendLine(entry.message); } } } } // Open entry using return key if ((GUIUtility.keyboardControl == m_ListView.ID) && (e.type == EventType.KeyDown) && (e.keyCode == KeyCode.Return) && (m_ListView.row != 0)) { selectedRow = m_ListView.row; openSelectedItem = true; } if (e.type != EventType.Layout && ListViewGUI.ilvState.rectHeight != 1) { ms_LVHeight = ListViewGUI.ilvState.rectHeight; } if (openSelectedItem) { rowDoubleClicked = selectedRow; e.Use(); } } // Prevent dead locking in EditorMonoConsole by delaying callbacks (which can log to the console) until after LogEntries.EndGettingEntries() has been // called (this releases the mutex in EditorMonoConsole so logging again is allowed). Fix for case 1081060. if (rowDoubleClicked != -1) { LogEntries.RowGotDoubleClicked(rowDoubleClicked); } // Display active text (We want word wrapped text with a vertical scrollbar) m_TextScroll = GUILayout.BeginScrollView(m_TextScroll, Constants.Box); string stackWithHyperlinks = StacktraceWithHyperlinks(m_ActiveText); float height = Constants.MessageStyle.CalcHeight(GUIContent.Temp(stackWithHyperlinks), position.width); EditorGUILayout.SelectableLabel(stackWithHyperlinks, Constants.MessageStyle, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true), GUILayout.MinHeight(height + 10)); GUILayout.EndScrollView(); SplitterGUILayout.EndVerticalSplit(); // Copy & Paste selected item if ((e.type == EventType.ValidateCommand || e.type == EventType.ExecuteCommand) && e.commandName == EventCommandNames.Copy && m_CopyString != null) { if (e.type == EventType.ExecuteCommand) { EditorGUIUtility.systemCopyBuffer = m_CopyString.ToString(); } e.Use(); } }
void OnGUI() { Event e = Event.current; LoadIcons(); LogEntries.wrapped.UpdateEntries(); if (!m_HasUpdatedGuiStyles) { m_LineHeight = Mathf.RoundToInt(Constants.ErrorStyle.lineHeight); m_BorderHeight = Constants.ErrorStyle.border.top + Constants.ErrorStyle.border.bottom; UpdateListView(); } GUILayout.BeginHorizontal(Constants.Toolbar); if (GUILayout.Button(Constants.ClearLabel, Constants.MiniButton)) { LogEntries.Clear(); GUIUtility.keyboardControl = 0; } int currCount = LogEntries.wrapped.GetCount(); if (m_ListView.totalRows != currCount && m_ListView.totalRows > 0) { // scroll bar was at the bottom? if (m_ListView.scrollPos.y >= m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight) { m_ListView.scrollPos.y = currCount * RowHeight - ms_LVHeight; } } if (LogEntries.wrapped.searchFrame) { LogEntries.wrapped.searchFrame = false; int selectedIndex = LogEntries.wrapped.GetSelectedEntryIndex(); if (selectedIndex != -1) { int showIndex = selectedIndex + 1; if (currCount > showIndex) { int showCount = ms_LVHeight / RowHeight; showIndex = showIndex + showCount / 2; } m_ListView.scrollPos.y = showIndex * RowHeight - ms_LVHeight; } } EditorGUILayout.Space(); bool wasCollapsed = LogEntries.wrapped.collapse; LogEntries.wrapped.collapse = GUILayout.Toggle(wasCollapsed, Constants.CollapseLabel, Constants.MiniButton); bool collapsedChanged = (wasCollapsed != LogEntries.wrapped.collapse); if (collapsedChanged) { // unselect if collapsed flag changed m_ListView.row = -1; // scroll to bottom m_ListView.scrollPos.y = LogEntries.wrapped.GetCount() * RowHeight; } SetFlag(ConsoleFlags.ClearOnPlay, GUILayout.Toggle(HasFlag(ConsoleFlags.ClearOnPlay), Constants.ClearOnPlayLabel, Constants.MiniButton)); #if UNITY_2019_1_OR_NEWER SetFlag(ConsoleFlags.ClearOnBuild, GUILayout.Toggle(HasFlag(ConsoleFlags.ClearOnBuild), Constants.ClearOnBuildLabel, Constants.MiniButton)); #endif SetFlag(ConsoleFlags.ErrorPause, GUILayout.Toggle(HasFlag(ConsoleFlags.ErrorPause), Constants.ErrorPauseLabel, Constants.MiniButton)); #if UNITY_2018_3_OR_NEWER ConnectionGUILayout.AttachToPlayerDropdown(m_ConsoleAttachToPlayerState, EditorStyles.toolbarDropDown); #endif EditorGUILayout.Space(); if (m_DevBuild) { GUILayout.FlexibleSpace(); SetFlag(ConsoleFlags.StopForAssert, GUILayout.Toggle(HasFlag(ConsoleFlags.StopForAssert), Constants.StopForAssertLabel, Constants.MiniButton)); SetFlag(ConsoleFlags.StopForError, GUILayout.Toggle(HasFlag(ConsoleFlags.StopForError), Constants.StopForErrorLabel, Constants.MiniButton)); } GUILayout.FlexibleSpace(); // Search bar GUILayout.Space(4f); SearchField(e); int errorCount = 0, warningCount = 0, logCount = 0; LogEntries.wrapped.GetCountsByType(ref errorCount, ref warningCount, ref logCount); EditorGUI.BeginChangeCheck(); bool setLogFlag = GUILayout.Toggle(LogEntries.wrapped.HasFlag((int)ConsoleFlags.LogLevelLog), new GUIContent((logCount <= 999 ? logCount.ToString() : "999+"), logCount > 0 ? iconInfoSmall : iconInfoMono), Constants.MiniButton); bool setWarningFlag = GUILayout.Toggle(LogEntries.wrapped.HasFlag((int)ConsoleFlags.LogLevelWarning), new GUIContent((warningCount <= 999 ? warningCount.ToString() : "999+"), warningCount > 0 ? iconWarnSmall : iconWarnMono), Constants.MiniButton); bool setErrorFlag = GUILayout.Toggle(LogEntries.wrapped.HasFlag((int)ConsoleFlags.LogLevelError), new GUIContent((errorCount <= 999 ? errorCount.ToString() : "999+"), errorCount > 0 ? iconErrorSmall : iconErrorMono), Constants.MiniButton); // Active entry index may no longer be valid if (EditorGUI.EndChangeCheck()) { } LogEntries.wrapped.SetFlag((int)ConsoleFlags.LogLevelLog, setLogFlag); LogEntries.wrapped.SetFlag((int)ConsoleFlags.LogLevelWarning, setWarningFlag); LogEntries.wrapped.SetFlag((int)ConsoleFlags.LogLevelError, setErrorFlag); if (GUILayout.Button(new GUIContent(errorCount > 0 ? iconFirstErrorSmall : iconFirstErrorMono, Constants.FirstErrorLabel), Constants.MiniButton)) { int firstErrorIndex = LogEntries.wrapped.GetFirstErrorEntryIndex(); if (firstErrorIndex != -1) { SetActiveEntry(firstErrorIndex); LogEntries.wrapped.searchFrame = true; } } GUILayout.EndHorizontal(); SplitterGUILayout.BeginVerticalSplit(spl); int rowHeight = RowHeight; EditorGUIUtility.SetIconSize(new Vector2(rowHeight, rowHeight)); GUIContent tempContent = new GUIContent(); int id = GUIUtility.GetControlID(0); int rowDoubleClicked = -1; /////@TODO: Make Frame selected work with ListViewState using (new GettingLogEntriesScope(m_ListView)) { int selectedRow = -1; bool openSelectedItem = false; bool collapsed = LogEntries.wrapped.collapse; foreach (ListViewElement el in ListViewGUI.ListView(m_ListView, Constants.Box)) { if (e.type == EventType.MouseDown && e.button == 0 && el.position.Contains(e.mousePosition)) { m_ListView.row = el.row; selectedRow = el.row; if (e.clickCount == 2) { openSelectedItem = true; } } else if (e.type == EventType.Repaint) { int mode = 0; int entryCount = 0; int searchIndex = 0; int searchEndIndex = 0; string text = LogEntries.wrapped.GetEntryLinesAndFlagAndCount(el.row, ref mode, ref entryCount, ref searchIndex, ref searchEndIndex); ConsoleFlags flag = (ConsoleFlags)mode; bool isSelected = LogEntries.wrapped.IsEntrySelected(el.row); // Draw the background GUIStyle s = el.row % 2 == 0 ? Constants.OddBackground : Constants.EvenBackground; s.Draw(el.position, false, false, isSelected, false); // Draw the icon #if !UNITY_2017_3_OR_NEWER if (Constants.LogStyleLineCount == 1) { Rect rt = el.position; rt.x += 6f; rt.y += 2f; rt.width = 16f; rt.height = 16f; GUI.DrawTexture(rt, GetIconForErrorMode(flag, false)); } else #endif { GUIStyle iconStyle = GetStyleForErrorMode(flag, true, Constants.LogStyleLineCount == 1); iconStyle.Draw(el.position, false, false, isSelected, false); } // Draw the text tempContent.text = text; GUIStyle errorModeStyle = GetStyleForErrorMode(flag, false, Constants.LogStyleLineCount == 1); if (string.IsNullOrEmpty(LogEntries.wrapped.searchString) || searchIndex == -1 || searchIndex >= text.Length) { errorModeStyle.Draw(el.position, tempContent, id, isSelected); } else { errorModeStyle.DrawWithTextSelection(el.position, tempContent, GUIUtility.keyboardControl, searchIndex, searchEndIndex); } if (collapsed) { Rect badgeRect = el.position; tempContent.text = entryCount.ToString(CultureInfo.InvariantCulture); Vector2 badgeSize = Constants.CountBadge.CalcSize(tempContent); badgeRect.xMin = badgeRect.xMax - badgeSize.x; badgeRect.yMin += ((badgeRect.yMax - badgeRect.yMin) - badgeSize.y) * 0.5f; badgeRect.x -= 5f; GUI.Label(badgeRect, tempContent, Constants.CountBadge); } } } if (selectedRow != -1) { if (m_ListView.scrollPos.y >= m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight) { m_ListView.scrollPos.y = m_ListView.rowHeight * m_ListView.totalRows - ms_LVHeight - 1; } } // Make sure the selected entry is up to date if (m_ListView.totalRows == 0 || m_ListView.row >= m_ListView.totalRows || m_ListView.row < 0) { } else { if (m_ListView.selectionChanged) { SetActiveEntry(m_ListView.row); } } // Open entry using return key if ((GUIUtility.keyboardControl == m_ListView.ID) && (e.type == EventType.KeyDown) && (e.keyCode == KeyCode.Return) && (m_ListView.row != 0)) { selectedRow = m_ListView.row; openSelectedItem = true; } if (e.type != EventType.Layout && ListViewGUI.ilvState.rectHeight != 1) { ms_LVHeight = ListViewGUI.ilvState.rectHeight; } if (openSelectedItem) { rowDoubleClicked = selectedRow; e.Use(); } if (selectedRow != -1) { SetActiveEntry(selectedRow); } } // Prevent dead locking in EditorMonoConsole by delaying callbacks (which can log to the console) until after LogEntries.EndGettingEntries() has been // called (this releases the mutex in EditorMonoConsole so logging again is allowed). Fix for case 1081060. if (rowDoubleClicked != -1) { LogEntries.wrapped.StacktraceListView_RowGotDoubleClicked(); } EditorGUIUtility.SetIconSize(Vector2.zero); StacktraceListView(e, tempContent); SplitterGUILayout.EndVerticalSplit(); // Copy & Paste selected item if ((e.type == EventType.ValidateCommand || e.type == EventType.ExecuteCommand) && e.commandName == "Copy") { if (e.type == EventType.ExecuteCommand) { LogEntries.wrapped.StacktraceListView_CopyAll(); } e.Use(); } }