// 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; }
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); }