ItemAction.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. [ActiveInMode(TimelineModes.Default)]
  8. abstract class ItemAction<T> : MenuItemActionBase where T : class
  9. {
  10. public abstract bool Execute(WindowState state, T[] items);
  11. protected virtual MenuActionDisplayState GetDisplayState(WindowState state, T[] items)
  12. {
  13. return items.Length > 0 ? MenuActionDisplayState.Visible : MenuActionDisplayState.Disabled;
  14. }
  15. protected virtual string GetDisplayName(T[] items)
  16. {
  17. return menuName;
  18. }
  19. public bool CanExecute(WindowState state, T[] items)
  20. {
  21. return GetDisplayState(state, items) == MenuActionDisplayState.Visible;
  22. }
  23. protected virtual void AddMenuItem(WindowState state, T[] items, List<MenuActionItem> menuItem)
  24. {
  25. var mode = TimelineWindow.instance.currentMode.mode;
  26. menuItem.Add(
  27. new MenuActionItem()
  28. {
  29. category = category,
  30. entryName = GetDisplayName(items),
  31. shortCut = this.shortCut,
  32. isChecked = false,
  33. isActiveInMode = IsActionActiveInMode(this, mode),
  34. priority = priority,
  35. state = GetDisplayState(state, items),
  36. callback = () => Execute(state, items)
  37. }
  38. );
  39. }
  40. public static bool HandleShortcut(WindowState state, Event evt, T item)
  41. {
  42. T[] items = { item };
  43. foreach (ItemAction<T> action in actions)
  44. {
  45. var attr = action.GetType().GetCustomAttributes(typeof(ShortcutAttribute), true);
  46. foreach (ShortcutAttribute shortcut in attr)
  47. {
  48. if (shortcut.MatchesEvent(evt))
  49. {
  50. if (s_ShowActionTriggeredByShortcut)
  51. Debug.Log(action.GetType().Name);
  52. if (!IsActionActiveInMode(action, TimelineWindow.instance.currentMode.mode))
  53. return false;
  54. var result = action.Execute(state, items);
  55. state.Refresh();
  56. state.Evaluate();
  57. return result;
  58. }
  59. }
  60. }
  61. return false;
  62. }
  63. static List<ItemAction<T>> s_ActionClasses;
  64. static List<ItemAction<T>> actions
  65. {
  66. get
  67. {
  68. if (s_ActionClasses == null)
  69. {
  70. s_ActionClasses = GetActionsOfType(typeof(ItemAction<T>)).Select(x => (ItemAction<T>)x.GetConstructors()[0].Invoke(null)).ToList();
  71. }
  72. return s_ActionClasses;
  73. }
  74. }
  75. public static void GetMenuEntries(T[] items, List<MenuActionItem> menuItems)
  76. {
  77. if (items == null || items.Length == 0)
  78. return;
  79. foreach (var action in actions)
  80. {
  81. if (action.showInMenu)
  82. action.AddMenuItem(TimelineWindow.instance.state, items, menuItems);
  83. }
  84. }
  85. public static bool Invoke<TAction>(WindowState state, T[] items)
  86. where TAction : ItemAction<T>
  87. {
  88. var itemsDerived = items.ToArray();
  89. if (!itemsDerived.Any())
  90. return false;
  91. var action = actions.FirstOrDefault(x => x.GetType() == typeof(TAction));
  92. if (action != null)
  93. return action.Execute(state, itemsDerived);
  94. return false;
  95. }
  96. public static bool Invoke<TAction>(WindowState state, T item)
  97. where TAction : ItemAction<T>
  98. {
  99. return Invoke<TAction>(state, new[] {item});
  100. }
  101. }
  102. }