FEventEditor.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections.Generic;
  4. using Flux;
  5. namespace FluxEditor
  6. {
  7. public class FEventEditor : FEditor
  8. {
  9. public FTrackEditor TrackEditor { get { return (FTrackEditor)Owner; } }
  10. public FEvent Evt { get { return (FEvent)Obj; } }
  11. private int _mouseOffsetFrames;
  12. protected Rect _eventRect;
  13. public override FSequenceEditor SequenceEditor { get { return TrackEditor != null ? TrackEditor.SequenceEditor : null; } }
  14. public override float Height { get { return FTrackEditor.DEFAULT_TRACK_HEIGHT; } }
  15. public override void Render( Rect rect, float headerWidth )
  16. {
  17. }
  18. // pixelsPerFrame can be calculated from rect and viewRange, but being cached on a higher level
  19. public void Render( Rect rect, FrameRange viewRange, float pixelsPerFrame, FrameRange validKeyframeRange )
  20. {
  21. Rect = rect;
  22. _eventRect = rect;
  23. int eventStartFrame = Mathf.Max( Evt.Start, viewRange.Start );
  24. int eventEndFrame = Mathf.Min( Evt.End, viewRange.End );
  25. // _eventRect.xMin = Evt.Start * pixelsPerFrame;
  26. // _eventRect.xMax = Evt.End * pixelsPerFrame;
  27. _eventRect.xMin = SequenceEditor.GetXForFrame(eventStartFrame);
  28. _eventRect.xMax = SequenceEditor.GetXForFrame(eventEndFrame);
  29. // _eventRect.xMin += (eventStartFrame-viewRange.Start) * pixelsPerFrame; // first set the start
  30. // _eventRect.xMax = _eventRect.xMin + Mathf.Max( 4, (eventEndFrame-eventStartFrame) * pixelsPerFrame ); // then width
  31. if( _eventRect.Contains( Event.current.mousePosition ) )
  32. SequenceEditor.SetMouseHover( Event.current.mousePosition.x, this );
  33. RenderEvent( viewRange, validKeyframeRange );
  34. }
  35. private int _leftHandleGuiId = 0;
  36. private int _rightHandleGuiId = 0;
  37. public override void ReserveGuiIds ()
  38. {
  39. base.ReserveGuiIds();
  40. _leftHandleGuiId = EditorGUIUtility.GetControlID( FocusType.Passive );
  41. _rightHandleGuiId = EditorGUIUtility.GetControlID( FocusType.Passive );
  42. }
  43. protected virtual void RenderEvent( FrameRange viewRange, FrameRange validKeyframeRange )
  44. {
  45. bool leftHandleVisible = viewRange.Contains( Evt.Start );
  46. bool rightHandleVisible = viewRange.Contains( Evt.End );
  47. Rect leftHandleRect = _eventRect; leftHandleRect.width = 4;
  48. Rect rightHandleRect = _eventRect; rightHandleRect.xMin = rightHandleRect.xMax - 4;
  49. if( leftHandleVisible && IsSelected )
  50. EditorGUIUtility.AddCursorRect( leftHandleRect, MouseCursor.ResizeHorizontal, _leftHandleGuiId );
  51. if( rightHandleVisible && IsSelected )
  52. EditorGUIUtility.AddCursorRect( rightHandleRect, MouseCursor.ResizeHorizontal, _rightHandleGuiId );
  53. // if( SequenceEditor.EditorDragged == this )
  54. // {
  55. // Rect editorDraggedRect = _eventRect;
  56. // editorDraggedRect.y = -Offset.value.y;
  57. //
  58. // SequenceEditor.EditorDraggedRect = editorDraggedRect;
  59. //
  60. // SequenceEditor.Repaint();
  61. // }
  62. switch( Event.current.type )
  63. {
  64. case EventType.Repaint:
  65. if( !viewRange.Overlaps(Evt.FrameRange) )
  66. {
  67. break;
  68. }
  69. GUIStyle evtStyle = GetEventStyle();
  70. GUI.backgroundColor = GetColor ();
  71. evtStyle.Draw( _eventRect, _isSelected, _isSelected, false, false );
  72. string text = Evt.Text;
  73. if( text != null )
  74. GUI.Label( _eventRect, text, GetTextStyle() );
  75. break;
  76. case EventType.MouseDown:
  77. if( EditorGUIUtility.hotControl == 0 && IsSelected && !Event.current.control && !Event.current.shift )
  78. {
  79. Vector2 mousePos = Event.current.mousePosition;
  80. if( Event.current.button == 0 ) // left click?
  81. {
  82. if( rightHandleVisible && rightHandleRect.Contains( mousePos ) )
  83. {
  84. EditorGUIUtility.hotControl = _rightHandleGuiId;
  85. // keyframeOnSelect = evt.Start;
  86. Event.current.Use();
  87. }
  88. else if( leftHandleVisible && leftHandleRect.Contains( mousePos ) )
  89. {
  90. EditorGUIUtility.hotControl = _leftHandleGuiId;
  91. // keyframeOnSelect = evt.End;
  92. Event.current.Use();
  93. }
  94. else if( _eventRect.Contains( mousePos ) )
  95. {
  96. EditorGUIUtility.hotControl = GuiId;
  97. _mouseOffsetFrames = SequenceEditor.GetFrameForX( mousePos.x ) - Evt.Start;
  98. if( IsSelected )
  99. {
  100. if( Event.current.control )
  101. {
  102. SequenceEditor.Deselect( this );
  103. }
  104. }
  105. else
  106. {
  107. if( Event.current.shift )
  108. SequenceEditor.Select( this );
  109. else if( !Event.current.control )
  110. SequenceEditor.SelectExclusive( this );
  111. }
  112. Event.current.Use();
  113. }
  114. }
  115. else if( Event.current.button == 1 && _eventRect.Contains(Event.current.mousePosition) ) // right click?
  116. {
  117. CreateEventContextMenu().ShowAsContext();
  118. Event.current.Use();
  119. }
  120. }
  121. break;
  122. case EventType.MouseUp:
  123. if( EditorGUIUtility.hotControl != 0 )
  124. {
  125. if( EditorGUIUtility.hotControl == GuiId
  126. || EditorGUIUtility.hotControl == _leftHandleGuiId
  127. || EditorGUIUtility.hotControl == _rightHandleGuiId )
  128. {
  129. EditorGUIUtility.hotControl = 0;
  130. Event.current.Use();
  131. SequenceEditor.Repaint();
  132. FinishMovingEventEditors();
  133. }
  134. }
  135. break;
  136. case EventType.MouseDrag:
  137. if( EditorGUIUtility.hotControl != 0 )
  138. {
  139. if( EditorGUIUtility.hotControl == GuiId )
  140. {
  141. // if( !TrackEditor.Rect.Contains( Event.current.mousePosition ) )
  142. // {
  143. // SequenceEditor.StartDraggingEditor( this );
  144. // }
  145. // else
  146. {
  147. int t = SequenceEditor.GetFrameForX( Event.current.mousePosition.x ) - _mouseOffsetFrames;
  148. int delta = t-Evt.Start;
  149. SequenceEditor.MoveEvents( delta );
  150. }
  151. Event.current.Use();
  152. }
  153. else if( EditorGUIUtility.hotControl == _leftHandleGuiId || EditorGUIUtility.hotControl == _rightHandleGuiId )
  154. {
  155. int leftLimit = 0;
  156. int rightLimit = 0;
  157. bool draggingStart = EditorGUIUtility.hotControl == _leftHandleGuiId;
  158. if( draggingStart )
  159. {
  160. leftLimit = validKeyframeRange.Start;
  161. rightLimit = Evt.End-1;
  162. }
  163. else
  164. {
  165. leftLimit = Evt.Start+1;
  166. rightLimit = validKeyframeRange.End;
  167. }
  168. int t = SequenceEditor.GetFrameForX( Event.current.mousePosition.x );
  169. t = Mathf.Clamp( t, leftLimit, rightLimit );
  170. int delta = t - (draggingStart ? Evt.Start : Evt.End);
  171. if( draggingStart )
  172. {
  173. int newLength = Evt.Length - delta;
  174. if( newLength < Evt.GetMinLength() )
  175. {
  176. delta += newLength - Evt.GetMinLength();
  177. }
  178. if( newLength > Evt.GetMaxLength() )
  179. {
  180. delta += newLength - Evt.GetMaxLength();
  181. }
  182. }
  183. else
  184. {
  185. int newLength = Evt.Length + delta;
  186. if( newLength < Evt.GetMinLength() )
  187. {
  188. delta -= newLength - Evt.GetMinLength();
  189. }
  190. if( newLength > Evt.GetMaxLength() )
  191. {
  192. delta -= newLength - Evt.GetMaxLength();
  193. }
  194. }
  195. if( delta != 0 )
  196. {
  197. if( draggingStart )
  198. SequenceEditor.ResizeEventsLeft( delta );
  199. else
  200. SequenceEditor.ResizeEventsRight( delta );
  201. }
  202. Event.current.Use();
  203. }
  204. }
  205. break;
  206. case EventType.Ignore:
  207. if( EditorGUIUtility.hotControl == GuiId
  208. || EditorGUIUtility.hotControl == _leftHandleGuiId
  209. || EditorGUIUtility.hotControl == _rightHandleGuiId )
  210. {
  211. EditorGUIUtility.hotControl = 0;
  212. SequenceEditor.Repaint();
  213. FinishMovingEventEditors();
  214. }
  215. break;
  216. }
  217. }
  218. public virtual void OnEventMoved( FrameRange oldFrameRange )
  219. {
  220. AddEventEditorBeingMoved( this, oldFrameRange );
  221. }
  222. public virtual void OnEventFinishedMoving( FrameRange oldFrameRange )
  223. {
  224. }
  225. public virtual Color GetColor()
  226. {
  227. return FluxEditor.FUtility.GetEventColor( Evt.GetType().ToString() );
  228. }
  229. public virtual GUIStyle GetEventStyle()
  230. {
  231. return FUtility.GetEventStyle();
  232. }
  233. public virtual GUIStyle GetTextStyle()
  234. {
  235. return EditorStyles.label;
  236. }
  237. protected virtual GenericMenu CreateEventContextMenu()
  238. {
  239. GenericMenu menu = new GenericMenu();
  240. menu.AddItem(new GUIContent("Copy"), false, Copy);
  241. menu.AddItem(new GUIContent("Cut"), false, Cut);
  242. menu.AddItem(new GUIContent("Delete"), false, Delete);
  243. return menu;
  244. }
  245. private void Copy()
  246. {
  247. SequenceEditor.CopyEditor( this );
  248. }
  249. private void Cut()
  250. {
  251. SequenceEditor.CutEditor( this );
  252. }
  253. private void Delete()
  254. {
  255. List<FEventEditor> eventEditors = new List<FEventEditor>();
  256. eventEditors.Add( this );
  257. SequenceEditor.DestroyEvents( eventEditors );
  258. }
  259. #region Event editors being moved
  260. // holds the event editors being moved / resized, so that we can call a function at the end of the move
  261. // with the full change and not just the delta each update. Useful when you have other assets that have
  262. // to be changed but you only want to do it at the end (e.g. resize animations, to minimize errors)
  263. private static Dictionary<FEventEditor, FrameRange> _eventEditorsBeingMoved = new Dictionary<FEventEditor, FrameRange>();
  264. private static void AddEventEditorBeingMoved( FEventEditor evtEditor, FrameRange oldFrameRange )
  265. {
  266. if( !_eventEditorsBeingMoved.ContainsKey( evtEditor ) )
  267. {
  268. _eventEditorsBeingMoved.Add( evtEditor, oldFrameRange );
  269. }
  270. }
  271. public static void FinishMovingEventEditors()
  272. {
  273. Dictionary<FEventEditor, FrameRange>.Enumerator e = _eventEditorsBeingMoved.GetEnumerator();
  274. while( e.MoveNext() )
  275. {
  276. e.Current.Key.OnEventFinishedMoving( e.Current.Value );
  277. }
  278. _eventEditorsBeingMoved.Clear();
  279. }
  280. #endregion
  281. }
  282. }