using System; using System.Linq; using UnityEngine; using UnityEngine.Timeline; namespace UnityEditor.Timeline { class MovingItems : ItemsPerTrack { TrackAsset m_ReferenceTrack; readonly bool m_AllowTrackSwitch; readonly Rect[] m_ItemsBoundsOnTrack; readonly Vector2[] m_ItemsMouseOffsets; static readonly Rect s_InvisibleBounds = new Rect(float.MaxValue, float.MaxValue, 0.0f, 0.0f); public TrackAsset originalTrack { get; } public override TrackAsset targetTrack { get { if (m_AllowTrackSwitch) return m_ReferenceTrack; return originalTrack; } } public bool canDrop; public double start { get { return m_ItemsGroup.start; } set { m_ItemsGroup.start = value; } } public double end { get { return m_ItemsGroup.end; } } public Rect[] onTrackItemsBounds { get { return m_ItemsBoundsOnTrack; } } public MovingItems(WindowState state, TrackAsset parentTrack, ITimelineItem[] items, TrackAsset referenceTrack, Vector2 mousePosition, bool allowTrackSwitch) : base(parentTrack, items) { originalTrack = parentTrack; m_ReferenceTrack = referenceTrack; m_AllowTrackSwitch = allowTrackSwitch; m_ItemsBoundsOnTrack = new Rect[items.Length]; m_ItemsMouseOffsets = new Vector2[items.Length]; for (int i = 0; i < items.Length; ++i) { var itemGUi = items[i].gui; if (itemGUi != null) { m_ItemsBoundsOnTrack[i] = itemGUi.rect; m_ItemsMouseOffsets[i] = mousePosition - m_ItemsBoundsOnTrack[i].position; } } canDrop = true; } public void SetReferenceTrack(TrackAsset track) { m_ReferenceTrack = track; } public bool HasAnyDetachedParents() { return m_ItemsGroup.items.Any(x => x.parentTrack == null); } public void RefreshBounds(WindowState state, Vector2 mousePosition) { for (int i = 0; i < m_ItemsGroup.items.Length; ++i) { ITimelineItem item = m_ItemsGroup.items[i]; TimelineItemGUI itemGUI = item.gui; if (itemGUI == null) continue; if (item.parentTrack != null) { m_ItemsBoundsOnTrack[i] = itemGUI.visible ? itemGUI.rect : s_InvisibleBounds; } else { if (targetTrack != null) { var trackGUI = (TimelineTrackGUI)TimelineWindow.instance.allTracks.FirstOrDefault(t => t.track == targetTrack); if (trackGUI == null) return; var trackRect = trackGUI.boundingRect; m_ItemsBoundsOnTrack[i] = itemGUI.RectToTimeline(trackRect, state); } else { m_ItemsBoundsOnTrack[i].position = mousePosition - m_ItemsMouseOffsets[i]; } } } } public void Draw(bool isValid) { for (int i = 0; i < m_ItemsBoundsOnTrack.Length; ++i) { var rect = m_ItemsBoundsOnTrack[i]; DrawItemInternal(m_ItemsGroup.items[i], rect, isValid); } } static void DrawItemInternal(ITimelineItem item, Rect rect, bool isValid) { var clipGUI = item.gui as TimelineClipGUI; if (clipGUI != null) { if (isValid) { clipGUI.DrawGhostClip(rect); } else { clipGUI.DrawInvalidClip(rect); } } } } }