A game about forced loneliness, made by TACStudios
1// UITK TreeView is not supported in earlier versions
2// Therefore the UITK version of the InputActionAsset Editor is not available on earlier Editor versions either.
3#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
4using System.Threading.Tasks;
5using UnityEditor;
6using UnityEngine.UIElements;
7
8namespace UnityEngine.InputSystem.Editor
9{
10 /// <summary>
11 /// A visual element that supports renaming of items.
12 /// </summary>
13 internal class InputActionsTreeViewItem : VisualElement
14 {
15 public EventCallback<string> EditTextFinishedCallback;
16
17 private const string kRenameTextField = "rename-text-field";
18 public event EventCallback<string> EditTextFinished;
19
20 private bool m_IsEditing;
21 private static InputActionsTreeViewItem s_EditingItem = null;
22
23 public InputActionsTreeViewItem()
24 {
25 var template = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(
26 InputActionsEditorConstants.PackagePath +
27 InputActionsEditorConstants.ResourcesPath +
28 InputActionsEditorConstants.InputActionsTreeViewItemUxml);
29 template.CloneTree(this);
30
31 focusable = true;
32 delegatesFocus = false;
33
34 renameTextfield.selectAllOnFocus = true;
35 renameTextfield.selectAllOnMouseUp = false;
36
37
38 RegisterCallback<MouseDownEvent>(OnMouseDownEventForRename);
39 renameTextfield.RegisterCallback<FocusOutEvent>(e => OnEditTextFinished());
40 }
41
42 public Label label => this.Q<Label>();
43 private TextField renameTextfield => this.Q<TextField>(kRenameTextField);
44
45
46 public void UnregisterInputField()
47 {
48 renameTextfield.SetEnabled(false);
49 renameTextfield.selectAllOnFocus = false;
50 UnregisterCallback<MouseDownEvent>(OnMouseDownEventForRename);
51 renameTextfield.UnregisterCallback<FocusOutEvent>(e => OnEditTextFinished());
52 }
53
54 private float lastSingleClick;
55 private static InputActionsTreeViewItem selected;
56
57 private void OnMouseDownEventForRename(MouseDownEvent e)
58 {
59 if (e.clickCount != 1 || e.button != (int)MouseButton.LeftMouse || e.target == null)
60 return;
61
62 if (selected == this && Time.time - lastSingleClick < 3f)
63 {
64 FocusOnRenameTextField();
65 e.StopImmediatePropagation();
66 lastSingleClick = 0;
67 }
68 lastSingleClick = Time.time;
69 selected = this;
70 }
71
72 public void Reset()
73 {
74 EditTextFinished = null;
75 m_IsEditing = false;
76 }
77
78 public void FocusOnRenameTextField()
79 {
80 if (m_IsEditing)
81 return;
82 delegatesFocus = true;
83
84 renameTextfield.SetValueWithoutNotify(label.text);
85 renameTextfield.RemoveFromClassList(InputActionsEditorConstants.HiddenStyleClassName);
86 label?.AddToClassList(InputActionsEditorConstants.HiddenStyleClassName);
87
88 //a bit hacky - e.StopImmediatePropagation() for events does not work like expected on ListViewItems or TreeViewItems because
89 //the listView/treeView reclaims the focus - this is a workaround with less overhead than rewriting the events
90 DelayCall();
91 renameTextfield.SelectAll();
92
93 s_EditingItem = this;
94 m_IsEditing = true;
95 }
96
97 public static void CancelRename()
98 {
99 s_EditingItem?.OnEditTextFinished();
100 }
101
102 async void DelayCall()
103 {
104 await Task.Delay(120);
105 renameTextfield.Q<TextField>().Focus();
106 }
107
108 private void OnEditTextFinished()
109 {
110 if (!m_IsEditing)
111 return;
112 lastSingleClick = 0;
113 delegatesFocus = false;
114
115 renameTextfield.AddToClassList(InputActionsEditorConstants.HiddenStyleClassName);
116 label.RemoveFromClassList(InputActionsEditorConstants.HiddenStyleClassName);
117 s_EditingItem = null;
118 m_IsEditing = false;
119
120 var text = renameTextfield.text?.Trim();
121 if (string.IsNullOrEmpty(text))
122 {
123 renameTextfield.schedule.Execute(() => renameTextfield.SetValueWithoutNotify(text));
124 return;
125 }
126 EditTextFinished?.Invoke(text);
127 }
128 }
129}
130#endif