in Assets/MRTK/Core/Inspectors/ControllerPopupWindow.cs [357:774]
private void RenderInteractionList(SerializedProperty interactionList, bool useCustomInteractionMapping)
{
if (interactionList == null) { throw new Exception(); }
bool noInteractions = interactionList.arraySize == 0;
if (currentControllerOption != null && (currentControllerOption.IsLabelFlipped == null || currentControllerOption.IsLabelFlipped.Length != interactionList.arraySize))
{
currentControllerOption.IsLabelFlipped = new bool[interactionList.arraySize];
}
GUILayout.BeginVertical();
if (useCustomInteractionMapping)
{
horizontalScrollPosition = EditorGUILayout.BeginScrollView(horizontalScrollPosition, false, false, GUILayout.ExpandWidth(true), GUILayout.ExpandWidth(true));
}
if (useCustomInteractionMapping)
{
if (GUILayout.Button(InteractionAddButtonContent))
{
interactionList.arraySize += 1;
var interaction = interactionList.GetArrayElementAtIndex(interactionList.arraySize - 1);
var axisType = interaction.FindPropertyRelative("axisType");
axisType.enumValueIndex = 0;
var inputType = interaction.FindPropertyRelative("inputType");
inputType.enumValueIndex = 0;
var action = interaction.FindPropertyRelative("inputAction");
var actionId = action.FindPropertyRelative("id");
var actionDescription = action.FindPropertyRelative("description");
actionDescription.stringValue = "None";
actionId.intValue = 0;
}
if (noInteractions)
{
EditorGUILayout.HelpBox("Create an Interaction Mapping.", MessageType.Warning);
EditorGUILayout.EndScrollView();
GUILayout.EndVertical();
return;
}
}
else if (EnableWysiwyg)
{
EditorGUI.BeginChangeCheck();
editInputActionPositions = EditorGUILayout.Toggle("Edit Input Action Positions", editInputActionPositions);
if (EditorGUI.EndChangeCheck())
{
string editorWindowOptionsPath = ResolveEditorWindowOptionsPath();
if (!editInputActionPositions)
{
File.WriteAllText(editorWindowOptionsPath, JsonUtility.ToJson(controllerInputActionOptions, true));
}
else
{
if (!controllerInputActionOptions.Controllers.Any(
option => option.Controller == currentControllerMapping.SupportedControllerType && option.Handedness == currentControllerMapping.Handedness))
{
currentControllerOption = new ControllerInputActionOption
{
Controller = currentControllerMapping.SupportedControllerType,
Handedness = currentControllerMapping.Handedness,
InputLabelPositions = new Vector2[currentInteractionList.arraySize],
IsLabelFlipped = new bool[currentInteractionList.arraySize]
};
controllerInputActionOptions.Controllers.Add(currentControllerOption);
isMouseInRects = new bool[currentInteractionList.arraySize];
if (controllerInputActionOptions.Controllers.Any(option => option.Controller == 0))
{
controllerInputActionOptions.Controllers.Remove(
controllerInputActionOptions.Controllers.Find(option =>
option.Controller == 0));
}
File.WriteAllText(editorWindowOptionsPath, JsonUtility.ToJson(controllerInputActionOptions, true));
}
}
}
}
GUILayout.BeginHorizontal();
if (useCustomInteractionMapping)
{
EditorGUILayout.LabelField("Id", GUILayout.Width(32f));
EditorGUIUtility.labelWidth = 24f;
EditorGUIUtility.fieldWidth = 24f;
EditorGUILayout.LabelField(ControllerInputTypeContent, GUILayout.Width(InputActionLabelWidth));
EditorGUILayout.LabelField(AxisTypeContent, GUILayout.Width(InputActionLabelWidth));
EditorGUILayout.LabelField(ActionContent, GUILayout.Width(InputActionLabelWidth));
EditorGUILayout.LabelField(KeyCodeContent, GUILayout.Width(InputActionLabelWidth));
EditorGUILayout.LabelField(XAxisContent, GUILayout.Width(InputActionLabelWidth));
EditorGUILayout.LabelField(YAxisContent, GUILayout.Width(InputActionLabelWidth));
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField(string.Empty, GUILayout.Width(24f));
EditorGUIUtility.labelWidth = defaultLabelWidth;
EditorGUIUtility.fieldWidth = defaultFieldWidth;
}
GUILayout.EndHorizontal();
for (int i = 0; i < interactionList.arraySize; i++)
{
using (new EditorGUILayout.HorizontalScope())
{
SerializedProperty interaction = interactionList.GetArrayElementAtIndex(i);
if (useCustomInteractionMapping)
{
EditorGUILayout.LabelField($"{i + 1}", GUILayout.Width(32f));
var inputType = interaction.FindPropertyRelative("inputType");
EditorGUILayout.PropertyField(inputType, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
var axisType = interaction.FindPropertyRelative("axisType");
EditorGUILayout.PropertyField(axisType, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
var invertXAxis = interaction.FindPropertyRelative("invertXAxis");
var invertYAxis = interaction.FindPropertyRelative("invertYAxis");
var interactionAxisConstraint = interaction.FindPropertyRelative("axisType");
var action = interaction.FindPropertyRelative("inputAction");
var actionId = action.FindPropertyRelative("id");
var actionDescription = action.FindPropertyRelative("description");
var actionConstraint = action.FindPropertyRelative("axisConstraint");
GUIContent[] labels;
int[] ids;
switch ((AxisType)interactionAxisConstraint.intValue)
{
default:
case AxisType.None:
labels = actionLabels;
ids = actionIds;
break;
case AxisType.Raw:
labels = rawActionLabels;
ids = rawActionIds;
break;
case AxisType.Digital:
labels = digitalActionLabels;
ids = digitalActionIds;
break;
case AxisType.SingleAxis:
labels = singleAxisActionLabels;
ids = singleAxisActionIds;
break;
case AxisType.DualAxis:
labels = dualAxisActionLabels;
ids = dualAxisActionIds;
break;
case AxisType.ThreeDofPosition:
labels = threeDofPositionActionLabels;
ids = threeDofPositionActionIds;
break;
case AxisType.ThreeDofRotation:
labels = threeDofRotationActionLabels;
ids = threeDofRotationActionIds;
break;
case AxisType.SixDof:
labels = sixDofActionLabels;
ids = sixDofActionIds;
break;
}
EditorGUI.BeginChangeCheck();
actionId.intValue = EditorGUILayout.IntPopup(GUIContent.none, actionId.intValue, labels, ids, GUILayout.Width(InputActionLabelWidth));
if (EditorGUI.EndChangeCheck())
{
var inputAction = actionId.intValue == 0 ? MixedRealityInputAction.None : MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions[actionId.intValue - 1];
actionDescription.stringValue = inputAction.Description;
actionConstraint.enumValueIndex = (int)inputAction.AxisConstraint;
}
if ((AxisType)axisType.intValue == AxisType.Digital)
{
var keyCode = interaction.FindPropertyRelative("keyCode");
EditorGUILayout.PropertyField(keyCode, GUIContent.none, GUILayout.Width(InputActionLabelWidth));
}
else
{
if ((AxisType)axisType.intValue == AxisType.DualAxis)
{
EditorGUIUtility.labelWidth = InputActionLabelWidth * 0.5f;
EditorGUIUtility.fieldWidth = InputActionLabelWidth * 0.5f;
int currentAxisSetting = 0;
if (invertXAxis.boolValue)
{
currentAxisSetting += 1;
}
if (invertYAxis.boolValue)
{
currentAxisSetting += 2;
}
EditorGUI.BeginChangeCheck();
currentAxisSetting = EditorGUILayout.IntPopup(InvertContent, currentAxisSetting, InvertAxisContent, InvertAxisValues, GUILayout.Width(InputActionLabelWidth));
if (EditorGUI.EndChangeCheck())
{
switch (currentAxisSetting)
{
case 0:
invertXAxis.boolValue = false;
invertYAxis.boolValue = false;
break;
case 1:
invertXAxis.boolValue = true;
invertYAxis.boolValue = false;
break;
case 2:
invertXAxis.boolValue = false;
invertYAxis.boolValue = true;
break;
case 3:
invertXAxis.boolValue = true;
invertYAxis.boolValue = true;
break;
}
}
EditorGUIUtility.labelWidth = defaultLabelWidth;
EditorGUIUtility.fieldWidth = defaultFieldWidth;
}
else if ((AxisType)axisType.intValue == AxisType.SingleAxis)
{
invertXAxis.boolValue = EditorGUILayout.ToggleLeft("Invert X", invertXAxis.boolValue, GUILayout.Width(InputActionLabelWidth));
EditorGUIUtility.labelWidth = defaultLabelWidth;
}
else
{
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
}
}
if ((AxisType)axisType.intValue == AxisType.SingleAxis ||
(AxisType)axisType.intValue == AxisType.DualAxis)
{
var axisCodeX = interaction.FindPropertyRelative("axisCodeX");
RenderAxisPopup(axisCodeX, InputActionLabelWidth);
}
else
{
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
}
if ((AxisType)axisType.intValue == AxisType.DualAxis)
{
var axisCodeY = interaction.FindPropertyRelative("axisCodeY");
RenderAxisPopup(axisCodeY, InputActionLabelWidth);
}
else
{
EditorGUILayout.LabelField(GUIContent.none, GUILayout.Width(InputActionLabelWidth));
}
if (GUILayout.Button(InteractionMinusButtonContent, EditorStyles.miniButtonRight, GUILayout.ExpandWidth(true)))
{
interactionList.DeleteArrayElementAtIndex(i);
}
}
else
{
var interactionDescription = interaction.FindPropertyRelative("description");
var interactionAxisConstraint = interaction.FindPropertyRelative("axisType");
var action = interaction.FindPropertyRelative("inputAction");
var actionId = action.FindPropertyRelative("id");
var actionDescription = action.FindPropertyRelative("description");
var actionConstraint = action.FindPropertyRelative("axisConstraint");
GUIContent[] labels;
int[] ids;
switch ((AxisType)interactionAxisConstraint.intValue)
{
default:
case AxisType.None:
labels = actionLabels;
ids = actionIds;
break;
case AxisType.Raw:
labels = rawActionLabels;
ids = rawActionIds;
break;
case AxisType.Digital:
labels = digitalActionLabels;
ids = digitalActionIds;
break;
case AxisType.SingleAxis:
labels = singleAxisActionLabels;
ids = singleAxisActionIds;
break;
case AxisType.DualAxis:
labels = dualAxisActionLabels;
ids = dualAxisActionIds;
break;
case AxisType.ThreeDofPosition:
labels = threeDofPositionActionLabels;
ids = threeDofPositionActionIds;
break;
case AxisType.ThreeDofRotation:
labels = threeDofRotationActionLabels;
ids = threeDofRotationActionIds;
break;
case AxisType.SixDof:
labels = sixDofActionLabels;
ids = sixDofActionIds;
break;
}
EditorGUI.BeginChangeCheck();
if (currentControllerOption == null || currentControllerTexture == null)
{
bool skip = false;
var description = interactionDescription.stringValue;
if (currentControllerMapping.SupportedControllerType == SupportedControllerType.GGVHand
&& currentControllerMapping.Handedness == Handedness.None)
{
if (description != "Select")
{
skip = true;
}
}
if (!skip)
{
actionId.intValue = EditorGUILayout.IntPopup(GUIContent.none, actionId.intValue, labels, ids, GUILayout.Width(80f));
EditorGUILayout.LabelField(description, GUILayout.ExpandWidth(true));
}
}
else
{
var rectPosition = currentControllerOption.InputLabelPositions[i];
var rectSize = InputActionLabelPosition + InputActionDropdownPosition + new Vector2(currentControllerOption.IsLabelFlipped[i] ? 0f : 8f, EditorGUIUtility.singleLineHeight);
GUI.Box(new Rect(rectPosition, rectSize), GUIContent.none, EditorGUIUtility.isProSkin ? "ObjectPickerBackground" : "ObjectPickerResultsEven");
var offset = currentControllerOption.IsLabelFlipped[i] ? InputActionLabelPosition : Vector2.zero;
var popupRect = new Rect(rectPosition + offset, new Vector2(InputActionDropdownPosition.x, EditorGUIUtility.singleLineHeight));
actionId.intValue = EditorGUI.IntPopup(popupRect, actionId.intValue, labels, ids);
offset = currentControllerOption.IsLabelFlipped[i] ? Vector2.zero : InputActionDropdownPosition;
var labelRect = new Rect(rectPosition + offset, new Vector2(InputActionLabelPosition.x, EditorGUIUtility.singleLineHeight));
EditorGUI.LabelField(labelRect, interactionDescription.stringValue, currentControllerOption.IsLabelFlipped[i] ? flippedLabelStyle : EditorStyles.label);
if (editInputActionPositions)
{
offset = currentControllerOption.IsLabelFlipped[i] ? InputActionLabelPosition + InputActionDropdownPosition + HorizontalSpace : InputActionFlipTogglePosition;
var toggleRect = new Rect(rectPosition + offset, new Vector2(-InputActionFlipTogglePosition.x, EditorGUIUtility.singleLineHeight));
EditorGUI.BeginChangeCheck();
currentControllerOption.IsLabelFlipped[i] = EditorGUI.Toggle(toggleRect, currentControllerOption.IsLabelFlipped[i]);
if (EditorGUI.EndChangeCheck())
{
if (currentControllerOption.IsLabelFlipped[i])
{
currentControllerOption.InputLabelPositions[i] -= InputActionLabelPosition;
}
else
{
currentControllerOption.InputLabelPositions[i] += InputActionLabelPosition;
}
}
if (!isMouseInRects.Any(value => value) || isMouseInRects[i])
{
if (Event.current.type == EventType.MouseDrag && labelRect.Contains(Event.current.mousePosition) && !isMouseInRects[i])
{
isMouseInRects[i] = true;
mouseDragOffset = Event.current.mousePosition - currentControllerOption.InputLabelPositions[i];
}
else if (Event.current.type == EventType.Repaint && isMouseInRects[i])
{
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
}
else if (Event.current.type == EventType.DragUpdated && isMouseInRects[i])
{
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
}
else if (Event.current.type == EventType.MouseUp && isMouseInRects[i])
{
currentControllerOption.InputLabelPositions[i] = Event.current.mousePosition - mouseDragOffset;
mouseDragOffset = Vector2.zero;
isMouseInRects[i] = false;
}
}
}
}
if (EditorGUI.EndChangeCheck())
{
MixedRealityInputAction inputAction = actionId.intValue == 0 ?
MixedRealityInputAction.None :
MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions[actionId.intValue - 1];
actionId.intValue = (int)inputAction.Id;
actionDescription.stringValue = inputAction.Description;
actionConstraint.enumValueIndex = (int)inputAction.AxisConstraint;
interactionList.serializedObject.ApplyModifiedProperties();
}
}
}
}
if (useCustomInteractionMapping)
{
EditorGUILayout.EndScrollView();
interactionList.serializedObject.ApplyModifiedProperties();
}
GUILayout.EndVertical();
}