| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using UnityEditor.Timeline.Actions; |
| using UnityEngine; |
| using UnityEngine.Timeline; |
| using Object = UnityEngine.Object; |
|
|
| namespace UnityEditor.Timeline |
| { |
| class TimelineMarkerHeaderGUI : IRowGUI, ILayerable |
| { |
| static readonly GUIContent k_Muted = L10n.TextContent("Muted"); |
|
|
| int m_TrackHash; |
| TimelineAsset timeline { get; } |
| WindowState state { get; } |
| MarkersLayer m_Layer; |
| LayerZOrder m_ZOrder = new LayerZOrder(Layer.MarkerHeaderTrack, 0); |
|
|
| struct DrawData |
| { |
| public Rect headerRect; |
| public Rect contentRect; |
| public GUIStyle trackHeaderFont; |
| public Color colorTrackFont; |
| public bool isMuted; |
| public bool isSelected; |
| } |
|
|
| public TimelineMarkerHeaderGUI(TimelineAsset asset, WindowState state) |
| { |
| m_TrackHash = -1; |
| timeline = asset; |
| this.state = state; |
| } |
|
|
| public TrackAsset asset => timeline.markerTrack; |
| public Rect boundingRect { get; private set; } |
|
|
| public bool showMarkers => state.showMarkerHeader; |
| public bool muted => timeline.markerTrack != null && timeline.markerTrack.muted; |
| public bool locked => timeline.markerTrack.locked; |
| public LayerZOrder zOrder => m_ZOrder; |
|
|
| Rect IRowGUI.ToWindowSpace(Rect rect) |
| { |
| |
| return rect; |
| } |
|
|
| public void Draw(Rect markerHeaderRect, Rect markerContentRect, WindowState state) |
| { |
| boundingRect = markerContentRect; |
| var data = new DrawData |
| { |
| headerRect = markerHeaderRect, |
| contentRect = markerContentRect, |
| trackHeaderFont = DirectorStyles.Instance.trackHeaderFont, |
| colorTrackFont = DirectorStyles.Instance.customSkin.colorTrackFont, |
| isMuted = muted, |
| isSelected = IsSelected() |
| }; |
|
|
| if (state.showMarkerHeader) |
| { |
| DrawMarkerDrawer(data); |
| if (Event.current.type == EventType.Repaint) |
| state.spacePartitioner.AddBounds(this, boundingRect); |
| } |
|
|
| if (asset != null && Hash() != m_TrackHash) |
| Rebuild(); |
|
|
| Rect rect = state.showMarkerHeader ? markerContentRect : state.timeAreaRect; |
| using (new GUIViewportScope(rect)) |
| { |
| if (m_Layer != null) |
| m_Layer.Draw(rect, state); |
|
|
| HandleDragAndDrop(); |
| } |
|
|
| if (state.showMarkerHeader && data.isMuted) |
| DrawMuteOverlay(data); |
| } |
|
|
| public void Rebuild() |
| { |
| if (asset == null) |
| return; |
|
|
| m_Layer = new MarkersLayer(Layer.MarkersOnHeader, this); |
| m_TrackHash = Hash(); |
| } |
|
|
| void HandleDragAndDrop() |
| { |
| if (state.editSequence.isReadOnly || !state.showMarkerHeader) |
| return; |
|
|
| if (Event.current == null || Event.current.type != EventType.DragUpdated && |
| Event.current.type != EventType.DragPerform && Event.current.type != EventType.DragExited) |
| return; |
|
|
| var objectsBeingDropped = DragAndDrop.objectReferences.OfType<Object>(); |
| var candidateTime = TimelineHelpers.GetCandidateTime(Event.current.mousePosition); |
| var perform = Event.current.type == EventType.DragPerform; |
| var director = state.editSequence != null ? state.editSequence.director : null; |
| DragAndDrop.visualMode = TimelineDragging.HandleClipPaneObjectDragAndDrop(objectsBeingDropped, timeline.markerTrack, perform, |
| timeline, null, director, candidateTime, ResolveType); |
| if (perform && DragAndDrop.visualMode == DragAndDropVisualMode.Copy) |
| { |
| DragAndDrop.AcceptDrag(); |
| } |
| } |
|
|
| static bool ResolveType(IEnumerable<Type> types, Action<Type> onComplete, string formatString) |
| { |
| void CreateMarkerTrackOnComplete(Type type) |
| { |
| WindowState state = TimelineWindow.instance.state; |
| state.editSequence.asset.CreateMarkerTrack(); |
| state.showMarkerHeader = true; |
| onComplete(type); |
| } |
|
|
| return TimelineDragging.ResolveType(types, CreateMarkerTrackOnComplete, formatString); |
| } |
|
|
| int Hash() |
| { |
| return timeline.markerTrack == null ? 0 : timeline.markerTrack.Hash(); |
| } |
|
|
| static void DrawMarkerDrawer(DrawData data) |
| { |
| DrawMarkerDrawerHeaderBackground(data); |
| DrawMarkerDrawerHeader(data); |
| DrawMarkerDrawerContentBackground(data); |
| } |
|
|
| static void DrawMarkerDrawerHeaderBackground(DrawData data) |
| { |
| Color backgroundColor = data.isSelected |
| ? DirectorStyles.Instance.customSkin.colorSelection |
| : DirectorStyles.Instance.customSkin.markerHeaderDrawerBackgroundColor; |
| EditorGUI.DrawRect(data.headerRect, backgroundColor); |
| } |
|
|
| static void DrawMarkerDrawerHeader(DrawData data) |
| { |
| var textStyle = data.trackHeaderFont; |
| textStyle.normal.textColor = data.colorTrackFont; |
| var labelRect = data.headerRect; |
| labelRect.x += DirectorStyles.kBaseIndent; |
|
|
| EditorGUI.LabelField(labelRect, DirectorStyles.timelineMarkerTrackHeader); |
|
|
| const float buttonSize = WindowConstants.trackHeaderButtonSize; |
| const float padding = WindowConstants.trackHeaderButtonPadding; |
| var x = data.headerRect.xMax - buttonSize - padding - 2f; |
| var y = data.headerRect.y + (data.headerRect.height - buttonSize) / 2.0f; |
| var buttonRect = new Rect(x, y, buttonSize, buttonSize); |
|
|
| DrawTrackDropDownMenu(buttonRect); |
| buttonRect.x -= 21.0f; |
|
|
| DrawMuteButton(buttonRect, data); |
| } |
|
|
| static void DrawMarkerDrawerContentBackground(DrawData data) |
| { |
| Color trackBackgroundColor = DirectorStyles.Instance.customSkin.markerDrawerBackgroundColor; |
| if (data.isSelected) |
| trackBackgroundColor = DirectorStyles.Instance.customSkin.colorTrackBackgroundSelected; |
| EditorGUI.DrawRect(data.contentRect, trackBackgroundColor); |
| } |
|
|
| static void DrawMuteOverlay(DrawData data) |
| { |
| DirectorStyles styles = TimelineWindow.styles; |
|
|
| var colorOverlay = OverlayDrawer.CreateColorOverlay(GUIClip.Unclip(data.contentRect), styles.customSkin.colorTrackDarken); |
| colorOverlay.Draw(); |
|
|
| Rect textRect = Graphics.CalculateTextBoxSize(data.contentRect, styles.fontClip, k_Muted, WindowConstants.overlayTextPadding); |
| var boxOverlay = OverlayDrawer.CreateTextBoxOverlay( |
| GUIClip.Unclip(textRect), |
| k_Muted.text, |
| styles.fontClip, |
| Color.white, |
| styles.customSkin.colorLockTextBG, |
| styles.displayBackground); |
| boxOverlay.Draw(); |
| } |
|
|
| static void DrawTrackDropDownMenu(Rect rect) |
| { |
| if (GUI.Button(rect, GUIContent.none, DirectorStyles.Instance.trackOptions)) |
| { |
| SelectionManager.SelectOnly(TimelineEditor.inspectedAsset.markerTrack); |
| SequencerContextMenu.ShowTrackContextMenu(null); |
| } |
| } |
|
|
| static void DrawMuteButton(Rect rect, DrawData data) |
| { |
| bool muted = GUI.Toggle(rect, data.isMuted, string.Empty, TimelineWindow.styles.trackMuteButton); |
| if (muted != data.isMuted) |
| new[] { TimelineEditor.inspectedAsset.markerTrack }.Invoke<MuteTrack>(); |
| } |
|
|
| bool IsSelected() |
| { |
| return SelectionManager.Contains(asset); |
| } |
| } |
| } |
|
|