/// <summary> /// Adds our '+ / -' new entry / remove entry edit buttons after an entry. If entry is null, we're adding a top-level element /// </summary> /// <param name="entry"></param> protected void CreateEntryEditControls(GenericHierarchyEntry entry) { // show our add / remove buttons for each entry (to add a child or remove the current entry) GUI.backgroundColor = Loc.doneColor; var add = new GUIContent(imgAdd, Loc.TOOLTIP_ADDCHILDELEMENT); if (GUILayout.Button(add, GUILayout.Width(SMALLBUTTONSIZE), GUILayout.Height(SMALLBUTTONSIZE))) { Control.ShowNewFolderEntryDialog(entry); } GUI.backgroundColor = Loc.cancelColor; var remove = new GUIContent(imgRemove, Loc.TOOLTIP_REMOVEELEMENT); if (GUILayout.Button(remove, GUILayout.Width(SMALLBUTTONSIZE), GUILayout.Height(SMALLBUTTONSIZE))) { var entryMessage = Loc.DIALOG_CONFIRMDELETEENTRY_MESSAGE + " : " + entry.name; if (EditorUtility.DisplayDialog(Loc.DIALOG_CONFIRMDELETE_TITLE, entryMessage, Loc.DIALOG_OK, Loc.DIALOG_CANCEL)) { Control.FindAndRemoveConfigEntry(entry); } } GUI.backgroundColor = Loc.defaultColor; }
private static void CreateFolder(GenericHierarchyEntry entry, string parent) { var newPath = string.Empty; // save the path in case we need to generate a placeholder file var created = false; if (!AssetDatabase.IsValidFolder(entry.name)) { var guid = AssetDatabase.CreateFolder(parent, entry.name); newPath = AssetDatabase.GUIDToAssetPath(guid); Debug.Log("Created folder: " + newPath); created = true; } else { Debug.Log("Folder exists: " + entry.name); created = false; } if (entry.addEmptyPlaceholder && created) { Core.WriteEmptyFile(newPath); } if (entry.children != null) { foreach (var child in entry.children) { CreateFolder((GenericHierarchyEntry)child, parent + "/" + entry.name); } } }
/// <summary> /// Set which entry in our folder list we're currently editing /// </summary> /// <param name="entry"></param> public static void SetActiveEntrySelection(GenericHierarchyEntry entry) { // reset our 'dirty' state for the other elements entryEditDirty = false; activeEntrySelection = entry; tempEntrySelectionString = entry.name; // cache the entry name for the editor UI UpdateComponentsForEntry(activeEntrySelection); }
/// <summary> /// Add a new component to an entry in a template /// </summary> public static void AddComponentToEntry(GenericHierarchyEntry entry, COMPONENT_TYPE type) { if (entry != null) { var newComponent = new SceneComponentType(); newComponent.type = type; newComponent.requiresSubAsset = DoesComponentRequireSubassets(type); entry.components.Add(newComponent); SetActiveConfigDirty(true); } }
/// <summary> /// resets our selection completely /// </summary> public static void ClearSelection() { SetActiveConfigDirty(false); activeSelection = null; activeEntrySelection = null; activeConfig = null; configNameDirty = false; configDescriptionDirty = false; tempConfigDescriptionString = string.Empty; tempConfigNameString = string.Empty; }
/// <summary> /// Remove a component from an entry in a template /// </summary> public static void RemoveComponentFromEntry(GenericHierarchyEntry entry, COMPONENT_TYPE type) { if (entry != null) { for (var i = 0; i < entry.components.Count; i++) { if (entry.components[i].type == type) { entry.components.RemoveAt(i); SetActiveConfigDirty(true); } } } }
/// <summary> /// generates a new list of available components for the current selected entry /// </summary> /// <param name="entry"></param> public static void UpdateComponentsForEntry(GenericHierarchyEntry entry) { // copy our full list (deep copy) componentsForEntry.Clear(); foreach (var src in supportedComponentTypes) { componentsForEntry.Add(src); } // and remove any entries that are already added on the entry foreach (var comp in entry.components) { if (componentsForEntry.Contains(comp.type.ToString())) { componentsForEntry.Remove(comp.type.ToString()); } } }
/// <summary> /// The popup dialog that prompts for a name for the new Folder Entry /// </summary> /// <param name="entry">Optional parent</param> public static void ShowNewFolderEntryDialog(GenericHierarchyEntry entry) { // show dialog to get the desired name of the new entry var dialog = EditorWindow.CreateInstance <DialogGetNewEntryName>(); { dialog.entry = entry; dialog.dialogTitle = Loc.DIALOG_ADDNEWENTRY_TITLE; dialog.dialogMessage = Loc.DIALOG_ADDNEWENTRY_MESSAGE; // make sure the dialog is centered var dialogPosition = dialog.position; dialogPosition.center = new Rect(0f, 0f, Screen.currentResolution.width, Screen.currentResolution.height).center; dialog.position = dialogPosition; dialog.maxSize = new Vector2(250f, 110f); dialog.minSize = new Vector2(250f, 110f); } dialog.ShowUtility(); }
/// <summary> /// Create an entry from the sceneConfig. Can be called recursively for children /// </summary> /// <param name="entry"></param> private static void CreateEntry(GenericHierarchyEntry entry, Transform parent) { GameObject go = null; // find any existing objects with the same name if we're not supposed // to make new ones (Main Camera for example) if (!entry.createNewIfAlreadyExists) { go = EditorUtilities.GetSceneObject(entry.name); } if (go == null) { go = new GameObject(); } if (parent != null) { go.transform.parent = parent; } go.name = entry.name; // add any components that we need to the new gameobject if (entry.components != null) { foreach (var comp in entry.components) { AddNewComponent(go, comp.type); } } // if there are children that we need to add to this gameobject, call us recursively as needed if (entry.children != null) { foreach (var child in entry.children) { CreateEntry(child, go.transform); } } }
/// <summary> /// Recursive find & remove /// </summary> /// <param name="thisEntry"></param> /// <param name="entries"></param> public static void RemoveConfigEntry(GenericHierarchyEntry thisEntry, List <GenericHierarchyEntry> entries) { if (entries.Contains(thisEntry)) { // Debug.Log("Found entry, removing"); activeConfigEditDirty = true; entries.Remove(thisEntry); return; } else { for (var i = 0; i < entries.Count; i++) { if (entries[i].children.Count > 0) { // Debug.Log("searching entry children : " + entries[i].name); RemoveConfigEntry(thisEntry, entries[i].children); } } } }
/// <summary> /// Create a new entry in our folder list. If parentEntry is null, adds it as a new top-level folder /// </summary> /// <param name="parentEntry"></param> /// <param name="name"></param> public static void AddFolderEntry(GenericHierarchyEntry parentEntry, string name) { // Debug.Log("Add new folder entry to parent: " + parentEntry.name + " name: " + name); var newEntry = new GenericHierarchyEntry { name = name }; activeConfigEditDirty = true; // if we have a parent, add our new entry as a child if (parentEntry != null) { parentEntry.children.Add(newEntry); } else { // otherwise add it to the top level activeConfig.entries.Add(newEntry); } activeEntrySelection = null; }
public static void FindAndRemoveConfigEntry(GenericHierarchyEntry thisEntry) { RemoveConfigEntry(thisEntry, activeConfig.entries); }
/// <summary> /// Generates the component editor for an individual entry - pick component, configure etc /// </summary> /// <param name="entry"></param> protected void CreateComponentEditor(GenericHierarchyEntry entry, bool canEdit) { switch (Control.activeConfig.type) { case TEMPLATE_TYPE.SCENE: { GUILayout.BeginVertical(); { GUILayout.Space(10f); if (entry.components.Count > 0) { GUILayout.Label("Component List:"); } for (var i = 0; i < entry.components.Count; i++) { GUILayout.BeginHorizontal(); { GUILayout.Label("Type:", GUILayout.MaxWidth(50f)); var componentType = entry.components[i].type.ToString(); GUILayout.Label(componentType, EditorStyles.helpBox, GUILayout.MaxWidth(150f)); if (canEdit) { GUILayout.Space(SMALLBUTTONSIZE + 5); GUI.backgroundColor = Loc.cancelColor; var remove = new GUIContent(imgRemove, Loc.TOOLTIP_REMOVEELEMENT); if (GUILayout.Button(remove, GUILayout.Width(SMALLBUTTONSIZE), GUILayout.Height(SMALLBUTTONSIZE))) { var confirmDeleteComponentMessage = new StringBuilder(); confirmDeleteComponentMessage.Append(Loc.DIALOG_CONFIRMDELETECOMPONENT_MESSAGE); confirmDeleteComponentMessage.Append(componentType); confirmDeleteComponentMessage.Append(" from entry: "); confirmDeleteComponentMessage.Append(entry.name); if (EditorUtility.DisplayDialog(Loc.DIALOG_CONFIRMDELETE_TITLE, confirmDeleteComponentMessage.ToString(), Loc.DIALOG_OK, Loc.DIALOG_CANCEL)) { Control.RemoveComponentFromEntry(entry, entry.components[i].type); break; } } GUI.backgroundColor = Loc.defaultColor; } } GUILayout.EndHorizontal(); if (canEdit) { if (Control.DoesComponentRequireSubassets(entry.components[i].type)) { Control.entryCreateSubAsset = EditorGUILayout.Toggle("Create Sub-Asset?", Control.entryCreateSubAsset); if (Control.entryCreateSubAsset) { GUILayout.Label("Select template for sub asset"); } } } } if (canEdit) { GUILayout.Space(10f); GUILayout.Label("Add new Component:", GUILayout.MaxWidth(STANDARDBUTTONSIZE)); // dropdown of supported component types Control.entrySelectedComponent = EditorGUILayout.Popup(Control.entrySelectedComponent, Control.componentsForEntry.ToArray(), GUILayout.MaxWidth(STANDARDBUTTONSIZE)); if (Control.entrySelectedComponent > 0) { GUI.backgroundColor = Loc.doneColor; if (GUILayout.Button("[ Add ]", GUILayout.MaxWidth(STANDARDBUTTONSIZE))) { // figure out what type this is, and add it to the list var type = Enum.Parse(typeof(COMPONENT_TYPE), Control.componentsForEntry[Control.entrySelectedComponent]); Control.AddComponentToEntry(entry, (COMPONENT_TYPE)type); } GUI.backgroundColor = Loc.defaultColor; } } } GUILayout.EndVertical(); break; } } }
/// <summary> /// Recursively generate the UI required to display the treeview structure that the template will generate /// </summary> /// <param name="entry">This entry</param> /// <param name="parent">name of the parent (if any)</param> /// <param name="canEdit">whether we are in edit mode or just view</param> /// /// <param name="offset">Horizontal offset for the entry</param> protected void CreateTreeViewUI(GenericHierarchyEntry entry, string parent, bool canEdit, float offset) { var hasChildren = false; if (entry.children != null) { if (entry.children.Count > 0) { hasChildren = true; } } if (parent != string.Empty) { offset += HIERARCHYINDENTOFFSET; } // draw the entry GUILayout.BeginHorizontal(); { GUILayout.Space(offset); // indent if (hasChildren) { GUILayout.Label(imgArrowDown, GUILayout.Width(SMALLBUTTONSIZE), GUILayout.Height(SMALLBUTTONSIZE)); } else { GUILayout.Label(imgArrowRight, GUILayout.Width(SMALLBUTTONSIZE), GUILayout.Height(SMALLBUTTONSIZE)); } // draw the list entry like a label, but it's actually a button, make it bold if we are in edit mode & selected var style = EditorStyles.label; if (canEdit) { // if we're selected, make us bold if (Control.activeEntrySelection == entry) { style = EditorStyles.boldLabel; } } if (GUILayout.Button(entry.name, style, GUILayout.ExpandWidth(true))) { Control.SetActiveEntrySelection(entry); } if (canEdit) { // add the appropriate edit controls CreateEntryEditControls(entry); } } GUILayout.EndHorizontal(); if (hasChildren) { parent = entry.name; // can't use a foreach because we remove entries, breaks enumeration for (var i = 0; i < entry.children.Count; i++) { // Debug.Log("Creating child " + child.name + " with offset: " + offset); CreateTreeViewUI(entry.children[i], parent, canEdit, offset); } } }