281 lines
9.2 KiB
C#
281 lines
9.2 KiB
C#
using System;
|
|
using Codice.Utils;
|
|
using PlasticGui;
|
|
using Unity.PlasticSCM.Editor.UI;
|
|
using Unity.PlasticSCM.Editor.UI.UIElements;
|
|
using UnityEditor;
|
|
using UnityEditor.UIElements;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace Unity.PlasticSCM.Editor.Views.BranchExplorer
|
|
{
|
|
internal class BrExSearchField : VisualElement
|
|
{
|
|
internal string Text
|
|
{
|
|
get { return mSearchField.value; }
|
|
set { mSearchField.value = value; }
|
|
}
|
|
|
|
internal event Action DelayedSearchTextChanged;
|
|
internal event Action NextSearchResultRequested;
|
|
internal event Action PreviousSearchResultRequested;
|
|
|
|
internal BrExSearchField()
|
|
{
|
|
CreateGUI();
|
|
|
|
mSearchRunner = new DelayedActionBySecondsRunner(
|
|
OnDelayedSearchChanged,
|
|
UnityConstants.SEARCH_DELAYED_INPUT_ACTION_INTERVAL);
|
|
}
|
|
|
|
internal void Dispose()
|
|
{
|
|
mSearchField.UnregisterValueChangedCallback(OnSearchFieldChanged);
|
|
mSearchField.UnregisterCallback<KeyDownEvent>(OnSearchFieldKeyDown, TrickleDown.TrickleDown);
|
|
|
|
mPreviousButton.UnregisterCallback<MouseEnterEvent>(OnNavigationButtonMouseEnter);
|
|
mPreviousButton.UnregisterCallback<MouseLeaveEvent>(OnNavigationButtonMouseLeave);
|
|
|
|
mNextButton.UnregisterCallback<MouseEnterEvent>(OnNavigationButtonMouseEnter);
|
|
mNextButton.UnregisterCallback<MouseLeaveEvent>(OnNavigationButtonMouseLeave);
|
|
}
|
|
|
|
internal void FocusSearchField()
|
|
{
|
|
mSearchField.Focus();
|
|
}
|
|
|
|
internal void UpdateSearchCounter(int currentIndex, int totalResults)
|
|
{
|
|
if (string.IsNullOrEmpty(mSearchField.value))
|
|
return;
|
|
|
|
if (totalResults == 0)
|
|
{
|
|
mSearchCounterLabel.text = "0/0";
|
|
mPreviousButton.SetEnabled(false);
|
|
mNextButton.SetEnabled(false);
|
|
}
|
|
else
|
|
{
|
|
mSearchCounterLabel.text = string.Format("{0}/{1}", currentIndex, totalResults);
|
|
mPreviousButton.SetEnabled(true);
|
|
mNextButton.SetEnabled(true);
|
|
}
|
|
}
|
|
|
|
void OnDelayedSearchChanged()
|
|
{
|
|
DelayedSearchTextChanged?.Invoke();
|
|
}
|
|
|
|
void CreateGUI()
|
|
{
|
|
style.flexDirection = FlexDirection.Row;
|
|
style.alignItems = Align.Center;
|
|
|
|
mSearchField = BuildSearchField();
|
|
Add(mSearchField);
|
|
|
|
var overlayContainer = BuildOverlayContainer();
|
|
Add(overlayContainer);
|
|
}
|
|
|
|
ToolbarSearchField BuildSearchField()
|
|
{
|
|
var searchField = new ToolbarSearchField();
|
|
searchField.style.width = 220;
|
|
searchField.style.flexGrow = 1;
|
|
searchField.tooltip = string.Format("{0}{1}{2}",
|
|
PlasticLocalization.Name.BranchExplorerSearchFieldTooltip.GetString(),
|
|
Environment.NewLine,
|
|
GetSearchTextBoxShortcutsTooltipString());
|
|
searchField.RegisterValueChangedCallback(OnSearchFieldChanged);
|
|
searchField.RegisterCallback<KeyDownEvent>(OnSearchFieldKeyDown, TrickleDown.TrickleDown);
|
|
|
|
var textField = searchField.Q<TextField>();
|
|
if (textField != null)
|
|
{
|
|
textField.style.paddingRight = 55;
|
|
textField.SetTextCursor();
|
|
}
|
|
|
|
return searchField;
|
|
}
|
|
|
|
VisualElement BuildOverlayContainer()
|
|
{
|
|
var container = new VisualElement();
|
|
container.style.position = Position.Absolute;
|
|
container.style.right = 18;
|
|
container.style.top = 0;
|
|
container.style.bottom = 0;
|
|
container.style.flexDirection = FlexDirection.Row;
|
|
container.style.alignItems = Align.Center;
|
|
container.pickingMode = PickingMode.Ignore;
|
|
|
|
mSearchCounterLabel = BuildSearchCounterLabel();
|
|
container.Add(mSearchCounterLabel);
|
|
|
|
mPreviousButton = CreateNavigationButton(
|
|
OnPreviousButtonClicked,
|
|
PlasticLocalization.Name.PreviousLabel.GetString(),
|
|
Images.GetArrowCaretLeftIcon(),
|
|
marginRight: 2);
|
|
container.Add(mPreviousButton);
|
|
|
|
mNextButton = CreateNavigationButton(
|
|
OnNextButtonClicked,
|
|
PlasticLocalization.Name.NextLabel.GetString(),
|
|
Images.GetArrowCaretRightIcon());
|
|
container.Add(mNextButton);
|
|
|
|
return container;
|
|
}
|
|
|
|
Label BuildSearchCounterLabel()
|
|
{
|
|
var label = new Label();
|
|
label.style.color = UnityStyles.Colors.SecondaryLabel;
|
|
label.style.fontSize = 11;
|
|
label.style.unityTextAlign = TextAnchor.MiddleCenter;
|
|
label.style.marginLeft = 4;
|
|
label.style.marginRight = 0;
|
|
label.pickingMode = PickingMode.Ignore;
|
|
return label;
|
|
}
|
|
|
|
void OnNavigationButtonMouseEnter(MouseEnterEvent evt)
|
|
{
|
|
VisualElement button = (VisualElement)evt.currentTarget;
|
|
button.style.backgroundColor = StyleKeyword.Null;
|
|
}
|
|
|
|
void OnNavigationButtonMouseLeave(MouseLeaveEvent evt)
|
|
{
|
|
VisualElement button = (VisualElement)evt.currentTarget;
|
|
button.style.backgroundColor = Color.clear;
|
|
}
|
|
|
|
Button CreateNavigationButton(
|
|
Action clickEvent,
|
|
string tooltip,
|
|
Texture2D image,
|
|
float marginRight = 0)
|
|
{
|
|
Button result = new Button(clickEvent);
|
|
|
|
result.tooltip = tooltip;
|
|
result.style.backgroundImage = image;
|
|
result.style.width = NAVIGATION_BUTTON_SIZE;
|
|
result.style.height = NAVIGATION_BUTTON_SIZE;
|
|
result.style.marginLeft = 0;
|
|
result.style.marginRight = marginRight;
|
|
result.style.paddingLeft = 0;
|
|
result.style.paddingRight = 0;
|
|
result.style.paddingTop = 0;
|
|
result.style.paddingBottom = 0;
|
|
result.style.borderLeftWidth = 0;
|
|
result.style.borderRightWidth = 0;
|
|
result.style.borderTopWidth = 0;
|
|
result.style.borderBottomWidth = 0;
|
|
result.visible = false;
|
|
result.style.backgroundColor = Color.clear;
|
|
|
|
result.SetMouseCursor(MouseCursor.Arrow);
|
|
result.RegisterCallback<MouseEnterEvent>(OnNavigationButtonMouseEnter);
|
|
result.RegisterCallback<MouseLeaveEvent>(OnNavigationButtonMouseLeave);
|
|
|
|
return result;
|
|
}
|
|
|
|
void OnSearchFieldKeyDown(KeyDownEvent evt)
|
|
{
|
|
KeyboardActions.SearchAction searchAction =
|
|
KeyboardActions.GetSearchAction(evt);
|
|
|
|
if (searchAction == KeyboardActions.SearchAction.None)
|
|
return;
|
|
|
|
if (searchAction == KeyboardActions.SearchAction.Clean)
|
|
{
|
|
evt.StopPropagation();
|
|
mSearchField.value = string.Empty;
|
|
return;
|
|
}
|
|
|
|
if (searchAction == KeyboardActions.SearchAction.PreviousSearch)
|
|
{
|
|
evt.StopPropagation();
|
|
PreviousSearchResultRequested?.Invoke();
|
|
return;
|
|
}
|
|
|
|
if (searchAction == KeyboardActions.SearchAction.NextSearch)
|
|
{
|
|
evt.StopPropagation();
|
|
NextSearchResultRequested?.Invoke();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void OnSearchFieldChanged(ChangeEvent<string> evt)
|
|
{
|
|
mSearchRunner.Run();
|
|
UpdateSearchControlsVisibility();
|
|
}
|
|
|
|
void UpdateSearchControlsVisibility()
|
|
{
|
|
if (string.IsNullOrEmpty(mSearchField.value))
|
|
{
|
|
mSearchCounterLabel.text = string.Empty;
|
|
mSearchCounterLabel.visible = false;
|
|
mPreviousButton.visible = false;
|
|
mNextButton.visible = false;
|
|
return;
|
|
}
|
|
|
|
mSearchCounterLabel.visible = true;
|
|
mPreviousButton.visible = true;
|
|
mNextButton.visible = true;
|
|
}
|
|
|
|
void OnNextButtonClicked()
|
|
{
|
|
NextSearchResultRequested?.Invoke();
|
|
}
|
|
|
|
void OnPreviousButtonClicked()
|
|
{
|
|
PreviousSearchResultRequested?.Invoke();
|
|
}
|
|
|
|
static string GetSearchTextBoxShortcutsTooltipString()
|
|
{
|
|
if (PlatformIdentifier.IsWindows())
|
|
return PlasticLocalization.Name
|
|
.BranchExplorerSearchFieldShortcutsTooltipForWindows.GetString();
|
|
|
|
if (PlatformIdentifier.IsMac())
|
|
return PlasticLocalization.Name
|
|
.BranchExplorerSearchFieldShortcutsTooltipForMacOS.GetString();
|
|
|
|
return PlasticLocalization.Name
|
|
.BranchExplorerSearchFieldShortcutsTooltipForLinux.GetString();
|
|
}
|
|
|
|
ToolbarSearchField mSearchField;
|
|
Label mSearchCounterLabel;
|
|
Button mPreviousButton;
|
|
Button mNextButton;
|
|
|
|
readonly DelayedActionBySecondsRunner mSearchRunner;
|
|
|
|
const float NAVIGATION_BUTTON_SIZE = 12f;
|
|
}
|
|
}
|