///Credit perchik ///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/ using System.Collections.Generic; using System.Linq; namespace UnityEngine.UI.Extensions { [RequireComponent(typeof(RectTransform))] [AddComponentMenu("UI/Extensions/AutoComplete ComboBox")] public class AutoCompleteComboBox : MonoBehaviour { public Color disabledTextColor; public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it public List AvailableOptions; public System.Action OnSelectionChanged; // fires when selection is changed; //private bool isInitialized = false; private bool _isPanelActive = false; private bool _hasDrawnOnce = false; private InputField _mainInput; private RectTransform _inputRT; private RectTransform _rectTransform; private RectTransform _overlayRT; private RectTransform _scrollPanelRT; private RectTransform _scrollBarRT; private RectTransform _slidingAreaRT; // private RectTransform scrollHandleRT; private RectTransform _itemsPanelRT; private Canvas _canvas; private RectTransform _canvasRT; private ScrollRect _scrollRect; private List _panelItems; //items that will get shown in the dropdown private List _prunedPanelItems; //items that used to show in the dropdown private Dictionary panelObjects; private GameObject itemTemplate; public string Text { get; private set; } [SerializeField] private float _scrollBarWidth = 20.0f; public float ScrollBarWidth { get { return _scrollBarWidth; } set { _scrollBarWidth = value; RedrawPanel(); } } // private int scrollOffset; //offset of the selected item // private int _selectedIndex = 0; [SerializeField] private int _itemsToDisplay; public int ItemsToDisplay { get { return _itemsToDisplay; } set { _itemsToDisplay = value; RedrawPanel(); } } public void Awake() { Initialize(); } private bool Initialize() { bool success = true; try { _rectTransform = GetComponent(); _inputRT = _rectTransform.FindChild("InputField").GetComponent(); _mainInput = _inputRT.GetComponent(); _overlayRT = _rectTransform.FindChild("Overlay").GetComponent(); _overlayRT.gameObject.SetActive(false); _scrollPanelRT = _overlayRT.FindChild("ScrollPanel").GetComponent(); _scrollBarRT = _scrollPanelRT.FindChild("Scrollbar").GetComponent(); _slidingAreaRT = _scrollBarRT.FindChild("SlidingArea").GetComponent(); // scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent(); _itemsPanelRT = _scrollPanelRT.FindChild("Items").GetComponent(); //itemPanelLayout = itemsPanelRT.gameObject.GetComponent(); _canvas = GetComponentInParent(); _canvasRT = _canvas.GetComponent(); _scrollRect = _scrollPanelRT.GetComponent(); _scrollRect.scrollSensitivity = _rectTransform.sizeDelta.y / 2; _scrollRect.movementType = ScrollRect.MovementType.Clamped; _scrollRect.content = _itemsPanelRT; itemTemplate = _rectTransform.FindChild("ItemTemplate").gameObject; itemTemplate.SetActive(false); } catch (System.NullReferenceException ex) { Debug.LogException(ex); Debug.LogError("Something is setup incorrectly with the dropdownlist component causing a Null Refernece Exception"); success = false; } panelObjects = new Dictionary(); _prunedPanelItems = new List(); _panelItems = AvailableOptions.ToList(); RebuildPanel(); //RedrawPanel(); - causes an initialisation failure in U5 return success; } /* currently just using items in the list instead of being able to add to it. public void AddItems(params object[] list) { List ddItems = new List(); foreach (var obj in list) { if (obj is DropDownListItem) { ddItems.Add((DropDownListItem)obj); } else if (obj is string) { ddItems.Add(new DropDownListItem(caption: (string)obj)); } else if (obj is Sprite) { ddItems.Add(new DropDownListItem(image: (Sprite)obj)); } else { throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed"); } } Items.AddRange(ddItems); Items = Items.Distinct().ToList();//remove any duplicates RebuildPanel(); } */ /// /// Rebuilds the contents of the panel in response to items being added. /// private void RebuildPanel() { //panel starts with all options _panelItems.Clear(); foreach (string option in AvailableOptions) { _panelItems.Add(option.ToLower()); } _panelItems.Sort(); _prunedPanelItems.Clear(); List itemObjs = new List(panelObjects.Values); panelObjects.Clear(); int indx = 0; while (itemObjs.Count < AvailableOptions.Count) { GameObject newItem = Instantiate(itemTemplate) as GameObject; newItem.name = "Item " + indx; newItem.transform.SetParent(_itemsPanelRT, false); itemObjs.Add(newItem); indx++; } for (int i = 0; i < itemObjs.Count; i++) { itemObjs[i].SetActive(i <= AvailableOptions.Count); if (i < AvailableOptions.Count) { itemObjs[i].name = "Item " + i + " " + _panelItems[i]; itemObjs[i].transform.FindChild("Text").GetComponent().text = _panelItems[i]; //set the text value Button itemBtn = itemObjs[i].GetComponent