129 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using JetBrains.Annotations;
 | |
| using UnityEngine;
 | |
| using UnityEngine.UIElements;
 | |
| 
 | |
| namespace UnityEditor.Searcher
 | |
| {
 | |
|     public enum ItemExpanderState
 | |
|     {
 | |
|         Hidden,
 | |
|         Collapsed,
 | |
|         Expanded
 | |
|     }
 | |
| 
 | |
|     [PublicAPI]
 | |
|     public interface ISearcherAdapter
 | |
|     {
 | |
|         VisualElement MakeItem();
 | |
|         VisualElement Bind(VisualElement target, SearcherItem item, ItemExpanderState expanderState, string text);
 | |
| 
 | |
|         string Title { get; }
 | |
|         bool HasDetailsPanel { get; }
 | |
|         bool AddAllChildResults { get; }
 | |
|         bool MultiSelectEnabled { get; }
 | |
|         float InitialSplitterDetailRatio { get; }
 | |
|         void OnSelectionChanged(IEnumerable<SearcherItem> items);
 | |
|         SearcherItem OnSearchResultsFilter(IEnumerable<SearcherItem> searchResults, string searchQuery);
 | |
|         void InitDetailsPanel(VisualElement detailsPanel);
 | |
|     }
 | |
| 
 | |
|     [PublicAPI]
 | |
|     public class SearcherAdapter : ISearcherAdapter
 | |
|     {
 | |
|         const string k_EntryName = "smartSearchItem";
 | |
|         const int k_IndentDepthFactor = 15;
 | |
| 
 | |
|         readonly VisualTreeAsset m_DefaultItemTemplate;
 | |
|         public virtual string Title { get; }
 | |
|         public virtual bool HasDetailsPanel => true;
 | |
|         public virtual bool AddAllChildResults => true;
 | |
|         public virtual bool MultiSelectEnabled => false;
 | |
| 
 | |
|         Label m_DetailsLabel;
 | |
|         public virtual float InitialSplitterDetailRatio => 1.0f;
 | |
| 
 | |
|         public SearcherAdapter(string title)
 | |
|         {
 | |
|             Title = title;
 | |
|             m_DefaultItemTemplate = Resources.Load<VisualTreeAsset>("SearcherItem");
 | |
|         }
 | |
| 
 | |
|         public virtual VisualElement MakeItem()
 | |
|         {
 | |
|             // Create a visual element hierarchy for this search result.
 | |
|             var item = m_DefaultItemTemplate.CloneTree();
 | |
|             return item;
 | |
|         }
 | |
| 
 | |
|         public virtual VisualElement Bind(VisualElement element, SearcherItem item, ItemExpanderState expanderState, string query)
 | |
|         {
 | |
|             var indent = element.Q<VisualElement>("itemIndent");
 | |
|             indent.style.width = item.Depth * k_IndentDepthFactor;
 | |
| 
 | |
|             var expander = element.Q<VisualElement>("itemChildExpander");
 | |
| 
 | |
|             var icon = expander.Query("expanderIcon").First();
 | |
|             icon.ClearClassList();
 | |
| 
 | |
|             switch (expanderState)
 | |
|             {
 | |
|                 case ItemExpanderState.Expanded:
 | |
|                     icon.AddToClassList("Expanded");
 | |
|                     break;
 | |
| 
 | |
|                 case ItemExpanderState.Collapsed:
 | |
|                     icon.AddToClassList("Collapsed");
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             var nameLabelsContainer = element.Q<VisualElement>("labelsContainer");
 | |
|             nameLabelsContainer.Clear();
 | |
| 
 | |
|             var iconElement = element.Q<VisualElement>("itemIconVisualElement");
 | |
|             iconElement.style.backgroundImage = item.Icon;
 | |
|             if (item.Icon == null && item.CollapseEmptyIcon)
 | |
|             {
 | |
|                 iconElement.style.display = DisplayStyle.None;
 | |
|             } else
 | |
|             {
 | |
|                 iconElement.style.display = DisplayStyle.Flex;
 | |
|             }
 | |
| 
 | |
|             if (string.IsNullOrWhiteSpace(query))
 | |
|                 nameLabelsContainer.Add(new Label(item.Name));
 | |
|             else
 | |
|                 SearcherHighlighter.HighlightTextBasedOnQuery(nameLabelsContainer, item.Name, query);
 | |
| 
 | |
|             element.userData = item;
 | |
|             element.name = k_EntryName;
 | |
| 
 | |
|             return expander;
 | |
|         }
 | |
| 
 | |
|         public virtual void InitDetailsPanel(VisualElement detailsPanel)
 | |
|         {
 | |
|             m_DetailsLabel = new Label();
 | |
|             detailsPanel.Add(m_DetailsLabel);
 | |
|         }
 | |
| 
 | |
|         public virtual void OnSelectionChanged(IEnumerable<SearcherItem> items)
 | |
|         {
 | |
|             if (m_DetailsLabel != null)
 | |
|             {
 | |
|                 var itemsList = items.ToList();
 | |
|                 m_DetailsLabel.text = itemsList.Any() ? itemsList[0].Help : "No results";
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // How to handle filtering and prioritization of search results is specific to clients of the searcher window
 | |
|         // This callback is meant to be implemented by child classes of SearcherAdapter as they need
 | |
|         public virtual SearcherItem OnSearchResultsFilter(IEnumerable<SearcherItem> searchResults, string searchQuery)
 | |
|         {
 | |
|             return new SearcherItem("");
 | |
|         }
 | |
|     }
 | |
| }
 |