/// <summary>
/// Displays a clip.
/// </summary>
/// <param name="trackRect">The Rect of the track the clip sits on.</param>
/// <param name="track">The track the clip sits on.</param>
/// <param name="clip">The clip to display.</param>
void DisplayClip(Rect trackRect, CutsceneTrack track, CutsceneClip clip)
{
const float trimWidth = 5f;
GUIStyle clipStyle = ed.style.GetStyle("Selected Clip");
// Set the clip style if this isn't the selected clip (selected clips all share the same style)
if (clip != ed.selectedClip) {
switch (clip.type) {
case Cutscene.MediaType.Shots:
clipStyle = ed.style.GetStyle("Shot Clip");
break;
case Cutscene.MediaType.Actors:
clipStyle = ed.style.GetStyle("Actor Clip");
break;
case Cutscene.MediaType.Audio:
clipStyle = ed.style.GetStyle("Audio Clip");
break;
default: // Cutscene.MediaType.Subtitles
clipStyle = ed.style.GetStyle("Subtitle Clip");
break;
}
}
Rect rect = new Rect((trackRect.x + clip.timelineStart) * ed.timelineZoom, trackRect.y + 1, clip.duration * ed.timelineZoom, clipStyle.fixedHeight);
GUI.BeginGroup(rect, clipStyle);
GUIContent clipLabel = new GUIContent(clip.name, "Clip: " + clip.name + "\nDuration: " + clip.duration + "\nTimeline start: " + clip.timelineStart + "\nTimeline end: " + (clip.timelineStart + clip.duration));
Rect clipLabelRect = new Rect(clipStyle.contentOffset.x, 0, rect.width - clipStyle.contentOffset.x, rect.height);
GUI.Label(clipLabelRect, clipLabel);
GUI.EndGroup();
// Handle mouse clicks
Vector2 mousePos = Event.current.mousePosition;
if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
switch (Event.current.button) {
case 0: // Left mouse button
ed.selectedClip = clip;
ed.selectedTrack = track;
break;
case 1: // Right mouse button
EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "CONTEXT/CutsceneClip/", new MenuCommand(clip));
Event.current.Use();
break;
default:
break;
}
}
if (clip.setToDelete) {
ed.selectedTrack.clips.Remove(clip);
return;
}
// Don't allow actions to be performed on the clip if the track is disabled or locked
if (!track.enabled || track.locked) {
return;
}
switch (ed.currentTool) {
case Tool.MoveResize:
// Define edit areas, adding custom cursors when hovered over
// Move
Rect move = new Rect(rect.x + trimWidth, rect.y, rect.width - (2 * trimWidth), rect.height);
EditorGUIUtility.AddCursorRect(move, MouseCursor.SlideArrow);
// Resize left
Rect resizeLeft = new Rect(rect.x, rect.y, trimWidth, rect.height);
EditorGUIUtility.AddCursorRect(resizeLeft, MouseCursor.ResizeHorizontal);
// Resize right
Rect resizeRight = new Rect(rect.xMax - trimWidth, rect.y, trimWidth, rect.height);
EditorGUIUtility.AddCursorRect(resizeRight, MouseCursor.ResizeHorizontal);
if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
ed.dragClip = clip;
// Move
if (move.Contains(Event.current.mousePosition)) {
ed.dragEvent = DragEvent.Move;
EDebug.Log("Cutscene Editor: starting clip move");
// Resize left
} else if (resizeLeft.Contains(Event.current.mousePosition)) {
ed.dragEvent = DragEvent.ResizeLeft;
EDebug.Log("Cutscene Editor: starting clip resize left");
// Resize right
} else if (resizeRight.Contains(Event.current.mousePosition)) {
ed.dragEvent = DragEvent.ResizeRight;
EDebug.Log("Cutscene Editor: starting clip resize right");
}
Event.current.Use();
} else if (Event.current.type == EventType.MouseDrag && ed.dragClip == clip) {
float shift = Event.current.delta.x / ed.timelineZoom;
switch (ed.dragEvent) {
case DragEvent.Move:
float newPos = clip.timelineStart + shift;
// Left collisions
CutsceneClip leftCollision = track.ContainsClipAtTime(newPos, clip);
if (leftCollision != null) {
newPos = leftCollision.timelineStart + leftCollision.duration;
}
// Right collisions
CutsceneClip rightCollision = track.ContainsClipAtTime(newPos + clip.duration, clip);
if (rightCollision != null) {
newPos = rightCollision.timelineStart - clip.duration;
}
if (newPos + clip.duration > ed.scene.duration) {
newPos = ed.scene.duration - clip.duration;
}
clip.SetTimelineStart(newPos);
break;
case DragEvent.ResizeLeft:
clip.SetTimelineStart(clip.timelineStart + shift);
clip.SetInPoint(clip.inPoint + shift);
// TODO Improve collision behaviour
CutsceneClip leftResizeCollision = track.ContainsClipAtTime(clip.timelineStart, clip);
if (leftResizeCollision != null) {
clip.SetTimelineStart(leftResizeCollision.timelineStart + leftResizeCollision.duration);
}
break;
case DragEvent.ResizeRight:
float newOut = clip.outPoint + shift;
// Right collisions
CutsceneClip rightResizeCollision = track.ContainsClipAtTime(clip.timelineStart + clip.duration + shift, clip);
if (rightResizeCollision != null) {
newOut = rightResizeCollision.timelineStart - clip.timelineStart + clip.inPoint;
}
clip.SetOutPoint(newOut);
break;
default:
break;
}
Event.current.Use();
} else if (Event.current.type == EventType.MouseUp) {
ed.dragClip = null;
Event.current.Use();
}
break;
case Tool.Scissors:
// TODO Switch to something better than the text cursor, if possible
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Text);
if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) {
SplitClip(track, clip, Event.current.mousePosition);
Event.current.Use();
}
break;
default:
break;
}
}