/// <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; } }