Files
MMORPG/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs
cooney ce83f21c93 UI 자동화를 위해 바인딩 기능 구현
- 유니티 에셋 인증 오류로 meta 재생성
2026-01-25 01:31:34 +09:00

186 lines
7.8 KiB
C#

#if UNITY_EDITOR
using System.Linq;
using UnityEditor;
using UnityEngine.UIElements;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.Utilities;
using System.Collections.Generic;
namespace UnityEngine.InputSystem.Editor
{
internal class BindingPropertiesView : ViewBase<BindingPropertiesView.ViewState>
{
private readonly Foldout m_ParentFoldout;
private CompositeBindingPropertiesView m_CompositeBindingPropertiesView;
private CompositePartBindingPropertiesView m_CompositePartBindingPropertiesView;
public BindingPropertiesView(VisualElement root, Foldout foldout, StateContainer stateContainer)
: base(root, stateContainer)
{
m_ParentFoldout = foldout;
CreateSelector(state => state.selectedBindingIndex,
s => new ViewStateCollection<InputControlScheme>(Selectors.GetControlSchemes(s)),
(_, controlSchemes, s) => new ViewState
{
controlSchemes = controlSchemes,
currentControlScheme = s.selectedControlScheme,
selectedBinding = Selectors.GetSelectedBinding(s),
selectedBindingIndex = s.selectedBindingIndex,
selectedBindingPath = Selectors.GetSelectedBindingPath(s),
selectedInputAction = Selectors.GetSelectedAction(s)
});
}
public override void RedrawUI(ViewState viewState)
{
var selectedBindingIndex = viewState.selectedBindingIndex;
if (selectedBindingIndex == -1)
return;
rootElement.Clear();
var binding = viewState.selectedBinding;
if (!binding.HasValue)
return;
m_ParentFoldout.text = "Binding";
if (binding.Value.isComposite)
{
m_ParentFoldout.text = "Composite";
m_CompositeBindingPropertiesView = CreateChildView(new CompositeBindingPropertiesView(rootElement, stateContainer));
}
else if (binding.Value.isPartOfComposite)
{
m_CompositePartBindingPropertiesView = CreateChildView(new CompositePartBindingPropertiesView(rootElement, stateContainer));
DrawMatchingControlPaths(viewState);
DrawControlSchemeToggles(viewState, binding.Value);
}
else
{
var controlPathEditor = new InputControlPathEditor(viewState.selectedBindingPath, new InputControlPickerState(),
() => { Dispatch(Commands.ApplyModifiedProperties()); });
controlPathEditor.SetControlPathsToMatch(viewState.currentControlScheme.deviceRequirements.Select(x => x.controlPath));
var inputAction = viewState.selectedInputAction;
controlPathEditor.SetExpectedControlLayout(inputAction?.expectedControlType ?? "");
var controlPathContainer = new IMGUIContainer(controlPathEditor.OnGUI);
rootElement.Add(controlPathContainer);
DrawMatchingControlPaths(viewState);
DrawControlSchemeToggles(viewState, binding.Value);
}
}
static bool s_showMatchingLayouts = false;
internal void DrawMatchingControlPaths(ViewState viewState)
{
bool controlPathUsagePresent = false;
bool showPaths = s_showMatchingLayouts;
List<MatchingControlPath> matchingControlPaths = MatchingControlPath.CollectMatchingControlPaths(viewState.selectedBindingPath.stringValue, showPaths, ref controlPathUsagePresent);
var parentElement = rootElement;
if (matchingControlPaths == null || matchingControlPaths.Count != 0)
{
var controllingElement = new Foldout()
{
text = $"Show Derived Bindings",
value = showPaths
};
rootElement.Add(controllingElement);
controllingElement.RegisterValueChangedCallback(changeEvent =>
{
if (changeEvent.target == controllingElement) // only react to foldout and not tree elements
s_showMatchingLayouts = changeEvent.newValue;
});
parentElement = controllingElement;
}
if (matchingControlPaths == null)
{
var messageString = controlPathUsagePresent ? "No registered controls match this current binding. Some controls are only registered at runtime." :
"No other registered controls match this current binding. Some controls are only registered at runtime.";
var helpBox = new HelpBox(messageString, HelpBoxMessageType.Warning);
helpBox.AddToClassList("matching-controls");
parentElement.Add(helpBox);
}
else if (matchingControlPaths.Count > 0)
{
List<TreeViewItemData<MatchingControlPath>> treeViewMatchingControlPaths = MatchingControlPath.BuildMatchingControlPathsTreeData(matchingControlPaths);
var treeView = new TreeView();
parentElement.Add(treeView);
treeView.selectionType = UIElements.SelectionType.None;
treeView.AddToClassList("matching-controls");
treeView.fixedItemHeight = 20;
treeView.SetRootItems(treeViewMatchingControlPaths);
// Set TreeView.makeItem to initialize each node in the tree.
treeView.makeItem = () =>
{
var label = new Label();
label.AddToClassList("matching-controls-labels");
return label;
};
// Set TreeView.bindItem to bind an initialized node to a data item.
treeView.bindItem = (VisualElement element, int index) =>
{
var label = (element as Label);
var matchingControlPath = treeView.GetItemDataForIndex<MatchingControlPath>(index);
label.text = $"{matchingControlPath.deviceName} > {matchingControlPath.controlName}";
};
treeView.ExpandRootItems();
}
}
public override void DestroyView()
{
m_CompositeBindingPropertiesView?.DestroyView();
m_CompositePartBindingPropertiesView?.DestroyView();
}
private void DrawControlSchemeToggles(ViewState viewState, SerializedInputBinding binding)
{
if (!viewState.controlSchemes.Any()) return;
var useInControlSchemeLabel = new Label("Use in control scheme")
{
name = "control-scheme-usage-title"
};
rootElement.Add(useInControlSchemeLabel);
foreach (var controlScheme in viewState.controlSchemes)
{
var checkbox = new Toggle(controlScheme.name)
{
value = binding.controlSchemes.Any(scheme => controlScheme.name == scheme)
};
rootElement.Add(checkbox);
checkbox.RegisterValueChangedCallback(changeEvent =>
{
Dispatch(ControlSchemeCommands.ChangeSelectedBindingsControlSchemes(controlScheme.name, changeEvent.newValue));
});
}
}
internal class ViewState
{
public int selectedBindingIndex;
public SerializedInputBinding? selectedBinding;
public ViewStateCollection<InputControlScheme> controlSchemes;
public InputControlScheme currentControlScheme;
public SerializedProperty selectedBindingPath;
public SerializedInputAction? selectedInputAction;
}
}
}
#endif