using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI; public class LogicTrayUI : LogicElementHolder { //[SerializeField] //protected List list; [SerializeField] protected LogicElementUI Prefab; [SerializeField] protected int insertIndex = -1; [SerializeField] private Transform content; [SerializeField] public BlockReader reader; #region Unity Functions public void Start() { UpdateDisplay(); } protected override void OnEnable() { base.OnEnable(); if (reader != null) reader.OnUpdate += UpdateDisplay; } protected override void OnDisable() { base.OnDisable(); if (reader != null) reader.OnUpdate -= UpdateDisplay; } #endregion Unity Functions public void SetBlockReader(BlockReader newBlockReader) { if (reader != null) reader.OnUpdate -= UpdateDisplay; reader = newBlockReader; reader.OnUpdate += UpdateDisplay; UpdateDisplay(); } [ContextMenu("Update Display")] public void UpdateDisplay() { if (reader == null) return; //Destroy all children int destroyedCount = content.childCount; //we need to know how many were destroyed since unity doesn't actually destroy anything until the end of the frame foreach (Transform child in content) Destroy(child.gameObject); //Instatiate logicElement prefab foreach (LogicBlock element in reader.LogicChain) { LogicElementUI elementUI = Instantiate(Prefab.gameObject, content).GetComponent(); elementUI.Initialise(element, this); } //Add insertIndex object if needed if (insertIndex != -1) { GameObject elementObject = Instantiate(Prefab.gameObject, content); elementObject.GetComponentInChildren().text = "insert"; elementObject.GetComponentInChildren().color = new Color(0.5f, 0.5f, 0.5f, 0.25f); //Set sibling index to where we want it in list + add destroyedCount since technically they are still here elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex); } } #region LogicElementHolder Implementation /// /// When a LogicElement has started being dragged from this Tray /// /// Element which is being dragged public override void OnRemove(LogicElementUI element) { Vector2 offset = new Vector2(element.rectTransform.rect.width/2, 0); int index = GetInsertIndex(element.rectTransform,offset); if (index >= reader.LogicChain.Count) index = reader.LogicChain.Count - 1; reader.LogicChain.RemoveAt(index); } /// /// When a logicElement needs to be added back to this Tray /// /// Element to add public override void OnAdd(LogicElementUI element) { int index = GetInsertIndex(element.rectTransform); reader.Insert(index, element.logicElement); Destroy(element.gameObject); } /// /// When a logic Element is hovering over this holder /// /// Element which is hovering public override void OnHover(LogicElementUI element) { insertIndex = GetInsertIndex(element.rectTransform); UpdateDisplay(); } /// /// First frame a logic Element is hovering over this holder /// /// Element which is hovering public override void OnHoverStart(LogicElementUI element) { Debug.Log("OnHoverStart"); //Create insert prefab at End insertIndex = content.childCount; UpdateDisplay(); } /// /// first frame a logic Element is no longer hovering over this holder /// /// Element which is hovering public override void OnHoverEnd(LogicElementUI element) { //Remove insert prefab insertIndex = -1; UpdateDisplay(); } #endregion LogicElementHolder Implementation /// /// Called when an element in this holder is double clicked /// /// element which was double clicked public override void OnDoubleClick(LogicElementUI element) { throw new System.NotImplementedException(); } #region Helper Functions public int GetInsertIndex(RectTransform rt, Vector2 offset) { Rect rect = rt.GlobalRect(); rect.center += offset; foreach (Transform child in content) { RectTransform childRect = child as RectTransform; if (rect.Overlaps(childRect.GlobalRect())) return child.GetSiblingIndex(); } return reader.LogicChain.Count; } public int GetInsertIndex(RectTransform rt) { return GetInsertIndex(rt, Vector2.zero); } #endregion Helper Functions }