HeavenStudio/Assets/Scripts/LevelEditor/Timeline/TimelineEventObj.cs

485 lines
16 KiB
C#
Raw Normal View History

2022-01-09 23:35:55 +00:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Starpelly;
using DG.Tweening;
2022-03-14 14:21:05 +00:00
namespace HeavenStudio.Editor.Track
2022-01-09 23:35:55 +00:00
{
public class TimelineEventObj : MonoBehaviour
{
private float startPosX;
private float startPosY;
private Vector3 lastPos;
public Vector2 moveStartPos;
2022-01-17 19:23:18 +00:00
private RectTransform rectTransform;
2022-01-09 23:35:55 +00:00
[Header("Components")]
[SerializeField] private RectTransform PosPreview;
[SerializeField] private RectTransform PosPreviewRef;
[SerializeField] public Image Icon;
[SerializeField] private Image selectedImage;
[SerializeField] private RectTransform outline;
[SerializeField] private RectTransform resizeGraphic;
2022-01-21 21:09:14 +00:00
[SerializeField] private RectTransform leftDrag;
[SerializeField] private RectTransform rightDrag;
2022-06-30 01:58:21 +00:00
// private GameObject moveTemp;
2022-01-09 23:35:55 +00:00
[Header("Properties")]
public DynamicBeatmap.DynamicEntity entity;
2022-01-09 23:35:55 +00:00
public float length;
public bool eligibleToMove = false;
2022-01-12 03:29:27 +00:00
private bool lastVisible;
2022-01-13 03:59:54 +00:00
public bool selected;
public bool mouseHovering;
2022-01-17 19:23:18 +00:00
public bool resizable;
public bool resizing;
public bool moving;
public bool wasDuplicated;
2022-01-21 21:09:14 +00:00
private bool resizingLeft;
private bool resizingRight;
private bool inResizeRegion;
public bool isCreating;
public string eventObjID;
2022-01-12 03:29:27 +00:00
[Header("Colors")]
public Color NormalCol;
2022-01-09 23:35:55 +00:00
2022-01-17 19:23:18 +00:00
private void Start()
{
moveStartPos = transform.localPosition;
2022-01-17 19:23:18 +00:00
rectTransform = GetComponent<RectTransform>();
if (!resizable)
{
Destroy(resizeGraphic.gameObject);
2022-01-17 19:23:18 +00:00
}
2022-06-30 01:58:21 +00:00
// what the fuck????
// moveTemp = new GameObject();
// moveTemp.transform.SetParent(this.transform.parent);
2022-02-03 07:28:14 +00:00
2022-02-03 08:25:27 +00:00
bool visible = rectTransform.IsVisibleFrom(Editor.instance.EditorCamera);
2022-02-03 07:28:14 +00:00
for (int i = 0; i < this.transform.childCount; i++)
{
if (i != 4)
this.transform.GetChild(i).gameObject.SetActive(visible);
}
2022-01-17 19:23:18 +00:00
}
2022-01-09 23:35:55 +00:00
private void Update()
{
selected = Selections.instance.eventsSelected.Contains(this);
entity = GameManager.instance.Beatmap.entities.Find(a => a.eventObj == this);
2022-02-03 08:25:27 +00:00
mouseHovering = RectTransformUtility.RectangleContainsScreenPoint(rectTransform, Input.mousePosition, Editor.instance.EditorCamera) && Timeline.instance.timelineState.selected;
2022-01-13 03:59:54 +00:00
#region Optimizations
2022-01-12 03:29:27 +00:00
// thank you to @chrislo27 for suggesting the fix for this.
// only renders blocks if they're in view of the timeline viewport
var leftSide = rectTransform.localPosition.x;
var rightSide = leftSide + rectTransform.sizeDelta.x;
bool visible = (rightSide >= Timeline.instance.leftSide && leftSide <= Timeline.instance.rightSide);
2022-01-12 03:29:27 +00:00
if (visible != lastVisible)
{
for (int i = 0; i < this.transform.childCount; i++)
{
2022-02-03 07:28:14 +00:00
if (transform.GetChild(i).gameObject != selectedImage)
this.transform.GetChild(i).gameObject.SetActive(visible);
2022-01-12 03:29:27 +00:00
}
}
lastVisible = visible;
2022-01-13 03:59:54 +00:00
#endregion
2022-06-30 01:58:21 +00:00
SetColor(entity.track);
2022-01-13 03:59:54 +00:00
if (selected)
{
if (Input.GetKeyDown(KeyCode.Delete))
{
/*Selections.instance.Deselect(this);
Timeline.instance.DestroyEventObject(entity);*/
}
2022-01-16 19:23:46 +00:00
selectedImage.gameObject.SetActive(true);
for (int i = 0; i < outline.childCount; i++)
2022-01-17 19:23:18 +00:00
{
if (moving)
outline.GetChild(i).GetComponent<Image>().color = Color.magenta;
else
outline.GetChild(i).GetComponent<Image>().color = Color.cyan;
2022-01-17 19:23:18 +00:00
}
2022-01-16 19:23:46 +00:00
}
else
{
selectedImage.gameObject.SetActive(false);
2022-01-16 19:23:46 +00:00
for (int i = 0; i < outline.childCount; i++)
outline.GetChild(i).GetComponent<Image>().color = new Color32(0, 0, 0, 51);
2022-01-09 23:35:55 +00:00
}
2022-02-03 07:28:14 +00:00
if (Conductor.instance.NotStopped())
{
Cancel();
2022-06-30 01:58:21 +00:00
if (moving)
moving = false;
if (selected)
{
selected = false;
selectedImage.gameObject.SetActive(false);
for (int i = 0; i < outline.childCount; i++)
outline.GetChild(i).GetComponent<Image>().color = new Color32(0, 0, 0, 51);
}
rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, Timeline.instance.LayerHeight());
this.transform.localPosition = new Vector3(this.transform.localPosition.x, -entity.track * Timeline.instance.LayerHeight());
2022-02-03 07:28:14 +00:00
return;
}
2022-01-17 19:23:18 +00:00
if (!resizing)
2022-01-13 03:59:54 +00:00
{
if (Timeline.instance.eventObjs.FindAll(c => c.moving).Count > 0 && selected)
2022-01-13 03:59:54 +00:00
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
//duplicate the entity if holding alt or m-click
if ((!wasDuplicated) && (Input.GetKey(KeyCode.LeftAlt) || Input.GetMouseButton(2)))
2022-01-13 03:59:54 +00:00
{
Selections.instance.Deselect(this);
this.wasDuplicated = false;
this.moving = false;
transform.localPosition = moveStartPos;
OnComplete(false);
var te = Timeline.instance.CopyEventObject(this);
Selections.instance.DragSelect(te);
te.wasDuplicated = true;
te.transform.localPosition = transform.localPosition;
te.moveStartPos = transform.localPosition;
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
2022-01-17 19:23:18 +00:00
{
Timeline.instance.eventObjs[i].startPosX = mousePos.x - Timeline.instance.eventObjs[i].transform.position.x;
Timeline.instance.eventObjs[i].startPosY = mousePos.y - Timeline.instance.eventObjs[i].transform.position.y;
2022-01-17 19:23:18 +00:00
}
2022-01-21 21:09:14 +00:00
te.moving = true;
2022-07-04 16:57:19 +00:00
}
else
{
this.transform.position = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY - 0.40f, 0);
this.transform.localPosition = new Vector3(Mathf.Max(Mathp.Round2Nearest(this.transform.localPosition.x, Timeline.SnapInterval()), 0), Timeline.instance.SnapToLayer(this.transform.localPosition.y));
}
2022-01-13 03:59:54 +00:00
2022-02-03 22:20:26 +00:00
if (lastPos != transform.localPosition)
{
2022-01-17 19:23:18 +00:00
OnMove();
}
2022-01-17 19:23:18 +00:00
2022-02-03 22:20:26 +00:00
lastPos = transform.localPosition;
2022-01-17 19:23:18 +00:00
}
2022-01-13 03:59:54 +00:00
}
2022-01-21 21:09:14 +00:00
else if (resizingLeft)
{
if (moving)
moving = false;
2022-01-21 21:09:14 +00:00
SetPivot(new Vector2(1, rectTransform.pivot.y));
Vector2 sizeDelta = rectTransform.sizeDelta;
Vector2 mousePos;
2022-02-03 08:25:27 +00:00
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, Editor.instance.EditorCamera, out mousePos);
2022-01-21 21:09:14 +00:00
sizeDelta = new Vector2(-mousePos.x + 0.15f, sizeDelta.y);
sizeDelta = new Vector2(Mathf.Clamp(sizeDelta.x, Timeline.SnapInterval(), rectTransform.localPosition.x), sizeDelta.y);
2022-01-21 21:09:14 +00:00
rectTransform.sizeDelta = new Vector2(Mathp.Round2Nearest(sizeDelta.x, Timeline.SnapInterval()), sizeDelta.y);
2022-01-21 21:09:14 +00:00
SetPivot(new Vector2(0, rectTransform.pivot.y));
OnComplete(false);
2022-01-21 21:09:14 +00:00
}
else if (resizingRight)
{
if (moving)
moving = false;
2022-01-21 21:09:14 +00:00
Vector2 sizeDelta = rectTransform.sizeDelta;
Vector2 mousePos;
2022-02-03 08:25:27 +00:00
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, Editor.instance.EditorCamera, out mousePos);
2022-01-21 21:09:14 +00:00
sizeDelta = new Vector2(mousePos.x + 0.15f, sizeDelta.y);
sizeDelta = new Vector2(Mathf.Clamp(sizeDelta.x, Timeline.SnapInterval(), Mathf.Infinity), sizeDelta.y);
2022-01-21 21:09:14 +00:00
rectTransform.sizeDelta = new Vector2(Mathp.Round2Nearest(sizeDelta.x, Timeline.SnapInterval()), sizeDelta.y);
2022-01-21 21:09:14 +00:00
SetPivot(new Vector2(0, rectTransform.pivot.y));
OnComplete(false);
2022-01-21 21:09:14 +00:00
}
if (Input.GetMouseButtonUp(0))
{
OnLeftUp();
OnRightUp();
}
2022-01-13 03:59:54 +00:00
2022-01-21 21:09:14 +00:00
if (resizing && selected || inResizeRegion && selected)
{
if (resizable)
Cursor.SetCursor(Resources.Load<Texture2D>("Cursors/horizontal_resize"), new Vector2(8, 8), CursorMode.Auto);
}
// should consider adding this someday
// else if (moving && selected || mouseHovering && selected)
// {
// Cursor.SetCursor(Resources.Load<Texture2D>("Cursors/move"), new Vector2(8, 8), CursorMode.Auto);
// }
else
2022-01-21 21:09:14 +00:00
{
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
}
2022-06-30 01:58:21 +00:00
rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, Timeline.instance.LayerHeight());
this.transform.localPosition = new Vector3(this.transform.localPosition.x, -entity.track * Timeline.instance.LayerHeight());
2022-01-17 19:23:18 +00:00
}
#region ClickEvents
public void OnClick()
{
if (Input.GetMouseButton(0) && Timeline.instance.timelineState.selected)
{
if (Input.GetKey(KeyCode.LeftShift))
2022-01-21 21:09:14 +00:00
{
Selections.instance.ShiftClickSelect(this);
}
else
{
if (!selected)
{
Selections.instance.ClickSelect(this);
}
2022-01-21 21:09:14 +00:00
}
}
}
public void OnDown()
{
2022-02-03 22:20:26 +00:00
if (Input.GetMouseButton(0))
2022-01-21 21:09:14 +00:00
{
2022-02-03 22:20:26 +00:00
if (selected && Timeline.instance.timelineState.selected)
2022-01-21 21:09:14 +00:00
{
moveStartPos = transform.localPosition;
2022-02-03 22:20:26 +00:00
for (int i = 0; i < Timeline.instance.eventObjs.Count; i++)
{
Vector3 mousePos = Editor.instance.EditorCamera.ScreenToWorldPoint(Input.mousePosition);
Timeline.instance.eventObjs[i].startPosX = mousePos.x - Timeline.instance.eventObjs[i].transform.position.x;
Timeline.instance.eventObjs[i].startPosY = mousePos.y - Timeline.instance.eventObjs[i].transform.position.y;
}
moving = true;
}
2022-01-21 21:09:14 +00:00
}
else if (Input.GetMouseButton(1))
{
EventParameterManager.instance.StartParams(entity);
}
}
public void OnUp()
{
// lastPos_ = this.lastPos_;
// previousPos = this.transform.localPosition;
if (selected && Timeline.instance.timelineState.selected)
{
if (wasDuplicated)
{
Timeline.instance.FinalizeDuplicateEventStack();
wasDuplicated = false;
}
if (eligibleToMove)
{
OnComplete(true);
moveStartPos = transform.localPosition;
}
moving = false;
Cancel();
if (isCreating == true)
{
isCreating = false;
CommandManager.instance.Execute(new Commands.Place(this));
}
}
}
private void Cancel()
{
eligibleToMove = false;
}
#endregion
2022-01-17 19:23:18 +00:00
#region ResizeEvents
public void DragEnter()
{
2022-01-21 21:09:14 +00:00
inResizeRegion = true;
2022-01-17 19:23:18 +00:00
}
public void DragExit()
{
2022-01-21 21:09:14 +00:00
inResizeRegion = false;
2022-01-17 19:23:18 +00:00
}
public void OnLeftDown()
{
2022-01-21 21:09:14 +00:00
if (resizable && selected)
{
ResetResize();
resizing = true;
resizingLeft = true;
}
2022-01-17 19:23:18 +00:00
}
2022-01-09 23:35:55 +00:00
2022-01-17 19:23:18 +00:00
public void OnLeftUp()
{
2022-01-21 21:09:14 +00:00
if (resizable && selected)
{
ResetResize();
}
2022-01-17 19:23:18 +00:00
}
2022-01-21 21:09:14 +00:00
2022-01-17 19:23:18 +00:00
public void OnRightDown()
{
2022-01-21 21:09:14 +00:00
if (resizable && selected)
{
ResetResize();
resizing = true;
resizingRight = true;
}
2022-01-17 19:23:18 +00:00
}
2022-01-21 21:09:14 +00:00
public void OnRightUp()
2022-01-17 19:23:18 +00:00
{
2022-01-21 21:09:14 +00:00
if (resizable && selected)
{
ResetResize();
}
2022-01-09 23:35:55 +00:00
}
2022-01-21 21:09:14 +00:00
private void ResetResize()
2022-01-17 19:23:18 +00:00
{
2022-01-21 21:09:14 +00:00
resizingLeft = false;
resizingRight = false;
2022-01-17 19:23:18 +00:00
resizing = false;
}
private void SetPivot(Vector2 pivot)
{
if (rectTransform == null) return;
Vector2 size = rectTransform.rect.size;
Vector2 deltaPivot = rectTransform.pivot - pivot;
Vector3 deltaPosition = new Vector3(deltaPivot.x * size.x, deltaPivot.y * size.y);
rectTransform.pivot = pivot;
rectTransform.localPosition -= deltaPosition;
}
#endregion
#region OnEvents
2022-01-09 23:35:55 +00:00
private void OnMove()
{
if (GameManager.instance.Beatmap.entities.FindAll(c => c.beat == this.transform.localPosition.x && c.track == GetTrack() && c != this.entity).Count > 0)
2022-01-09 23:35:55 +00:00
{
eligibleToMove = false;
}
else
{
eligibleToMove = true;
}
OnComplete(true);
2022-01-09 23:35:55 +00:00
}
private void OnComplete(bool move)
2022-01-09 23:35:55 +00:00
{
2022-01-17 19:23:18 +00:00
entity.length = rectTransform.sizeDelta.x;
2022-01-11 00:17:29 +00:00
entity.beat = this.transform.localPosition.x;
2022-01-09 23:35:55 +00:00
GameManager.instance.SortEventsList();
entity.track = GetTrack();
2022-01-13 03:59:54 +00:00
}
2022-01-17 19:23:18 +00:00
#endregion
2022-01-13 03:59:54 +00:00
#region Selection
#endregion
#region Extra
2022-01-12 03:29:27 +00:00
public void SetColor(int type)
{
Color c = Color.white;
switch (type)
{
case 0:
c = EditorTheme.theme.properties.Layer1Col.Hex2RGB();
2022-01-12 03:29:27 +00:00
break;
case 1:
c = EditorTheme.theme.properties.Layer2Col.Hex2RGB();
2022-01-12 03:29:27 +00:00
break;
case 2:
c = EditorTheme.theme.properties.Layer3Col.Hex2RGB();
break;
case 3:
c = EditorTheme.theme.properties.Layer4Col.Hex2RGB();
2022-01-12 03:29:27 +00:00
break;
case 4:
c = EditorTheme.theme.properties.Layer5Col.Hex2RGB();
break;
2022-01-12 03:29:27 +00:00
}
2022-01-14 22:46:14 +00:00
// c = new Color(c.r, c.g, c.b, 0.85f);
2022-01-12 03:29:27 +00:00
transform.GetChild(0).GetComponent<Image>().color = c;
2022-01-17 20:08:32 +00:00
if (resizable)
{
c = new Color(0, 0, 0, 0.35f);
transform.GetChild(1).GetChild(0).GetComponent<Image>().color = c;
transform.GetChild(1).GetChild(1).GetComponent<Image>().color = c;
transform.GetChild(1).GetChild(2).GetComponent<Image>().color = c;
}
2022-01-12 03:29:27 +00:00
}
2022-01-13 03:59:54 +00:00
public int GetTrack()
{
return (int)Mathf.Round(this.transform.localPosition.y / Timeline.instance.LayerHeight()) * -1;
}
2022-01-13 03:59:54 +00:00
private void OnDestroy()
{
// better safety net than canada's healthcare system
// this is still hilarious
// GameManager.instance.Beatmap.entities.Remove(GameManager.instance.Beatmap.entities.Find(c => c.eventObj = this));
2022-01-13 03:59:54 +00:00
}
#endregion
2022-01-09 23:35:55 +00:00
}
}