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.
322 lines
11 KiB
322 lines
11 KiB
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. =========== |
|
|
|
using HTC.UnityPlugin.Utility; |
|
using HTC.UnityPlugin.VRModuleManagement; |
|
using System; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
using UnityEngine.Events; |
|
|
|
namespace HTC.UnityPlugin.Vive.BindingInterface |
|
{ |
|
public class BindingInterfaceRoleSetPanelController : MonoBehaviour |
|
{ |
|
public Type DEFAULT_SELECTED_ROLE = typeof(BodyRole); |
|
|
|
[Serializable] |
|
public class UnityEventSelectRole : UnityEvent<ViveRole.IMap> { } |
|
|
|
[Serializable] |
|
public class UnityEventString : UnityEvent<string> { } |
|
|
|
[SerializeField] |
|
private Animator m_animator; |
|
[SerializeField] |
|
private BindingInterfaceRoleSetButtonItem m_roleSetButtonItem; |
|
[SerializeField] |
|
private BindingInterfaceRoleSetBindingItem m_bindingItem; |
|
[SerializeField] |
|
private UnityEventSelectRole m_onSelectRoleSet; |
|
[SerializeField] |
|
private UnityEventString m_onEditBinding; |
|
[SerializeField] |
|
private UnityEvent m_onFinishEditBinding; |
|
|
|
private int m_maxBindingCount; |
|
private List<BindingInterfaceRoleSetButtonItem> m_roleSetButtonList = new List<BindingInterfaceRoleSetButtonItem>(); |
|
private int m_selectedRoleIndex = -1; |
|
|
|
private List<BindingInterfaceRoleSetBindingItem> m_bindingList = new List<BindingInterfaceRoleSetBindingItem>(); |
|
private string m_editingDevice = string.Empty; |
|
private string m_heighLightDevice = string.Empty; |
|
private OrderedIndexedSet<string> m_boundDevices = new OrderedIndexedSet<string>(); |
|
|
|
public ViveRole.IMap selectedRoleMap { get { return m_roleSetButtonList[m_selectedRoleIndex].roleMap; } } |
|
public bool isEditing { get { return !string.IsNullOrEmpty(m_editingDevice); } } |
|
public bool hasHeightLight { get { return !string.IsNullOrEmpty(m_heighLightDevice); } } |
|
|
|
private void Awake() |
|
{ |
|
RefreshRoleSelection(); |
|
|
|
// select the role that have largest binding count |
|
for (int i = 0, imax = m_roleSetButtonList.Count; i < imax; ++i) |
|
{ |
|
if (!m_roleSetButtonList[i].roleMap.Handler.BlockBindings && m_roleSetButtonList[i].roleMap.BindingCount == m_maxBindingCount) |
|
{ |
|
SelectRoleSet(i); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
private void OnEnable() |
|
{ |
|
VRModule.onDeviceConnected += OnDeviceConnected; |
|
} |
|
|
|
private void OnDisable() |
|
{ |
|
VRModule.onDeviceConnected -= OnDeviceConnected; |
|
|
|
FinishEditBinding(); |
|
} |
|
|
|
private void OnDeviceConnected(uint deviceIndex, bool connected) |
|
{ |
|
RefreshSelectedRoleBindings(); |
|
} |
|
|
|
public void SetAnimatorSlideLeft() |
|
{ |
|
if (m_animator.isInitialized) |
|
{ |
|
m_animator.SetTrigger("SlideRoleSetViewLeft"); |
|
} |
|
} |
|
|
|
public void SetAnimatorSlideRight() |
|
{ |
|
if (m_animator.isInitialized) |
|
{ |
|
m_animator.SetTrigger("SlideRoleSetViewRight"); |
|
} |
|
} |
|
|
|
public void EnableSelection() |
|
{ |
|
for (int i = 0, imax = m_roleSetButtonList.Count; i < imax; ++i) |
|
{ |
|
m_roleSetButtonList[i].interactable = true; |
|
} |
|
} |
|
|
|
public void DisableSelection() |
|
{ |
|
for (int i = 0, imax = m_roleSetButtonList.Count; i < imax; ++i) |
|
{ |
|
m_roleSetButtonList[i].interactable = false; |
|
} |
|
} |
|
|
|
public void SelectRoleSet(int index) |
|
{ |
|
m_roleSetButtonList[index].SetIsOn(); |
|
|
|
if (m_selectedRoleIndex == index) { return; } |
|
|
|
m_selectedRoleIndex = index; |
|
|
|
m_boundDevices.Clear(); |
|
|
|
RefreshSelectedRoleBindings(); |
|
|
|
if (m_onSelectRoleSet != null) |
|
{ |
|
m_onSelectRoleSet.Invoke(selectedRoleMap); |
|
} |
|
} |
|
|
|
public void StartEditBinding(string deviceSN) |
|
{ |
|
if (m_editingDevice == deviceSN) { return; } |
|
|
|
FinishEditBindingNoEvent(); |
|
|
|
var bindingItemIndex = m_boundDevices.IndexOf(deviceSN); |
|
if (bindingItemIndex < 0) |
|
{ |
|
selectedRoleMap.BindDeviceToRoleValue(deviceSN, selectedRoleMap.RoleValueInfo.InvalidRoleValue); |
|
|
|
m_editingDevice = deviceSN; |
|
RefreshSelectedRoleBindings(); |
|
RefreshRoleSelection(); |
|
} |
|
else |
|
{ |
|
m_editingDevice = deviceSN; |
|
m_bindingList[m_boundDevices.IndexOf(deviceSN)].isEditing = true; |
|
} |
|
|
|
EnableHeightLightBinding(deviceSN); |
|
|
|
if (m_onEditBinding != null) |
|
{ |
|
m_onEditBinding.Invoke(m_editingDevice); |
|
} |
|
} |
|
|
|
public void FinishEditBindingNoEvent() |
|
{ |
|
if (isEditing) |
|
{ |
|
m_bindingList[m_boundDevices.IndexOf(m_editingDevice)].isEditing = false; |
|
} |
|
|
|
m_editingDevice = string.Empty; |
|
} |
|
|
|
public void FinishEditBinding() |
|
{ |
|
FinishEditBindingNoEvent(); |
|
|
|
if (m_onFinishEditBinding != null) |
|
{ |
|
m_onFinishEditBinding.Invoke(); |
|
} |
|
} |
|
|
|
public void EnableHeightLightBinding(string deviceSN) |
|
{ |
|
if (m_heighLightDevice == deviceSN) { return; } |
|
|
|
DisableHeightLightBinding(); |
|
|
|
if (string.IsNullOrEmpty(deviceSN)) { return; } |
|
|
|
var itemIndex = m_boundDevices.IndexOf(deviceSN); |
|
if (itemIndex < 0) { return; } |
|
|
|
m_heighLightDevice = deviceSN; |
|
m_bindingList[itemIndex].isHeighLight = true; |
|
} |
|
|
|
public void DisableHeightLightBinding() |
|
{ |
|
if (hasHeightLight) |
|
{ |
|
m_bindingList[m_boundDevices.IndexOf(m_heighLightDevice)].isHeighLight = false; |
|
m_heighLightDevice = string.Empty; |
|
} |
|
} |
|
|
|
public void RemoveBinding(string deviceSN) |
|
{ |
|
if (isEditing && m_editingDevice == deviceSN) |
|
{ |
|
FinishEditBinding(); |
|
} |
|
|
|
selectedRoleMap.UnbindDevice(deviceSN); |
|
|
|
RefreshRoleSelection(); |
|
RefreshSelectedRoleBindings(); |
|
} |
|
|
|
public void RefreshRoleSelection() |
|
{ |
|
ViveRole.Initialize(); |
|
|
|
if (m_roleSetButtonList.Count == 0) |
|
{ |
|
m_roleSetButtonList.Add(m_roleSetButtonItem); |
|
m_roleSetButtonItem.index = 0; |
|
m_roleSetButtonItem.onSelected += SelectRoleSet; |
|
} |
|
|
|
m_maxBindingCount = 0; |
|
var buttonIndex = 0; |
|
for (int i = 0, imax = ViveRoleEnum.ValidViveRoleTable.Count; i < imax; ++i) |
|
{ |
|
var roleType = ViveRoleEnum.ValidViveRoleTable.GetValueByIndex(i); |
|
var roleMap = ViveRole.GetMap(roleType); |
|
|
|
if (roleMap.Handler.BlockBindings) { continue; } |
|
|
|
BindingInterfaceRoleSetButtonItem item; |
|
if (buttonIndex >= m_roleSetButtonList.Count) |
|
{ |
|
var itemObj = Instantiate(m_roleSetButtonItem.gameObject); |
|
itemObj.transform.SetParent(m_roleSetButtonItem.transform.parent, false); |
|
|
|
m_roleSetButtonList.Add(item = itemObj.GetComponent<BindingInterfaceRoleSetButtonItem>()); |
|
item.index = buttonIndex; |
|
item.onSelected += SelectRoleSet; |
|
} |
|
else |
|
{ |
|
item = m_roleSetButtonList[buttonIndex]; |
|
} |
|
|
|
m_maxBindingCount = Mathf.Max(m_maxBindingCount, roleMap.BindingCount); |
|
item.roleMap = roleMap; |
|
|
|
++buttonIndex; |
|
} |
|
} |
|
|
|
private IndexedSet<string> m_tempDevices = new OrderedIndexedSet<string>(); |
|
public void RefreshSelectedRoleBindings() |
|
{ |
|
var roleMap = m_roleSetButtonList[m_selectedRoleIndex].roleMap; |
|
var bindingTable = roleMap.BindingTable; |
|
|
|
// update bound device list and keep the original order |
|
for (int i = 0, imax = m_boundDevices.Count; i < imax; ++i) { m_tempDevices.Add(m_boundDevices[i]); } |
|
for (int i = 0, imax = bindingTable.Count; i < imax; ++i) |
|
{ |
|
var boundDevice = bindingTable.GetKeyByIndex(i); |
|
if (!m_tempDevices.Remove(boundDevice)) |
|
{ |
|
m_boundDevices.Add(boundDevice); |
|
} |
|
} |
|
for (int i = 0, imax = m_tempDevices.Count; i < imax; ++i) { m_boundDevices.Remove(m_tempDevices[i]); } |
|
m_tempDevices.Clear(); |
|
|
|
if (m_bindingList.Count == 0) |
|
{ |
|
m_bindingList.Add(m_bindingItem); |
|
m_bindingItem.onEditPress += StartEditBinding; |
|
m_bindingItem.onRemovePress += RemoveBinding; |
|
} |
|
|
|
var bindingIndex = 0; |
|
for (int max = m_boundDevices.Count; bindingIndex < max; ++bindingIndex) |
|
{ |
|
BindingInterfaceRoleSetBindingItem item; |
|
if (bindingIndex >= m_bindingList.Count) |
|
{ |
|
var itemObj = Instantiate(m_bindingItem.gameObject); |
|
itemObj.transform.SetParent(m_bindingItem.transform.parent, false); |
|
|
|
// set child index to secnd last, last index is for add item |
|
itemObj.transform.SetSiblingIndex(itemObj.transform.parent.childCount - 2); |
|
|
|
m_bindingList.Add(item = itemObj.GetComponent<BindingInterfaceRoleSetBindingItem>()); |
|
item.onEditPress += StartEditBinding; |
|
item.onRemovePress += RemoveBinding; |
|
} |
|
else |
|
{ |
|
item = m_bindingList[bindingIndex]; |
|
} |
|
|
|
item.gameObject.SetActive(true); |
|
item.deviceSN = m_boundDevices[bindingIndex]; |
|
item.isEditing = isEditing && item.deviceSN == m_editingDevice; |
|
item.isHeighLight = hasHeightLight && item.deviceSN == m_heighLightDevice; |
|
item.RefreshDisplayInfo(roleMap); |
|
} |
|
|
|
// FIXME: issue in 2017.2.0b2, item won't refresh at the first time, force refresh |
|
m_bindingItem.transform.parent.gameObject.SetActive(false); |
|
m_bindingItem.transform.parent.gameObject.SetActive(true); |
|
|
|
for (int max = m_bindingList.Count; bindingIndex < max; ++bindingIndex) |
|
{ |
|
m_bindingList[bindingIndex].gameObject.SetActive(false); |
|
} |
|
} |
|
} |
|
} |