Updated panel drawing for ComboBox controls and added DropdownOffset

Resolves: https://github.com/Unity-UI-Extensions/com.unity.uiextensions/issues/393
pull/413/head
Simon Jackson 2023-01-01 16:52:08 +00:00
parent 9b23206c9a
commit fe97fa7599
3 changed files with 178 additions and 238 deletions

View File

@ -13,7 +13,7 @@ namespace UnityEngine.UI.Extensions
} }
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[AddComponentMenu("UI/Extensions/AutoComplete ComboBox")] [AddComponentMenu("UI/Extensions/ComboBox/AutoComplete ComboBox")]
public class AutoCompleteComboBox : MonoBehaviour public class AutoCompleteComboBox : MonoBehaviour
{ {
public Color disabledTextColor; public Color disabledTextColor;
@ -26,15 +26,12 @@ namespace UnityEngine.UI.Extensions
/// </summary> /// </summary>
public List<string> AvailableOptions; public List<string> AvailableOptions;
//private bool isInitialized = false;
private bool _isPanelActive = false; private bool _isPanelActive = false;
private bool _hasDrawnOnce = false; private bool _hasDrawnOnce = false;
private InputField _mainInput; private InputField _mainInput;
private RectTransform _inputRT; private RectTransform _inputRT;
//private Button _arrow_Button;
private RectTransform _rectTransform; private RectTransform _rectTransform;
private RectTransform _overlayRT; private RectTransform _overlayRT;
@ -57,6 +54,9 @@ namespace UnityEngine.UI.Extensions
public string Text { get; private set; } public string Text { get; private set; }
[SerializeField]
private float dropdownOffset;
[SerializeField] [SerializeField]
private float _scrollBarWidth = 20.0f; private float _scrollBarWidth = 20.0f;
public float ScrollBarWidth public float ScrollBarWidth
@ -69,9 +69,6 @@ namespace UnityEngine.UI.Extensions
} }
} }
// private int scrollOffset; //offset of the selected item
// private int _selectedIndex = 0;
[SerializeField] [SerializeField]
private int _itemsToDisplay; private int _itemsToDisplay;
public int ItemsToDisplay public int ItemsToDisplay
@ -89,20 +86,21 @@ namespace UnityEngine.UI.Extensions
[SerializeField] [SerializeField]
[Tooltip("Change input text color based on matching items")] [Tooltip("Change input text color based on matching items")]
private bool _ChangeInputTextColorBasedOnMatchingItems = false; private bool _ChangeInputTextColorBasedOnMatchingItems = false;
public bool InputColorMatching{ public bool InputColorMatching
{
get { return _ChangeInputTextColorBasedOnMatchingItems; } get { return _ChangeInputTextColorBasedOnMatchingItems; }
set set
{ {
_ChangeInputTextColorBasedOnMatchingItems = value; _ChangeInputTextColorBasedOnMatchingItems = value;
if (_ChangeInputTextColorBasedOnMatchingItems) { if (_ChangeInputTextColorBasedOnMatchingItems)
SetInputTextColor (); {
SetInputTextColor();
} }
} }
} }
public float DropdownOffset = 10f; public float DropdownOffset = 10f;
//TODO design as foldout for Inspector
public Color ValidSelectionTextColor = Color.green; public Color ValidSelectionTextColor = Color.green;
public Color MatchingItemsRemainingTextColor = Color.black; public Color MatchingItemsRemainingTextColor = Color.black;
public Color NoItemsRemainingTextColor = Color.red; public Color NoItemsRemainingTextColor = Color.red;
@ -115,16 +113,13 @@ namespace UnityEngine.UI.Extensions
private bool _selectionIsValid = false; private bool _selectionIsValid = false;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string, bool> { public class SelectionChangedEvent : Events.UnityEvent<string, bool> { }
}
[System.Serializable] [System.Serializable]
public class SelectionTextChangedEvent : UnityEngine.Events.UnityEvent<string> { public class SelectionTextChangedEvent : Events.UnityEvent<string> { }
}
[System.Serializable] [System.Serializable]
public class SelectionValidityChangedEvent : UnityEngine.Events.UnityEvent<bool> { public class SelectionValidityChangedEvent : Events.UnityEvent<bool> { }
}
// fires when input text is changed; // fires when input text is changed;
public SelectionTextChangedEvent OnSelectionTextChanged; public SelectionTextChangedEvent OnSelectionTextChanged;
@ -140,9 +135,10 @@ namespace UnityEngine.UI.Extensions
public void Start() public void Start()
{ {
if (SelectFirstItemOnStart && AvailableOptions.Count > 0) { if (SelectFirstItemOnStart && AvailableOptions.Count > 0)
ToggleDropdownPanel (false); {
OnItemClicked (AvailableOptions [0]); ToggleDropdownPanel(false);
OnItemClicked(AvailableOptions[0]);
} }
RedrawPanel(); RedrawPanel();
} }
@ -156,8 +152,6 @@ namespace UnityEngine.UI.Extensions
_inputRT = _rectTransform.Find("InputField").GetComponent<RectTransform>(); _inputRT = _rectTransform.Find("InputField").GetComponent<RectTransform>();
_mainInput = _inputRT.GetComponent<InputField>(); _mainInput = _inputRT.GetComponent<InputField>();
//_arrow_Button = _rectTransform.FindChild ("ArrowBtn").GetComponent<Button> ();
_overlayRT = _rectTransform.Find("Overlay").GetComponent<RectTransform>(); _overlayRT = _rectTransform.Find("Overlay").GetComponent<RectTransform>();
_overlayRT.gameObject.SetActive(false); _overlayRT.gameObject.SetActive(false);
@ -167,7 +161,6 @@ namespace UnityEngine.UI.Extensions
_slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>(); _slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>();
_scrollHandleRT = _slidingAreaRT.Find("Handle").GetComponent<RectTransform>(); _scrollHandleRT = _slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
_itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>(); _itemsPanelRT = _scrollPanelRT.Find("Items").GetComponent<RectTransform>();
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
_canvas = GetComponentInParent<Canvas>(); _canvas = GetComponentInParent<Canvas>();
_canvasRT = _canvas.GetComponent<RectTransform>(); _canvasRT = _canvas.GetComponent<RectTransform>();
@ -231,15 +224,8 @@ namespace UnityEngine.UI.Extensions
/// <param name="newOptions">New entries.</param> /// <param name="newOptions">New entries.</param>
public void SetAvailableOptions(List<string> newOptions) public void SetAvailableOptions(List<string> newOptions)
{ {
var uniqueOptions = newOptions.Distinct().ToList(); var uniqueOptions = newOptions.Distinct().ToArray();
if (newOptions.Count != uniqueOptions.Count) SetAvailableOptions(uniqueOptions);
{
Debug.LogWarning($"{nameof(AutoCompleteComboBox)}.{nameof(SetAvailableOptions)}: items may only exists once. {newOptions.Count - uniqueOptions.Count} duplicates.");
}
this.AvailableOptions.Clear();
this.AvailableOptions = uniqueOptions;
this.RebuildPanel();
} }
/// <summary> /// <summary>
@ -255,18 +241,21 @@ namespace UnityEngine.UI.Extensions
} }
this.AvailableOptions.Clear(); this.AvailableOptions.Clear();
for (int i = 0; i < newOptions.Length; i++) for (int i = 0; i < newOptions.Length; i++)
{ {
this.AvailableOptions.Add(newOptions[i]); this.AvailableOptions.Add(newOptions[i]);
} }
this.RebuildPanel(); this.RebuildPanel();
this.RedrawPanel();
} }
public void ResetItems() public void ResetItems()
{ {
AvailableOptions.Clear(); AvailableOptions.Clear();
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -322,7 +311,7 @@ namespace UnityEngine.UI.Extensions
panelObjects[_panelItems[i]] = itemObjs[i]; panelObjects[_panelItems[i]] = itemObjs[i];
} }
} }
SetInputTextColor (); SetInputTextColor();
} }
/// <summary> /// <summary>
@ -337,35 +326,6 @@ namespace UnityEngine.UI.Extensions
ToggleDropdownPanel(true); ToggleDropdownPanel(true);
} }
//private void UpdateSelected()
//{
// SelectedItem = (_selectedIndex > -1 && _selectedIndex < Items.Count) ? Items[_selectedIndex] : null;
// if (SelectedItem == null) return;
// bool hasImage = SelectedItem.Image != null;
// if (hasImage)
// {
// mainButton.img.sprite = SelectedItem.Image;
// mainButton.img.color = Color.white;
// //if (Interactable) mainButton.img.color = Color.white;
// //else mainButton.img.color = new Color(1, 1, 1, .5f);
// }
// else
// {
// mainButton.img.sprite = null;
// }
// mainButton.txt.text = SelectedItem.Caption;
// //update selected index color
// for (int i = 0; i < itemsPanelRT.childCount; i++)
// {
// panelItems[i].btnImg.color = (_selectedIndex == i) ? mainButton.btn.colors.highlightedColor : new Color(0, 0, 0, 0);
// }
//}
private void RedrawPanel() private void RedrawPanel()
{ {
float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items
@ -376,23 +336,26 @@ namespace UnityEngine.UI.Extensions
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay var itemsRemaining = _panelItems.Count - ItemsToDisplay;
itemsRemaining = itemsRemaining < 0 ? 0 : itemsRemaining;
_scrollPanelRT.SetParent(transform, true);
_scrollPanelRT.anchoredPosition = _displayPanelAbove ? _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, DropdownOffset + _rectTransform.sizeDelta.y * _panelItems.Count - 1) : new Vector2(0, dropdownOffset + _rectTransform.sizeDelta.y * (_panelItems.Count - itemsRemaining) - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y); new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);
_overlayRT.SetParent(transform, true);//reattach to this object _overlayRT.SetParent(transform, true);
_scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay _scrollPanelRT.SetParent(_overlayRT, true);
} }
if (_panelItems.Count < 1) return; if (_panelItems.Count < 1) return;
float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + DropdownOffset; float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + dropdownOffset;
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
@ -413,7 +376,6 @@ namespace UnityEngine.UI.Extensions
Text = currText; Text = currText;
PruneItems(currText); PruneItems(currText);
RedrawPanel(); RedrawPanel();
//Debug.Log("value changed to: " + currText);
if (_panelItems.Count == 0) if (_panelItems.Count == 0)
{ {
@ -425,31 +387,37 @@ namespace UnityEngine.UI.Extensions
ToggleDropdownPanel(false); ToggleDropdownPanel(false);
} }
bool validity_changed = (_panelItems.Contains (Text) != _selectionIsValid); bool validity_changed = (_panelItems.Contains(Text) != _selectionIsValid);
_selectionIsValid = _panelItems.Contains (Text); _selectionIsValid = _panelItems.Contains(Text);
OnSelectionChanged.Invoke (Text, _selectionIsValid); OnSelectionChanged.Invoke(Text, _selectionIsValid);
OnSelectionTextChanged.Invoke (Text); OnSelectionTextChanged.Invoke(Text);
if(validity_changed){ if (validity_changed)
OnSelectionValidityChanged.Invoke (_selectionIsValid); {
OnSelectionValidityChanged.Invoke(_selectionIsValid);
} }
SetInputTextColor (); SetInputTextColor();
} }
private void SetInputTextColor(){ private void SetInputTextColor()
if (InputColorMatching) { {
if (_selectionIsValid) { if (InputColorMatching)
{
if (_selectionIsValid)
{
_mainInput.textComponent.color = ValidSelectionTextColor; _mainInput.textComponent.color = ValidSelectionTextColor;
} else if (_panelItems.Count > 0) { }
else if (_panelItems.Count > 0)
{
_mainInput.textComponent.color = MatchingItemsRemainingTextColor; _mainInput.textComponent.color = MatchingItemsRemainingTextColor;
} else { }
else
{
_mainInput.textComponent.color = NoItemsRemainingTextColor; _mainInput.textComponent.color = NoItemsRemainingTextColor;
} }
} }
} }
/// <summary> /// <summary>
/// Toggle the drop down list /// Toggle the drop down list
/// </summary> /// </summary>

