using System; using UnityEngine; using UnityEngine.Experimental.UIElements; namespace UnityEditor.PackageManager.UI { #if !UNITY_2018_3_OR_NEWER internal class PackageSearchToolbarFactory : UxmlFactory<PackageSearchToolbar> { protected override PackageSearchToolbar DoCreate(IUxmlAttributes bag, CreationContext cc) { return new PackageSearchToolbar(); } } #endif internal class PackageSearchToolbar : VisualElement { #if UNITY_2018_3_OR_NEWER internal new class UxmlFactory : UxmlFactory<PackageSearchToolbar> { } #endif private const string kPlaceHolder = "Search by package name, verified, preview or version number..."; public event Action OnFocusChange = delegate { }; public event Action<string> OnSearchChange = delegate { }; private string searchText; private bool showingPlaceHolder; private readonly VisualElement root; public PackageSearchToolbar() { root = Resources.GetTemplate("PackageSearchToolbar.uxml"); Add(root); root.StretchToParentSize(); SearchTextField.value = searchText; SearchTextField.maxLength = 54; SearchCancelButton.clickable.clicked += SearchCancelButtonClick; RegisterCallback<AttachToPanelEvent>(OnEnterPanel); RegisterCallback<DetachFromPanelEvent>(OnLeavePanel); searchText = PackageSearchFilter.Instance.SearchText; if (string.IsNullOrEmpty(searchText)) { showingPlaceHolder = true; SearchTextField.value = kPlaceHolder; SearchTextField.AddToClassList("placeholder"); } else { showingPlaceHolder = false; SearchTextField.value = searchText; SearchTextField.RemoveFromClassList("placeholder"); } } public void GrabFocus() { SearchTextField.Focus(); } public new void SetEnabled(bool enable) { base.SetEnabled(enable); SearchTextField.SetEnabled(enable); SearchCancelButton.SetEnabled(enable); } private void OnSearchTextFieldChange(ChangeEvent<string> evt) { if (showingPlaceHolder && evt.newValue == kPlaceHolder) return; if (!string.IsNullOrEmpty(evt.newValue)) SearchCancelButton.AddToClassList("on"); else SearchCancelButton.RemoveFromClassList("on"); searchText = evt.newValue; OnSearchChange(searchText); } private void OnSearchTextFieldFocus(FocusEvent evt) { if (showingPlaceHolder) { SearchTextField.value = string.Empty; SearchTextField.RemoveFromClassList("placeholder"); showingPlaceHolder = false; } } private void OnSearchTextFieldFocusOut(FocusOutEvent evt) { if (string.IsNullOrEmpty(searchText)) { showingPlaceHolder = true; SearchTextField.AddToClassList("placeholder"); SearchTextField.value = kPlaceHolder; } } private void SearchCancelButtonClick() { if (!string.IsNullOrEmpty(SearchTextField.value)) { SearchTextField.value = string.Empty; } showingPlaceHolder = true; SearchTextField.AddToClassList("placeholder"); SearchTextField.value = kPlaceHolder; } private void OnEnterPanel(AttachToPanelEvent evt) { SearchTextField.RegisterCallback<FocusEvent>(OnSearchTextFieldFocus); SearchTextField.RegisterCallback<FocusOutEvent>(OnSearchTextFieldFocusOut); SearchTextField.RegisterCallback<ChangeEvent<string>>(OnSearchTextFieldChange); SearchTextField.RegisterCallback<KeyDownEvent>(OnKeyDownShortcut); } private void OnLeavePanel(DetachFromPanelEvent evt) { SearchTextField.UnregisterCallback<FocusEvent>(OnSearchTextFieldFocus); SearchTextField.UnregisterCallback<FocusOutEvent>(OnSearchTextFieldFocusOut); SearchTextField.UnregisterCallback<ChangeEvent<string>>(OnSearchTextFieldChange); SearchTextField.UnregisterCallback<KeyDownEvent>(OnKeyDownShortcut); } private void OnKeyDownShortcut(KeyDownEvent evt) { if (evt.keyCode == KeyCode.Escape) { SearchCancelButtonClick(); SearchCancelButton.Focus(); evt.StopImmediatePropagation(); return; } if (evt.keyCode == KeyCode.Tab) { OnFocusChange(); evt.StopImmediatePropagation(); } } private TextField SearchTextField { get { return root.Q<TextField>("searchTextField"); } } private Button SearchCancelButton { get { return root.Q<Button>("searchCancelButton"); } } } }