예제 #1
0
        static void FillSerializedPropertyColumns(UnityEngine.Object obj, Type objType, List <SearchColumn> columns)
        {
            var iconType = Utils.FindTextureForType(objType);

            using (var so = new SerializedObject(obj))
            {
                var p    = so.GetIterator();
                var next = p.NextVisible(true);
                while (next)
                {
                    var supported = SearchUtils.IsPropertyTypeSupported(p);
                    if (supported)
                    {
                        var column = new SearchColumn(
                            path: $"{objType.Name}/{p.propertyPath.Replace(".", "/")}",
                            selector: "#" + p.propertyPath,
                            provider: p.propertyType.ToString(),
                            content: new GUIContent(Utils.TrimText(p.displayName, 31), iconType, p.tooltip));
                        Styles.itemLabel.CalcMinMaxWidth(column.content, out column.width, out _);
                        if (p.hasVisibleChildren)
                        {
                            column.width = Mathf.Min(220, column.width);
                        }
                        columns.Add(column);
                    }

                    var isVector = p.propertyType == SerializedPropertyType.Vector3 ||
                                   p.propertyType == SerializedPropertyType.Vector4 ||
                                   p.propertyType == SerializedPropertyType.Quaternion ||
                                   p.propertyType == SerializedPropertyType.Vector2;

                    next = p.NextVisible(supported && !p.isArray && !p.isFixedBuffer && !isVector);
                }
            }
        }
예제 #2
0
        internal static Texture2D GetSceneObjectPreview(GameObject obj, Vector2 previewSize, FetchPreviewOptions options, Texture2D defaultThumbnail)
        {
            var sr = obj.GetComponent <SpriteRenderer>();

            if (sr && sr.sprite && sr.sprite.texture)
            {
                return(sr.sprite.texture);
            }


            if (!options.HasAny(FetchPreviewOptions.Large))
            {
                var preview = AssetPreview.GetAssetPreview(obj);
                if (preview)
                {
                    return(preview);
                }
            }

            var assetPath = SearchUtils.GetHierarchyAssetPath(obj, true);

            if (string.IsNullOrEmpty(assetPath))
            {
                return(AssetPreview.GetAssetPreview(obj) ?? defaultThumbnail);
            }
            return(GetAssetPreviewFromPath(assetPath, previewSize, options));
        }
예제 #3
0
        private void IndexScene(string scenePath, bool checkIfDocumentExists)
        {
            bool sceneAdded = false;
            var  scene      = EditorSceneManager.GetSceneByPath(scenePath);

            try
            {
                if (scene == null || !scene.isLoaded)
                {
                    scene      = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);
                    sceneAdded = scene != null && scene.isLoaded;
                }

                if (scene == null || !scene.isLoaded)
                {
                    return;
                }

                var objects = SearchUtils.FetchGameObjects(scene);
                IndexObjects(objects, "scene", scene.name, scenePath, checkIfDocumentExists);
            }
            finally
            {
                if (sceneAdded)
                {
                    EditorSceneManager.CloseScene(scene, true);
                }
            }
        }
        public override void OpenContextualMenu()
        {
            var menu = new GenericMenu();

            if (treeView.GetCurrentQuery() == m_Query)
            {
                menu.AddItem(new GUIContent("Save"), false, () => treeView.searchView.SaveActiveSearchQuery());
                menu.AddSeparator("");
            }
            menu.AddItem(new GUIContent("Open in new window"), false, () =>
            {
                SearchQuery.Open(m_Query, SearchFlags.None);
            });
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Rename"), false, () => treeView.BeginRename(this, 0f));
            menu.AddItem(new GUIContent("Set Icon..."), false, () => SearchUtils.ShowIconPicker((newIcon, canceled) =>
            {
                if (canceled)
                {
                    return;
                }
                m_Query.thumbnail = newIcon;
                SearchQuery.SaveSearchQuery(m_Query);
            }));
            menu.AddItem(new GUIContent("Search Template"), m_Query.isSearchTemplate, () => m_Query.isSearchTemplate = !m_Query.isSearchTemplate);
            menu.AddItem(new GUIContent(Utils.GetRevealInFinderLabel()), false, () => EditorUtility.RevealInFinder(m_Query.filePath));
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Delete"), false, () =>
            {
                SearchQuery.RemoveSearchQuery(m_Query);
                treeView.RemoveItem(this);
            });
            menu.ShowAsContext();
        }
 internal SearchValue(UnityEngine.Object obj)
 {
     this.type   = ValueType.Object;
     this.text   = SearchUtils.GetObjectPath(obj);
     this.number = float.NaN;
     this.color  = default;
     this.v4     = default;
 }
