void CopyPropertyData(ref FilterResult result, HierarchyProperty property) { if (result == null) { result = new FilterResult(); } result.instanceID = property.GetInstanceIDIfImported(); result.name = property.name; result.hasChildren = property.hasChildren; result.colorCode = property.colorCode; result.isMainRepresentation = property.isMainRepresentation; result.hasFullPreviewImage = property.hasFullPreviewImage; result.iconDrawStyle = property.iconDrawStyle; result.isFolder = property.isFolder; result.type = hierarchyType; // If this is not the main representation, cache the icon, as we don't have an API to access it later. // Otherwise, don't - as this may cause Textures to load unintendedly (e.g if we have 3000 search results we do not want to load icons before needed when rendering) if (!property.isMainRepresentation) { result.icon = property.icon; } else { result.icon = null; } if (m_HierarchyType == HierarchyType.Assets) { result.m_Guid = property.guid; } }
void SetAssetsResults(HashSet <int> instanceIdsSet, Dictionary <string, int> idsUnderEachRoot) { System.Array.Resize(ref m_Results, instanceIdsSet.Count); var currentResultIndex = 0; var rootPaths = idsUnderEachRoot.Keys.ToArray(); var idCounts = idsUnderEachRoot.Values.ToArray(); for (var i = 0; i < rootPaths.Length; ++i) { var rootPath = rootPaths[i]; var nbIds = idCounts[i]; HierarchyProperty property = new HierarchyProperty(rootPath, false); var propertiesFound = 0; while (property.Next(null) && propertiesFound < nbIds) { var instanceId = property.GetInstanceIDIfImported(); if (instanceIdsSet.Contains(instanceId)) { ++propertiesFound; CopyPropertyData(ref m_Results[currentResultIndex], property); ++currentResultIndex; } } } }
static bool AnyTargetMaterialHasChildren(string[] targetPaths) { GUID[] guids = targetPaths.Select(path => AssetDatabase.GUIDFromAssetPath(path)).ToArray(); Func <string, bool> HasChildrenInPath = (string rootPath) => { var property = new HierarchyProperty(rootPath, false); property.SetSearchFilter(new SearchFilter { classNames = new string[] { "Material" }, searchArea = SearchFilter.SearchArea.AllAssets }); while (property.Next(null)) { GUID parent; var child = InternalEditorUtility.GetLoadedObjectFromInstanceID(property.GetInstanceIDIfImported()) as Material; if (child) { if (AssetDatabase.IsForeignAsset(child)) { continue; } parent = AssetDatabase.GUIDFromAssetPath(AssetDatabase.GetAssetPath(child.parent)); } else { var path = AssetDatabase.GUIDToAssetPath(property.guid); if (!path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase)) { continue; } parent = EditorMaterialUtility.GetMaterialParentFromFile(path); } for (int i = 0; i < guids.Length; i++) { if (guids[i] == parent) { return(true); } } } return(false); }; if (HasChildrenInPath("Assets")) { return(true); } foreach (var package in PackageManagerUtilityInternal.GetAllVisiblePackages(false)) { if (package.source == PackageManager.PackageSource.Local && HasChildrenInPath(package.assetPath)) { return(true); } } return(false); }
static void ReparentMaterialChildren(string assetPath) { var toDelete = AssetDatabase.LoadAssetAtPath <Material>(assetPath); var toDeleteGUID = AssetDatabase.GUIDFromAssetPath(assetPath); var newParent = toDelete.parent; Action <string> ReparentInPath = (string rootPath) => { var property = new HierarchyProperty(rootPath, false); property.SetSearchFilter(new SearchFilter { classNames = new string[] { "Material" }, searchArea = SearchFilter.SearchArea.AllAssets }); while (property.Next(null)) { var child = InternalEditorUtility.GetLoadedObjectFromInstanceID(property.GetInstanceIDIfImported()) as Material; if (!child) { // First check guid from file to avoid loading all materials in memory string path = AssetDatabase.GUIDToAssetPath(property.guid); if (EditorMaterialUtility.GetMaterialParentFromFile(path) != toDeleteGUID) { continue; } child = AssetDatabase.LoadAssetAtPath <Material>(path); } if (child != null && child.parent == toDelete && !AssetDatabase.IsForeignAsset(child)) { child.parent = newParent; } } }; ReparentInPath("Assets"); foreach (var package in PackageManagerUtilityInternal.GetAllVisiblePackages(false)) { if (package.source == PackageManager.PackageSource.Local) { ReparentInPath(package.assetPath); } } }
public override void FetchData() { // Create root Item int depth = 0; var multiRoot = (m_Roots.Count > 1); if (multiRoot) { m_RootItem = new TreeViewItem(-1, depth, null, "Invisible Root Item"); SetExpanded(m_RootItem, true); } else { var rootInstanceID = m_Roots[0].instanceID; var displayName = m_Roots[0].displayName ?? CreateDisplayName(rootInstanceID); m_RootItem = new TreeViewItem(rootInstanceID, depth, null, displayName); SetExpanded(m_RootItem, true); } m_Rows = new List <TreeViewItem>(m_Roots.Count * 256); Texture2D folderIcon = EditorGUIUtility.FindTexture(EditorResources.folderIconName); var assetsInstanceIDs = AssetDatabase.GetMainAssetOrInProgressProxyInstanceID("Assets"); var projectPath = Path.GetFileName(Directory.GetCurrentDirectory()); // Fetch root Items m_RootsTreeViewItem = new Dictionary <string, TreeViewItem>(m_Roots.Count); foreach (var root in m_Roots) { var rootInstanceID = root.instanceID; var displayName = root.displayName ?? CreateDisplayName(rootInstanceID); var rootPath = root.path ?? AssetDatabase.GetAssetPath(rootInstanceID); var rootGuid = AssetDatabase.AssetPathToGUID(rootPath); var property = new HierarchyProperty(rootPath); if (!root.skipValidation && !property.Find(rootInstanceID, null)) { if (rootInstanceID == 0) { Debug.LogError("Root Asset with path " + rootPath + " not valid!!"); } continue; } var minDepth = property.depth; var subDepth = multiRoot ? 0 : -1; TreeViewItem rootItem; if (multiRoot) { var parentItem = m_RootItem; var rootDepth = minDepth; rootDepth++; // Find parent treeView item var parentPath = Directory.GetParent(rootPath).Name; if (parentPath != projectPath) { if (!m_RootsTreeViewItem.TryGetValue(parentPath, out parentItem)) { Debug.LogError("Cannot find parent for " + rootInstanceID); continue; } rootDepth++; subDepth++; } // Create root item TreeView item if (subDepth > 0) { rootItem = new FolderTreeItem(rootGuid, !property.hasChildren, rootInstanceID, rootDepth, parentItem, displayName); } else { rootItem = new RootTreeItem(rootInstanceID, rootDepth, parentItem, displayName); } rootItem.icon = folderIcon; parentItem.AddChild(rootItem); } else { rootItem = m_RootItem; } m_RootsTreeViewItem[rootPath] = rootItem; if (!skipHiddenPackages) { property.SetSearchFilter(new SearchFilter { skipHidden = false }); } var expandIDs = GetExpandedIDs(); var rows = new List <TreeViewItem>(); bool shouldExpandIt = m_ExpandAtFirstTime && (rootItem.id == assetsInstanceIDs); if (IsExpanded(rootItem.id) && (rootItem == m_RootItem || IsExpanded(rootItem.parent.id)) || shouldExpandIt) { m_ExpandAtFirstTime = false; while (property.NextWithDepthCheck(expandIDs, minDepth)) { if (!foldersOnly || property.isFolder) { depth = property.depth - minDepth; TreeViewItem item; if (property.isFolder) { item = new FolderTreeItem(property.guid, !property.hasChildren, property.instanceID, depth + subDepth, null, property.name); } else { item = new NonFolderTreeItem(property.guid, property.GetInstanceIDIfImported(), depth + subDepth, null, property.name); } item.icon = property.icon; if (property.hasChildren) { item.AddChild(null); // add a dummy child in children list to ensure we show the collapse arrow (because we do not fetch data for collapsed items) } rows.Add(item); } } // Setup reference between child and parent items TreeViewUtility.SetChildParentReferences(rows, rootItem); } else { rootItem.AddChild(null); } if (shouldExpandIt && !IsExpanded(rootItem)) { SetExpanded(rootItem, true); } if (multiRoot && IsExpanded(rootItem.parent.id)) { m_Rows.Add(rootItem); } ((List <TreeViewItem>)m_Rows).AddRange(rows); } if (foldersFirst) { FoldersFirstRecursive(m_RootItem); m_Rows.Clear(); GetVisibleItemsRecursive(m_RootItem, m_Rows); } // Must be called before InitSelection (it calls GetVisibleItems) m_NeedRefreshRows = false; // We want to reset selection on copy/duplication/delete bool frameLastSelected = false; // use false because we might just be expanding/collapsing a Item (which would prevent collapsing a Item with a selected child) m_TreeView.SetSelection(Selection.instanceIDs, frameLastSelected); }
private void ReadAssetDatabase(string assetFolderRootPath, TreeViewItem parent, int baseDepth, IList <TreeViewItem> allRows) { // Read from Assets directory IHierarchyProperty property = new HierarchyProperty(assetFolderRootPath); property.Reset(); if (!IsExpanded(parent)) { if (HasSubFolders(property)) { parent.children = CreateChildListForCollapsedParent(); } return; } Texture2D folderIcon = EditorGUIUtility.FindTexture(EditorResources.folderIconName); List <TreeViewItem> allFolders = new List <TreeViewItem>(); var expandedIDs = m_TreeView.state.expandedIDs.ToArray(); while (property.Next(expandedIDs)) { if (property.isFolder) { AssetsTreeViewDataSource.FolderTreeItem folderItem = new AssetsTreeViewDataSource.FolderTreeItem(property.guid, !property.hasChildren, property.GetInstanceIDIfImported(), baseDepth + property.depth, null, property.name); folderItem.icon = folderIcon; allFolders.Add(folderItem); allRows.Add(folderItem); if (!IsExpanded(folderItem)) { if (HasSubFolders(property)) { folderItem.children = CreateChildListForCollapsedParent(); } } else // expanded status does not get updated when deleting/moving folders. We need to check if the expanded folder still has subFolders when reading the AssetDatabase { if (!HasSubFolders(property)) { SetExpanded(folderItem, false); } } } } // Fix references TreeViewUtility.SetChildParentReferences(allFolders, parent); }
private void ReadAssetDatabase(string assetFolderRootPath, TreeViewItem parent, int baseDepth) { // Read from Assets directory IHierarchyProperty property = new HierarchyProperty(assetFolderRootPath); property.Reset(); Texture2D folderIcon = EditorGUIUtility.FindTexture(EditorResources.folderIconName); List <TreeViewItem> allFolders = new List <TreeViewItem>(); while (property.Next(null)) { if (property.isFolder) { AssetsTreeViewDataSource.FolderTreeItem folderItem = new AssetsTreeViewDataSource.FolderTreeItem(property.guid, !property.hasChildren, property.GetInstanceIDIfImported(), baseDepth + property.depth, null, property.name); folderItem.icon = folderIcon; allFolders.Add(folderItem); } } // Fix references TreeViewUtility.SetChildParentReferences(allFolders, parent); }