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 Search = delegate { }; public SearchBar() : this(null) { } public SearchBar([CanBeNull] Action 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(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(className: ToolbarSearchField.textUssClassName); textField.RegisterCallback(e => { m_Focused = true; UpdatePlaceholderVisibility(); }); textField.RegisterCallback(e => { m_Focused = false; UpdatePlaceholderVisibility(); }); m_SearchField.RegisterValueChangedCallback(SearchEventThrottle); // Set initial placeholder hide/show status. ShowPlaceholder(); } void SearchEventThrottle(ChangeEvent 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 { } } }