View File

@ -7,11 +7,11 @@ using System.Linq;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
{ {
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[AddComponentMenu("UI/Extensions/ComboBox")] [AddComponentMenu("UI/Extensions/ComboBox/ComboBox")]
public class ComboBox : MonoBehaviour public class ComboBox : MonoBehaviour
{ {
public Color disabledTextColor; public Color disabledTextColor;
public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it public DropDownListItem SelectedItem { get; private set; }
public List<string> AvailableOptions; public List<string> AvailableOptions;
@ -21,17 +21,15 @@ namespace UnityEngine.UI.Extensions
[SerializeField] [SerializeField]
private int _itemsToDisplay; private int _itemsToDisplay;
//Sorting disabled as it causes issues. [SerializeField]
//[SerializeField] private float dropdownOffset;
//private bool _sortItems = true;
[SerializeField] [SerializeField]
private bool _displayPanelAbove = false; private bool _displayPanelAbove = false;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<string> public class SelectionChangedEvent : Events.UnityEvent<string> { }
{
}
// fires when item is changed; // fires when item is changed;
public SelectionChangedEvent OnSelectionChanged; public SelectionChangedEvent OnSelectionChanged;
@ -74,9 +72,6 @@ namespace UnityEngine.UI.Extensions
} }
} }
// private int scrollOffset; //offset of the selected item
// private int _selectedIndex = 0;
public int ItemsToDisplay public int ItemsToDisplay
{ {
get { return _itemsToDisplay; } get { return _itemsToDisplay; }
@ -157,26 +152,34 @@ namespace UnityEngine.UI.Extensions
public void SetAvailableOptions(List<string> newOptions) public void SetAvailableOptions(List<string> newOptions)
{ {
AvailableOptions.Clear(); var uniqueOptions = newOptions.Distinct().ToArray();
AvailableOptions = newOptions; SetAvailableOptions(uniqueOptions);
RebuildPanel();
} }
public void SetAvailableOptions(string[] newOptions) public void SetAvailableOptions(string[] newOptions)
{ {
AvailableOptions.Clear(); var uniqueOptions = newOptions.Distinct().ToList();
if (newOptions.Length != uniqueOptions.Count)
{
Debug.LogWarning($"{nameof(ComboBox)}.{nameof(SetAvailableOptions)}: items may only exists once. {newOptions.Length - uniqueOptions.Count} duplicates.");
}
this.AvailableOptions.Clear();
for (int i = 0; i < newOptions.Length; i++) for (int i = 0; i < newOptions.Length; i++)
{ {
AvailableOptions.Add(newOptions[i]); this.AvailableOptions.Add(newOptions[i]);
} }
RebuildPanel();
this.RebuildPanel();
this.RedrawPanel();
} }
public void ResetItems() public void ResetItems()
{ {
AvailableOptions.Clear(); AvailableOptions.Clear();
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -190,7 +193,6 @@ namespace UnityEngine.UI.Extensions
{ {
_panelItems.Add(option.ToLower()); _panelItems.Add(option.ToLower());
} }
//if(_sortItems) _panelItems.Sort();
List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values); List<GameObject> itemObjs = new List<GameObject>(panelObjects.Values);
panelObjects.Clear(); panelObjects.Clear();
@ -237,35 +239,6 @@ namespace UnityEngine.UI.Extensions
ToggleDropdownPanel(true); ToggleDropdownPanel(true);
} }
//private void UpdateSelected()
//{
// SelectedItem = (_selectedIndex > -1 && _selectedIndex < Items.Count) ? Items[_selectedIndex] : null;
// if (SelectedItem == null) return;
// bool hasImage = SelectedItem.Image != null;
// if (hasImage)
// {
// mainButton.img.sprite = SelectedItem.Image;
// mainButton.img.color = Color.white;
// //if (Interactable) mainButton.img.color = Color.white;
// //else mainButton.img.color = new Color(1, 1, 1, .5f);
// }
// else
// {
// mainButton.img.sprite = null;
// }
// mainButton.txt.text = SelectedItem.Caption;
// //update selected index color
// for (int i = 0; i < itemsPanelRT.childCount; i++)
// {
// panelItems[i].btnImg.color = (_selectedIndex == i) ? mainButton.btn.colors.highlightedColor : new Color(0, 0, 0, 0);
// }
//}
private void RedrawPanel() private void RedrawPanel()
{ {
float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items
@ -276,23 +249,26 @@ namespace UnityEngine.UI.Extensions
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y); _inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay var itemsRemaining = _panelItems.Count - ItemsToDisplay;
itemsRemaining = itemsRemaining < 0 ? 0 : itemsRemaining;
_scrollPanelRT.SetParent(transform, true);
_scrollPanelRT.anchoredPosition = _displayPanelAbove ? _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, _rectTransform.sizeDelta.y * ItemsToDisplay - 1) : new Vector2(0, dropdownOffset + _rectTransform.sizeDelta.y * (_panelItems.Count - itemsRemaining) - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y); new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);
_overlayRT.SetParent(transform, true);//reattach to this object _overlayRT.SetParent(transform, true);
_scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay _scrollPanelRT.SetParent(_overlayRT, true);
} }
if (_panelItems.Count < 1) return; if (_panelItems.Count < 1) return;
float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count); float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + dropdownOffset;
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
@ -312,7 +288,6 @@ namespace UnityEngine.UI.Extensions
{ {
Text = currText; Text = currText;
RedrawPanel(); RedrawPanel();
//Debug.Log("value changed to: " + currText);
if (_panelItems.Count == 0) if (_panelItems.Count == 0)
{ {

View File

@ -1,7 +1,6 @@
///Credit perchik ///Credit perchik
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/ ///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.Collections.Generic;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
@ -10,7 +9,7 @@ namespace UnityEngine.UI.Extensions
/// Extension to the UI class which creates a dropdown list /// Extension to the UI class which creates a dropdown list
/// </summary> /// </summary>
[RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(RectTransform))]
[AddComponentMenu("UI/Extensions/Dropdown List")] [AddComponentMenu("UI/Extensions/ComboBox/Dropdown List")]
public class DropDownList : MonoBehaviour public class DropDownList : MonoBehaviour
{ {
public Color disabledTextColor; public Color disabledTextColor;
@ -42,6 +41,9 @@ namespace UnityEngine.UI.Extensions
private GameObject _itemTemplate; private GameObject _itemTemplate;
[SerializeField]
private float dropdownOffset;
[SerializeField] [SerializeField]
private float _scrollBarWidth = 20.0f; private float _scrollBarWidth = 20.0f;
public float ScrollBarWidth public float ScrollBarWidth
@ -74,12 +76,8 @@ namespace UnityEngine.UI.Extensions
[SerializeField] [SerializeField]
private bool _displayPanelAbove = false; private bool _displayPanelAbove = false;
[SerializeField]
[Tooltip("Override the Text width for the values.")]
private bool _overrideTextWidth = true;
[System.Serializable] [System.Serializable]
public class SelectionChangedEvent : UnityEngine.Events.UnityEvent<int> { } public class SelectionChangedEvent : Events.UnityEvent<int> { }
// fires when item is changed; // fires when item is changed;
public SelectionChangedEvent OnSelectionChanged; public SelectionChangedEvent OnSelectionChanged;
@ -103,8 +101,6 @@ namespace UnityEngine.UI.Extensions
_overlayRT = _rectTransform.Find("Overlay").GetComponent<RectTransform>(); _overlayRT = _rectTransform.Find("Overlay").GetComponent<RectTransform>();
_overlayRT.gameObject.SetActive(false); _overlayRT.gameObject.SetActive(false);
_scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>(); _scrollPanelRT = _overlayRT.Find("ScrollPanel").GetComponent<RectTransform>();
_scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>(); _scrollBarRT = _scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
_slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>(); _slidingAreaRT = _scrollBarRT.Find("SlidingArea").GetComponent<RectTransform>();
@ -120,7 +116,6 @@ namespace UnityEngine.UI.Extensions
_scrollRect.movementType = ScrollRect.MovementType.Clamped; _scrollRect.movementType = ScrollRect.MovementType.Clamped;
_scrollRect.content = _itemsPanelRT; _scrollRect.content = _itemsPanelRT;
_itemTemplate = _rectTransform.Find("ItemTemplate").gameObject; _itemTemplate = _rectTransform.Find("ItemTemplate").gameObject;
_itemTemplate.SetActive(false); _itemTemplate.SetActive(false);
} }
@ -171,6 +166,7 @@ namespace UnityEngine.UI.Extensions
} }
Items.AddRange(ddItems); Items.AddRange(ddItems);
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -181,6 +177,7 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Add(item); Items.Add(item);
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -191,6 +188,7 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Add(new DropDownListItem(caption: (string)item)); Items.Add(new DropDownListItem(caption: (string)item));
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -201,6 +199,7 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Add(new DropDownListItem(image: (Sprite)item)); Items.Add(new DropDownListItem(image: (Sprite)item));
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -211,6 +210,7 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Remove(item); Items.Remove(item);
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -221,6 +221,7 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Remove(new DropDownListItem(caption: (string)item)); Items.Remove(new DropDownListItem(caption: (string)item));
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -231,12 +232,14 @@ namespace UnityEngine.UI.Extensions
{ {
Items.Remove(new DropDownListItem(image: (Sprite)item)); Items.Remove(new DropDownListItem(image: (Sprite)item));
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
public void ResetItems() public void ResetItems()
{ {
Items.Clear(); Items.Clear();
RebuildPanel(); RebuildPanel();
RedrawPanel();
} }
/// <summary> /// <summary>
@ -302,9 +305,6 @@ namespace UnityEngine.UI.Extensions
{ {
_mainButton.img.sprite = SelectedItem.Image; _mainButton.img.sprite = SelectedItem.Image;
_mainButton.img.color = Color.white; _mainButton.img.color = Color.white;
//if (Interactable) mainButton.img.color = Color.white;
//else mainButton.img.color = new Color(1, 1, 1, .5f);
} }
else else
{ {
@ -316,7 +316,6 @@ namespace UnityEngine.UI.Extensions
//update selected index color //update selected index color
if (OverrideHighlighted) if (OverrideHighlighted)
{ {
for (int i = 0; i < _itemsPanelRT.childCount; i++) for (int i = 0; i < _itemsPanelRT.childCount; i++)
{ {
_panelItems[i].btnImg.color = (_selectedIndex == i) ? _mainButton.btn.colors.highlightedColor : new Color(0, 0, 0, 0); _panelItems[i].btnImg.color = (_selectedIndex == i) ? _mainButton.btn.colors.highlightedColor : new Color(0, 0, 0, 0);
@ -324,38 +323,36 @@ namespace UnityEngine.UI.Extensions
} }
} }
private void RedrawPanel() private void RedrawPanel()
{ {
float scrollbarWidth = Items.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items float scrollbarWidth = _panelItems.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items
_scrollBarRT.gameObject.SetActive(_panelItems.Count > ItemsToDisplay);
if (!_hasDrawnOnce || _rectTransform.sizeDelta != _mainButton.rectTransform.sizeDelta) if (!_hasDrawnOnce || _rectTransform.sizeDelta != _mainButton.rectTransform.sizeDelta)
{ {
_hasDrawnOnce = true; _hasDrawnOnce = true;
_mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
_mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y); _mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
if (_overrideTextWidth)
{
_mainButton.txt.rectTransform.offsetMax = new Vector2(4, 0);
}
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay var itemsRemaining = _panelItems.Count - ItemsToDisplay;
itemsRemaining = itemsRemaining < 0 ? 0 : itemsRemaining;
_scrollPanelRT.SetParent(transform, true);
_scrollPanelRT.anchoredPosition = _displayPanelAbove ? _scrollPanelRT.anchoredPosition = _displayPanelAbove ?
new Vector2(0, _rectTransform.sizeDelta.y * ItemsToDisplay - 1) : new Vector2(0, dropdownOffset + _rectTransform.sizeDelta.y * (_panelItems.Count - itemsRemaining) - 1) :
new Vector2(0, -_rectTransform.sizeDelta.y); new Vector2(0, -_rectTransform.sizeDelta.y);
//make the overlay fill the screen //make the overlay fill the screen
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object _overlayRT.SetParent(_canvas.transform, false);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y); _overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);
_overlayRT.SetParent(transform, true);//reattach to this object _overlayRT.SetParent(transform, true);
_scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay _scrollPanelRT.SetParent(_overlayRT, true);
} }
if (Items.Count < 1) return; if (_panelItems.Count < 1) return;
float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, Items.Count); float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count) + dropdownOffset;
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x); _scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);