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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class LogicTrayUI : LogicElementHolder
{
//[SerializeField]
//protected List<LogicBlock> list;
[SerializeField]
protected LogicElementUI Prefab;
[SerializeField]
protected int insertIndex = -1;
[SerializeField]
private Transform content;
[SerializeField]
private GameObject playButton;
[SerializeField]
private GameObject returnButton;
[SerializeField]
private Image border;
[SerializeField]
private int maxLength = 6;
[SerializeField]
public BlockReader reader;
[SerializeField]
private List<QueueData> readerQueue = new List<QueueData>();
#region Unity Functions
public void Start()
{
readerQueue.Add(new QueueData(null, reader, border.color));
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();
}
public void OnClick_Return()
{
if (readerQueue.Count <= 1)
return;
QueueData lastData = readerQueue[readerQueue.Count - 1];
readerQueue.RemoveAt(readerQueue.Count - 1);
//lastData.block.blockReader.LogicChain = new List<LogicBlock>(lastData.reader.LogicChain);
border.color = readerQueue[readerQueue.Count - 1].color;
// readerQueue[readerQueue.Count - 1].reader.LogicChain = new List<LogicBlock>(reader.LogicChain);
SetBlockReader(readerQueue[readerQueue.Count - 1].reader);
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<LogicElementUI>();
elementUI.Initialise(element, this,false);
}
//Add insertIndex object if needed
if (insertIndex != -1)
{
GameObject elementObject = Instantiate(Prefab.gameObject, content);
if (reader.Length < maxLength)
{
elementObject.GetComponentInChildren<TextMeshProUGUI>().text = "insert";
elementObject.GetComponentInChildren<Image>().color = new Color(0.5f, 0.5f, 0.5f, 0.25f);
}
else
{
elementObject.GetComponentInChildren<TextMeshProUGUI>().text = "X";
elementObject.GetComponentInChildren<Image>().color = new Color(1.0f, 0.25f, 0.25f, 0.5f);
}
//Set sibling index to where we want it in list + add destroyedCount since technically they are still here
elementObject.transform.SetSiblingIndex(destroyedCount + insertIndex);
}
playButton.SetActive(readerQueue.Count <= 1);
returnButton.SetActive(readerQueue.Count > 1);
}
#region LogicElementHolder Implementation
/// <summary>
/// When a LogicElement has started being dragged from this Tray
/// </summary>
/// <param name="element">Element which is being dragged</param>
public override void OnRemove(LogicElementUI element)
{
Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
int index = GetInsertIndex(element.rectTransform, offset);
Debug.Log("Removing at " + index);
if (index >= reader.LogicChain.Count)
index = reader.LogicChain.Count - 1;
reader.LogicChain.RemoveAt(index);
}
/// <summary>
/// When a logicElement needs to be added back to this Tray
/// </summary>
/// <param name="element">Element to add</param>
public override void OnAdd(LogicElementUI element)
{
Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
int index = GetInsertIndex(element.rectTransform,offset);
reader.Insert(index, element.logicElement);
Destroy(element.gameObject);
}
/// <summary>
/// When a logic Element is hovering over this holder
/// </summary>
/// <param name="element">Element which is hovering</param>
public override void OnHover(LogicElementUI element)
{
Vector2 offset = new Vector2(element.rectTransform.rect.width / 2, 0);
insertIndex = GetInsertIndex(element.rectTransform, offset);
UpdateDisplay();
}
/// <summary>
/// First frame a logic Element is hovering over this holder
/// </summary>
/// <param name="element">Element which is hovering</param>
public override void OnHoverStart(LogicElementUI element)
{
Debug.Log("OnHoverStart");
//Create insert prefab at End
insertIndex = content.childCount;
UpdateDisplay();
}
/// <summary>
/// first frame a logic Element is no longer hovering over this holder
/// </summary>
/// <param name="element">Element which is hovering</param>
public override void OnHoverEnd(LogicElementUI element)
{
//Remove insert prefab
insertIndex = -1;
UpdateDisplay();
}
/// <summary>
/// Called when an element in this holder is double clicked
/// </summary>
/// <param name="element">element which was double clicked</param>
public override void OnDoubleClick(LogicElementUI element)
{
CombinedBlock block = element.logicElement as CombinedBlock;
if (block == null || !block.isEditable)
return;
readerQueue.Add(new QueueData(block,block.blockReader,block.Color));
border.color = block.Color;
SetBlockReader(block.blockReader);
}
/// <summary>
/// Called to check if this holder can hold the provided element;
/// </summary>
/// <param name="element">element to check if it can hold</param>
/// <returns>returns true if this can hold the element </returns>
public override bool canHold(LogicBlock element)
{
return readerQueue[0].reader.Length < maxLength;
}
#endregion LogicElementHolder Implementation
#region Helper Functions
public int GetInsertIndex(RectTransform rt, Vector2 offset)
{
Rect rect = rt.rect;
rect.center += offset;
rect = rt.TransformRect(rect);
DebugExtensions.DrawRect(rect, Color.green);
foreach (Transform child in content)
{
RectTransform childRect = child as RectTransform;
if (rect.Overlaps(childRect.GlobalRect()))
return child.GetSiblingIndex();
}
Debug.Log("Returning last");
return reader.LogicChain.Count;
}
public int GetInsertIndex(RectTransform rt)
{
return GetInsertIndex(rt, Vector2.zero);
}
#endregion Helper Functions
[System.Serializable]
public class QueueData
{
public Color color;
public BlockReader reader;
public CombinedBlock block;
public QueueData(CombinedBlock block, BlockReader reader, Color color)
{
this.color = color;
this.reader = reader;
this.block = block;
}
}
}