void InitListArea()
        {
            m_ListAreaState.m_GridSize = m_SavedGridSize;
            m_ListArea = new ObjectListArea(m_ListAreaState, editorWindow, false)
            {
                allowDeselection      = true,
                allowMultiSelect      = false,
                allowRenaming         = false,
                allowBuiltinResources = true,
            };

            m_ListArea.itemSelectedCallback += (bool doubleClicked) =>
            {
                if (m_ListArea.GetSelection().Length == 0)
                {
                    return;
                }
                var selection = m_ListArea.GetSelection()[0];
                if (doubleClicked)
                {
                    Selection.SetActiveObjectWithContext(EditorUtility.InstanceIDToObject(selection), null);
                    Event.current.Use();
                    editorWindow.Close();
                    GUIUtility.ExitGUI();
                }
                else
                {
                    EditorGUIUtility.PingObject(selection);
                    Event.current.Use();
                }
            };

            SearchFilterChanged();
        }
        void DoObjectLabel(Rect rect, Object entry, GUIStyle style)
        {
            GUI.Label(rect, AssetPreview.GetMiniThumbnail(entry));

            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition))
            {
                // One click shows where the referenced object is
                if (Event.current.clickCount == 1)
                {
                    GUIUtility.keyboardControl = GUIUtility.GetControlID(FocusType.Keyboard);

                    EditorGUIUtility.PingObject(entry);
                    Event.current.Use();
                }
                // Double click changes selection to referenced object
                else if (Event.current.clickCount == 2)
                {
                    if (entry)
                    {
                        Selection.SetActiveObjectWithContext(entry, null);
                        Event.current.Use();
                        editorWindow.Close();
                        GUIUtility.ExitGUI();
                    }
                }
            }

            rect.x     += rect.height;
            rect.width -= rect.height;
            GUI.Label(rect, EditorGUIUtility.TempContent(entry.name, entry.name), style);
        }
Example #3
0
            static void GotoLockOriginAction(Object[] targets)
            {
                // Find lock origin
                Material origin = targets[0] as Material;

                while ((origin = origin.parent))
                {
                    bool isLocked = false;
                    foreach (var prop in capturedProperties)
                    {
                        origin.GetPropertyState(Shader.PropertyToID(prop.name), out _, out isLocked, out _);
                        if (isLocked)
                        {
                            break;
                        }
                    }
                    if (isLocked)
                    {
                        break;
                    }

                    foreach (var prop in capturedSerializedProperties)
                    {
                        origin.GetPropertyState(prop, out _, out isLocked, out _);
                        if (isLocked)
                        {
                            break;
                        }
                    }
                    if (isLocked)
                    {
                        break;
                    }
                }

                if (origin)
                {
                    int clickCount = 1;
                    if (Event.current != null)
                    {
                        clickCount = Event.current.clickCount;
                        Event.current.Use();
                    }
                    if (clickCount == 1)
                    {
                        EditorGUIUtility.PingObject(origin);
                    }
                    else
                    {
                        Selection.SetActiveObjectWithContext(origin, null);
                        GUIUtility.ExitGUI();
                    }
                }
            }
        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();
        }