예제 #6
0
 static string GetAssetType(SearchItem item)
 {
     if (SearchUtils.GetAssetPath(item) is string assetPath)
     {
         return(AssetDatabase.GetMainAssetTypeAtPath(assetPath)?.Name);
     }
     return(null);
 }
예제 #7
0
 static object GetAssetFileSize(SearchItem item)
 {
     if (SearchUtils.GetAssetPath(item) is string assetPath && !string.IsNullOrEmpty(assetPath))
     {
         var fi = new FileInfo(assetPath);
         return(fi.Exists ? fi.Length : 0);
     }
     return(null);
 }
예제 #8
0
        static object GetSceneObjectPath(SearchSelectorArgs args)
        {
            var go = args.current.ToObject <GameObject>();

            if (!go)
            {
                return(null);
            }
            return(SearchUtils.GetHierarchyPath(go, false));
        }
예제 #9
0
        static IEnumerable <SearchProposition> GetPropositionsFromType(IQueryEngineFilter filter, Type type, string category = null, Type blockType = null, int priority = 0, Texture2D icon = null, Color color = default)
        {
            var filterId        = filter.token;
            var defaultOperator = filter.supportedOperators == null ? ":" : filter.supportedOperators.FirstOrDefault();

            if (type.IsEnum)
            {
                return(SearchUtils.FetchEnumPropositions(type, category, filterId, defaultOperator, blockType, priority, icon, color));
            }

            return(Enumerable.Empty <SearchProposition>());
        }
예제 #10
0
        private void IndexObjects(GameObject[] objects, string type, string containerName, string containerPath, bool checkIfDocumentExists)
        {
            var options   = settings.options;
            var globalIds = new GlobalObjectId[objects.Length];

            GlobalObjectId.GetGlobalObjectIdsSlow(objects, globalIds);

            for (int i = 0; i < objects.Length; ++i)
            {
                var obj = objects[i];
                if (!obj || (obj.hideFlags & (HideFlags.DontSave | HideFlags.HideInHierarchy)) != 0)
                {
                    continue;
                }

                var gid = globalIds[i];
                if (gid.identifierType == 0 || gid.assetGUID.Empty())
                {
                    continue;
                }

                if (PrefabUtility.IsPrefabAssetMissing(obj))
                {
                    continue;
                }

                if (obj.tag?.Equals("noindex~", StringComparison.Ordinal) ?? false)
                {
                    continue;
                }

                var id            = gid.ToString();
                var transformPath = SearchUtils.GetTransformPath(obj.transform);
                var documentIndex = AddDocument(id, options.types ? transformPath : null, containerPath, checkIfDocumentExists, SearchDocumentFlags.Nested | SearchDocumentFlags.Object);

                if (options.types)
                {
                    IndexNumber(documentIndex, "depth", GetObjectDepth(obj));
                    IndexProperty(documentIndex, "from", type, saveKeyword: true, exact: true);
                }

                if (options.dependencies)
                {
                    IndexProperty(documentIndex, type, containerName, saveKeyword: false);
                    IndexProperty(documentIndex, type, containerPath, exact: true, saveKeyword: false);
                }

                IndexWord(documentIndex, Path.GetFileName(transformPath));
                IndexProperty(documentIndex, "is", "nested", saveKeyword: true, exact: true);
                IndexGameObject(documentIndex, obj, options);
                IndexCustomGameObjectProperties(id, documentIndex, obj);
            }
        }
예제 #11
0
        private static object GetObjectPath(SearchColumnEventArgs args)
        {
            var value = args.column.SelectValue(args.item, args.context);

            if (value is UnityEngine.Object obj)
            {
                var objPath = AssetDatabase.GetAssetPath(obj);
                if (!string.IsNullOrEmpty(objPath))
                {
                    return(objPath);
                }
                if (obj is GameObject go)
                {
                    return(SearchUtils.GetTransformPath(go.transform));
                }
            }
            return(value);
        }
