135 lines
4.0 KiB
C#
135 lines
4.0 KiB
C#
|
using System;
|
||
|
using System.Threading;
|
||
|
using JetBrains.Annotations;
|
||
|
using Unity.Cloud.Collaborate.Assets;
|
||
|
using Unity.Cloud.Collaborate.UserInterface;
|
||
|
using UnityEditor;
|
||
|
using UnityEditor.UIElements;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.UIElements;
|
||
|
|
||
|
namespace Unity.Cloud.Collaborate.Components
|
||
|
{
|
||
|
class SearchBar : VisualElement
|
||
|
{
|
||
|
public const string UssClassName = "unity-search-bar";
|
||
|
public const string SearchFieldUssClassName = UssClassName + "__search-field";
|
||
|
public const string PlaceholderUssClassName = UssClassName + "__placeholder";
|
||
|
|
||
|
static readonly string k_StylePath = $"{CollaborateWindow.StylePath}/{nameof(SearchBar)}.uss";
|
||
|
|
||
|
public const int timeoutMilliseconds = 1000;
|
||
|
|
||
|
readonly ToolbarSearchField m_SearchField;
|
||
|
readonly Label m_Placeholder;
|
||
|
|
||
|
string m_LatestSearchValue;
|
||
|
bool m_SearchEventFlag;
|
||
|
readonly Timer m_SearchEventTimer;
|
||
|
|
||
|
bool m_Focused;
|
||
|
|
||
|
public event Action<string> Search = delegate { };
|
||
|
|
||
|
public SearchBar() : this(null)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public SearchBar([CanBeNull] Action<string> searchEvent = null)
|
||
|
{
|
||
|
// Setup delayed search event to throttle requests.
|
||
|
m_SearchEventTimer = new Timer(_ => EditorApplication.delayCall += () =>
|
||
|
{
|
||
|
m_SearchEventFlag = false;
|
||
|
Search(m_LatestSearchValue);
|
||
|
});
|
||
|
|
||
|
AddToClassList(UssClassName);
|
||
|
styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>(k_StylePath));
|
||
|
|
||
|
m_SearchField = new ToolbarSearchField();
|
||
|
m_Placeholder = new Label { text = StringAssets.search, pickingMode = PickingMode.Ignore };
|
||
|
|
||
|
m_SearchField.AddToClassList(SearchFieldUssClassName);
|
||
|
m_Placeholder.AddToClassList(PlaceholderUssClassName);
|
||
|
|
||
|
Add(m_SearchField);
|
||
|
Add(m_Placeholder);
|
||
|
|
||
|
// Setup search event
|
||
|
if (searchEvent != null)
|
||
|
{
|
||
|
Search += searchEvent;
|
||
|
}
|
||
|
|
||
|
// Setup events to hide/show placeholder.
|
||
|
var textField = m_SearchField.Q<TextField>(className: ToolbarSearchField.textUssClassName);
|
||
|
textField.RegisterCallback<FocusInEvent>(e =>
|
||
|
{
|
||
|
m_Focused = true;
|
||
|
UpdatePlaceholderVisibility();
|
||
|
});
|
||
|
textField.RegisterCallback<FocusOutEvent>(e =>
|
||
|
{
|
||
|
m_Focused = false;
|
||
|
UpdatePlaceholderVisibility();
|
||
|
});
|
||
|
m_SearchField.RegisterValueChangedCallback(SearchEventThrottle);
|
||
|
|
||
|
// Set initial placeholder hide/show status.
|
||
|
ShowPlaceholder();
|
||
|
}
|
||
|
|
||
|
void SearchEventThrottle(ChangeEvent<string> evt)
|
||
|
{
|
||
|
UpdatePlaceholderVisibility();
|
||
|
m_LatestSearchValue = evt.newValue;
|
||
|
if (m_SearchEventFlag) return;
|
||
|
m_SearchEventFlag = true;
|
||
|
m_SearchEventTimer.Change(timeoutMilliseconds, Timeout.Infinite);
|
||
|
}
|
||
|
|
||
|
public string Value
|
||
|
{
|
||
|
get => m_SearchField.value;
|
||
|
set
|
||
|
{
|
||
|
m_SearchField.value = value;
|
||
|
UpdatePlaceholderVisibility();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void SetValueWithoutNotify(string value)
|
||
|
{
|
||
|
m_SearchField.SetValueWithoutNotify(value);
|
||
|
UpdatePlaceholderVisibility();
|
||
|
}
|
||
|
|
||
|
void UpdatePlaceholderVisibility()
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(m_SearchField.value) && !m_Focused)
|
||
|
{
|
||
|
|
||
|
ShowPlaceholder();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HidePlaceholder();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void HidePlaceholder()
|
||
|
{
|
||
|
m_Placeholder.AddToClassList(UiConstants.ussHidden);
|
||
|
}
|
||
|
|
||
|
void ShowPlaceholder()
|
||
|
{
|
||
|
m_Placeholder.RemoveFromClassList(UiConstants.ussHidden);
|
||
|
}
|
||
|
|
||
|
[UsedImplicitly]
|
||
|
public new class UxmlFactory : UxmlFactory<SearchBar> { }
|
||
|
}
|
||
|
}
|