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.

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