예제 #12
0
        static AdvancedObjectSelector GenerateAdvancedObjectSelectorWrapper(Dictionary <int, AdvancedObjectSelectorValidator> validators, AdvancedObjectSelectorAttribute attribute, AdvancedObjectSelectorHandler handler)
        {
            if (!validators.TryGetValue(attribute.id.GetHashCode(), out var validator))
            {
                throw new CustomAttributeFormatException($"Advanced Object Selector id \"{attribute.id}\" does not have a matching validator.");
            }

            var priority    = attribute.defaultPriority;
            var active      = attribute.defaultActive;
            var displayName = string.IsNullOrEmpty(attribute.displayName) ? SearchUtils.ToPascalWithSpaces(attribute.id) : attribute.displayName;

            if (SearchSettings.TryGetObjectSelectorSettings(attribute.id, out var settings))
            {
                priority = settings.priority;
                active   = settings.active;
            }
            return(new AdvancedObjectSelector(attribute.id, displayName, priority, active, handler, validator));
        }
예제 #13
0
        public static IEnumerable <SearchItem> GroupBy(SearchExpressionContext c)
        {
            string selector = null;

            if (c.args.Length > 1)
            {
                selector = c.args[1].innerText.ToString();
            }

            var outputValueFieldName = System.Guid.NewGuid().ToString("N");
            var dataSet = SelectorManager.SelectValues(c.search, c.args[0].Execute(c), selector, outputValueFieldName);

            foreach (var _group in dataSet.GroupBy(item => item.GetValue(outputValueFieldName)))
            {
                var group   = _group;
                var groupId = group.Key?.ToString() ?? $"group{++s_NextGroupId}";

                if (c.HasFlag(SearchExpressionExecutionFlags.Expand))
                {
                    var evaluator = new SearchExpressionEvaluator(groupId, _ => group, SearchExpressionEvaluationHints.Default);
                    var genExpr   = new SearchExpression(SearchExpressionType.Group,
                                                         groupId.GetStringView(), groupId.GetStringView(), (group.Key?.ToString() ?? groupId).GetStringView(),
                                                         evaluator);

                    yield return(EvaluatorUtils.CreateSearchExpressionItem(genExpr));
                }
                else
                {
                    SearchProvider groupProvider = null;
                    foreach (var item in group)
                    {
                        if (groupProvider == null)
                        {
                            groupProvider = SearchUtils.CreateGroupProvider(item.provider, groupId, s_NextGroupId);
                        }
                        item.provider = groupProvider;
                        yield return(item);
                    }
                }
            }
        }
        public override void OpenContextualMenu()
        {
            var menu = new GenericMenu();

            if (treeView.GetCurrentQuery() == (ISearchQuery)m_Query)
            {
                menu.AddItem(new GUIContent("Save"), false, () => treeView.searchView.SaveActiveSearchQuery());
                menu.AddSeparator("");
            }
            menu.AddItem(new GUIContent("Open in new window"), false, () =>
            {
                SearchQuery.Open(m_Query, SearchFlags.None);
            });
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Rename"), false, () => treeView.BeginRename(this, 0f));
            menu.AddItem(new GUIContent("Set Icon..."), false, () => SearchUtils.ShowIconPicker((newIcon, canceled) =>
            {
                if (canceled)
                {
                    return;
                }
                m_Query.icon = newIcon;
                EditorUtility.SetDirty(m_Query);
            }));
            menu.AddItem(new GUIContent("Search Template"), m_Query.isSearchTemplate, () => m_Query.isSearchTemplate = !m_Query.isSearchTemplate);
            menu.AddItem(new GUIContent("Edit in Inspector"), false, () => Selection.activeObject = m_Query);
            menu.AddItem(new GUIContent(Utils.GetRevealInFinderLabel()), false, () => EditorUtility.RevealInFinder(AssetDatabase.GetAssetPath(m_Query)));
            menu.AddSeparator("");
            menu.AddItem(new GUIContent("Delete"), false, () =>
            {
                if (!EditorUtility.DisplayDialog($"Deleting search query {m_Query.name}?",
                                                 $"You are about to delete the search query {m_Query.name}, are you sure?", "Yes", "No"))
                {
                    return;
                }
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(m_Query));
                treeView.RemoveItem(this);
            });
            menu.ShowAsContext();
        }
