A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR
2using System.Text;
3using UnityEditor;
4using UnityEngine.InputSystem.Layouts;
5
6namespace UnityEngine.InputSystem.Editor
7{
8 internal abstract class InputControlDropdownItem : AdvancedDropdownItem
9 {
10 protected string m_ControlPath;
11 protected string m_Device;
12 protected string m_Usage;
13 protected bool m_Searchable;
14
15 public string controlPath => m_ControlPath;
16
17 public virtual string controlPathWithDevice
18 {
19 get
20 {
21 var path = new StringBuilder($"<{m_Device}>");
22 if (!string.IsNullOrEmpty(m_Usage))
23 path.Append($"{{{m_Usage}}}");
24 if (!string.IsNullOrEmpty(m_ControlPath))
25 path.Append($"/{m_ControlPath}");
26 return path.ToString();
27 }
28 }
29
30 public override string searchableName
31 {
32 get
33 {
34 // ToHumanReadableString is expensive, especially given that we build the whole tree
35 // every time the control picker comes up. Build searchable names only on demand
36 // to save some time.
37 if (m_SearchableName == null)
38 {
39 if (m_Searchable)
40 m_SearchableName = InputControlPath.ToHumanReadableString(controlPathWithDevice);
41 else
42 m_SearchableName = string.Empty;
43 }
44 return m_SearchableName;
45 }
46 }
47
48 protected InputControlDropdownItem(string name)
49 : base(name) {}
50 }
51
52 // NOTE: Optional control items, unlike normal control items, are displayed with their internal control
53 // names rather that their display names. The reason is that we're looking at controls that have
54 // the same internal name in one or more derived layouts but each of those derived layouts may
55 // give the control a different display name.
56 //
57 // Also, if we generate a control path for an optional binding, InputControlPath.ToHumanReadableName()
58 // not find the referenced control on the referenced device layout and will thus not be able to
59 // find a display name for it either. So, in the binding UI, these paths will also show with their
60 // internal control names rather than display names.
61 internal sealed class OptionalControlDropdownItem : InputControlDropdownItem
62 {
63 public OptionalControlDropdownItem(EditorInputControlLayoutCache.OptionalControl optionalControl, string deviceControlId, string commonUsage)
64 : base(optionalControl.name)
65 {
66 m_ControlPath = optionalControl.name;
67 m_Device = deviceControlId;
68 m_Usage = commonUsage;
69 // Not searchable.
70 }
71 }
72
73 internal sealed class ControlUsageDropdownItem : InputControlDropdownItem
74 {
75 public override string controlPathWithDevice => BuildControlPath();
76 private string BuildControlPath()
77 {
78 if (m_Device == "*")
79 {
80 var path = new StringBuilder(m_Device);
81 if (!string.IsNullOrEmpty(m_Usage))
82 path.Append($"{{{m_Usage}}}");
83 if (!string.IsNullOrEmpty(m_ControlPath))
84 path.Append($"/{m_ControlPath}");
85 return path.ToString();
86 }
87 else
88 return base.controlPathWithDevice;
89 }
90
91 public ControlUsageDropdownItem(string device, string usage, string controlUsage)
92 : base(usage)
93 {
94 m_Device = string.IsNullOrEmpty(device) ? "*" : device;
95 m_Usage = usage;
96 m_ControlPath = $"{{{ controlUsage }}}";
97 name = controlUsage;
98 id = controlPathWithDevice.GetHashCode();
99 m_Searchable = true;
100 }
101 }
102
103 internal sealed class DeviceDropdownItem : InputControlDropdownItem
104 {
105 public DeviceDropdownItem(InputControlLayout layout, string usage = null, bool searchable = true)
106 : base(layout.m_DisplayName ?? ObjectNames.NicifyVariableName(layout.name))
107 {
108 m_Device = layout.name;
109 m_Usage = usage;
110 if (usage != null)
111 name += " (" + usage + ")";
112 id = name.GetHashCode();
113 m_Searchable = searchable;
114 }
115 }
116
117 internal sealed class ControlDropdownItem : InputControlDropdownItem
118 {
119 public ControlDropdownItem(ControlDropdownItem parent, string controlName, string displayName, string device, string usage, bool searchable)
120 : base("")
121 {
122 m_Device = device;
123 m_Usage = usage;
124 m_Searchable = searchable;
125
126 if (parent != null)
127 m_ControlPath = $"{parent.controlPath}/{controlName}";
128 else
129 m_ControlPath = controlName;
130
131 name = !string.IsNullOrEmpty(displayName) ? displayName : ObjectNames.NicifyVariableName(controlName);
132
133 id = controlPathWithDevice.GetHashCode();
134 indent = parent?.indent + 1 ?? 0;
135 }
136 }
137}
138
139#endif // UNITY_EDITOR