A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using UnityEditor.Timeline.Actions;
5using UnityEngine;
6using UnityEngine.Timeline;
7using Object = UnityEngine.Object;
8
9namespace UnityEditor.Timeline
10{
11 class TimelineMarkerHeaderGUI : IRowGUI, ILayerable
12 {
13 static readonly GUIContent k_Muted = L10n.TextContent("Muted");
14
15 int m_TrackHash;
16 TimelineAsset timeline { get; }
17 WindowState state { get; }
18 MarkersLayer m_Layer;
19 LayerZOrder m_ZOrder = new LayerZOrder(Layer.MarkerHeaderTrack, 0);
20
21 struct DrawData
22 {
23 public Rect headerRect;
24 public Rect contentRect;
25 public GUIStyle trackHeaderFont;
26 public Color colorTrackFont;
27 public bool isMuted;
28 public bool isSelected;
29 }
30
31 public TimelineMarkerHeaderGUI(TimelineAsset asset, WindowState state)
32 {
33 m_TrackHash = -1;
34 timeline = asset;
35 this.state = state;
36 }
37
38 public TrackAsset asset => timeline.markerTrack;
39 public Rect boundingRect { get; private set; }
40
41 public bool showMarkers => state.showMarkerHeader;
42 public bool muted => timeline.markerTrack != null && timeline.markerTrack.muted;
43 public bool locked => timeline.markerTrack.locked;
44 public LayerZOrder zOrder => m_ZOrder;
45
46 Rect IRowGUI.ToWindowSpace(Rect rect)
47 {
48 //header gui is already in global coordinates
49 return rect;
50 }
51
52 public void Draw(Rect markerHeaderRect, Rect markerContentRect, WindowState state)
53 {
54 boundingRect = markerContentRect;
55 var data = new DrawData
56 {
57 headerRect = markerHeaderRect,
58 contentRect = markerContentRect,
59 trackHeaderFont = DirectorStyles.Instance.trackHeaderFont,
60 colorTrackFont = DirectorStyles.Instance.customSkin.colorTrackFont,
61 isMuted = muted,
62 isSelected = IsSelected()
63 };
64
65 if (state.showMarkerHeader)
66 {
67 DrawMarkerDrawer(data);
68 if (Event.current.type == EventType.Repaint)
69 state.spacePartitioner.AddBounds(this, boundingRect);
70 }
71
72 if (asset != null && Hash() != m_TrackHash)
73 Rebuild();
74
75 Rect rect = state.showMarkerHeader ? markerContentRect : state.timeAreaRect;
76 using (new GUIViewportScope(rect))
77 {
78 if (m_Layer != null)
79 m_Layer.Draw(rect, state);
80
81 HandleDragAndDrop();
82 }
83
84 if (state.showMarkerHeader && data.isMuted)
85 DrawMuteOverlay(data);
86 }
87
88 public void Rebuild()
89 {
90 if (asset == null)
91 return;
92
93 m_Layer = new MarkersLayer(Layer.MarkersOnHeader, this);
94 m_TrackHash = Hash();
95 }
96
97 void HandleDragAndDrop()
98 {
99 if (state.editSequence.isReadOnly || !state.showMarkerHeader)
100 return;
101
102 if (Event.current == null || Event.current.type != EventType.DragUpdated &&
103 Event.current.type != EventType.DragPerform && Event.current.type != EventType.DragExited)
104 return;
105
106 var objectsBeingDropped = DragAndDrop.objectReferences.OfType<Object>();
107 var candidateTime = TimelineHelpers.GetCandidateTime(Event.current.mousePosition);
108 var perform = Event.current.type == EventType.DragPerform;
109 var director = state.editSequence != null ? state.editSequence.director : null;
110 DragAndDrop.visualMode = TimelineDragging.HandleClipPaneObjectDragAndDrop(objectsBeingDropped, timeline.markerTrack, perform,
111 timeline, null, director, candidateTime, ResolveType);
112 if (perform && DragAndDrop.visualMode == DragAndDropVisualMode.Copy)
113 {
114 DragAndDrop.AcceptDrag();
115 }
116 }
117
118 static bool ResolveType(IEnumerable<Type> types, Action<Type> onComplete, string formatString)
119 {
120 void CreateMarkerTrackOnComplete(Type type)
121 {
122 WindowState state = TimelineWindow.instance.state;
123 state.editSequence.asset.CreateMarkerTrack();
124 state.showMarkerHeader = true;
125 onComplete(type);
126 }
127
128 return TimelineDragging.ResolveType(types, CreateMarkerTrackOnComplete, formatString);
129 }
130
131 int Hash()
132 {
133 return timeline.markerTrack == null ? 0 : timeline.markerTrack.Hash();
134 }
135
136 static void DrawMarkerDrawer(DrawData data)
137 {
138 DrawMarkerDrawerHeaderBackground(data);
139 DrawMarkerDrawerHeader(data);
140 DrawMarkerDrawerContentBackground(data);
141 }
142
143 static void DrawMarkerDrawerHeaderBackground(DrawData data)
144 {
145 Color backgroundColor = data.isSelected
146 ? DirectorStyles.Instance.customSkin.colorSelection
147 : DirectorStyles.Instance.customSkin.markerHeaderDrawerBackgroundColor;
148 EditorGUI.DrawRect(data.headerRect, backgroundColor);
149 }
150
151 static void DrawMarkerDrawerHeader(DrawData data)
152 {
153 var textStyle = data.trackHeaderFont;
154 textStyle.normal.textColor = data.colorTrackFont;
155 var labelRect = data.headerRect;
156 labelRect.x += DirectorStyles.kBaseIndent;
157
158 EditorGUI.LabelField(labelRect, DirectorStyles.timelineMarkerTrackHeader);
159
160 const float buttonSize = WindowConstants.trackHeaderButtonSize;
161 const float padding = WindowConstants.trackHeaderButtonPadding;
162 var x = data.headerRect.xMax - buttonSize - padding - 2f;
163 var y = data.headerRect.y + (data.headerRect.height - buttonSize) / 2.0f;
164 var buttonRect = new Rect(x, y, buttonSize, buttonSize);
165
166 DrawTrackDropDownMenu(buttonRect);
167 buttonRect.x -= 21.0f;
168
169 DrawMuteButton(buttonRect, data);
170 }
171
172 static void DrawMarkerDrawerContentBackground(DrawData data)
173 {
174 Color trackBackgroundColor = DirectorStyles.Instance.customSkin.markerDrawerBackgroundColor;
175 if (data.isSelected)
176 trackBackgroundColor = DirectorStyles.Instance.customSkin.colorTrackBackgroundSelected;
177 EditorGUI.DrawRect(data.contentRect, trackBackgroundColor);
178 }
179
180 static void DrawMuteOverlay(DrawData data)
181 {
182 DirectorStyles styles = TimelineWindow.styles;
183
184 var colorOverlay = OverlayDrawer.CreateColorOverlay(GUIClip.Unclip(data.contentRect), styles.customSkin.colorTrackDarken);
185 colorOverlay.Draw();
186
187 Rect textRect = Graphics.CalculateTextBoxSize(data.contentRect, styles.fontClip, k_Muted, WindowConstants.overlayTextPadding);
188 var boxOverlay = OverlayDrawer.CreateTextBoxOverlay(
189 GUIClip.Unclip(textRect),
190 k_Muted.text,
191 styles.fontClip,
192 Color.white,
193 styles.customSkin.colorLockTextBG,
194 styles.displayBackground);
195 boxOverlay.Draw();
196 }
197
198 static void DrawTrackDropDownMenu(Rect rect)
199 {
200 if (GUI.Button(rect, GUIContent.none, DirectorStyles.Instance.trackOptions))
201 {
202 SelectionManager.SelectOnly(TimelineEditor.inspectedAsset.markerTrack);
203 SequencerContextMenu.ShowTrackContextMenu(null);
204 }
205 }
206
207 static void DrawMuteButton(Rect rect, DrawData data)
208 {
209 bool muted = GUI.Toggle(rect, data.isMuted, string.Empty, TimelineWindow.styles.trackMuteButton);
210 if (muted != data.isMuted)
211 new[] { TimelineEditor.inspectedAsset.markerTrack }.Invoke<MuteTrack>();
212 }
213
214 bool IsSelected()
215 {
216 return SelectionManager.Contains(asset);
217 }
218 }
219}