No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

InputControlDropdownItem.cs 5.1KB

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