Added new combo box and Editor Menu option
Added FlowLayout and AimerInput module but yet to test. --HG-- branch : developpull/413/head
parent
a1f391f365
commit
744c52b370
|
@ -0,0 +1,4 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c35f61edc180166489847c79f4b8ea46
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
|
@ -0,0 +1,92 @@
|
||||||
|
/// Credit Chris Trueman
|
||||||
|
/// Sourced from - http://forum.unity3d.com/threads/use-reticle-like-mouse-for-worldspace-uis.295271/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UnityEngine.EventSystems.Extensions
|
||||||
|
{
|
||||||
|
|
||||||
|
[RequireComponent(typeof(EventSystem))]
|
||||||
|
[AddComponentMenu("UI/Extensions/Aimer Input Module")]
|
||||||
|
public class AimerInputModule : BaseInputModule
|
||||||
|
{
|
||||||
|
public string ActivateAxis = "Interact";
|
||||||
|
|
||||||
|
public static GameObject ObjectUnderAimer;
|
||||||
|
|
||||||
|
public static Camera CurrentPlayerCamera;
|
||||||
|
|
||||||
|
protected AimerInputModule() { }
|
||||||
|
|
||||||
|
public void Awake()
|
||||||
|
{
|
||||||
|
var StandAloneSystem = GetComponent<StandaloneInputModule>();
|
||||||
|
if (StandAloneSystem != null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Aimer Input Module is incompatible with the StandAloneInputSystem, please remove it from the Event System in this scene");
|
||||||
|
}
|
||||||
|
if (!CurrentPlayerCamera)
|
||||||
|
{
|
||||||
|
CurrentPlayerCamera = Camera.main;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateModule()
|
||||||
|
{
|
||||||
|
GetObjectUnderAimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
if (ObjectUnderAimer)
|
||||||
|
{
|
||||||
|
if (Input.GetButtonDown(ActivateAxis))
|
||||||
|
{
|
||||||
|
BaseEventData eventData = GetBaseEventData();
|
||||||
|
eventData.selectedObject = ObjectUnderAimer;
|
||||||
|
ExecuteEvents.Execute(ObjectUnderAimer, eventData, ExecuteEvents.submitHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RaycastResult> results = new List<RaycastResult>();
|
||||||
|
|
||||||
|
private bool GetObjectUnderAimer()
|
||||||
|
{
|
||||||
|
PointerEventData pointerData = new PointerEventData(eventSystem);
|
||||||
|
pointerData.worldPosition = CurrentPlayerCamera.transform.position;
|
||||||
|
|
||||||
|
eventSystem.RaycastAll(pointerData, results);
|
||||||
|
|
||||||
|
if (results.Count > 0)
|
||||||
|
{
|
||||||
|
RaycastResult rayResult = FindFirstRaycast(results);
|
||||||
|
if (ObjectUnderAimer != rayResult.gameObject)
|
||||||
|
{
|
||||||
|
Debug.Log(rayResult.gameObject.name);
|
||||||
|
ObjectUnderAimer = rayResult.gameObject;
|
||||||
|
BaseEventData eData = GetBaseEventData();
|
||||||
|
eData.selectedObject = ObjectUnderAimer;
|
||||||
|
ExecuteEvents.Execute(ObjectUnderAimer, eData, ExecuteEvents.pointerEnterHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We didn't hit anything
|
||||||
|
|
||||||
|
if (ObjectUnderAimer)
|
||||||
|
{
|
||||||
|
BaseEventData eData = GetBaseEventData();
|
||||||
|
eData.selectedObject = ObjectUnderAimer;
|
||||||
|
|
||||||
|
ExecuteEvents.Execute(ObjectUnderAimer, eData, ExecuteEvents.pointerExitHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
ObjectUnderAimer = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 33a5d65e2f7d10648af0fde6d2de99cc
|
guid: f7d3d69aa5226dc4493464d3b5e4ddc3
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
|
@ -1,13 +0,0 @@
|
||||||
///Credit perchik
|
|
||||||
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/
|
|
||||||
|
|
||||||
using UnityEngine;
|
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
public class ClickBtn : MonoBehaviour
|
|
||||||
{
|
|
||||||
public void Click()
|
|
||||||
{
|
|
||||||
Debug.Log("Clicked");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,616 +10,335 @@ namespace UnityEngine.UI.Extensions
|
||||||
[AddComponentMenu("UI/Extensions/ComboBox")]
|
[AddComponentMenu("UI/Extensions/ComboBox")]
|
||||||
public class ComboBox : MonoBehaviour
|
public class ComboBox : MonoBehaviour
|
||||||
{
|
{
|
||||||
#region declarations
|
public Color disabledTextColor;
|
||||||
#region private members
|
public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it
|
||||||
|
|
||||||
private bool _isActive = false; //is the drop down panel active
|
public List<string> AvailableOptions;
|
||||||
|
|
||||||
private Button comboBtn;
|
public System.Action<int> OnSelectionChanged; // fires when selection is changed;
|
||||||
private Image comboBtnImg;
|
|
||||||
private Text comboBtnText;
|
|
||||||
|
|
||||||
private Button overlayBtn;
|
//private bool isInitialized = false;
|
||||||
|
private bool _isPanelActive = false;
|
||||||
|
private bool _hasDrawnOnce = false;
|
||||||
|
|
||||||
private GridLayoutGroup itemLayout;
|
private InputField _mainInput;
|
||||||
|
private RectTransform _inputRT;
|
||||||
|
|
||||||
|
|
||||||
private float _scrollbarWidth = 20.0f;
|
|
||||||
|
|
||||||
private int scrollOffset; //offset of the selected item
|
|
||||||
|
|
||||||
private int _itemsToDisplay = 4; //how many items to show in the dropdown panel
|
|
||||||
|
|
||||||
private bool _hideFirstItem = false; //lets us hide the prompt after something is chosen
|
|
||||||
|
|
||||||
private int _selectedIndex = 0;
|
|
||||||
|
|
||||||
private List<ComboBoxItem> _items; //conceptual items in the list
|
|
||||||
|
|
||||||
private bool _interactable = true;
|
|
||||||
|
|
||||||
private Canvas _canvas;
|
|
||||||
|
|
||||||
#region private rect transforms
|
|
||||||
/// <remarks> All of these have to be properties so that the editor script can access them</remarks>
|
|
||||||
|
|
||||||
private RectTransform _overlay; //overlayRT is a screensized box to handle clicks *not* on the button. (although this might have to change with multiple things on the screen.
|
|
||||||
private RectTransform overlayRT
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_overlay == null)
|
|
||||||
{
|
|
||||||
_overlay = rectTransform.FindChild("Overlay").GetComponent<RectTransform>();
|
|
||||||
overlayBtn = _overlay.gameObject.GetComponent<Button>();
|
|
||||||
}
|
|
||||||
return _overlay;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_overlay = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform _rectTransform;
|
private RectTransform _rectTransform;
|
||||||
private RectTransform rectTransform
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_rectTransform == null)
|
|
||||||
{
|
|
||||||
_rectTransform = GetComponent<RectTransform>();
|
|
||||||
}
|
|
||||||
return _rectTransform;
|
|
||||||
}
|
|
||||||
set { _rectTransform = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform _comboBtnRT;
|
|
||||||
private RectTransform comboBtnRT
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_comboBtnRT == null)
|
|
||||||
{
|
|
||||||
_comboBtnRT = rectTransform.FindChild("ComboButton").GetComponent<RectTransform>();
|
|
||||||
comboBtn = _comboBtnRT.GetComponent<Button>();
|
|
||||||
comboBtnImg = _comboBtnRT.FindChild("Image").GetComponent<Image>();
|
|
||||||
comboBtnText = _comboBtnRT.FindChild("Text").GetComponent<Text>();
|
|
||||||
}
|
|
||||||
return _comboBtnRT;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_comboBtnRT = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private GameObject _scrollPanel;
|
|
||||||
private GameObject scrollPanel
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_scrollPanel == null)
|
|
||||||
_scrollPanel = overlayRT.FindChild("ScrollPanel").gameObject;
|
|
||||||
return _scrollPanel;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_scrollPanel = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private RectTransform _overlayRT;
|
||||||
private RectTransform _scrollPanelRT;
|
private RectTransform _scrollPanelRT;
|
||||||
private RectTransform scrollPanelRT
|
private RectTransform _scrollBarRT;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_scrollPanelRT == null)
|
|
||||||
_scrollPanelRT = scrollPanel.GetComponent<RectTransform>();
|
|
||||||
return _scrollPanelRT;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_scrollPanelRT = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform _itemsRT;
|
|
||||||
private RectTransform itemsRT
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_itemsRT == null)
|
|
||||||
{
|
|
||||||
_itemsRT = scrollPanelRT.Find("Items").GetComponent<RectTransform>();
|
|
||||||
itemLayout = _itemsRT.gameObject.GetComponent<GridLayoutGroup>();
|
|
||||||
}
|
|
||||||
return _itemsRT;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_itemsRT = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform _scrollbarRT;
|
|
||||||
private RectTransform scrollbarRT
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_scrollbarRT == null)
|
|
||||||
_scrollbarRT = scrollPanelRT.Find("Scrollbar").GetComponent<RectTransform>();
|
|
||||||
return _scrollbarRT;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_scrollbarRT = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RectTransform _slidingAreaRT;
|
private RectTransform _slidingAreaRT;
|
||||||
private RectTransform slidingAreaRT
|
// private RectTransform scrollHandleRT;
|
||||||
|
private RectTransform _itemsPanelRT;
|
||||||
|
private Canvas _canvas;
|
||||||
|
private RectTransform _canvasRT;
|
||||||
|
|
||||||
|
private ScrollRect _scrollRect;
|
||||||
|
|
||||||
|
private List<string> _panelItems; //items that will get shown in the dropdown
|
||||||
|
private List<string> _prunedPanelItems; //items that used to show in the dropdown
|
||||||
|
|
||||||
|
private Dictionary<string, GameObject> panelObjects;
|
||||||
|
|
||||||
|
private GameObject itemTemplate;
|
||||||
|
|
||||||
|
public string Text { get; private set; }
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private float _scrollBarWidth = 20.0f;
|
||||||
|
public float ScrollBarWidth
|
||||||
{
|
{
|
||||||
get
|
get { return _scrollBarWidth; }
|
||||||
{
|
|
||||||
if (_slidingAreaRT == null)
|
|
||||||
_slidingAreaRT = scrollbarRT.Find("SlidingArea").GetComponent<RectTransform>();
|
|
||||||
return _slidingAreaRT;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_slidingAreaRT = value;
|
_scrollBarWidth = value;
|
||||||
|
RedrawPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RectTransform _scrollHandleRT;
|
// private int scrollOffset; //offset of the selected item
|
||||||
private RectTransform scrollHandleRT
|
private int _selectedIndex = 0;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_scrollHandleRT == null)
|
|
||||||
_scrollHandleRT = slidingAreaRT.Find("Handle").GetComponent<RectTransform>();
|
|
||||||
return _scrollHandleRT;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_scrollHandleRT = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
#region public accessors
|
|
||||||
|
|
||||||
public string HeaderOption = "";
|
|
||||||
public Color32 disabledTextColor = new Color32(174, 174, 174, 255);
|
|
||||||
public bool Interactable
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _interactable;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_interactable = value;
|
|
||||||
|
|
||||||
comboBtn.interactable = _interactable;
|
|
||||||
if (comboBtnImg.sprite != null)
|
|
||||||
{
|
|
||||||
comboBtnImg.color = _interactable ?
|
|
||||||
comboBtn.colors.normalColor :
|
|
||||||
comboBtn.colors.disabledColor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
comboBtnImg.color = new Color(1, 1, 1, 0); //transparent
|
|
||||||
}
|
|
||||||
if (!Application.isPlaying)//stop it from messing up in the editor
|
|
||||||
return;
|
|
||||||
if (!_interactable && _isActive)
|
|
||||||
ToggleComboBox(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SelectedIndex
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _selectedIndex;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_selectedIndex == value)
|
|
||||||
return;
|
|
||||||
if (value > -1 && value < Items.Count)
|
|
||||||
{
|
|
||||||
_selectedIndex = value;
|
|
||||||
RefreshSelected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<ComboBoxItem> Items
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_items == null)
|
|
||||||
{
|
|
||||||
_items = new List<ComboBoxItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _items;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_items = value;
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HideFirstItem
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _hideFirstItem;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
scrollOffset--;
|
|
||||||
else
|
|
||||||
scrollOffset++;
|
|
||||||
_hideFirstItem = value;
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private int _itemsToDisplay;
|
||||||
public int ItemsToDisplay
|
public int ItemsToDisplay
|
||||||
{
|
{
|
||||||
get
|
get { return _itemsToDisplay; }
|
||||||
{
|
|
||||||
return _itemsToDisplay;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_itemsToDisplay == value)
|
|
||||||
return;
|
|
||||||
_itemsToDisplay = value;
|
_itemsToDisplay = value;
|
||||||
Refresh();
|
RedrawPanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Action<int> OnSelectionChanged;//fires when selection is changed.
|
public void Awake()
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region public methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Update the main button with the selected item's parameters
|
|
||||||
/// </summary>
|
|
||||||
public void RefreshSelected()
|
|
||||||
{
|
{
|
||||||
//get the selected item
|
Initialize();
|
||||||
ComboBoxItem item = (SelectedIndex > -1 && SelectedIndex < Items.Count) ? Items[SelectedIndex] : null;
|
}
|
||||||
if (item == null) return;
|
|
||||||
|
|
||||||
bool hasImage = (item.Image != null);
|
private bool Initialize()
|
||||||
comboBtnImg.sprite = hasImage ? item.Image : null;
|
{
|
||||||
comboBtnImg.color = !hasImage ? new Color(1, 1, 1, 0)//transparent if there's no image.
|
bool success = true;
|
||||||
: !Interactable ? new Color(1, 1, 1, .5f) //semitransparent if the combobox is disabled
|
try
|
||||||
: Color.white; //fully opaque if it has an image and the combobox is enabled
|
|
||||||
UpdateComboBoxText(comboBtnRT, hasImage);
|
|
||||||
comboBtnText.text = item.Caption;
|
|
||||||
|
|
||||||
comboBtn.onClick.RemoveAllListeners();
|
|
||||||
comboBtn.onClick.AddListener(() =>
|
|
||||||
{
|
{
|
||||||
ToggleComboBox(true);
|
_rectTransform = GetComponent<RectTransform>();
|
||||||
});
|
_inputRT = _rectTransform.FindChild("InputField").GetComponent<RectTransform>();
|
||||||
if (!Application.isPlaying) return; //if it was running in editor we stop here.
|
_mainInput = _inputRT.GetComponent<InputField>();
|
||||||
|
|
||||||
for (int i = 0; i < itemsRT.childCount; i++)
|
_overlayRT = _rectTransform.FindChild("Overlay").GetComponent<RectTransform>();
|
||||||
{
|
_overlayRT.gameObject.SetActive(false);
|
||||||
Image tempImg = itemsRT.GetChild(i).GetComponent<Image>();
|
|
||||||
tempImg.color = (SelectedIndex == (i + (HideFirstItem ? 1 : 0))) ? comboBtn.colors.highlightedColor : comboBtn.colors.normalColor;
|
|
||||||
|
_scrollPanelRT = _overlayRT.FindChild("ScrollPanel").GetComponent<RectTransform>();
|
||||||
|
_scrollBarRT = _scrollPanelRT.FindChild("Scrollbar").GetComponent<RectTransform>();
|
||||||
|
_slidingAreaRT = _scrollBarRT.FindChild("SlidingArea").GetComponent<RectTransform>();
|
||||||
|
// scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent<RectTransform>();
|
||||||
|
_itemsPanelRT = _scrollPanelRT.FindChild("Items").GetComponent<RectTransform>();
|
||||||
|
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
|
||||||
|
|
||||||
|
_canvas = GetComponentInParent<Canvas>();
|
||||||
|
_canvasRT = _canvas.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
_scrollRect = _scrollPanelRT.GetComponent<ScrollRect>();
|
||||||
|
_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<string, GameObject>();
|
||||||
|
|
||||||
|
_prunedPanelItems = new List<string>();
|
||||||
|
_panelItems = AvailableOptions.ToList();
|
||||||
|
|
||||||
|
RebuildPanel();
|
||||||
|
RedrawPanel();
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/* currently just using items in the list instead of being able to add to it.
|
||||||
/// what happens when an item in the list is selected
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index"></param>
|
|
||||||
public void OnItemClicked(int index)
|
|
||||||
{
|
|
||||||
Debug.Log("item " + index + " was clicked");
|
|
||||||
bool selectionChanged = (index != SelectedIndex);
|
|
||||||
SelectedIndex = index;
|
|
||||||
ToggleComboBox(true);
|
|
||||||
if (selectionChanged && OnSelectionChanged != null) OnSelectionChanged(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add items to the dropdown list. Accepts any object of type ComboBoxItem, String, or Image
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="list"></param>
|
|
||||||
public void AddItems(params object[] list)
|
public void AddItems(params object[] list)
|
||||||
{
|
{
|
||||||
List<ComboBoxItem> cbItems = new List<ComboBoxItem>();
|
List<DropDownListItem> ddItems = new List<DropDownListItem>();
|
||||||
foreach (var obj in list)
|
foreach (var obj in list)
|
||||||
{
|
{
|
||||||
if (obj is ComboBoxItem)
|
if (obj is DropDownListItem)
|
||||||
{
|
{
|
||||||
cbItems.Add((ComboBoxItem)obj);
|
ddItems.Add((DropDownListItem)obj);
|
||||||
}
|
}
|
||||||
else if (obj is string)
|
else if (obj is string)
|
||||||
{
|
{
|
||||||
cbItems.Add(new ComboBoxItem(caption: (string)obj));
|
ddItems.Add(new DropDownListItem(caption: (string)obj));
|
||||||
}
|
}
|
||||||
else if (obj is Sprite)
|
else if (obj is Sprite)
|
||||||
{
|
{
|
||||||
cbItems.Add(new ComboBoxItem(image: (Sprite)obj));
|
ddItems.Add(new DropDownListItem(image: (Sprite)obj));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed");
|
throw new System.Exception("Only ComboBoxItems, Strings, and Sprite types are allowed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Items.AddRange(cbItems);
|
Items.AddRange(ddItems);
|
||||||
Items = Items.Distinct().ToList();//remove any duplicates
|
Items = Items.Distinct().ToList();//remove any duplicates
|
||||||
|
RebuildPanel();
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearItems()
|
|
||||||
{
|
|
||||||
Items.Clear();
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Redraw the graphics (in response to something changing)
|
/// Rebuilds the contents of the panel in response to items being added.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateGraphics()
|
private void RebuildPanel()
|
||||||
{
|
{
|
||||||
//center the handle in the scrollbar
|
//panel starts with all options
|
||||||
float scrollbarWidth = Items.Count - (HideFirstItem ? 1 : 0) > ItemsToDisplay ? _scrollbarWidth : 0.0f;
|
_panelItems.Clear();
|
||||||
scrollHandleRT.offsetMin = -scrollbarWidth / 2 * Vector2.one;
|
foreach (string option in AvailableOptions)
|
||||||
scrollHandleRT.offsetMax = scrollbarWidth / 2 * Vector2.one;
|
|
||||||
|
|
||||||
if (rectTransform.sizeDelta != comboBtnRT.sizeDelta)
|
|
||||||
{
|
{
|
||||||
comboBtnRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, rectTransform.sizeDelta.x);
|
_panelItems.Add(option.ToLower());
|
||||||
comboBtnRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, rectTransform.sizeDelta.y);
|
}
|
||||||
comboBtnText.rectTransform.offsetMax = new Vector2(4, 0);
|
_panelItems.Sort();
|
||||||
|
|
||||||
scrollPanelRT.SetParent(transform, true);
|
_prunedPanelItems.Clear();
|
||||||
scrollPanelRT.anchoredPosition = new Vector2(0, -comboBtnRT.sizeDelta.y);
|
List<GameObject> itemObjs = new List<GameObject>(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++;
|
||||||
|
}
|
||||||
|
|
||||||
//make hte overlay fill the whole screen
|
for (int i = 0; i < itemObjs.Count; i++)
|
||||||
overlayRT.SetParent(_canvas.transform, false);
|
{
|
||||||
overlayRT.offsetMax = Vector2.zero;
|
itemObjs[i].SetActive(i <= AvailableOptions.Count);
|
||||||
overlayRT.offsetMin = Vector2.zero;
|
if (i < AvailableOptions.Count)
|
||||||
|
{
|
||||||
|
itemObjs[i].name = "Item " + i + " " + _panelItems[i];
|
||||||
|
itemObjs[i].transform.FindChild("Text").GetComponent<Text>().text = _panelItems[i]; //set the text value
|
||||||
|
|
||||||
//reattach to correct parents, maintining global position
|
Button itemBtn = itemObjs[i].GetComponent<Button>();
|
||||||
overlayRT.SetParent(transform, true);
|
itemBtn.onClick.RemoveAllListeners();
|
||||||
scrollPanelRT.SetParent(overlayRT, true);
|
string textOfItem = _panelItems[i]; //has to be copied for anonymous function or it gets garbage collected away
|
||||||
|
itemBtn.onClick.AddListener(() =>
|
||||||
scrollPanel.GetComponent<ScrollRect>().scrollSensitivity = comboBtnRT.sizeDelta.y;
|
{
|
||||||
|
OnItemClicked(textOfItem);
|
||||||
UpdateComboBoxText(comboBtnRT, Items[SelectedIndex].Image != null);
|
});
|
||||||
Refresh();
|
panelObjects[_panelItems[i]] = itemObjs[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// toggle the drop down list
|
/// what happens when an item in the list is selected
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="directClick">whether it was toggled by directly clicking on </param>
|
/// <param name="item"></param>
|
||||||
public void ToggleComboBox(bool directClick)
|
private void OnItemClicked(string item)
|
||||||
{
|
{
|
||||||
if (HeaderOption != "") HideFirstItem = true;
|
//Debug.Log("item " + item + " clicked");
|
||||||
_isActive = !_isActive;
|
Text = item;
|
||||||
// Debug.Log("toggling combo box tp "+ _isActive);
|
_mainInput.text = Text;
|
||||||
overlayRT.gameObject.SetActive(_isActive);
|
ToggleDropdownPanel(true);
|
||||||
if (_isActive)
|
}
|
||||||
|
|
||||||
|
//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()
|
||||||
|
{
|
||||||
|
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 != _inputRT.sizeDelta)
|
||||||
|
{
|
||||||
|
_hasDrawnOnce = true;
|
||||||
|
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
|
||||||
|
_inputRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
|
||||||
|
|
||||||
|
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
|
||||||
|
_scrollPanelRT.anchoredPosition = new Vector2(0, -_rectTransform.sizeDelta.y); //anchor it to the bottom of the button
|
||||||
|
|
||||||
|
//make the overlay fill the screen
|
||||||
|
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
|
||||||
|
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
|
||||||
|
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);
|
||||||
|
|
||||||
|
_overlayRT.SetParent(transform, true);//reattach to this object
|
||||||
|
_scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_panelItems.Count < 1) return;
|
||||||
|
|
||||||
|
float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, _panelItems.Count);
|
||||||
|
|
||||||
|
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||||
|
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
|
||||||
|
|
||||||
|
_itemsPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _scrollPanelRT.sizeDelta.x - scrollbarWidth - 5);
|
||||||
|
_itemsPanelRT.anchoredPosition = new Vector2(5, 0);
|
||||||
|
|
||||||
|
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||||
|
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||||
|
|
||||||
|
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
||||||
|
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnValueChanged(string currText)
|
||||||
|
{
|
||||||
|
Text = currText;
|
||||||
|
PruneItems(currText);
|
||||||
|
RedrawPanel();
|
||||||
|
//Debug.Log("value changed to: " + currText);
|
||||||
|
|
||||||
|
if (_panelItems.Count == 0)
|
||||||
|
{
|
||||||
|
_isPanelActive = true;//this makes it get turned off
|
||||||
|
ToggleDropdownPanel(false);
|
||||||
|
}
|
||||||
|
else if (!_isPanelActive)
|
||||||
|
{
|
||||||
|
ToggleDropdownPanel(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggle the drop down list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="directClick"> whether an item was directly clicked on</param>
|
||||||
|
public void ToggleDropdownPanel(bool directClick)
|
||||||
|
{
|
||||||
|
_isPanelActive = !_isPanelActive;
|
||||||
|
|
||||||
|
_overlayRT.gameObject.SetActive(_isPanelActive);
|
||||||
|
if (_isPanelActive)
|
||||||
{
|
{
|
||||||
transform.SetAsLastSibling();
|
transform.SetAsLastSibling();
|
||||||
FixScrollOffset();
|
|
||||||
}
|
}
|
||||||
else if (directClick)
|
else if (directClick)
|
||||||
{
|
{
|
||||||
scrollOffset = Mathf.RoundToInt(_itemsRT.anchoredPosition.y / rectTransform.sizeDelta.y);
|
// scrollOffset = Mathf.RoundToInt(itemsPanelRT.anchoredPosition.y / _rectTransform.sizeDelta.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PruneItems(string currText)
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region private methods
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
{
|
||||||
_canvas = GetComponentInParent<Canvas>();
|
List<string> notToPrune = _panelItems.Where(x => x.ToLower().Contains(currText.ToLower())).ToList();
|
||||||
Initialize();
|
List<string> toPrune = _panelItems.Except(notToPrune).ToList();
|
||||||
}
|
foreach (string key in toPrune)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initialize the control
|
|
||||||
/// </summary>
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
overlayRT.gameObject.SetActive(false);
|
|
||||||
overlayBtn.onClick.AddListener(() => { ToggleComboBox(false); });
|
|
||||||
|
|
||||||
if (HeaderOption != "") AddItems(HeaderOption);
|
|
||||||
|
|
||||||
//float dropdownHeight = comboBtnRT.sizeDelta.y * Mathf.Min(ItemsToDisplay, Items.Length - (HideFirstItem ? 1 : 0));
|
|
||||||
|
|
||||||
//scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
|
||||||
//scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, comboBtnRT.sizeDelta.x);
|
|
||||||
|
|
||||||
ScrollRect scrollPanelScrollRect = scrollPanel.GetComponent<ScrollRect>();
|
|
||||||
scrollPanelScrollRect.scrollSensitivity = comboBtnRT.sizeDelta.y;
|
|
||||||
scrollPanelScrollRect.content = itemsRT;
|
|
||||||
|
|
||||||
itemLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
|
||||||
itemLayout.constraintCount = 1;
|
|
||||||
|
|
||||||
//float scrollbarWidth = Items.Length - (HideFirstItem ? 1 : 0) > _itemsToDisplay ? _scrollbarWidth : 0.0f;
|
|
||||||
//itemsRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollPanelRT.sizeDelta.x - scrollbarWidth);
|
|
||||||
|
|
||||||
//itemLayout.cellSize = new Vector2(comboBtnRT.sizeDelta.x - scrollbarWidth, comboBtnRT.sizeDelta.y);
|
|
||||||
//itemLayout.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
|
|
||||||
//itemLayout.constraintCount = 1;
|
|
||||||
|
|
||||||
//scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
|
||||||
//scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
|
||||||
|
|
||||||
//slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
|
||||||
//slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - scrollbarRT.sizeDelta.x);
|
|
||||||
|
|
||||||
//scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
|
||||||
//scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, scrollbarWidth);
|
|
||||||
|
|
||||||
Interactable = Interactable; //call the logic in the getter.
|
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Redraw the component, with realigning.
|
|
||||||
/// </summary>
|
|
||||||
public void Refresh()
|
|
||||||
{
|
|
||||||
// Debug.Log("Refreshing");
|
|
||||||
|
|
||||||
int itemsLength = Items.Count - (HideFirstItem ? 1 : 0);
|
|
||||||
if (itemsLength < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float dropdownHeight = comboBtnRT.sizeDelta.y * Mathf.Min(_itemsToDisplay, itemsLength);
|
|
||||||
float scrollbarWidth = itemsLength > ItemsToDisplay ? _scrollbarWidth : 0.0f;
|
|
||||||
|
|
||||||
|
|
||||||
scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
|
||||||
scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, comboBtnRT.sizeDelta.x);
|
|
||||||
|
|
||||||
itemsRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollPanelRT.sizeDelta.x - scrollbarWidth);
|
|
||||||
|
|
||||||
itemLayout.cellSize = new Vector2(comboBtnRT.sizeDelta.x - scrollbarWidth, comboBtnRT.sizeDelta.y);
|
|
||||||
|
|
||||||
scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
|
||||||
scrollbarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
|
||||||
|
|
||||||
slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
|
||||||
slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - scrollbarRT.sizeDelta.x);
|
|
||||||
|
|
||||||
scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
|
||||||
scrollHandleRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, scrollbarWidth);
|
|
||||||
|
|
||||||
for (int i = itemsRT.childCount - 1; i >= 0; i--)//delete in reverse to avoid having to re-allocate memory on each delete. (ie if I deleted child 0, everythign would get shifted forward in the array)
|
|
||||||
{
|
{
|
||||||
DestroyImmediate(itemsRT.GetChild(0).gameObject);
|
// Debug.Log("pruning key " + key);
|
||||||
|
panelObjects[key].SetActive(false);
|
||||||
|
_panelItems.Remove(key);
|
||||||
|
_prunedPanelItems.Add(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = (HideFirstItem ? 1 : 0); i < Items.Count; i++) //for each element to be shown in the dropdown list
|
List<string> toAddBack = _prunedPanelItems.Where(x => x.ToLower().Contains(currText)).ToList();
|
||||||
|
foreach (string key in toAddBack)
|
||||||
{
|
{
|
||||||
ComboBoxItem item = Items[i];
|
// Debug.Log("adding back key " + key);
|
||||||
item.OnUpdate = Refresh;
|
panelObjects[key].SetActive(true);
|
||||||
|
_panelItems.Add(key);
|
||||||
Transform itemTfm = Instantiate(comboBtnRT) as Transform;//copy the top level combo box
|
_prunedPanelItems.Remove(key);
|
||||||
itemTfm.name += " " + i;
|
|
||||||
itemTfm.SetParent(itemsRT, false);
|
|
||||||
itemTfm.GetComponent<Image>().sprite = null; //hide the original background image (so that the dropdown box shows)
|
|
||||||
|
|
||||||
Text itemText = itemTfm.Find("Text").GetComponent<Text>();
|
|
||||||
itemText.text = item.Caption;
|
|
||||||
if (item.IsDisabled) itemText.color = disabledTextColor;
|
|
||||||
|
|
||||||
Image itemImg = itemTfm.Find("Image").GetComponent<Image>();
|
|
||||||
itemImg.sprite = item.Image;
|
|
||||||
itemImg.color = (item.Image == null) ? new Color(1, 1, 1, 0)
|
|
||||||
: item.IsDisabled ? new Color(1, 1, 1, .5f)
|
|
||||||
: Color.white;
|
|
||||||
Button itemBtn = itemTfm.GetComponent<Button>();
|
|
||||||
itemBtn.interactable = !item.IsDisabled;
|
|
||||||
|
|
||||||
int indx = i;
|
|
||||||
itemBtn.onClick.RemoveAllListeners();
|
|
||||||
itemBtn.onClick.AddListener(() =>
|
|
||||||
{
|
|
||||||
OnItemClicked(indx);
|
|
||||||
if (item.OnSelect != null) item.OnSelect();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshSelected();
|
|
||||||
UpdateComboBoxItems();
|
|
||||||
UpdateGraphics();
|
|
||||||
FixScrollOffset();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// adjusts all of the items in the dropdown list to account for any images
|
|
||||||
/// </summary>
|
|
||||||
private void UpdateComboBoxItems()
|
|
||||||
{
|
|
||||||
//decide if any item in the list has images
|
|
||||||
bool includeImages = false;
|
|
||||||
foreach (ComboBoxItem item in Items)
|
|
||||||
{
|
|
||||||
if (item.Image != null)
|
|
||||||
{
|
|
||||||
includeImages = true; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//either align all of the text 10 units from the side, or 8+image width.
|
|
||||||
foreach (Transform child in itemsRT)
|
|
||||||
{
|
|
||||||
UpdateComboBoxText(child, includeImages);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void UpdateComboBoxText(Transform child, bool includeImages)
|
|
||||||
{
|
|
||||||
child.Find("Text").GetComponent<RectTransform>().offsetMin = Vector2.right * (includeImages ? comboBtnImg.rectTransform.rect.width + 8.0f : 10.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void FixScrollOffset()
|
|
||||||
{
|
|
||||||
int selectedIndex = SelectedIndex + (HideFirstItem ? 1 : 0);
|
|
||||||
if (selectedIndex < scrollOffset)
|
|
||||||
scrollOffset = selectedIndex;
|
|
||||||
else
|
|
||||||
if (selectedIndex > scrollOffset + ItemsToDisplay - 1)
|
|
||||||
scrollOffset = selectedIndex - ItemsToDisplay + 1;
|
|
||||||
|
|
||||||
|
|
||||||
int itemsCount = Items.Count - (HideFirstItem ? 1 : 0);
|
|
||||||
if (scrollOffset > itemsCount - ItemsToDisplay)
|
|
||||||
scrollOffset = itemsCount - ItemsToDisplay;
|
|
||||||
if (scrollOffset < 0)
|
|
||||||
scrollOffset = 0;
|
|
||||||
|
|
||||||
_itemsRT.anchoredPosition = new Vector2(0.0f, scrollOffset * rectTransform.sizeDelta.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,292 @@
|
||||||
|
///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;
|
||||||
|
|
||||||
|
namespace UnityEngine.UI.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extenension to the UI class which creates a dropdown list
|
||||||
|
/// </summary>
|
||||||
|
[RequireComponent(typeof(RectTransform))]
|
||||||
|
[AddComponentMenu("UI/Extensions/Dropdown List")]
|
||||||
|
public class DropDownList : MonoBehaviour
|
||||||
|
{
|
||||||
|
public Color disabledTextColor;
|
||||||
|
public DropDownListItem SelectedItem { get; private set; } //outside world gets to get this, not set it
|
||||||
|
|
||||||
|
public List<DropDownListItem> Items;
|
||||||
|
public System.Action<int> OnSelectionChanged; // fires when selection is changed;
|
||||||
|
|
||||||
|
//private bool isInitialized = false;
|
||||||
|
private bool _isPanelActive = false;
|
||||||
|
private bool _hasDrawnOnce = false;
|
||||||
|
|
||||||
|
private DropDownListButton _mainButton;
|
||||||
|
|
||||||
|
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<DropDownListButton> _panelItems;
|
||||||
|
|
||||||
|
private GameObject _itemTemplate;
|
||||||
|
|
||||||
|
[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<RectTransform>();
|
||||||
|
_mainButton = new DropDownListButton(_rectTransform.FindChild("MainButton").gameObject);
|
||||||
|
|
||||||
|
_overlayRT = _rectTransform.FindChild("Overlay").GetComponent<RectTransform>();
|
||||||
|
_overlayRT.gameObject.SetActive(false);
|
||||||
|
|
||||||
|
|
||||||
|
_scrollPanelRT = _overlayRT.FindChild("ScrollPanel").GetComponent<RectTransform>();
|
||||||
|
_scrollBarRT = _scrollPanelRT.FindChild("Scrollbar").GetComponent<RectTransform>();
|
||||||
|
_slidingAreaRT = _scrollBarRT.FindChild("SlidingArea").GetComponent<RectTransform>();
|
||||||
|
// scrollHandleRT = slidingAreaRT.FindChild("Handle").GetComponent<RectTransform>();
|
||||||
|
_itemsPanelRT = _scrollPanelRT.FindChild("Items").GetComponent<RectTransform>();
|
||||||
|
//itemPanelLayout = itemsPanelRT.gameObject.GetComponent<LayoutGroup>();
|
||||||
|
|
||||||
|
_canvas = GetComponentInParent<Canvas>();
|
||||||
|
_canvasRT = _canvas.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
_scrollRect = _scrollPanelRT.GetComponent<ScrollRect>();
|
||||||
|
_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
_panelItems = new List<DropDownListButton>();
|
||||||
|
|
||||||
|
RebuildPanel();
|
||||||
|
RedrawPanel();
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* currently just using items in the list instead of being able to add to it.
|
||||||
|
public void AddItems(params object[] list)
|
||||||
|
{
|
||||||
|
List<DropDownListItem> ddItems = new List<DropDownListItem>();
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rebuilds the contents of the panel in response to items being added.
|
||||||
|
/// </summary>
|
||||||
|
private void RebuildPanel()
|
||||||
|
{
|
||||||
|
if (Items.Count == 0) return;
|
||||||
|
|
||||||
|
int indx = _panelItems.Count;
|
||||||
|
while (_panelItems.Count < Items.Count)
|
||||||
|
{
|
||||||
|
GameObject newItem = Instantiate(_itemTemplate) as GameObject;
|
||||||
|
newItem.name = "Item " + indx;
|
||||||
|
newItem.transform.SetParent(_itemsPanelRT, false);
|
||||||
|
|
||||||
|
_panelItems.Add(new DropDownListButton(newItem));
|
||||||
|
indx++;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < _panelItems.Count; i++)
|
||||||
|
{
|
||||||
|
if (i < Items.Count)
|
||||||
|
{
|
||||||
|
DropDownListItem item = Items[i];
|
||||||
|
|
||||||
|
_panelItems[i].txt.text = item.Caption;
|
||||||
|
if (item.IsDisabled) _panelItems[i].txt.color = disabledTextColor;
|
||||||
|
|
||||||
|
if (_panelItems[i].btnImg != null) _panelItems[i].btnImg.sprite = null;//hide the button image
|
||||||
|
_panelItems[i].img.sprite = item.Image;
|
||||||
|
_panelItems[i].img.color = (item.Image == null) ? new Color(1, 1, 1, 0)
|
||||||
|
: item.IsDisabled ? new Color(1, 1, 1, .5f)
|
||||||
|
: Color.white;
|
||||||
|
int ii = i; //have to copy the variable for use in anonymous function
|
||||||
|
_panelItems[i].btn.onClick.RemoveAllListeners();
|
||||||
|
_panelItems[i].btn.onClick.AddListener(() =>
|
||||||
|
{
|
||||||
|
OnItemClicked(ii);
|
||||||
|
if (item.OnSelect != null) item.OnSelect();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_panelItems[i].gameobject.SetActive(i < Items.Count);// if we have more thanks in the panel than Items in the list hide them
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnItemClicked(int indx)
|
||||||
|
{
|
||||||
|
Debug.Log("item " + indx + " clicked");
|
||||||
|
if (indx != _selectedIndex && OnSelectionChanged != null) OnSelectionChanged(indx);
|
||||||
|
|
||||||
|
_selectedIndex = indx;
|
||||||
|
ToggleDropdownPanel(true);
|
||||||
|
UpdateSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
float scrollbarWidth = Items.Count > ItemsToDisplay ? _scrollBarWidth : 0f;//hide the scrollbar if there's not enough items
|
||||||
|
|
||||||
|
if (!_hasDrawnOnce || _rectTransform.sizeDelta != _mainButton.rectTransform.sizeDelta)
|
||||||
|
{
|
||||||
|
_hasDrawnOnce = true;
|
||||||
|
_mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
|
||||||
|
_mainButton.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _rectTransform.sizeDelta.y);
|
||||||
|
_mainButton.txt.rectTransform.offsetMax = new Vector2(4, 0);
|
||||||
|
|
||||||
|
_scrollPanelRT.SetParent(transform, true);//break the scroll panel from the overlay
|
||||||
|
_scrollPanelRT.anchoredPosition = new Vector2(0, -_rectTransform.sizeDelta.y); //anchor it to the bottom of the button
|
||||||
|
|
||||||
|
//make the overlay fill the screen
|
||||||
|
_overlayRT.SetParent(_canvas.transform, false); //attach it to top level object
|
||||||
|
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _canvasRT.sizeDelta.x);
|
||||||
|
_overlayRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, _canvasRT.sizeDelta.y);
|
||||||
|
|
||||||
|
_overlayRT.SetParent(transform, true);//reattach to this object
|
||||||
|
_scrollPanelRT.SetParent(_overlayRT, true); //reattach the scrollpanel to the overlay
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Items.Count < 1) return;
|
||||||
|
|
||||||
|
float dropdownHeight = _rectTransform.sizeDelta.y * Mathf.Min(_itemsToDisplay, Items.Count);
|
||||||
|
|
||||||
|
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||||
|
_scrollPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _rectTransform.sizeDelta.x);
|
||||||
|
|
||||||
|
_itemsPanelRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, _scrollPanelRT.sizeDelta.x - scrollbarWidth - 5);
|
||||||
|
_itemsPanelRT.anchoredPosition = new Vector2(5, 0);
|
||||||
|
|
||||||
|
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, scrollbarWidth);
|
||||||
|
_scrollBarRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight);
|
||||||
|
|
||||||
|
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 0);
|
||||||
|
_slidingAreaRT.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, dropdownHeight - _scrollBarRT.sizeDelta.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggle the drop down list
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="directClick"> whether an item was directly clicked on</param>
|
||||||
|
public void ToggleDropdownPanel(bool directClick)
|
||||||
|
{
|
||||||
|
_isPanelActive = !_isPanelActive;
|
||||||
|
_overlayRT.gameObject.SetActive(_isPanelActive);
|
||||||
|
if (_isPanelActive)
|
||||||
|
{
|
||||||
|
transform.SetAsLastSibling();
|
||||||
|
}
|
||||||
|
else if (directClick)
|
||||||
|
{
|
||||||
|
// scrollOffset = Mathf.RoundToInt(itemsPanelRT.anchoredPosition.y / _rectTransform.sizeDelta.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 261044bc84e00294d9bcf19909da3aa2
|
guid: 7a00cad80d8a47b438b394bebe77d0d2
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
defaultReferences: []
|
defaultReferences: []
|
|
@ -0,0 +1,26 @@
|
||||||
|
///Credit perchik
|
||||||
|
///Sourced from - http://forum.unity3d.com/threads/receive-onclick-event-and-pass-it-on-to-lower-ui-elements.293642/
|
||||||
|
|
||||||
|
namespace UnityEngine.UI.Extensions
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(RectTransform), typeof(Button))]
|
||||||
|
public class DropDownListButton
|
||||||
|
{
|
||||||
|
public RectTransform rectTransform;
|
||||||
|
public Button btn;
|
||||||
|
public Text txt;
|
||||||
|
public Image btnImg;
|
||||||
|
public Image img;
|
||||||
|
public GameObject gameobject;
|
||||||
|
|
||||||
|
public DropDownListButton(GameObject btnObj)
|
||||||
|
{
|
||||||
|
gameobject = btnObj;
|
||||||
|
rectTransform = btnObj.GetComponent<RectTransform>();
|
||||||
|
btnImg = btnObj.GetComponent<Image>();
|
||||||
|
btn = btnObj.GetComponent<Button>();
|
||||||
|
txt = rectTransform.FindChild("Text").GetComponent<Text>();
|
||||||
|
img = rectTransform.FindChild("Image").GetComponent<Image>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 491c635e1f309294187ff24b5c71e8cb
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
|
@ -5,7 +5,8 @@ using System;
|
||||||
|
|
||||||
namespace UnityEngine.UI.Extensions
|
namespace UnityEngine.UI.Extensions
|
||||||
{
|
{
|
||||||
public class ComboBoxItem
|
[Serializable]
|
||||||
|
public class DropDownListItem
|
||||||
{
|
{
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private string _caption;
|
private string _caption;
|
||||||
|
@ -64,33 +65,36 @@ namespace UnityEngine.UI.Extensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private string _id;
|
||||||
|
///<summary>
|
||||||
|
///ID exists so that an item can have a caption and a value like in traditional windows forms. Ie. an item may be a student's name, and the ID can be the student's ID number
|
||||||
|
///</summary>
|
||||||
|
public string ID
|
||||||
|
{
|
||||||
|
get { return _id; }
|
||||||
|
set { _id = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public Action OnSelect; //action to be called when this item is selected
|
public Action OnSelect; //action to be called when this item is selected
|
||||||
|
|
||||||
internal Action OnUpdate; //action to be called when something changes.
|
internal Action OnUpdate; //action to be called when something changes.
|
||||||
|
|
||||||
///<remarks> Value exists so that an item can have a caption and a value, like in traditional windows forms. Ie. an item may be a student's name, and the value could be the student's ID number</remarks>
|
|
||||||
private string _value;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor for ComboBoxOptions
|
/// Constructor for Drop Down List panelItems
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="caption">Caption for the item </param>
|
/// <param name="caption">Caption for the item </param>
|
||||||
/// <param name="val">Value of the item </param>
|
/// <param name="val">ID of the item </param>
|
||||||
/// <param name="image"></param>
|
/// <param name="image"></param>
|
||||||
/// <param name="disabled">Should the item start disabled</param>
|
/// <param name="disabled">Should the item start disabled</param>
|
||||||
/// <param name="onSelect">Action to be called when this item is selected</param>
|
/// <param name="onSelect">Action to be called when this item is selected</param>
|
||||||
public ComboBoxItem(string caption = "", string val = "", Sprite image = null, bool disabled = false, Action onSelect = null)
|
public DropDownListItem(string caption = "", string inId = "", Sprite image = null, bool disabled = false, Action onSelect = null)
|
||||||
{
|
{
|
||||||
_caption = caption;
|
_caption = caption;
|
||||||
_image = image;
|
_image = image;
|
||||||
_value = val;
|
_id = inId;
|
||||||
_isDisabled = disabled;
|
_isDisabled = disabled;
|
||||||
OnSelect = onSelect;
|
OnSelect = onSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e1dd512d0ed874740902b01df530b2dc
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
|
@ -1,4 +1,4 @@
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.UI.Extensions;
|
using UnityEngine.UI.Extensions;
|
||||||
|
@ -27,6 +27,7 @@ namespace UnityEditor.UI
|
||||||
//private static Vector2 s_ThinGUIElementSize = new Vector2(kWidth, kThinHeight);
|
//private static Vector2 s_ThinGUIElementSize = new Vector2(kWidth, kThinHeight);
|
||||||
private static Vector2 s_ImageGUIElementSize = new Vector2(100f, 100f);
|
private static Vector2 s_ImageGUIElementSize = new Vector2(100f, 100f);
|
||||||
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
|
||||||
|
private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);
|
||||||
#endregion
|
#endregion
|
||||||
#region Unity Builder methods - Do not change unless UI Source (Editor\MenuOptions) changes
|
#region Unity Builder methods - Do not change unless UI Source (Editor\MenuOptions) changes
|
||||||
private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
|
private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
|
||||||
|
@ -105,7 +106,6 @@ namespace UnityEditor.UI
|
||||||
return go;
|
return go;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Canvas", false, 2009)]
|
|
||||||
static public void AddCanvas(MenuCommand menuCommand)
|
static public void AddCanvas(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
var go = CreateNewUI();
|
var go = CreateNewUI();
|
||||||
|
@ -195,12 +195,20 @@ namespace UnityEditor.UI
|
||||||
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
|
colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
|
||||||
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
|
colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void SetDefaultTextValues(Text lbl)
|
||||||
|
{
|
||||||
|
// Set text values we want across UI elements in default controls.
|
||||||
|
// Don't set values which are the same as the default values for the Text component,
|
||||||
|
// since there's no point in that, and it's good to keep them as consistent as possible.
|
||||||
|
lbl.color = s_TextColor;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region UI Extensions "Create" Menu items
|
#region UI Extensions "Create" Menu items
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/Horizontal Scroll Snap", false, 2000)]
|
[MenuItem("GameObject/UI/Extensions/Horizontal Scroll Snap", false)]
|
||||||
static public void AddHorizontalScrollSnap(MenuCommand menuCommand)
|
static public void AddHorizontalScrollSnap(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject horizontalScrollSnapRoot = CreateUIElementRoot("Horizontal Scroll Snap", menuCommand, s_ThickGUIElementSize);
|
GameObject horizontalScrollSnapRoot = CreateUIElementRoot("Horizontal Scroll Snap", menuCommand, s_ThickGUIElementSize);
|
||||||
|
@ -273,7 +281,7 @@ namespace UnityEditor.UI
|
||||||
Selection.activeGameObject = horizontalScrollSnapRoot;
|
Selection.activeGameObject = horizontalScrollSnapRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/UI Button", false, 2001)]
|
[MenuItem("GameObject/UI/Extensions/UI Button", false)]
|
||||||
static public void AddUIButton(MenuCommand menuCommand)
|
static public void AddUIButton(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject uiButtonRoot = CreateUIElementRoot("UI Button", menuCommand, s_ThickGUIElementSize);
|
GameObject uiButtonRoot = CreateUIElementRoot("UI Button", menuCommand, s_ThickGUIElementSize);
|
||||||
|
@ -301,7 +309,7 @@ namespace UnityEditor.UI
|
||||||
Selection.activeGameObject = uiButtonRoot;
|
Selection.activeGameObject = uiButtonRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/UI Flippable", false, 2003)]
|
[MenuItem("GameObject/UI/Extensions/UI Flippable", false)]
|
||||||
static public void AddUIFlippableImage(MenuCommand menuCommand)
|
static public void AddUIFlippableImage(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject go = CreateUIElementRoot("UI Flippable", menuCommand, s_ImageGUIElementSize);
|
GameObject go = CreateUIElementRoot("UI Flippable", menuCommand, s_ImageGUIElementSize);
|
||||||
|
@ -310,7 +318,7 @@ namespace UnityEditor.UI
|
||||||
Selection.activeGameObject = go;
|
Selection.activeGameObject = go;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/UI Window Base", false, 2004)]
|
[MenuItem("GameObject/UI/Extensions/UI Window Base", false)]
|
||||||
static public void AddUIWindowBase(MenuCommand menuCommand)
|
static public void AddUIWindowBase(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject go = CreateUIElementRoot("UI Window Base", menuCommand, s_ThickGUIElementSize);
|
GameObject go = CreateUIElementRoot("UI Window Base", menuCommand, s_ThickGUIElementSize);
|
||||||
|
@ -319,7 +327,7 @@ namespace UnityEditor.UI
|
||||||
Selection.activeGameObject = go;
|
Selection.activeGameObject = go;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Group", false, 2002)]
|
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Group", false)]
|
||||||
static public void AddAccordionGroup(MenuCommand menuCommand)
|
static public void AddAccordionGroup(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize);
|
GameObject go = CreateUIElementRoot("Accordion Group", menuCommand, s_ThickGUIElementSize);
|
||||||
|
@ -330,7 +338,7 @@ namespace UnityEditor.UI
|
||||||
Selection.activeGameObject = go;
|
Selection.activeGameObject = go;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Element", false, 2002)]
|
[MenuItem("GameObject/UI/Extensions/Accordion/Accordion Element", false)]
|
||||||
static public void AddAccordionElement(MenuCommand menuCommand)
|
static public void AddAccordionElement(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
GameObject go = CreateUIElementRoot("Accordion Element", menuCommand, s_ThickGUIElementSize);
|
GameObject go = CreateUIElementRoot("Accordion Element", menuCommand, s_ThickGUIElementSize);
|
||||||
|
@ -340,16 +348,103 @@ namespace UnityEditor.UI
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Awaiting updated control from autor - Use PreFab for now
|
[MenuItem("GameObject/UI/Extensions/ComboBox", false)]
|
||||||
//[MenuItem("GameObject/UI/Extensions/ComboBox", false, 2002)]
|
static public void AddComboBox(MenuCommand menuCommand)
|
||||||
//static public void AddComboBox(MenuCommand menuCommand)
|
{
|
||||||
//{
|
GameObject comboBoxRoot = CreateUIElementRoot("ComboBox", menuCommand, s_ThickGUIElementSize);
|
||||||
// GameObject go = CreateUIElementRoot("ComboBox", menuCommand, s_ThickGUIElementSize);
|
|
||||||
// go.AddComponent<ComboBox>();
|
|
||||||
// Selection.activeGameObject = go;
|
|
||||||
//}
|
|
||||||
|
|
||||||
[MenuItem("GameObject/UI/Extensions/Selection Box", false, 2009)]
|
//Create Template
|
||||||
|
GameObject itemTemplate = AddButtonAsChild(comboBoxRoot);
|
||||||
|
|
||||||
|
//Create Inputfield
|
||||||
|
GameObject inputField = AddInputFieldAsChild(comboBoxRoot);
|
||||||
|
|
||||||
|
//Create Overlay
|
||||||
|
GameObject overlay = CreateUIObject("Overlay", comboBoxRoot);
|
||||||
|
GameObject overlayScrollPanel = CreateUIObject("ScrollPanel", overlay);
|
||||||
|
GameObject overlayScrollPanelItems = CreateUIObject("Items", overlayScrollPanel);
|
||||||
|
GameObject overlayScrollPanelScrollBar = AddScrollbarAsChild(overlayScrollPanel);
|
||||||
|
|
||||||
|
//Create Arrow Button
|
||||||
|
GameObject arrowButton = AddButtonAsChild(comboBoxRoot);
|
||||||
|
|
||||||
|
//Setup ComboBox
|
||||||
|
var comboBox = comboBoxRoot.AddComponent<ComboBox>();
|
||||||
|
var cbbRT = comboBoxRoot.GetComponent<RectTransform>();
|
||||||
|
|
||||||
|
//Setup Template
|
||||||
|
itemTemplate.name = "ItemTemplate";
|
||||||
|
var itemTemplateRT = itemTemplate.GetComponent<RectTransform>();
|
||||||
|
itemTemplateRT.sizeDelta = cbbRT.sizeDelta;
|
||||||
|
var itemTemplateButton = itemTemplate.GetComponent<Button>();
|
||||||
|
itemTemplateButton.transition = Selectable.Transition.None;
|
||||||
|
var itemTemplateLayoutElement = itemTemplate.AddComponent<LayoutElement>();
|
||||||
|
itemTemplateLayoutElement.minHeight = cbbRT.rect.height;
|
||||||
|
itemTemplate.SetActive(false);
|
||||||
|
|
||||||
|
//Setup InputField
|
||||||
|
var inputFieldRT = inputField.GetComponent<RectTransform>();
|
||||||
|
inputFieldRT.anchorMin = Vector2.zero;
|
||||||
|
inputFieldRT.anchorMax = Vector2.one;
|
||||||
|
inputFieldRT.sizeDelta = Vector2.zero;
|
||||||
|
Events.UnityEventTools.AddPersistentListener<string>(inputField.GetComponent<InputField>().onValueChange, new UnityEngine.Events.UnityAction<string>(comboBox.OnValueChanged));
|
||||||
|
|
||||||
|
//Setup Overlay
|
||||||
|
var overlayRT = overlay.GetComponent<RectTransform>();
|
||||||
|
overlayRT.anchorMin = new Vector2(0f, 1f);
|
||||||
|
overlayRT.anchorMax = new Vector2(0f, 1f);
|
||||||
|
overlayRT.sizeDelta = new Vector2(0f, 1f);
|
||||||
|
overlayRT.pivot = new Vector2(0f, 1f);
|
||||||
|
overlay.AddComponent<Image>().color = new Color(0.243f, 0.871f, 0f, 0f);
|
||||||
|
Events.UnityEventTools.AddBoolPersistentListener(overlay.AddComponent<Button>().onClick, new UnityEngine.Events.UnityAction<bool>(comboBox.ToggleDropdownPanel), true);
|
||||||
|
//Overlay Scroll Panel
|
||||||
|
var overlayScrollPanelRT = overlayScrollPanel.GetComponent<RectTransform>();
|
||||||
|
overlayScrollPanelRT.position += new Vector3(0, -cbbRT.sizeDelta.y, 0);
|
||||||
|
overlayScrollPanelRT.anchorMin = new Vector2(0f, 1f);
|
||||||
|
overlayScrollPanelRT.anchorMax = new Vector2(0f, 1f);
|
||||||
|
overlayScrollPanelRT.sizeDelta = new Vector2(cbbRT.sizeDelta.x, cbbRT.sizeDelta.y * 3);
|
||||||
|
overlayScrollPanelRT.pivot = new Vector2(0f, 1f);
|
||||||
|
overlayScrollPanel.AddComponent<Image>();
|
||||||
|
overlayScrollPanel.AddComponent<Mask>();
|
||||||
|
var scrollRect = overlayScrollPanel.AddComponent<ScrollRect>();
|
||||||
|
scrollRect.horizontal = false;
|
||||||
|
scrollRect.movementType = ScrollRect.MovementType.Clamped;
|
||||||
|
scrollRect.verticalScrollbar = overlayScrollPanelScrollBar.GetComponent<Scrollbar>();
|
||||||
|
//Overlay Items list
|
||||||
|
var overlayScrollPanelItemsRT = overlayScrollPanelItems.GetComponent<RectTransform>();
|
||||||
|
overlayScrollPanelItemsRT.position += new Vector3(5, 0, 0);
|
||||||
|
overlayScrollPanelItemsRT.anchorMin = new Vector2(0f, 1f);
|
||||||
|
overlayScrollPanelItemsRT.anchorMax = new Vector2(0f, 1f);
|
||||||
|
overlayScrollPanelItemsRT.sizeDelta = new Vector2(120f, 5f);
|
||||||
|
overlayScrollPanelItemsRT.pivot = new Vector2(0f, 1f);
|
||||||
|
scrollRect.content = overlayScrollPanelItemsRT;
|
||||||
|
var overlayScrollPanelItemsVLG = overlayScrollPanelItems.AddComponent<VerticalLayoutGroup>();
|
||||||
|
overlayScrollPanelItemsVLG.padding = new RectOffset(0, 0, 5, 0);
|
||||||
|
var overlayScrollPanelItemsFitter = overlayScrollPanelItems.AddComponent<ContentSizeFitter>();
|
||||||
|
overlayScrollPanelItemsFitter.verticalFit = ContentSizeFitter.FitMode.MinSize;
|
||||||
|
//Overlay Scrollbar
|
||||||
|
var overlayScrollPanelScrollbarRT = overlayScrollPanelScrollBar.GetComponent<RectTransform>();
|
||||||
|
overlayScrollPanelScrollbarRT.anchorMin = new Vector2(1f, 0f);
|
||||||
|
overlayScrollPanelScrollbarRT.anchorMax = Vector2.one;
|
||||||
|
overlayScrollPanelScrollbarRT.sizeDelta = new Vector2(cbbRT.sizeDelta.y, 0f);
|
||||||
|
overlayScrollPanelScrollbarRT.pivot = Vector2.one;
|
||||||
|
overlayScrollPanelScrollbarRT.GetComponent<Scrollbar>().direction = Scrollbar.Direction.BottomToTop;
|
||||||
|
overlayScrollPanelScrollBar.transform.GetChild(0).name = "SlidingArea";
|
||||||
|
|
||||||
|
//Arrow Button
|
||||||
|
arrowButton.name = "ArrowBtn";
|
||||||
|
var arrowButtonRT = arrowButton.GetComponent<RectTransform>();
|
||||||
|
arrowButtonRT.anchorMin = Vector2.one;
|
||||||
|
arrowButtonRT.anchorMax = Vector2.one;
|
||||||
|
arrowButtonRT.sizeDelta = new Vector2(cbbRT.sizeDelta.y, cbbRT.sizeDelta.y);
|
||||||
|
arrowButtonRT.pivot = Vector2.one;
|
||||||
|
Events.UnityEventTools.AddBoolPersistentListener(arrowButton.GetComponent<Button>().onClick, new UnityEngine.Events.UnityAction<bool>(comboBox.ToggleDropdownPanel), true);
|
||||||
|
arrowButton.GetComponentInChildren<Text>().text = "▼";
|
||||||
|
|
||||||
|
Selection.activeGameObject = comboBoxRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("GameObject/UI/Extensions/Selection Box", false)]
|
||||||
static public void AddSelectionBox(MenuCommand menuCommand)
|
static public void AddSelectionBox(MenuCommand menuCommand)
|
||||||
{
|
{
|
||||||
var go = CreateNewUI();
|
var go = CreateNewUI();
|
||||||
|
@ -383,5 +478,128 @@ namespace UnityEditor.UI
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Helper Functions
|
||||||
|
private static GameObject AddInputFieldAsChild(GameObject parent)
|
||||||
|
{
|
||||||
|
GameObject root = CreateUIObject("InputField", parent);
|
||||||
|
|
||||||
|
GameObject childPlaceholder = CreateUIObject("Placeholder", root);
|
||||||
|
GameObject childText = CreateUIObject("Text", root);
|
||||||
|
|
||||||
|
Image image = root.AddComponent<Image>();
|
||||||
|
image.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kInputFieldBackgroundPath);
|
||||||
|
image.type = Image.Type.Sliced;
|
||||||
|
image.color = s_DefaultSelectableColor;
|
||||||
|
|
||||||
|
InputField inputField = root.AddComponent<InputField>();
|
||||||
|
SetDefaultColorTransitionValues(inputField);
|
||||||
|
|
||||||
|
Text text = childText.AddComponent<Text>();
|
||||||
|
text.text = "";
|
||||||
|
text.supportRichText = false;
|
||||||
|
SetDefaultTextValues(text);
|
||||||
|
|
||||||
|
Text placeholder = childPlaceholder.AddComponent<Text>();
|
||||||
|
placeholder.text = "Enter text...";
|
||||||
|
placeholder.fontStyle = FontStyle.Italic;
|
||||||
|
// Make placeholder color half as opaque as normal text color.
|
||||||
|
Color placeholderColor = text.color;
|
||||||
|
placeholderColor.a *= 0.5f;
|
||||||
|
placeholder.color = placeholderColor;
|
||||||
|
|
||||||
|
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||||
|
textRectTransform.anchorMin = Vector2.zero;
|
||||||
|
textRectTransform.anchorMax = Vector2.one;
|
||||||
|
textRectTransform.sizeDelta = Vector2.zero;
|
||||||
|
textRectTransform.offsetMin = new Vector2(10, 6);
|
||||||
|
textRectTransform.offsetMax = new Vector2(-10, -7);
|
||||||
|
|
||||||
|
RectTransform placeholderRectTransform = childPlaceholder.GetComponent<RectTransform>();
|
||||||
|
placeholderRectTransform.anchorMin = Vector2.zero;
|
||||||
|
placeholderRectTransform.anchorMax = Vector2.one;
|
||||||
|
placeholderRectTransform.sizeDelta = Vector2.zero;
|
||||||
|
placeholderRectTransform.offsetMin = new Vector2(10, 6);
|
||||||
|
placeholderRectTransform.offsetMax = new Vector2(-10, -7);
|
||||||
|
|
||||||
|
inputField.textComponent = text;
|
||||||
|
inputField.placeholder = placeholder;
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject AddScrollbarAsChild(GameObject parent)
|
||||||
|
{
|
||||||
|
// Create GOs Hierarchy
|
||||||
|
GameObject scrollbarRoot = CreateUIObject("Scrollbar", parent);
|
||||||
|
|
||||||
|
GameObject sliderArea = CreateUIObject("Sliding Area", scrollbarRoot);
|
||||||
|
GameObject handle = CreateUIObject("Handle", sliderArea);
|
||||||
|
|
||||||
|
Image bgImage = scrollbarRoot.AddComponent<Image>();
|
||||||
|
bgImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpriteResourcePath);
|
||||||
|
bgImage.type = Image.Type.Sliced;
|
||||||
|
bgImage.color = s_DefaultSelectableColor;
|
||||||
|
|
||||||
|
Image handleImage = handle.AddComponent<Image>();
|
||||||
|
handleImage.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
|
||||||
|
handleImage.type = Image.Type.Sliced;
|
||||||
|
handleImage.color = s_DefaultSelectableColor;
|
||||||
|
|
||||||
|
RectTransform sliderAreaRect = sliderArea.GetComponent<RectTransform>();
|
||||||
|
sliderAreaRect.sizeDelta = new Vector2(-20, -20);
|
||||||
|
sliderAreaRect.anchorMin = Vector2.zero;
|
||||||
|
sliderAreaRect.anchorMax = Vector2.one;
|
||||||
|
|
||||||
|
RectTransform handleRect = handle.GetComponent<RectTransform>();
|
||||||
|
handleRect.sizeDelta = new Vector2(20, 20);
|
||||||
|
|
||||||
|
Scrollbar scrollbar = scrollbarRoot.AddComponent<Scrollbar>();
|
||||||
|
scrollbar.handleRect = handleRect;
|
||||||
|
scrollbar.targetGraphic = handleImage;
|
||||||
|
SetDefaultColorTransitionValues(scrollbar);
|
||||||
|
|
||||||
|
return scrollbarRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject AddTextAsChild(GameObject parent)
|
||||||
|
{
|
||||||
|
GameObject go = CreateUIObject("Text", parent);
|
||||||
|
|
||||||
|
Text lbl = go.AddComponent<Text>();
|
||||||
|
lbl.text = "New Text";
|
||||||
|
SetDefaultTextValues(lbl);
|
||||||
|
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GameObject AddButtonAsChild(GameObject parent)
|
||||||
|
{
|
||||||
|
GameObject buttonRoot = CreateUIObject("Button", parent);
|
||||||
|
|
||||||
|
GameObject childText = new GameObject("Text");
|
||||||
|
GameObjectUtility.SetParentAndAlign(childText, buttonRoot);
|
||||||
|
|
||||||
|
Image image = buttonRoot.AddComponent<Image>();
|
||||||
|
image.sprite = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
|
||||||
|
image.type = Image.Type.Sliced;
|
||||||
|
image.color = s_DefaultSelectableColor;
|
||||||
|
|
||||||
|
Button bt = buttonRoot.AddComponent<Button>();
|
||||||
|
SetDefaultColorTransitionValues(bt);
|
||||||
|
|
||||||
|
Text text = childText.AddComponent<Text>();
|
||||||
|
text.text = "Button";
|
||||||
|
text.alignment = TextAnchor.MiddleCenter;
|
||||||
|
SetDefaultTextValues(text);
|
||||||
|
|
||||||
|
RectTransform textRectTransform = childText.GetComponent<RectTransform>();
|
||||||
|
textRectTransform.anchorMin = Vector2.zero;
|
||||||
|
textRectTransform.anchorMax = Vector2.one;
|
||||||
|
textRectTransform.sizeDelta = Vector2.zero;
|
||||||
|
|
||||||
|
return buttonRoot;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
/// Credit Simie
|
||||||
|
/// Sourced from - http://forum.unity3d.com/threads/flowlayoutgroup.296709/
|
||||||
|
/// Example http://forum.unity3d.com/threads/flowlayoutgroup.296709/
|
||||||
|
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace UnityEngine.UI.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Layout Group controller that arranges children in rows, fitting as many on a line until total width exceeds parent bounds
|
||||||
|
/// </summary>
|
||||||
|
[AddComponentMenu("UI/Extensions/Flow Layout Group")]
|
||||||
|
public class FlowLayoutGroup : LayoutGroup
|
||||||
|
{
|
||||||
|
public float Spacing = 0f;
|
||||||
|
|
||||||
|
public bool ChildForceExpandWidth = false;
|
||||||
|
public bool ChildForceExpandHeight = false;
|
||||||
|
|
||||||
|
private float _layoutHeight;
|
||||||
|
|
||||||
|
public override void CalculateLayoutInputHorizontal()
|
||||||
|
{
|
||||||
|
|
||||||
|
base.CalculateLayoutInputHorizontal();
|
||||||
|
|
||||||
|
var minWidth = GetGreatestMinimumChildWidth() + padding.left + padding.right;
|
||||||
|
|
||||||
|
SetLayoutInputForAxis(minWidth, -1, -1, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLayoutHorizontal()
|
||||||
|
{
|
||||||
|
SetLayout(rectTransform.rect.width, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetLayoutVertical()
|
||||||
|
{
|
||||||
|
SetLayout(rectTransform.rect.width, 1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CalculateLayoutInputVertical()
|
||||||
|
{
|
||||||
|
_layoutHeight = SetLayout(rectTransform.rect.width, 1, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool IsCenterAlign
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return childAlignment == TextAnchor.LowerCenter || childAlignment == TextAnchor.MiddleCenter ||
|
||||||
|
childAlignment == TextAnchor.UpperCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool IsRightAlign
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return childAlignment == TextAnchor.LowerRight || childAlignment == TextAnchor.MiddleRight ||
|
||||||
|
childAlignment == TextAnchor.UpperRight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool IsMiddleAlign
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return childAlignment == TextAnchor.MiddleLeft || childAlignment == TextAnchor.MiddleRight ||
|
||||||
|
childAlignment == TextAnchor.MiddleCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool IsLowerAlign
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return childAlignment == TextAnchor.LowerLeft || childAlignment == TextAnchor.LowerRight ||
|
||||||
|
childAlignment == TextAnchor.LowerCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Holds the rects that will make up the current row being processed
|
||||||
|
/// </summary>
|
||||||
|
private readonly IList<RectTransform> _rowList = new List<RectTransform>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Main layout method
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="width">Width to calculate the layout with</param>
|
||||||
|
/// <param name="axis">0 for horizontal axis, 1 for vertical</param>
|
||||||
|
/// <param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>
|
||||||
|
public float SetLayout(float width, int axis, bool layoutInput)
|
||||||
|
{
|
||||||
|
var groupHeight = rectTransform.rect.height;
|
||||||
|
|
||||||
|
// Width that is available after padding is subtracted
|
||||||
|
var workingWidth = rectTransform.rect.width - padding.left - padding.right;
|
||||||
|
|
||||||
|
// Accumulates the total height of the rows, including spacing and padding.
|
||||||
|
var yOffset = IsLowerAlign ? (float)padding.bottom : (float)padding.top;
|
||||||
|
|
||||||
|
var currentRowWidth = 0f;
|
||||||
|
var currentRowHeight = 0f;
|
||||||
|
|
||||||
|
for (var i = 0; i < rectChildren.Count; i++) {
|
||||||
|
|
||||||
|
// LowerAlign works from back to front
|
||||||
|
var index = IsLowerAlign ? rectChildren.Count - 1 - i : i;
|
||||||
|
|
||||||
|
var child = rectChildren[index];
|
||||||
|
|
||||||
|
var childWidth = LayoutUtility.GetPreferredSize(child, 0);
|
||||||
|
var childHeight = LayoutUtility.GetPreferredSize(child, 1);
|
||||||
|
|
||||||
|
// Max child width is layout group with - padding
|
||||||
|
childWidth = Mathf.Min(childWidth, workingWidth);
|
||||||
|
|
||||||
|
// If adding this element would exceed the bounds of the row,
|
||||||
|
// go to a new line after processing the current row
|
||||||
|
if (currentRowWidth + childWidth > workingWidth) {
|
||||||
|
|
||||||
|
currentRowWidth -= Spacing;
|
||||||
|
|
||||||
|
// Process current row elements positioning
|
||||||
|
if (!layoutInput) {
|
||||||
|
|
||||||
|
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
|
||||||
|
LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear existing row
|
||||||
|
_rowList.Clear();
|
||||||
|
|
||||||
|
// Add the current row height to total height accumulator, and reset to 0 for the next row
|
||||||
|
yOffset += currentRowHeight;
|
||||||
|
yOffset += Spacing;
|
||||||
|
|
||||||
|
currentRowHeight = 0;
|
||||||
|
currentRowWidth = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
currentRowWidth += childWidth;
|
||||||
|
_rowList.Add(child);
|
||||||
|
|
||||||
|
// We need the largest element height to determine the starting position of the next line
|
||||||
|
if (childHeight > currentRowHeight) {
|
||||||
|
currentRowHeight = childHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentRowWidth += Spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layoutInput) {
|
||||||
|
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
|
||||||
|
|
||||||
|
// Layout the final row
|
||||||
|
LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
_rowList.Clear();
|
||||||
|
|
||||||
|
// Add the last rows height to the height accumulator
|
||||||
|
yOffset += currentRowHeight;
|
||||||
|
yOffset += IsLowerAlign ? padding.top : padding.bottom;
|
||||||
|
|
||||||
|
if (layoutInput) {
|
||||||
|
|
||||||
|
if(axis == 1)
|
||||||
|
SetLayoutInputForAxis(yOffset, yOffset, -1, axis);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return yOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateRowVerticalOffset(float groupHeight, float yOffset, float currentRowHeight)
|
||||||
|
{
|
||||||
|
float h;
|
||||||
|
|
||||||
|
if (IsLowerAlign) {
|
||||||
|
h = groupHeight - yOffset - currentRowHeight;
|
||||||
|
} else if (IsMiddleAlign) {
|
||||||
|
h = groupHeight*0.5f - _layoutHeight * 0.5f + yOffset;
|
||||||
|
} else {
|
||||||
|
h = yOffset;
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void LayoutRow(IList<RectTransform> contents, float rowWidth, float rowHeight, float maxWidth, float xOffset, float yOffset, int axis)
|
||||||
|
{
|
||||||
|
var xPos = xOffset;
|
||||||
|
|
||||||
|
if (!ChildForceExpandWidth && IsCenterAlign)
|
||||||
|
xPos += (maxWidth - rowWidth) * 0.5f;
|
||||||
|
else if (!ChildForceExpandWidth && IsRightAlign)
|
||||||
|
xPos += (maxWidth - rowWidth);
|
||||||
|
|
||||||
|
var extraWidth = 0f;
|
||||||
|
|
||||||
|
if (ChildForceExpandWidth) {
|
||||||
|
extraWidth = (maxWidth - rowWidth)/_rowList.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < _rowList.Count; j++) {
|
||||||
|
|
||||||
|
var index = IsLowerAlign ? _rowList.Count - 1 - j : j;
|
||||||
|
|
||||||
|
var rowChild = _rowList[index];
|
||||||
|
|
||||||
|
var rowChildWidth = LayoutUtility.GetPreferredSize(rowChild, 0) + extraWidth;
|
||||||
|
var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1);
|
||||||
|
|
||||||
|
if (ChildForceExpandHeight)
|
||||||
|
rowChildHeight = rowHeight;
|
||||||
|
|
||||||
|
rowChildWidth = Mathf.Min(rowChildWidth, maxWidth);
|
||||||
|
|
||||||
|
var yPos = yOffset;
|
||||||
|
|
||||||
|
if (IsMiddleAlign)
|
||||||
|
yPos += (rowHeight - rowChildHeight) * 0.5f;
|
||||||
|
else if (IsLowerAlign)
|
||||||
|
yPos += (rowHeight - rowChildHeight);
|
||||||
|
|
||||||
|
if (axis == 0)
|
||||||
|
SetChildAlongAxis(rowChild, 0, xPos, rowChildWidth);
|
||||||
|
else
|
||||||
|
SetChildAlongAxis(rowChild, 1, yPos, rowChildHeight);
|
||||||
|
|
||||||
|
xPos += rowChildWidth + Spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetGreatestMinimumChildWidth()
|
||||||
|
{
|
||||||
|
var max = 0f;
|
||||||
|
|
||||||
|
for (var i = 0; i < rectChildren.Count; i++) {
|
||||||
|
var w = LayoutUtility.GetMinWidth(rectChildren[i]);
|
||||||
|
|
||||||
|
max = Mathf.Max(w, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 558b109da67a27b4686138b955f3a7e8
|
||||||
|
MonoImporter:
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
|
@ -0,0 +1,4 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bdcf5079609572e459e7d8531bceb480
|
||||||
|
DefaultImporter:
|
||||||
|
userData:
|
Loading…
Reference in New Issue