Newer
Older
HoloAnatomy / Assets / HoloToolkit-Examples / UX / Scripts / InteractiveSet.cs
SURFACEBOOK2\jackwynne on 25 May 2018 4 KB v1
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace HoloToolkit.Examples.InteractiveElements
{
    public enum SelectionType
    {
        single,
        multiple
    }

    /// <summary>
    /// A controller for managing multiple radial or tab type buttons
    /// </summary>
    public class InteractiveSet : MonoBehaviour
    {
        [Tooltip("Allow single or multiple selection")]
        public SelectionType Type = SelectionType.single;

        [Tooltip("Interactives that will be managed by this controller")]
        public List<InteractiveToggle> Interactives;

        [Tooltip("Currently selected indices or default starting indices")]
        public List<int> SelectedIndices = new List<int>() { 0 };

        [Tooltip("exposed selection changed event")]
        public UnityEvent OnSelectionEvents;

        // list of calls to remove events on recycled buttons
        private Dictionary<InteractiveToggle, UnityAction> Calls = new Dictionary<InteractiveToggle, UnityAction>();

        private bool mHasInit = false;

        private void Start()
        {
            UpdateInteractives();
        }

        public void UpdateInteractives()
        {
            foreach (InteractiveToggle toggle in Calls.Keys)
            {
                toggle.OnSelectEvents.RemoveListener(Calls[toggle]);
            }
            Calls.Clear();
            for (int i = 0; i < Interactives.Count; ++i)
            {
                int itemIndex = i;
                // add selection event handler to each button
                UnityAction call = () => HandleOnSelection(itemIndex);
                Calls.Add(Interactives[i], call);
                Interactives[i].OnSelectEvents.AddListener(call);
                if (Type == SelectionType.single)
                {
                    Interactives[i].AllowDeselect = false;
                }
                Interactives[i].HasSelection = SelectedIndices.Contains(i);
            }
            OnSelectionEvents.Invoke();
        }

        public void RemoveInteractive(int itemIndex)
        {
            Interactives[itemIndex].OnSelectEvents.RemoveListener(() => HandleOnSelection(itemIndex));
            Interactives.RemoveAt(itemIndex);
        }

        /// <summary>
        /// Sets the selected index and selected Interactive
        /// </summary>
        /// <param name="index"></param>
        public void SetSelection(int index)
        {
            if (!isActiveAndEnabled ||
                (index < 0 || Interactives.Count <= index))
            {
                return;
            }

            Interactives[index].OnInputClicked(null);
        }

        /// <summary>
        /// responds to selection events
        /// </summary>
        /// <param name="index"></param>
        private void HandleOnSelection(int index)
        {
            if (Type == SelectionType.single)
            {
                for (int i = 0; i < Interactives.Count; ++i)
                {
                    if (i != index)
                    {
                        Interactives[i].HasSelection = false;
                    }
                }

                if (!mHasInit)
                {
                    Interactives[index].HasSelection = true;
                    mHasInit = true;
                }

                SelectedIndices.Clear();
                SelectedIndices.Add(index);
            }
            else
            {
                Interactives[index].HasSelection = !Interactives[index].HasSelection;
                if (SelectedIndices.Contains(index))
                {
                    SelectedIndices.Remove(index);
                }
                else
                {
                    SelectedIndices.Add(index);
                }
            }
            OnSelectionEvents.Invoke();
        }

        private void OnDestroy()
        {
            for (int i = Interactives.Count - 1; i >= 0; i--)
            {
                RemoveInteractive(i);
            }
        }
    }
}