예제 #15
0
        /// <summary>
        /// Create a new SearchProvider
        /// </summary>
        /// <param name="id">Search Provider unique id.</param>
        /// <param name="displayName">Provider pretty name, use to display in UI.</param>
        /// <param name="fetchItemsHandler">Handler responsible to populate a list of SearchItems according to a query.</param>
        public SearchProvider(string id, string displayName, Func <SearchContext, List <SearchItem>, SearchProvider, object> fetchItemsHandler)
        {
            if (String.IsNullOrEmpty(id))
            {
                throw new ArgumentException("provider id must be non-empty", nameof(id));
            }

            this.id            = id;
            type               = id;
            active             = true;
            name               = displayName ?? SearchUtils.ToPascalWithSpaces(id);
            actions            = new List <SearchAction>();
            fetchItems         = fetchItemsHandler ?? ((context, items, provider) => null);
            fetchThumbnail     = (item, context) => item.thumbnail ?? Icons.quicksearch;
            fetchPreview       = null;
            fetchLabel         = (item, context) => item.label ?? item.id ?? String.Empty;
            fetchDescription   = null;
            priority           = 100;
            showDetails        = false;
            showDetailsOptions = ShowDetailsOptions.Default;
            filterId           = $"{id}:";

            defaultContext = new SearchContext(this);
        }
예제 #16
0
        public static IEnumerable <SearchColumn> Enumerate(IEnumerable <SearchItem> items)
        {
            var descriptors = new List <SearchColumn>();
            var templates   = SearchUtils.GetTemplates(items.Where(e => e != null).Select(e => e.ToObject()).Where(e => e));

            foreach (var obj in templates)
            {
                var objType = obj.GetType();
                var columns = new List <SearchColumn>();
                FillSerializedPropertyColumns(obj, objType, columns);
                if (columns.Count <= 0)
                {
                    continue;
                }

                foreach (var c in columns)
                {
                    c.content.image = Utils.FindTextureForType(objType);
                }
                descriptors.AddRange(columns);
            }

            return(descriptors);
        }
예제 #17
0
 /// <summary>
 /// Extended constructor to build a search action.
 /// </summary>
 /// <param name="providerId">Provider Id that supports this action.</param>
 /// <param name="name">Label name when displaying the action in the Action Menu</param>
 /// <param name="icon">Icon when displaying the action in the Action Menu</param>
 /// <param name="tooltip">Tooltip assocoated with the when displayed in the Action Menu</param>
 /// <param name="handler">Handler that will execute the action.</param>
 public SearchAction(string providerId, string name, Texture2D icon, string tooltip, Action <SearchItem> handler)
     : this(providerId, name, new GUIContent(SearchUtils.ToPascalWithSpaces(name), icon, tooltip ?? name), handler)
 {
 }
예제 #18
0
 /// <summary>
 /// Splits a string into multiple words that will be indexed.
 /// It works with paths and UpperCamelCase strings.
 /// </summary>
 /// <param name="entry">The string to be split.</param>
 /// <param name="documentIndex">The document index that will index that entry.</param>
 /// <returns>The entry components.</returns>
 public virtual IEnumerable <string> GetEntryComponents(string entry, int documentIndex)
 {
     return(SearchUtils.SplitFileEntryComponents(entry, SearchUtils.entrySeparators));
 }
예제 #19
0
 private string GetAssetPath(UnityEngine.Object obj)
 {
     return(SearchUtils.GetObjectPath(obj));
 }
