You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.3 KiB
128 lines
4.3 KiB
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(""); |
|
} |
|
} |
|
}
|
|
|