FSequenceEditorWindow.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System;
  4. using System.IO;
  5. using System.Collections.Generic;
  6. using System.Security;
  7. using Mono.Xml;
  8. using Flux;
  9. using Object = UnityEngine.Object;
  10. namespace FluxEditor
  11. {
  12. public enum TimeFormat
  13. {
  14. Frames = 0,
  15. Seconds,
  16. SecondsFormatted
  17. }
  18. public class FSequenceEditorWindow : EditorWindow
  19. {
  20. public const string MENU_PATH = "Skill_Tool/";
  21. public const string PRODUCT_NAME = "FrameEventPanel";
  22. #region Menus
  23. [MenuItem(MENU_PATH+PRODUCT_NAME+"/Open Editor %&c",false, 0)]
  24. public static void Open()
  25. {
  26. FSequenceEditorWindow window = GetWindow<FSequenceEditorWindow>();
  27. window.Show();
  28. window.titleContent = new GUIContent(PRODUCT_NAME);
  29. window.Update();
  30. }
  31. public static void Open( FSequence sequence )
  32. {
  33. Open();
  34. instance._sequenceEditor.OpenSequence( sequence );
  35. }
  36. public static FSequence CreateSequence()
  37. {
  38. // find new name & priority for sequence
  39. string sequenceNameFormat = "buff_{0}";
  40. int sequenceId = 0;
  41. string sequenceName = string.Format( sequenceNameFormat, sequenceId.ToString("000") );
  42. FSequence[] sequences = FindObjectsOfType<FSequence>();
  43. for( int i = 0, limit = sequences.Length; i != limit; ++i )
  44. {
  45. if( sequences[i].name == sequenceName )
  46. {
  47. // try new name
  48. ++sequenceId;
  49. sequenceName = string.Format( sequenceNameFormat, sequenceId.ToString("000") );
  50. i = -1; // restart search
  51. }
  52. }
  53. FSequence sequence = FSequence.CreateSequence();
  54. sequence.name = sequenceName;
  55. sequence.FrameRate = FUtility.FrameRate;
  56. sequence.Length = sequence.FrameRate * FSequence.DEFAULT_LENGTH;
  57. Undo.RegisterCreatedObjectUndo( sequence.gameObject, "Create FrameEvent" );
  58. return sequence;
  59. }
  60. #endregion
  61. public static FSequenceEditorWindow instance = null;
  62. // size of the whole window, cached to determine if it was resized
  63. private Rect _windowRect;
  64. // rect used for the header at the top of the window
  65. private Rect _windowHeaderRect;
  66. // header
  67. private FSequenceWindowHeader _windowHeader;
  68. // toolbar
  69. private FSequenceWindowToolbar _toolbar;
  70. // area for the toolbar
  71. private Rect _toolbarRect;
  72. [SerializeField]
  73. private FSequenceEditor _sequenceEditor;
  74. void OnEnable()
  75. {
  76. instance = this;
  77. wantsMouseMove = true;
  78. minSize = new Vector2(450, 300);
  79. _windowHeader = new FSequenceWindowHeader( this );
  80. _toolbar = new FSequenceWindowToolbar( this );
  81. _windowRect = new Rect();
  82. FUtility.LoadPreferences();
  83. }
  84. void OnSelectionChange()
  85. {
  86. if( !FUtility.OpenSequenceOnSelect )
  87. return;
  88. FSequence sequence = Selection.activeGameObject == null || PrefabUtility.GetPrefabType(Selection.activeGameObject) == PrefabType.Prefab ? null : Selection.activeGameObject.GetComponent<FSequence>();
  89. if( sequence != null )
  90. {
  91. Open( sequence );
  92. }
  93. }
  94. public FSequenceEditor GetSequenceEditor()
  95. {
  96. return _sequenceEditor;
  97. }
  98. void OnDestroy()
  99. {
  100. if(_windowHeader!=null)
  101. {
  102. _windowHeader.Destroy();
  103. }
  104. if( _sequenceEditor != null )
  105. {
  106. _sequenceEditor.Stop();
  107. DestroyImmediate( _sequenceEditor );
  108. }
  109. }
  110. void OnLostFocus()
  111. {
  112. }
  113. #region Editor state changes hookups
  114. private void OnDidOpenScene()
  115. {
  116. if( _sequenceEditor )
  117. _sequenceEditor.OpenSequence( null );
  118. }
  119. #endregion
  120. public bool IsPlaying { get { return _sequenceEditor.IsPlaying; } }
  121. void Update()
  122. {
  123. #if FLUX_PROFILE
  124. Profiler.BeginSample("flux Update");
  125. #endif
  126. if( _sequenceEditor == null )
  127. {
  128. _sequenceEditor = FSequenceEditor.CreateInstance<FSequenceEditor>();
  129. _sequenceEditor.Init( this );
  130. }
  131. FSequence sequence = _sequenceEditor.Sequence;
  132. if( Application.isPlaying && sequence != null && FUtility.RenderOnEditorPlay )
  133. {
  134. Repaint();
  135. }
  136. _sequenceEditor.Update();
  137. #if FLUX_PROFILE
  138. Profiler.EndSample();
  139. #endif
  140. }
  141. public void Play( bool restart )
  142. {
  143. _sequenceEditor.IsPlayingForward = true;
  144. _sequenceEditor.Play( restart );
  145. }
  146. public void PlayBackwards( bool restart )
  147. {
  148. _sequenceEditor.IsPlayingForward = false;
  149. _sequenceEditor.Play( restart );
  150. }
  151. public void Pause()
  152. {
  153. _sequenceEditor.Pause();
  154. }
  155. public void Stop()
  156. {
  157. _sequenceEditor.Stop();
  158. }
  159. private void RebuildLayout()
  160. {
  161. _windowRect = position;
  162. _windowRect.x = 0;
  163. _windowRect.y = 0;
  164. _windowHeaderRect = _windowRect;
  165. _windowHeaderRect.height = FSequenceWindowHeader.HEIGHT;
  166. _windowHeader.RebuildLayout( _windowHeaderRect );
  167. _toolbarRect = _windowRect;
  168. _toolbarRect.yMin = _toolbarRect.yMax - FSequenceWindowToolbar.HEIGHT;
  169. _toolbar.RebuildLayout( _toolbarRect );
  170. Rect timelineViewRect = _windowRect;
  171. timelineViewRect.yMin += FSequenceWindowHeader.HEIGHT;
  172. timelineViewRect.yMax -= FSequenceWindowToolbar.HEIGHT;
  173. _sequenceEditor.RebuildLayout( timelineViewRect );
  174. Repaint();
  175. }
  176. public void Refresh()
  177. {
  178. if( _sequenceEditor != null )
  179. {
  180. _sequenceEditor.OpenSequence( _sequenceEditor.Sequence );
  181. }
  182. Repaint();
  183. }
  184. public static void RefreshIfOpen()
  185. {
  186. if( instance != null )
  187. instance.Refresh();
  188. }
  189. void OnGUI()
  190. {
  191. #if FLUX_PROFILE
  192. Profiler.BeginSample("Flux OnGUI");
  193. #endif
  194. if( _sequenceEditor == null )
  195. return;
  196. Rect currentWindowRect = position;
  197. currentWindowRect.x = 0;
  198. currentWindowRect.y = 0;
  199. if( currentWindowRect != _windowRect )
  200. {
  201. RebuildLayout();
  202. }
  203. if( !FUtility.RenderOnEditorPlay && EditorApplication.isPlaying && !EditorApplication.isPaused )
  204. {
  205. GUI.Label( _windowRect, "Draw in play mode is disabled. You can change it on Flux Preferences" );
  206. return;
  207. }
  208. FSequence sequence = _sequenceEditor.Sequence;
  209. if( sequence == null )
  210. ShowNotification( new GUIContent( "Select Or Create FrameEvent" ) );
  211. else if( Event.current.isKey )
  212. {
  213. if( Event.current.keyCode == KeyCode.Space )
  214. {
  215. if( Event.current.type == EventType.KeyUp )
  216. {
  217. if( _sequenceEditor.IsPlaying )
  218. {
  219. if( Event.current.shift )
  220. Stop ();
  221. else
  222. Pause();
  223. }
  224. else
  225. Play( Event.current.shift );
  226. Repaint();
  227. }
  228. Event.current.Use();
  229. }
  230. if( Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return )
  231. {
  232. EditorGUIUtility.keyboardControl = 0;
  233. Event.current.Use();
  234. Repaint();
  235. }
  236. }
  237. // header
  238. _windowHeader.OnGUI();
  239. if( sequence == null )
  240. return;
  241. // toolbar
  242. _toolbar.OnGUI();
  243. switch( Event.current.type )
  244. {
  245. case EventType.KeyDown:
  246. if( Event.current.keyCode == KeyCode.Backspace || Event.current.keyCode == KeyCode.Delete )
  247. {
  248. _sequenceEditor.DestroyEvents( _sequenceEditor.EventSelection.Editors );
  249. Event.current.Use();
  250. }
  251. else if( Event.current.keyCode == KeyCode.K && _sequenceEditor.Sequence.CurrentFrame >= 0 )
  252. {
  253. _sequenceEditor.AddEvent( _sequenceEditor.Sequence.CurrentFrame );
  254. Event.current.Use();
  255. }
  256. // else if( Event.current.keyCode == KeyCode.C && _sequenceEditor.GetSequence().GetCurrentFrame() >= 0 )
  257. // {
  258. // _sequenceEditor.AddCommentEvent( _sequenceEditor.GetSequence().GetCurrentFrame() );
  259. // Event.current.Use();
  260. // }
  261. break;
  262. case EventType.MouseDown:
  263. break;
  264. case EventType.MouseUp:
  265. break;
  266. }
  267. if( Event.current.type == EventType.ValidateCommand )
  268. {
  269. Repaint();
  270. }
  271. _sequenceEditor.OnGUI();
  272. // because of a bug with windows editor, we have to not catch right button
  273. // otherwise ContextClick doesn't get called
  274. if( Event.current.type == EventType.MouseUp && Event.current.button != 1 )
  275. {
  276. Event.current.Use();
  277. }
  278. if( Event.current.type == EventType.Ignore )
  279. {
  280. EditorGUIUtility.hotControl = 0;
  281. }
  282. // // handle drag & drop
  283. // if( Event.current.type == EventType.DragUpdated )
  284. // {
  285. // if( _windowRect.Contains( Event.current.mousePosition ) )
  286. // {
  287. // DragAndDrop.visualMode = DragAndDropVisualMode.Link;
  288. // Event.current.Use();
  289. // }
  290. // }
  291. // else if( Event.current.type == EventType.DragPerform )
  292. // {
  293. // if( _windowRect.Contains( Event.current.mousePosition ) )
  294. // {
  295. // foreach( UnityEngine.Object obj in DragAndDrop.objectReferences )
  296. // {
  297. // if( !(obj is GameObject) )
  298. // {
  299. // continue;
  300. // }
  301. //
  302. // PrefabType prefabType = PrefabUtility.GetPrefabType(obj);
  303. // if( prefabType == PrefabType.ModelPrefab || prefabType == PrefabType.Prefab )
  304. // continue;
  305. //
  306. // Undo.IncrementCurrentGroup();
  307. // UnityEngine.Object[] objsToSave = new UnityEngine.Object[]{ sequence, this };
  308. //
  309. // Undo.RegisterCompleteObjectUndo( objsToSave, string.Empty );
  310. //
  311. // GameObject timelineGO = new GameObject(obj.name);
  312. // // TODO
  313. //// FTimeline timeline = timelineGO.AddComponent<Flux.FTimeline>();
  314. //// timeline.SetOwner( ((GameObject)obj).transform );
  315. //// sequence.Add( timeline );
  316. //
  317. //// Undo.RegisterCompleteObjectUndo( objsToSave, string.Empty );
  318. //// Undo.RegisterCreatedObjectUndo( timeline.gameObject, "create Timeline" );
  319. //// Undo.CollapseUndoOperations( Undo.GetCurrentGroup() );
  320. // }
  321. // RemoveNotification();
  322. // Event.current.Use();
  323. // DragAndDrop.AcceptDrag();
  324. // Refresh();
  325. // EditorGUIUtility.ExitGUI();
  326. // }
  327. // }
  328. if( Event.current.type == EventType.Repaint )
  329. {
  330. Handles.DrawLine( new Vector3( _windowHeaderRect.xMin, _windowHeaderRect.yMax, 0 ), new Vector3( _windowHeaderRect.xMax-FSequenceEditor.RIGHT_BORDER, _windowHeaderRect.yMax, 0 ) );
  331. }
  332. #if FLUX_PROFILE
  333. Profiler.EndSample();
  334. #endif
  335. }
  336. public float GetXForFrame( int frame )
  337. {
  338. return _sequenceEditor.GetXForFrame( frame );
  339. }
  340. public int GetFrameForX( float x )
  341. {
  342. return _sequenceEditor.GetFrameForX( x );
  343. }
  344. private string FormatTime( float time )
  345. {
  346. int timeInInt = (int)time;
  347. int minutes = timeInInt / 60;
  348. int seconds = timeInInt % 60;
  349. int deciSeconds = (int)((time - timeInInt)*100f);
  350. return minutes > 0 ? string.Format( "{0}:{1}.{2}",
  351. minutes.ToString("00"),
  352. seconds.ToString("00"),
  353. deciSeconds.ToString("00") ) : string.Format( "{0}.{1}", seconds.ToString("00"), deciSeconds.ToString("00") );
  354. }
  355. float timelineViewRectHeight;
  356. private void RenderHeader( Rect rect )
  357. {
  358. FSequence sequence = _sequenceEditor.Sequence;
  359. GUI.Label( rect, sequence.name );
  360. Rect r = rect;
  361. r.xMin = r.xMax - 100;
  362. EditorGUI.IntField( r, sequence.Length );
  363. GUIContent lengthLabel = new GUIContent( "Length" );
  364. r.x -= EditorStyles.label.CalcSize( lengthLabel ).x + 5;
  365. EditorGUI.PrefixLabel( r, lengthLabel );
  366. r.x -= 50;
  367. r.width = 40;
  368. EditorGUI.IntField( r, sequence.FrameRate );
  369. GUIContent framerateLabel = new GUIContent("Frame Rate");
  370. r.x -= EditorStyles.label.CalcSize( framerateLabel ).x + 5;
  371. EditorGUI.PrefixLabel( r, framerateLabel );
  372. r.x -= 110;
  373. r.width = 100;
  374. EditorGUI.EnumPopup( r, sequence.UpdateMode );
  375. GUIContent updateModeLabel = new GUIContent( "Update Mode" );
  376. Vector2 updateModeLabelSize = EditorStyles.label.CalcSize( updateModeLabel );
  377. r.x -= updateModeLabelSize.x + 5;
  378. r.width = updateModeLabelSize.x;
  379. EditorGUI.PrefixLabel( r, updateModeLabel );
  380. }
  381. }
  382. }