예제 #20
0
        public void ObjectIconDropDown(Rect position, SerializedProperty iconProperty)
        {
            const float kDropDownArrowMargin = 2;
            const float kDropDownArrowWidth  = 12;
            const float kDropDownArrowHeight = 12;

            if (s_IconTextureInactive == null)
            {
                s_IconTextureInactive = (Material)EditorGUIUtility.LoadRequired("Inspectors/InactiveGUI.mat");
            }

            if (s_IconButtonStyle == null)
            {
                s_IconButtonStyle = new GUIStyle("IconButton")
                {
                    fixedWidth = 0, fixedHeight = 0
                }
            }
            ;

            void SelectIcon(UnityEngine.Object obj, bool isCanceled)
            {
                if (!isCanceled)
                {
                    iconProperty.objectReferenceValue = obj;
                    iconProperty.serializedObject.ApplyModifiedProperties();
                    SearchService.RefreshWindows();
                }
            }

            if (EditorGUI.DropdownButton(position, GUIContent.none, FocusType.Passive, s_IconButtonStyle))
            {
                SearchUtils.ShowIconPicker(SelectIcon);
                GUIUtility.ExitGUI();
            }

            if (Event.current.type == EventType.Repaint)
            {
                var contentPosition = position;

                contentPosition.xMin += kDropDownArrowMargin;
                contentPosition.xMax -= kDropDownArrowMargin + kDropDownArrowWidth / 2;
                contentPosition.yMin += kDropDownArrowMargin;
                contentPosition.yMax -= kDropDownArrowMargin + kDropDownArrowWidth / 2;

                Rect arrowRect = new Rect(
                    contentPosition.x + contentPosition.width - kDropDownArrowWidth / 2,
                    contentPosition.y + contentPosition.height - kDropDownArrowHeight / 2,
                    kDropDownArrowWidth, kDropDownArrowHeight);
                Texture2D icon = null;

                if (!iconProperty.hasMultipleDifferentValues)
                {
                    icon = iconProperty.objectReferenceValue as Texture2D ?? AssetPreview.GetMiniThumbnail(targets[0]);
                }
                if (icon == null)
                {
                    icon = Icons.favorite;
                }

                Vector2 iconSize = contentPosition.size;

                if (icon)
                {
                    iconSize.x = Mathf.Min(icon.width, iconSize.x);
                    iconSize.y = Mathf.Min(icon.height, iconSize.y);
                }
                Rect iconRect = new Rect(
                    contentPosition.x + contentPosition.width / 2 - iconSize.x / 2,
                    contentPosition.y + contentPosition.height / 2 - iconSize.y / 2,
                    iconSize.x, iconSize.y);

                GUI.DrawTexture(iconRect, icon, ScaleMode.ScaleToFit);
                if (s_IconDropDown == null)
                {
                    s_IconDropDown = EditorGUIUtility.IconContent("Icon Dropdown");
                }
                GUIStyle.none.Draw(arrowRect, s_IconDropDown, false, false, false, false);
            }
        }

        void AddProvider(ReorderableList list)
        {
            var menu = new GenericMenu();
            var disabledProviders = GetDisabledProviders().ToList();

            for (var i = 0; i < disabledProviders.Count; ++i)
            {
                var provider = disabledProviders[i];
                menu.AddItem(new GUIContent(provider.name), false, AddProvider, provider);
                if (!provider.isExplicitProvider && i + 1 < disabledProviders.Count && disabledProviders[i + 1].isExplicitProvider)
                {
                    menu.AddSeparator(string.Empty);
                }
            }
            menu.ShowAsContext();
        }

        void AddProvider(object providerObj)
        {
            if (providerObj is SearchProvider provider && !m_EnabledProviderIds.Contains(provider.id))
            {
                m_EnabledProviderIds.Add(provider.id);
                UpdateEnabledProviders();
            }
        }

        void RemoveProvider(ReorderableList list)
        {
            var index = list.index;

            if (index != -1 && index < m_EnabledProviderIds.Count)
            {
                var toRemove = SearchService.GetProvider(m_EnabledProviderIds[index]);
                if (toRemove == null)
                {
                    return;
                }
                m_EnabledProviderIds.Remove(toRemove.id);
                UpdateEnabledProviders();

                if (index >= list.count)
                {
                    list.index = list.count - 1;
                }
            }
        }

        void UpdateEnabledProviders()
        {
            m_ProvidersProperty.arraySize = m_EnabledProviderIds.Count;
            for (var i = 0; i < m_EnabledProviderIds.Count; ++i)
            {
                m_ProvidersProperty.GetArrayElementAtIndex(i).stringValue = m_EnabledProviderIds[i];
            }
            serializedObject.ApplyModifiedProperties();
            SetupContext();
        }

        void DrawProviderElement(Rect rect, int index, bool selected, bool focused)
        {
            if (index >= 0 && index < m_EnabledProviderIds.Count)
            {
                GUI.Label(rect, SearchService.GetProvider(m_EnabledProviderIds[index])?.name ?? "<unknown>");
            }
        }

        void CheckContext()
        {
            if (m_SearchContext.searchText != m_TextProperty.stringValue)
            {
                SetupContext();
            }
        }
    }
예제 #21
0
 /// <summary>
 /// Extended constructor to build a search action.
 /// </summary>
 /// <param name="providerId">Provider Id that supports this action.</param>
 /// <param name="name">Label name when displaying the action in the Action Menu</param>
 /// <param name="icon">Icon when displaying the action in the Action Menu</param>
 /// <param name="tooltip">Tooltip associated with the when displayed in the Action Menu</param>
 public SearchAction(string providerId, string name, Texture2D icon = null, string tooltip = null)
     : this(providerId, name, new GUIContent(SearchUtils.ToPascalWithSpaces(name), icon, tooltip ?? name))
 {
 }