private void PerformParenting(AudioManagerCategory parent, List <AudioManagerCategory> categories, DragAndDropArgs args)
        {
            bool isChangingParent = categories.Any(c => c.Parent != parent);
            bool showWarning      = isChangingParent && !Event.current.control;

            if (!showWarning || EditorUtility.DisplayDialog("Reparent categories?",
                                                            "Are you sure you want to move " + categories.Count + " items to parent " + parent.ID + "?",
                                                            "Reparent", "Cancel"))
            {
                foreach (var cat in categories)
                {
                    SetParent(parent, cat);
                }

                if (args.dragAndDropPosition == DragAndDropPosition.BetweenItems)
                {
                    int insertIndex = args.insertAtIndex;
                    for (int i = categories.Count - 1; i >= 0; i--)
                    {
                        var cat = categories[i];
                        insertIndex = GetAdjustedInsertIndex(parent, cat, insertIndex);
                        SetSiblingIndex(cat, insertIndex);
                    }
                }

                m_Data.SaveTree();
                m_Data.ReconstructTreeChildren();
                m_Root = m_Data.TreeData;
            }
        }
        public static AssetMoveResult OnWillMoveAsset(string oldPath, string newPath)
        {
            //D.AudioLog("Moving " + oldPath + " to " + newPath);

            string           lowercase      = oldPath.ToLowerInvariant();
            AudioManagerData data           = null;
            bool             shouldSaveData = false;

            // this skips changes by hiding folders (if we want to exclude some files from the build)
            if (!newPath.Contains("/."))
            {
                // moving whole directory, need to check a lot of stuff :(
                if (Directory.Exists(Path.Combine(Application.dataPath, oldPath.Substring("Assets/".Length))))
                {
                    data = AudioManagerData.LoadInstanceData();
                    if (data != null)
                    {
                        //D.AudioLog("It's a direcotry, checking all sounds :(");
                        data.TreeData.RenameAssetPathRecursive(oldPath, newPath, ref shouldSaveData);
                    }
                }

                // moving a file
                else if (lowercase.EndsWith(".wav") || lowercase.EndsWith(".mp3") || lowercase.EndsWith(".aif") || lowercase.EndsWith(".ogg"))
                {
                    data = AudioManagerData.LoadInstanceData();
                    if (data != null)
                    {
                        // Check all the paths
                        data.TreeData.RenameAssetRecursive(oldPath, newPath, ref shouldSaveData);
                    }
                }
            }

            if (shouldSaveData)
            {
                D.AudioLog("Updating audio manager data!");
                data.SaveTree();
#if !UNITY_2018_2_OR_NEWER
                EditorUtility.SetDirty(data);
                AssetDatabase.SaveAssets();
#endif
            }

            return(AssetMoveResult.DidNotMove);
        }
        public void SaveTree()
        {
            if (m_TreeData == null)
            {
                InitTree();
            }

#if UNITY_2018_3_OR_NEWER
            var go = PrefabUtility.LoadPrefabContents(AudioPreferences.Instance.AudioManagerDataPrefabPath);
            AudioManagerData data = go.GetComponent <AudioManagerData>();

            data.TreeData  = m_TreeData;
            data.SavedTree = new List <AudioManagerCategory>();
            data.SaveTree(m_TreeData);

            PrefabUtility.SaveAsPrefabAsset(go, AudioPreferences.Instance.AudioManagerDataPrefabPath);
#else
            m_SavedTree = new List <AudioManagerCategory>();
            SaveTree(m_TreeData);
#endif
        }