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("");
|
||
|
}
|
||
|
}
|
||
|
}
|