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
3 years ago
|
//========= 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|