| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647 | using UnityEditor;using UnityEngine;using System.Collections.Generic;using UnityEditor.IMGUI.Controls;using System.Linq;using System;namespace AssetBundleBrowser{    internal class AssetBundleTree : TreeView    {         AssetBundleManageTab m_Controller;        private bool m_ContextOnItem = false;        List<UnityEngine.Object> m_EmptyObjectList = new List<UnityEngine.Object>();        internal AssetBundleTree(TreeViewState state, AssetBundleManageTab ctrl) : base(state)        {            AssetBundleModel.Model.Rebuild();            m_Controller = ctrl;            showBorder = true;        }        protected override bool CanMultiSelect(TreeViewItem item)        {            return true;        }        protected override bool CanRename(TreeViewItem item)        {            return item != null && item.displayName.Length > 0;        }        protected override bool DoesItemMatchSearch(TreeViewItem item, string search)        {            var bundleItem = item as AssetBundleModel.BundleTreeItem;            return bundleItem.bundle.DoesItemMatchSearch(search);        }        protected override void RowGUI(RowGUIArgs args)        {            var bundleItem = (args.item as AssetBundleModel.BundleTreeItem);            if (args.item.icon == null)                extraSpaceBeforeIconAndLabel = 16f;            else                extraSpaceBeforeIconAndLabel = 0f;            Color old = GUI.color;            if ((bundleItem.bundle as AssetBundleModel.BundleVariantFolderInfo) != null)                GUI.color = AssetBundleModel.Model.k_LightGrey; //new Color(0.3f, 0.5f, 0.85f);            base.RowGUI(args);            GUI.color = old;            var message = bundleItem.BundleMessage();            if(message.severity != MessageType.None)            {                var size = args.rowRect.height;                var right = args.rowRect.xMax;                Rect messageRect = new Rect(right - size, args.rowRect.yMin, size, size);                GUI.Label(messageRect, new GUIContent(message.icon, message.message ));            }        }        protected override void RenameEnded(RenameEndedArgs args)        {             base.RenameEnded(args);            if (args.newName.Length > 0 && args.newName != args.originalName)            {                args.newName = args.newName.ToLower();                args.acceptedRename = true;                AssetBundleModel.BundleTreeItem renamedItem = FindItem(args.itemID, rootItem) as AssetBundleModel.BundleTreeItem;                args.acceptedRename = AssetBundleModel.Model.HandleBundleRename(renamedItem, args.newName);                ReloadAndSelect(renamedItem.bundle.nameHashCode, false);            }            else            {                args.acceptedRename = false;            }        }        protected override TreeViewItem BuildRoot()        {            AssetBundleModel.Model.Refresh();            var root = AssetBundleModel.Model.CreateBundleTreeView();            return root;        }        protected override void SelectionChanged(IList<int> selectedIds)        {            var selectedBundles = new List<AssetBundleModel.BundleInfo>();            if (selectedIds != null)            {                foreach (var id in selectedIds)                {                    var item = FindItem(id, rootItem) as AssetBundleModel.BundleTreeItem;                    if(item != null && item.bundle != null)                    {                        item.bundle.RefreshAssetList();                        selectedBundles.Add(item.bundle);                    }                }            }            m_Controller.UpdateSelectedBundles(selectedBundles);        }        public override void OnGUI(Rect rect)        {            base.OnGUI(rect);            if(Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains(Event.current.mousePosition))            {                SetSelection(new int[0], TreeViewSelectionOptions.FireSelectionChanged);            }        }        protected override void ContextClicked()        {            if (m_ContextOnItem)            {                m_ContextOnItem = false;                return;            }            List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>();            GenericMenu menu = new GenericMenu();            if (!AssetBundleModel.Model.DataSource.IsReadOnly ()) {                menu.AddItem(new GUIContent("Add new bundle"), false, CreateNewBundle, selectedNodes);                 menu.AddItem(new GUIContent("Add new folder"), false, CreateFolder, selectedNodes);            }            menu.AddItem(new GUIContent("Reload all data"), false, ForceReloadData, selectedNodes);            menu.ShowAsContext();        }        protected override void ContextClickedItem(int id)        {            if (AssetBundleModel.Model.DataSource.IsReadOnly ()) {                return;            }            m_ContextOnItem = true;            List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>();            foreach (var nodeID in GetSelection())            {                selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.BundleTreeItem);            }                        GenericMenu menu = new GenericMenu();                        if(selectedNodes.Count == 1)            {                if ((selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo) != null)                {                    menu.AddItem(new GUIContent("Add Child/New Bundle"), false, CreateNewBundle, selectedNodes);                    menu.AddItem(new GUIContent("Add Child/New Folder"), false, CreateFolder, selectedNodes);                    menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes);                    menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes);                }                else if( (selectedNodes[0].bundle as AssetBundleModel.BundleVariantFolderInfo) != null)                {                    menu.AddItem(new GUIContent("Add Child/New Variant"), false, CreateNewVariant, selectedNodes);                    menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes);                    menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes);                }                else                {                    var variant = selectedNodes[0].bundle as AssetBundleModel.BundleVariantDataInfo;                    if (variant == null)                    {                        menu.AddItem(new GUIContent("Add Sibling/New Bundle"), false, CreateNewSiblingBundle, selectedNodes);                        menu.AddItem(new GUIContent("Add Sibling/New Folder"), false, CreateNewSiblingFolder, selectedNodes);                        menu.AddItem(new GUIContent("Convert to variant"), false, ConvertToVariant, selectedNodes);                    }                    else                    {                        menu.AddItem(new GUIContent("Add Sibling/New Variant"), false, CreateNewSiblingVariant, selectedNodes);                    }                }                if(selectedNodes[0].bundle.IsMessageSet(MessageSystem.MessageFlag.AssetsDuplicatedInMultBundles))                    menu.AddItem(new GUIContent("Move duplicates to new bundle"), false, DedupeAllBundles, selectedNodes);                menu.AddItem(new GUIContent("Rename"), false, RenameBundle, selectedNodes);                menu.AddItem(new GUIContent("Delete " + selectedNodes[0].displayName), false, DeleteBundles, selectedNodes);                            }            else if (selectedNodes.Count > 1)            {                 menu.AddItem(new GUIContent("Move duplicates shared by selected"), false, DedupeOverlappedBundles, selectedNodes);                menu.AddItem(new GUIContent("Move duplicates existing in any selected"), false, DedupeAllBundles, selectedNodes);                menu.AddItem(new GUIContent("Delete " + selectedNodes.Count + " selected bundles"), false, DeleteBundles, selectedNodes);            }            menu.ShowAsContext();        }        void ForceReloadData(object context)        {            AssetBundleModel.Model.ForceReloadData(this);        }        void CreateNewSiblingFolder(object context)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                AssetBundleModel.BundleFolderConcreteInfo folder = null;                folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleFolderConcreteInfo;                CreateFolderUnderParent(folder);            }            else                Debug.LogError("could not add 'sibling' with no bundles selected");        }        void CreateFolder(object context)        {            AssetBundleModel.BundleFolderConcreteInfo folder = null;            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                folder = selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo;            }            CreateFolderUnderParent(folder);        }        void CreateFolderUnderParent(AssetBundleModel.BundleFolderConcreteInfo folder)        {            var newBundle = AssetBundleModel.Model.CreateEmptyBundleFolder(folder);            ReloadAndSelect(newBundle.nameHashCode, true);        }        void RenameBundle(object context)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                BeginRename(FindItem(selectedNodes[0].bundle.nameHashCode, rootItem));            }        }        void CreateNewSiblingBundle(object context)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                AssetBundleModel.BundleFolderConcreteInfo folder = null;                folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleFolderConcreteInfo;                CreateBundleUnderParent(folder);            }            else                Debug.LogError("could not add 'sibling' with no bundles selected");        }        void CreateNewBundle(object context)        {            AssetBundleModel.BundleFolderConcreteInfo folder = null;            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                folder = selectedNodes[0].bundle as AssetBundleModel.BundleFolderConcreteInfo;            }            CreateBundleUnderParent(folder);        }        void CreateBundleUnderParent(AssetBundleModel.BundleFolderInfo folder)        {            var newBundle = AssetBundleModel.Model.CreateEmptyBundle(folder);            ReloadAndSelect(newBundle.nameHashCode, true);        }        void CreateNewSiblingVariant(object context)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count > 0)            {                AssetBundleModel.BundleVariantFolderInfo folder = null;                folder = selectedNodes[0].bundle.parent as AssetBundleModel.BundleVariantFolderInfo;                CreateVariantUnderParent(folder);            }            else                Debug.LogError("could not add 'sibling' with no bundles selected");        }        void CreateNewVariant(object context)        {            AssetBundleModel.BundleVariantFolderInfo folder = null;            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes != null && selectedNodes.Count == 1)            {                folder = selectedNodes[0].bundle as AssetBundleModel.BundleVariantFolderInfo;                CreateVariantUnderParent(folder);            }        }        void CreateVariantUnderParent(AssetBundleModel.BundleVariantFolderInfo folder)        {            if (folder != null)            {                var newBundle = AssetBundleModel.Model.CreateEmptyVariant(folder);                ReloadAndSelect(newBundle.nameHashCode, true);            }        }        void ConvertToVariant(object context)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            if (selectedNodes.Count == 1)            {                var bundle = selectedNodes[0].bundle as AssetBundleModel.BundleDataInfo;                var newBundle = AssetBundleModel.Model.HandleConvertToVariant(bundle);                int hash = 0;                if (newBundle != null)                    hash = newBundle.nameHashCode;                ReloadAndSelect(hash, true);            }        }        void DedupeOverlappedBundles(object context)        {            DedupeBundles(context, true);        }        void DedupeAllBundles(object context)        {            DedupeBundles(context, false);        }        void DedupeBundles(object context, bool onlyOverlappedAssets)        {            var selectedNodes = context as List<AssetBundleModel.BundleTreeItem>;            var newBundle = AssetBundleModel.Model.HandleDedupeBundles(selectedNodes.Select(item => item.bundle), onlyOverlappedAssets);            if(newBundle != null)            {                var selection = new List<int>();                selection.Add(newBundle.nameHashCode);                ReloadAndSelect(selection);            }            else            {                if (onlyOverlappedAssets)                    Debug.LogWarning("There were no duplicated assets that existed across all selected bundles.");                else                    Debug.LogWarning("No duplicate assets found after refreshing bundle contents.");            }        }        void DeleteBundles(object b)        {            var selectedNodes = b as List<AssetBundleModel.BundleTreeItem>;            AssetBundleModel.Model.HandleBundleDelete(selectedNodes.Select(item => item.bundle));            ReloadAndSelect(new List<int>());        }        protected override void KeyEvent()        {            if (Event.current.keyCode == KeyCode.Delete && GetSelection().Count > 0)            {                List<AssetBundleModel.BundleTreeItem> selectedNodes = new List<AssetBundleModel.BundleTreeItem>();                foreach (var nodeID in GetSelection())                {                    selectedNodes.Add(FindItem(nodeID, rootItem) as AssetBundleModel.BundleTreeItem);                }                DeleteBundles(selectedNodes);            }        }        class DragAndDropData        {            internal bool hasBundleFolder = false;            internal bool hasScene = false;            internal bool hasNonScene = false;            internal bool hasVariantChild = false;            internal List<AssetBundleModel.BundleInfo> draggedNodes;            internal AssetBundleModel.BundleTreeItem targetNode;            internal DragAndDropArgs args;            internal string[] paths;            internal DragAndDropData(DragAndDropArgs a)            {                args = a;                draggedNodes = DragAndDrop.GetGenericData("AssetBundleModel.BundleInfo") as List<AssetBundleModel.BundleInfo>;                targetNode = args.parentItem as AssetBundleModel.BundleTreeItem;                paths = DragAndDrop.paths;                if (draggedNodes != null)                {                    foreach (var bundle in draggedNodes)                    {                        if ((bundle as AssetBundleModel.BundleFolderInfo) != null)                        {                            hasBundleFolder = true;                        }                        else                        {                            var dataBundle = bundle as AssetBundleModel.BundleDataInfo;                            if (dataBundle != null)                            {                                if (dataBundle.isSceneBundle)                                    hasScene = true;                                else                                    hasNonScene = true;                                if ( (dataBundle as AssetBundleModel.BundleVariantDataInfo) != null)                                    hasVariantChild = true;                            }                        }                    }                }                else if (DragAndDrop.paths != null)                {                    foreach (var assetPath in DragAndDrop.paths)                    {                        if (AssetDatabase.GetMainAssetTypeAtPath(assetPath) == typeof(SceneAsset))                            hasScene = true;                        else                            hasNonScene = true;                    }                }            }        }        protected override DragAndDropVisualMode HandleDragAndDrop(DragAndDropArgs args)        {            DragAndDropVisualMode visualMode = DragAndDropVisualMode.None;            DragAndDropData data = new DragAndDropData(args);                        if (AssetBundleModel.Model.DataSource.IsReadOnly ()) {                return DragAndDropVisualMode.Rejected;            }            if ( (data.hasScene && data.hasNonScene) ||                (data.hasVariantChild) )                return DragAndDropVisualMode.Rejected;                        switch (args.dragAndDropPosition)            {                case DragAndDropPosition.UponItem:                    visualMode = HandleDragDropUpon(data);                    break;                case DragAndDropPosition.BetweenItems:                    visualMode = HandleDragDropBetween(data);                    break;                case DragAndDropPosition.OutsideItems:                    if (data.draggedNodes != null)                    {                        visualMode = DragAndDropVisualMode.Copy;                        if (data.args.performDrop)                        {                            AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, null);                            Reload();                        }                    }                    else if(data.paths != null)                    {                        visualMode = DragAndDropVisualMode.Copy;                        if (data.args.performDrop)                        {                            DragPathsToNewSpace(data.paths, null);                        }                    }                    break;            }            return visualMode;        }        private DragAndDropVisualMode HandleDragDropUpon(DragAndDropData data)        {            DragAndDropVisualMode visualMode = DragAndDropVisualMode.Copy;//Move;            var targetDataBundle = data.targetNode.bundle as AssetBundleModel.BundleDataInfo;            if (targetDataBundle != null)            {                if (targetDataBundle.isSceneBundle)                {                    if(data.hasNonScene)                        return DragAndDropVisualMode.Rejected;                }                else                {                    if (data.hasBundleFolder)                    {                        return DragAndDropVisualMode.Rejected;                    }                    else if (data.hasScene && !targetDataBundle.IsEmpty())                    {                        return DragAndDropVisualMode.Rejected;                    }                }                               if (data.args.performDrop)                {                    if (data.draggedNodes != null)                    {                        AssetBundleModel.Model.HandleBundleMerge(data.draggedNodes, targetDataBundle);                        ReloadAndSelect(targetDataBundle.nameHashCode, false);                    }                    else if (data.paths != null)                    {                        AssetBundleModel.Model.MoveAssetToBundle(data.paths, targetDataBundle.m_Name.bundleName, targetDataBundle.m_Name.variant);                        AssetBundleModel.Model.ExecuteAssetMove();                        ReloadAndSelect(targetDataBundle.nameHashCode, false);                    }                }            }            else            {                var folder = data.targetNode.bundle as AssetBundleModel.BundleFolderInfo;                if (folder != null)                {                    if (data.args.performDrop)                    {                        if (data.draggedNodes != null)                        {                            AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, folder);                            Reload();                        }                        else if (data.paths != null)                        {                            DragPathsToNewSpace(data.paths, folder);                        }                    }                }                else                    visualMode = DragAndDropVisualMode.Rejected; //must be a variantfolder                            }            return visualMode;        }        private DragAndDropVisualMode HandleDragDropBetween(DragAndDropData data)        {            DragAndDropVisualMode visualMode = DragAndDropVisualMode.Copy;//Move;            var parent = (data.args.parentItem as AssetBundleModel.BundleTreeItem);            if (parent != null)            {                var variantFolder = parent.bundle as AssetBundleModel.BundleVariantFolderInfo;                if (variantFolder != null)                    return DragAndDropVisualMode.Rejected;                if (data.args.performDrop)                {                    var folder = parent.bundle as AssetBundleModel.BundleFolderConcreteInfo;                    if (folder != null)                    {                        if (data.draggedNodes != null)                        {                            AssetBundleModel.Model.HandleBundleReparent(data.draggedNodes, folder);                            Reload();                        }                        else if (data.paths != null)                        {                            DragPathsToNewSpace(data.paths, folder);                        }                    }                }            }            return visualMode;        }        private string[] dragToNewSpacePaths = null;        private AssetBundleModel.BundleFolderInfo dragToNewSpaceRoot = null;        private void DragPathsAsOneBundle()        {            var newBundle = AssetBundleModel.Model.CreateEmptyBundle(dragToNewSpaceRoot);            AssetBundleModel.Model.MoveAssetToBundle(dragToNewSpacePaths, newBundle.m_Name.bundleName, newBundle.m_Name.variant);            AssetBundleModel.Model.ExecuteAssetMove();            ReloadAndSelect(newBundle.nameHashCode, true);        }        private void DragPathsAsManyBundles()        {            List<int> hashCodes = new List<int>();            foreach (var assetPath in dragToNewSpacePaths)            {                var newBundle = AssetBundleModel.Model.CreateEmptyBundle(dragToNewSpaceRoot, System.IO.Path.GetFileNameWithoutExtension(assetPath).ToLower());                AssetBundleModel.Model.MoveAssetToBundle(assetPath, newBundle.m_Name.bundleName, newBundle.m_Name.variant);                hashCodes.Add(newBundle.nameHashCode);            }            AssetBundleModel.Model.ExecuteAssetMove();            ReloadAndSelect(hashCodes);        }        private void DragPathsToNewSpace(string[] paths, AssetBundleModel.BundleFolderInfo root)        {            dragToNewSpacePaths = paths;            dragToNewSpaceRoot = root;            if (paths.Length > 1)            {                GenericMenu menu = new GenericMenu();                menu.AddItem(new GUIContent("Create 1 Bundle"), false, DragPathsAsOneBundle);                var message = "Create ";                message += paths.Length;                message += " Bundles";                menu.AddItem(new GUIContent(message), false, DragPathsAsManyBundles);                menu.ShowAsContext();            }            else                DragPathsAsManyBundles();        }        protected override void SetupDragAndDrop(SetupDragAndDropArgs args)        {            if (args.draggedItemIDs == null)                return;            DragAndDrop.PrepareStartDrag();            var selectedBundles = new List<AssetBundleModel.BundleInfo>();            foreach (var id in args.draggedItemIDs)            {                var item = FindItem(id, rootItem) as AssetBundleModel.BundleTreeItem;                selectedBundles.Add(item.bundle);            }            DragAndDrop.paths = null;            DragAndDrop.objectReferences = m_EmptyObjectList.ToArray();            DragAndDrop.SetGenericData("AssetBundleModel.BundleInfo", selectedBundles);            DragAndDrop.visualMode = DragAndDropVisualMode.Copy;//Move;            DragAndDrop.StartDrag("AssetBundleTree");        }        protected override bool CanStartDrag(CanStartDragArgs args)        {            return true;        }        internal void Refresh()        {            var selection = GetSelection();            Reload();            SelectionChanged(selection);        }        private void ReloadAndSelect(int hashCode, bool rename)        {            var selection = new List<int>();            selection.Add(hashCode);            ReloadAndSelect(selection);            if(rename)            {                BeginRename(FindItem(hashCode, rootItem), 0.25f);            }        }        private void ReloadAndSelect(IList<int> hashCodes)        {            Reload();            SetSelection(hashCodes, TreeViewSelectionOptions.RevealAndFrame);            SelectionChanged(hashCodes);        }    }}
 |