void DrawChildren(float yMin) { int listKeyboardControlID = GUIUtility.GetControlID(FocusType.Keyboard); var backgroundRect = new Rect(0, yMin, m_WindowWidth, k_SearchHeight); GUI.Label(backgroundRect, GUIContent.none, Styles.searchBackground); EditorGUI.BeginChangeCheck(); var searchRect = new Rect(k_OffsetX + k_Padding, backgroundRect.y + k_Padding, m_WindowWidth - 2 * k_OffsetX - k_Padding, Styles.searchFieldStyle.fixedHeight); m_SearchFilterString = EditorGUI.ToolbarSearchField(searchRect, m_SearchFilterString, false); if (EditorGUI.EndChangeCheck()) { m_Debounce.Execute(); } if (m_Enumerator != null) { Search(); } yMin = searchRect.height + (m_ListArea.gridSize < k_MinIconSize ? 11f : 0f); var listRect = new Rect(k_Padding, searchRect.y + yMin, m_WindowWidth - 2 * k_Padding, k_SearchHeight - yMin - k_Padding); m_ListArea.OnGUI(listRect, listKeyboardControlID); if (m_Enumerator == null && m_Results.Length == 0) { var labelRect = new Rect(m_NoResultsX, backgroundRect.y + 69f, m_WindowWidth, EditorGUI.kSingleLineHeight); EditorGUI.LabelField(backgroundRect, m_SearchFilter.nameFilter.Length == 0 ? Styles.noChildrenLabel : Styles.noResultsLabel, Styles.centered); } }
void SearchArea(Rect toolbarRect) { GUI.Label(toolbarRect, GUIContent.none, s_Styles.searchBg); // ESC clears search field and removes it's focus. But if we get an esc event we only want to clear search field. // So we need special handling afterwards. bool wasEscape = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape; GUI.SetNextControlName(kSearchFieldTag); string newSearchFilter = EditorGUI.SearchField(new Rect(5, 5, toolbarRect.width - 10, 15), m_SearchString); if (wasEscape && Event.current.type == EventType.Used) { // If we hit esc and the string WAS empty, it's an actual cancel event. if (m_SearchString != string.Empty) { // Otherwise the string has been cleared and focus has been lost. We don't have anything else to recieve focus, so we want to refocus the search field. m_FocusSearchFilter = true; } } if (newSearchFilter != m_SearchString || m_FocusSearchFilter) { m_SearchString = newSearchFilter; m_Debounce.Execute(); } if (m_FocusSearchFilter) { EditorGUI.FocusTextInControl(kSearchFieldTag); if (Event.current.type == EventType.Repaint) { m_FocusSearchFilter = false; } } }
// This is our search field void SearchArea() { GUI.Label(new Rect(0, 0, position.width, kToolbarHeight), GUIContent.none, EditorStyles.toolbar); // ESC clears search field and removes it's focus. But if we get an esc event we only want to clear search field. // So we need special handling afterwards. bool wasEscape = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape; GUI.SetNextControlName("SearchFilter"); string searchFilter = EditorGUI.ToolbarSearchField(new Rect(2, 2, position.width - 2, 16), m_SearchFilter, false); if (wasEscape && Event.current.type == EventType.Used) { // If we hit esc and the string WAS empty, it's an actual cancel event. if (m_SearchFilter == "") { Cancel(); } // Otherwise the string has been cleared and focus has been lost. We don't have anything else to recieve focus, so we want to refocus the search field. m_FocusSearchFilter = true; } if (searchFilter != m_SearchFilter || m_FocusSearchFilter) { m_SearchFilter = searchFilter; m_Debounce.Execute(); } if (m_FocusSearchFilter) { EditorGUI.FocusTextInControl("SearchFilter"); m_FocusSearchFilter = false; } GUI.changed = false; GUI.Label(new Rect(0, kToolbarHeight, position.width, kToolbarHeight), GUIContent.none, EditorStyles.toolbar); // TAB BAR GUILayout.BeginArea(new Rect(4, kToolbarHeight, position.width - 4, kToolbarHeight)); GUILayout.BeginHorizontal(); // Asset Tab bool showAssets = GUILayout.Toggle(m_IsShowingAssets, Styles.assetsTabLabel, Styles.tab); if (!m_IsShowingAssets && showAssets) { m_IsShowingAssets = true; } // The Scene Tab if (!m_AllowSceneObjects) { GUI.enabled = false; GUI.color = new Color(1, 1, 1, 0); } bool showingSceneTab = !m_IsShowingAssets; showingSceneTab = GUILayout.Toggle(showingSceneTab, Styles.sceneTabLabel, Styles.tab); if (m_IsShowingAssets && showingSceneTab) { m_IsShowingAssets = false; } if (!m_AllowSceneObjects) { GUI.color = new Color(1, 1, 1, 1); GUI.enabled = true; } GUILayout.EndHorizontal(); GUILayout.EndArea(); if (GUI.changed) { m_Debounce.Execute(); } var size = new Vector2(0, 0); if (m_IsShowingAssets) { Styles.packagesVisibilityContent.text = PackageManagerUtilityInternal.HiddenPackagesCount.ToString(); size = EditorStyles.toolbarButton.CalcSize(Styles.packagesVisibilityContent); } if (m_ListArea.CanShowThumbnails()) { EditorGUI.BeginChangeCheck(); var newGridSize = (int)GUI.HorizontalSlider(new Rect(position.width - (60 + size.x), kToolbarHeight + GUI.skin.horizontalSlider.margin.top, 55, EditorGUI.kSingleLineHeight), m_ListArea.gridSize, m_ListArea.minGridSize, m_ListArea.maxGridSize); if (EditorGUI.EndChangeCheck()) { m_ListArea.gridSize = newGridSize; } } if (m_IsShowingAssets) { EditorGUI.BeginChangeCheck(); var skipHiddenPackages = GUI.Toggle(new Rect(position.width - size.x, kToolbarHeight, size.x, EditorStyles.toolbarButton.fixedHeight), m_SkipHiddenPackages, Styles.packagesVisibilityContent, EditorStyles.toolbarButtonRight); if (EditorGUI.EndChangeCheck()) { m_SkipHiddenPackages = skipHiddenPackages; FilterSettingsChanged(); } } }
public override void OnGUI(Rect rect) { if (editorWindow.position.y != targetPositionY) { editorWindow.position = new Rect(editorWindow.position) { y = targetPositionY } } ; // Escape closes the window if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape) { editorWindow.Close(); GUIUtility.ExitGUI(); } if (!DrawHeader()) { return; } float height = k_HeaderHeight; if (target.isVariant) { height += DrawVariantHierarchy(); } height += DrawChildrenLabel(height); if (displayChildren) { DrawChildren(height); } if (materialEditor.convertState == ConvertAction.Flatten) { materialEditor.convertState = ConvertAction.None; Undo.RecordObject(target, "Flatten Material Variant"); target.parent = null; Init(); } } bool DrawHeader() { Rect headerRect = GUILayoutUtility.GetRect(20, windowWidth, k_HeaderHeight, k_HeaderHeight); EditorGUI.DrawRect(headerRect, Colors.headerBackground); var headerLabel = target.isVariant ? Styles.variantLabel : Styles.instanceLabel; float labelSize = Styles.boldRightAligned.CalcSize(headerLabel).x; Rect labelRect = new Rect(k_OffsetX, headerRect.y + k_Padding, labelSize, EditorGUIUtility.singleLineHeight); Rect contentRect = new Rect(labelRect.x + labelRect.width + k_Padding, labelRect.y, windowWidth, labelRect.height); GUI.Label(labelRect, headerLabel, Styles.boldRightAligned); DoObjectLabel(contentRect, target, EditorStyles.boldLabel); labelRect.y = labelRect.height + 2 * k_Padding; if (materialEditor.convertState == ConvertAction.None) { int result; labelRect.width = k_ConvertLabelWidth; using (new EditorGUI.DisabledScope(!enabled)) result = EditorGUI.Popup(labelRect, target.isVariant ? 1 : 0, Styles.headerPopupOptions); if (result == 0 && target.isVariant) { materialEditor.convertState = ConvertAction.Flatten; targetPositionY = singleLinePositionY; } if (result == 1 && !target.isVariant) { materialEditor.convertState = ConvertAction.Convert; targetPositionY = singleLinePositionY + k_PositionShiftY; } } else if (materialEditor.convertState == ConvertAction.Convert) { GUI.enabled = false; labelRect.width = 200f; EditorGUI.Button(labelRect, Styles.convertingLabel); GUI.enabled = true; // Conversion helper labelRect.y = k_HeaderHeight; labelRect.width = windowWidth; EditorGUI.LabelField(labelRect, Styles.conversionHelpLabel); labelRect.x = windowWidth - 14; if (GUI.Button(labelRect, GUIContent.none, EditorStyles.toolbarSearchFieldCancelButton)) { materialEditor.convertState = ConvertAction.None; targetPositionY = singleLinePositionY; materialEditor.Repaint(); } labelRect.x = k_OffsetX; var oldLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 70; EditorGUI.BeginChangeCheck(); var parent = target.parent; materialEditor.ParentField(new Rect(k_OffsetX, labelRect.yMax + k_Padding, windowWidth - 2 * k_OffsetX, k_EntryHeight)); if (EditorGUI.EndChangeCheck() && parent != target.parent) { materialEditor.convertState = ConvertAction.None; Init(); } EditorGUIUtility.labelWidth = oldLabelWidth; return(false); } return(true); } float DrawVariantHierarchy() { // Draw table header Rect entryRect = new Rect(0, k_HeaderHeight, windowWidth, k_EntryHeight); EditorGUI.DrawRect(entryRect, Colors.rowBackground(0)); var labelRect = entryRect; labelRect.x = k_TitleWidth; GUI.Label(labelRect, Styles.ancestorLabel, EditorStyles.miniLabel); labelRect.x = overridesX + k_Padding; GUI.Label(labelRect, Styles.overridesLabel, EditorStyles.miniLabel); labelRect.x = locksX + k_Padding; GUI.Label(labelRect, Styles.locksLabel, EditorStyles.miniLabel); float tableHeight = Mathf.Min(numRows, k_MaxTableRows) * k_EntryHeight + (namesWidth > maxNameWidth ? k_ScrollbarHeight : 0); float realHeight = numRows * k_EntryHeight + (namesWidth > maxNameWidth ? k_ScrollbarHeight : 0); var tableRect = new Rect(0, k_HeaderHeight + k_EntryHeight, windowWidth - 1, tableHeight); scroll.y = GUI.BeginScrollView(tableRect, scroll, new Rect(tableRect) { width = tableRect.width - k_ScrollbarWidth, height = realHeight }).y; // Draw overrides and locks table int i = numRows; Material current = target; while (current != null) { entryRect.y = k_HeaderHeight + i * k_EntryHeight; EditorGUI.DrawRect(entryRect, Colors.rowBackground(i--)); DisplayOverridesAndLocks(entryRect, current); current = current.parent; } var scrollRect = new Rect(k_TitleWidth, k_HeaderHeight + k_EntryHeight, Mathf.Min(namesWidth, maxNameWidth), numRows * k_EntryHeight); scroll.x = GUI.BeginScrollView(new Rect(scrollRect) { height = scrollRect.height + k_ScrollbarHeight }, scroll, new Rect(scrollRect) { width = namesWidth }).x; // Draw scrollable table i = numRows; current = target; entryRect.x = k_TitleWidth; while (i != 0) { entryRect.y = k_HeaderHeight + i-- *k_EntryHeight; if (current == null) { GUI.Label(entryRect, EditorGUIUtility.TempContent("Missing (Material)")); break; } DoObjectLabel(entryRect, current); current = current.parent; } GUI.EndScrollView(); float height = tableHeight + k_EntryHeight; // Draw selected label labelRect.x = k_OffsetX; labelRect.y = k_HeaderHeight + numRows * k_EntryHeight; labelRect.width = k_TitleWidth - labelRect.x; GUI.Label(labelRect, Styles.selectedLabel); // Draw parent label labelRect.y = k_HeaderHeight + (numRows - 1) * k_EntryHeight; GUI.Label(labelRect, Styles.parentLabel); // Draw root label if (labelRect.y != k_HeaderHeight + k_EntryHeight) { labelRect.y = k_HeaderHeight + k_EntryHeight; GUI.Label(labelRect, Styles.rootLabel); } // Draw vertical splits Rect splitBar = new Rect(overridesX - k_SplitWidth, k_HeaderHeight, k_SplitWidth, (numRows + 1) * k_EntryHeight); EditorGUI.DrawRect(splitBar, Colors.headerBackground); splitBar.x = locksX - k_SplitWidth; EditorGUI.DrawRect(splitBar, Colors.headerBackground); GUI.EndScrollView(); return(height); } float DrawChildrenLabel(float yMin) { var labelRect = new Rect(k_OffsetX, yMin, 100, k_EntryHeight); if (target.isVariant) { displayChildren = EditorGUI.Foldout(labelRect, displayChildren, Styles.childrenLabel, true); } else { EditorGUI.LabelField(labelRect, Styles.childrenLabel); } if (displayChildren) { if (listArea == null) { InitListArea(); } labelRect = new Rect(labelRect.x + 58 + (target.isVariant ? 12 : 0), labelRect.y + 2, k_SliderWidth, EditorGUI.kSingleLineHeight); if (results.Length != 0) { EditorGUI.LabelField(labelRect, results.Length.ToString(), Styles.boldNumber); } EditorGUI.BeginChangeCheck(); labelRect.x = windowWidth - k_OffsetX - k_SliderWidth; var newGridSize = (int)GUI.HorizontalSlider(labelRect, listArea.gridSize, listArea.minGridSize, listArea.maxGridSize); if (EditorGUI.EndChangeCheck()) { listArea.gridSize = newGridSize; } } return(k_EntryHeight); } void DrawChildren(float yMin) { var backgroundRect = new Rect(0, yMin, windowWidth, k_SearchHeight); GUI.Label(backgroundRect, GUIContent.none, Styles.searchBackground); EditorGUI.BeginChangeCheck(); var searchRect = new Rect(k_OffsetX + k_Padding, backgroundRect.y + k_Padding, windowWidth - 2 * k_OffsetX - k_Padding, Styles.searchFieldStyle.fixedHeight); searchFilterString = EditorGUI.ToolbarSearchField(searchRect, searchFilterString, false); if (EditorGUI.EndChangeCheck()) { debounce.Execute(); } if (enumerator != null) { Search(); } yMin = searchRect.height + (listArea.gridSize < k_MinIconSize ? 11f : 0f); var listRect = new Rect(k_Padding, searchRect.y + yMin, windowWidth - 2 * k_Padding, k_SearchHeight - yMin - k_Padding); int listKeyboardControlID = GUIUtility.GetControlID(FocusType.Keyboard); listArea.OnGUI(listRect, listKeyboardControlID); if (enumerator == null && results.Length == 0) { var labelRect = new Rect(noResultsX, backgroundRect.y + 69f, windowWidth, EditorGUI.kSingleLineHeight); EditorGUI.LabelField(backgroundRect, searchFilter.nameFilter.Length == 0 ? Styles.noChildrenLabel : Styles.noResultsLabel, Styles.centered); } } void InitListArea() { listArea = new ObjectListArea(s_ListAreaState, editorWindow, false) { allowDeselection = true, allowMultiSelect = false, allowRenaming = false, allowBuiltinResources = true, }; listArea.itemSelectedCallback += (bool doubleClicked) => { if (listArea.GetSelection().Length == 0) { return; } var selection = listArea.GetSelection()[0]; GUIUtility.keyboardControl = GUIUtility.GetControlID(FocusType.Keyboard); if (doubleClicked) { Selection.SetActiveObjectWithContext(EditorUtility.InstanceIDToObject(selection), null); Event.current.Use(); editorWindow.Close(); GUIUtility.ExitGUI(); } else { EditorGUIUtility.PingObject(selection); Event.current.Use(); } }; SearchFilterChanged(); }