Example #1
0
        // EditorWindow.OnGUI
        protected void OnGUI()
        {
            if (Data == null || Data.layers == null)
            {
                return;
            }
            if (Data.currentLayer >= Data.layers.Count || Data.layers[Data.currentLayer] == null)
            {
                Data.currentLayer = 0;
            }
            if (shelfScroll == null)
            {
                shelfScroll = new Vector2[Data.layers.Count];
            }
            if (shelfScroll.Length != Data.layers.Count)
            {
                var oldArray = shelfScroll;
                shelfScroll = new Vector2[Data.layers.Count];
                Array.Copy(oldArray, shelfScroll, Math.Min(oldArray.Length, shelfScroll.Length));
            }

            var    current     = Data.layers[Data.currentLayer];
            string windowTitle = "Shelf";

            // Force repaint if undo is triggered (only works when window has focus)
            if (Event.current.type == EventType.ValidateCommand &&
                Event.current.commandName == "UndoRedoPerformed")
            {
                Repaint();
            }

            // Force displaying all layers when the window is enlargened
            // to re-fit the highest number of layers into the toolbar
            if (Math.Abs(position.width - lastWindowWidth) > 5)
            {
                if (position.width > lastWindowWidth)
                {
                    lastWindowWidth = position.width;
                    showLayers      = int.MaxValue;
                }
                else
                {
                    lastWindowWidth = position.width;
                }
            }

            // Delay setting of showLayers until the end of the method
            int nextShowLayers = showLayers;

            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
            {
                bool  draggingOver = false;
                float width        = TOOLBAR_EXTRA_WIDTH + (showLayers < Data.layers.Count ? 12 : 0);
                for (int i = 0; i < showLayers && i < Data.layers.Count; i++)
                {
                    var layer = Data.layers[i];

                    var active = (Data.currentLayer == i);
                    if (GUILayout.Toggle(active, layer.name, EditorStyles.toolbarButton) != active)
                    {
                        Data.currentLayer = i;
                        return;
                    }

                    Rect buttonRect = GUILayoutUtility.GetLastRect();
                    if (buttonRect.Contains(Event.current.mousePosition))
                    {
                        // Drag-over layer switching
                        if (Event.current.type == EventType.DragUpdated &&
                            DragAndDrop.objectReferences.Length > 0)
                        {
                            DragAndDrop.visualMode = DragAndDropVisualMode.Link;
                            if (dragOverLayer != i)
                            {
                                dragOverLayer     = i;
                                dragOverLayerTime = Time.realtimeSinceStartup;
                            }
                            draggingOver = true;

                            // Dropping objects on layer button
                        }
                        else if (Event.current.type == EventType.DragPerform)
                        {
                            DragAndDrop.AcceptDrag();

                            layer.objects.AddRange(DragAndDrop.objectReferences);
                            Data.currentLayer = i;

                            Event.current.Use();
                            return;
                        }
                    }

                    // Stop showing layers if they don't fit anymore
                    width += buttonRect.width;
                    if (width > position.width)
                    {
                        nextShowLayers = i;
                        break;
                    }
                }

                // Reset tracking of toolbar hovering
                if (!draggingOver && (
                        Event.current.type == EventType.DragUpdated ||
                        Event.current.type == EventType.Repaint)
                    )
                {
                    dragOverLayer = -1;
                }

                // Put additional layers into dropdown menu
                if (showLayers < Data.layers.Count)
                {
                    if (Data.currentLayer >= showLayers)
                    {
                        windowTitle = "Shelf: " + current.name;
                    }

                    if (GUILayout.Button(GUIContent.none, EditorStyles.toolbarDropDown, GUILayout.Width(12)))
                    {
                        var menu = new GenericMenu();

                        for (int i = showLayers; i < Data.layers.Count; i++)
                        {
                            menu.AddItem(
                                new GUIContent(i + ": " + Data.layers[i].name),
                                (Data.currentLayer == i),
                                SwitchToLayer, i
                                );
                        }

                        menu.ShowAsContext();
                        Event.current.Use();
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            if (reorderable.List != current.objects)
            {
                reorderable.List = current.objects;
            }

            shelfScroll[Data.currentLayer] = EditorGUILayout.BeginScrollView(shelfScroll[Data.currentLayer]);
            {
                if (showInlinePrefs)
                {
                    EditorGUILayout.Space();

                    if (GUILayout.Button("Return"))
                    {
                        showInlinePrefs = false;
                    }

                    EditorGUILayout.Space();

                    inlinePrefs = true;
                    ShelfPreferences();
                    inlinePrefs = false;
                }
                else
                {
                    if (reorderable.OnGUI())
                    {
                        Repaint();
                    }
                }
            }
            EditorGUILayout.EndScrollView();

            if (!showInlinePrefs)
            {
                // Convert scene references to ShelfSceneReference instances
                for (int i = 0; i < current.objects.Count; i++)
                {
                    if (!EditorUtility.IsPersistent(current.objects[i]))
                    {
                        // We're only able to store references to Components or GameObjects
                        if (current.objects[i] is GameObject || current.objects[i] is Component)
                        {
                            current.objects[i] = ShelfSceneReference.Create(current.objects[i]);
                            AssetDatabase.AddObjectToAsset(current.objects[i], Data);
                            EditorUtility.SetDirty(Data);
                        }
                        else
                        {
                            Debug.LogError("Non-asset reference " + current.objects[i].name + " is neither " +
                                           "a GameObject nor a Component and cannot be saved on the shelf.");
                            current.objects.RemoveAt(i);
                            i--;
                        }
                    }
                }

                // Clear selection
                if (Event.current.type == EventType.MouseUp &&
                    Event.current.clickCount == 1)
                {
                    ClearSlection();
                }

                // Select all items on current shelf
                if (Event.current.commandName == "SelectAll")
                {
                    reorderable.SelectAll();
                    Event.current.Use();
                }
            }

            // Apply window title
            if (titleContent == null || titleContent.text != windowTitle)
            {
                titleContent = new GUIContent(windowTitle);
            }

            // Save shelf size
            if (EditorPrefs.GetFloat(SHELF_WIDTH_KEY) != position.width)
            {
                EditorPrefs.SetFloat(SHELF_WIDTH_KEY, position.width);
            }
            if (EditorPrefs.GetFloat(SHELF_HEIGHT_KEY) != position.height)
            {
                EditorPrefs.SetFloat(SHELF_HEIGHT_KEY, position.height);
            }

            // Apply showLayers now to avoid layout errors
            showLayers = nextShowLayers;
        }
Example #2
0
        protected static void ShelfPreferences()
        {
#if ENABLE_HACKS && PREFERENCES_WINDOW_REDRAW_HACK
            // HACK: Get private PreferencesWindow to type to get a
            // reference of the preferences window to trigger its redraw
            if (!inlinePrefs && preferencesWindow == null)
            {
                var prefWindowType = typeof(EditorApplication).Assembly.GetType("UnityEditor.PreferencesWindow");
                if (prefWindowType != null)
                {
                    preferencesWindow = EditorWindow.GetWindow(prefWindowType);
                }
            }
#endif

            if (Data == null)
            {
                return;
            }

            // Initialize reorderable list used to edit shelf layers
            if (preferencesList == null)
            {
                preferencesList = new EditorReorderableList <ShelfLayer>();
                preferencesList.allowMultiSelection      = false;
                preferencesList.undoTarget               = Data;
                preferencesList.objectReferencesCallback = PreferencesLayersReferences;
                preferencesList.listItemNameCallback     = PreferencesListItemName;
                preferencesList.listItemDrawCallback     = PreferencesDrawListItem;
                preferencesList.List = Data.layers;
            }

            EditorGUILayout.LabelField("Drag layers to reorder:");

            if (preferencesList.OnGUI())
            {
#if ENABLE_HACKS && PREFERENCES_WINDOW_REDRAW_HACK
                if (!inlinePrefs && preferencesWindow != null)
                {
                    preferencesWindow.Repaint();
                }
#endif
                if (editorInstance != null)
                {
                    editorInstance.Repaint();
                }
            }

            // Make sure the selected shelf index stays valid
            if (Data.currentLayer >= Data.layers.Count)
            {
                Data.currentLayer = Data.layers.Count - 1;
            }

            EditorGUILayout.Space();

            // Add new layer
            if (GUILayout.Button("Add Layer"))
            {
                Data.layers.Add(new ShelfLayer()
                {
                    name    = "New Layer",
                    objects = new List <UnityEngine.Object>()
                });
                EditorUtility.SetDirty(Data);
                if (editorInstance != null)
                {
                    editorInstance.Repaint();
                }
            }

            EditorGUILayout.Space();

            var enablePopup = EditorPrefs.GetBool(POPUP_PREFS_KEY, true);
            enablePopup = EditorGUILayout.Toggle("Enable Popup Shelf", enablePopup);
            EditorPrefs.SetBool(POPUP_PREFS_KEY, enablePopup);
        }