You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.2 KiB

5 years ago
5 years ago
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using TMPro;
  5. using UnityEngine.UI;
  6. public class LogicTrayUI : LogicElementHolder
  7. {
  8. //[SerializeField]
  9. //protected List<LogicBlock> list;
  10. [SerializeField]
  11. protected LogicElementUI Prefab;
  12. [SerializeField]
  13. protected int insertIndex = -1;
  14. [SerializeField]
  15. private Transform content;
  16. [SerializeField]
  17. private int maxLength = 6;
  18. [SerializeField]
  19. public BlockReader reader;
  20. #region Unity Functions
  21. public void Start()
  22. {
  23. UpdateDisplay();
  24. }
  25. protected override void OnEnable()
  26. {
  27. base.OnEnable();
  28. if (reader != null)
  29. reader.OnUpdate += UpdateDisplay;
  30. }
  31. protected override void OnDisable()
  32. {
  33. base.OnDisable();
  34. if (reader != null)
  35. reader.OnUpdate -= UpdateDisplay;
  36. }
  37. #endregion Unity Functions
  38. public void SetBlockReader(BlockReader newBlockReader)
  39. {
  40. if (reader != null)
  41. reader.OnUpdate -= UpdateDisplay;
  42. reader = newBlockReader;
  43. reader.OnUpdate += UpdateDisplay;
  44. UpdateDisplay();
  45. }
  46. [ContextMenu("Update Display")]
  47. public void UpdateDisplay()
  48. {
  49. if (reader == null)
  50. return;
  51. //Destroy all children
  52. 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
  53. foreach (Transform child in content)
  54. Destroy(child.gameObject);
  55. //Instatiate logicElement prefab
  56. foreach (LogicBlock element in reader.LogicChain)
  57. {
  58. LogicElementUI elementUI = Instantiate(Prefab.gameObject, content).GetComponent<LogicElementUI>();
  59. elementUI.Initialise(element, this);
  60. }
  61. //Add insertIndex object if needed
  62. if (insertIndex != -1)
  63. {
  64. GameObject elementObject = Instantiate(Prefab.gameObject, content);
  65. if (reader.Length < maxLength)
  66. {
  67. elementObject.GetComponentInChildren<TextMeshProUGUI>().text = "insert";
  68. elementObject.GetComponentInChildren<Image>().color = new Color(0.5f, 0.5f, 0.5f, 0.25f);
  69. }
  70. else
  71. {
  72. elementObject.GetComponentInChildren<TextMeshProUGUI>().text = "X";
  73. elementObject.GetComponentInChildren<Image>().color = new Color(1.0f, 0.25f, 0.25f, 0.5f);
  74. }
  75. //Set sibling index to where we want it in list + add destroyedCount since technically they are still here
  76. elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex);
  77. }
  78. }
  79. #region LogicElementHolder Implementation
  80. /// <summary>
  81. /// When a LogicElement has started being dragged from this Tray
  82. /// </summary>
  83. /// <param name="element">Element which is being dragged</param>
  84. public override void OnRemove(LogicElementUI element)
  85. {
  86. Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
  87. int index = GetInsertIndex(element.rectTransform, offset);
  88. Debug.Log("Removing at " + index);
  89. if (index >= reader.LogicChain.Count)
  90. index = reader.LogicChain.Count - 1;
  91. reader.LogicChain.RemoveAt(index);
  92. }
  93. /// <summary>
  94. /// When a logicElement needs to be added back to this Tray
  95. /// </summary>
  96. /// <param name="element">Element to add</param>
  97. public override void OnAdd(LogicElementUI element)
  98. {
  99. Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
  100. int index = GetInsertIndex(element.rectTransform,offset);
  101. reader.Insert(index, element.logicElement);
  102. Destroy(element.gameObject);
  103. }
  104. /// <summary>
  105. /// When a logic Element is hovering over this holder
  106. /// </summary>
  107. /// <param name="element">Element which is hovering</param>
  108. public override void OnHover(LogicElementUI element)
  109. {
  110. Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
  111. insertIndex = GetInsertIndex(element.rectTransform, offset);
  112. UpdateDisplay();
  113. }
  114. /// <summary>
  115. /// First frame a logic Element is hovering over this holder
  116. /// </summary>
  117. /// <param name="element">Element which is hovering</param>
  118. public override void OnHoverStart(LogicElementUI element)
  119. {
  120. Debug.Log("OnHoverStart");
  121. //Create insert prefab at End
  122. insertIndex = content.childCount;
  123. UpdateDisplay();
  124. }
  125. /// <summary>
  126. /// first frame a logic Element is no longer hovering over this holder
  127. /// </summary>
  128. /// <param name="element">Element which is hovering</param>
  129. public override void OnHoverEnd(LogicElementUI element)
  130. {
  131. //Remove insert prefab
  132. insertIndex = -1;
  133. UpdateDisplay();
  134. }
  135. /// <summary>
  136. /// Called when an element in this holder is double clicked
  137. /// </summary>
  138. /// <param name="element">element which was double clicked</param>
  139. public override void OnDoubleClick(LogicElementUI element)
  140. {
  141. throw new System.NotImplementedException();
  142. }
  143. /// <summary>
  144. /// Called to check if this holder can hold the provided element;
  145. /// </summary>
  146. /// <param name="element">element to check if it can hold</param>
  147. /// <returns>returns true if this can hold the element </returns>
  148. public override bool canHold(LogicElementUI element)
  149. {
  150. return reader.Length < maxLength;
  151. }
  152. #endregion LogicElementHolder Implementation
  153. #region Helper Functions
  154. public int GetInsertIndex(RectTransform rt, Vector2 offset)
  155. {
  156. Rect rect = rt.rect;
  157. rect.center += offset;
  158. rect = rt.TransformRect(rect);
  159. DebugExtensions.DrawRect(rect, Color.green);
  160. foreach (Transform child in content)
  161. {
  162. RectTransform childRect = child as RectTransform;
  163. if (rect.Overlaps(childRect.GlobalRect()))
  164. return child.GetSiblingIndex();
  165. }
  166. Debug.Log("Returning last");
  167. return reader.LogicChain.Count;
  168. }
  169. public int GetInsertIndex(RectTransform rt)
  170. {
  171. return GetInsertIndex(rt, Vector2.zero);
  172. }
  173. #endregion Helper Functions
  174. }