DirectorStyles.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. using UnityEditor.Experimental;
  2. using UnityEditor.StyleSheets;
  3. using UnityEngine;
  4. using UnityEngine.Timeline;
  5. namespace UnityEditor.Timeline
  6. {
  7. class DirectorStyles
  8. {
  9. const string k_Elipsis = "…";
  10. const string k_ImagePath = "Packages/com.unity.timeline/Editor/StyleSheets/Images/Icons/{0}.png";
  11. public const string resourcesPath = "Packages/com.unity.timeline/Editor/StyleSheets/res/";
  12. //Timeline resources
  13. public const string newTimelineDefaultNameSuffix = "Timeline";
  14. public static readonly GUIContent referenceTrackLabel = TrTextContent("R", "This track references an external asset");
  15. public static readonly GUIContent recordingLabel = TrTextContent("Recording...");
  16. public static readonly GUIContent noTimelineAssetSelected = TrTextContent("To start creating a timeline, select a GameObject");
  17. public static readonly GUIContent createTimelineOnSelection = TrTextContent("To begin a new timeline with {0}, create {1}");
  18. public static readonly GUIContent noTimelinesInScene = TrTextContent("No timeline found in the scene");
  19. public static readonly GUIContent createNewTimelineText = TrTextContent("Create a new Timeline and Director Component for Game Object");
  20. public static readonly GUIContent previewContent = TrTextContent("Preview", "Enable/disable scene preview mode");
  21. public static readonly GUIContent previewDisabledContent = EditorGUIUtility.TrTextContentWithIcon("Preview", "Scene preview is disabled for this TimelineAsset", MessageType.Info);
  22. public static readonly GUIContent mixOff = TrIconContent("TimelineEditModeMixOFF", "Mix Mode (1)");
  23. public static readonly GUIContent mixOn = TrIconContent("TimelineEditModeMixON", "Mix Mode (1)");
  24. public static readonly GUIContent rippleOff = TrIconContent("TimelineEditModeRippleOFF", "Ripple Mode (2)");
  25. public static readonly GUIContent rippleOn = TrIconContent("TimelineEditModeRippleON", "Ripple Mode (2)");
  26. public static readonly GUIContent replaceOff = TrIconContent("TimelineEditModeReplaceOFF", "Replace Mode (3)");
  27. public static readonly GUIContent replaceOn = TrIconContent("TimelineEditModeReplaceON", "Replace Mode (3)");
  28. public static readonly GUIContent showMarkersOn = TrIconContent("TimelineCollapseMarkerButtonEnabled", "Show / Hide Timeline Markers");
  29. public static readonly GUIContent showMarkersOff = TrIconContent("TimelineCollapseMarkerButtonDisabled", "Show / Hide Timeline Markers");
  30. public static readonly GUIContent showMarkersOnTimeline = TrTextContent("Show markers");
  31. public static readonly GUIContent timelineMarkerTrackHeader = TrTextContentWithIcon("Markers", string.Empty, "TimelineHeaderMarkerIcon");
  32. public static readonly GUIContent signalTrackIcon = IconContent("TimelineSignal");
  33. //Unity Default Resources
  34. public static readonly GUIContent playContent = EditorGUIUtility.TrIconContent("Animation.Play", "Play the timeline (Space)");
  35. public static readonly GUIContent gotoBeginingContent = EditorGUIUtility.TrIconContent("Animation.FirstKey", "Go to the beginning of the timeline (Shift+<)");
  36. public static readonly GUIContent gotoEndContent = EditorGUIUtility.TrIconContent("Animation.LastKey", "Go to the end of the timeline (Shift+>)");
  37. public static readonly GUIContent nextFrameContent = EditorGUIUtility.TrIconContent("Animation.NextKey", "Go to the next frame");
  38. public static readonly GUIContent previousFrameContent = EditorGUIUtility.TrIconContent("Animation.PrevKey", "Go to the previous frame");
  39. public static readonly GUIContent newContent = EditorGUIUtility.IconContent("CreateAddNew", "Add new tracks.");
  40. public static readonly GUIContent optionsCogIcon = EditorGUIUtility.TrIconContent("_Popup", "Options");
  41. public static readonly GUIContent animationTrackIcon = EditorGUIUtility.IconContent("AnimationClip Icon");
  42. public static readonly GUIContent audioTrackIcon = EditorGUIUtility.IconContent("AudioSource Icon");
  43. public static readonly GUIContent playableTrackIcon = EditorGUIUtility.IconContent("cs Script Icon");
  44. public static readonly GUIContent timelineSelectorArrow = EditorGUIUtility.TrIconContent("icon dropdown", "Timeline Selector");
  45. public GUIContent playrangeContent;
  46. public static readonly float kBaseIndent = 15.0f;
  47. public static readonly float kDurationGuiThickness = 5.0f;
  48. // matches dark skin warning color.
  49. public static readonly Color kClipErrorColor = new Color(0.957f, 0.737f, 0.008f, 1f);
  50. // TODO: Make skinnable? If we do, we should probably also make the associated cursors skinnable...
  51. public static readonly Color kMixToolColor = Color.white;
  52. public static readonly Color kRippleToolColor = new Color(255f / 255f, 210f / 255f, 51f / 255f);
  53. public static readonly Color kReplaceToolColor = new Color(165f / 255f, 30f / 255f, 30f / 255f);
  54. public const string markerDefaultStyle = "MarkerItem";
  55. public GUIStyle groupBackground;
  56. public GUIStyle displayBackground;
  57. public GUIStyle fontClip;
  58. public GUIStyle fontClipLoop;
  59. public GUIStyle trackHeaderFont;
  60. public GUIStyle trackGroupAddButton;
  61. public GUIStyle groupFont;
  62. public GUIStyle timeCursor;
  63. public GUIStyle endmarker;
  64. public GUIStyle tinyFont;
  65. public GUIStyle foldout;
  66. public GUIStyle trackMuteButton;
  67. public GUIStyle trackLockButton;
  68. public GUIStyle trackRecordButton;
  69. public GUIStyle playTimeRangeStart;
  70. public GUIStyle playTimeRangeEnd;
  71. public GUIStyle selectedStyle;
  72. public GUIStyle trackSwatchStyle;
  73. public GUIStyle connector;
  74. public GUIStyle keyframe;
  75. public GUIStyle warning;
  76. public GUIStyle extrapolationHold;
  77. public GUIStyle extrapolationLoop;
  78. public GUIStyle extrapolationPingPong;
  79. public GUIStyle extrapolationContinue;
  80. public GUIStyle trackMarkerButton;
  81. public GUIStyle markerMultiOverlay;
  82. public GUIStyle bottomShadow;
  83. public GUIStyle trackOptions;
  84. public GUIStyle infiniteTrack;
  85. public GUIStyle clipOut;
  86. public GUIStyle clipIn;
  87. public GUIStyle trackCurvesButton;
  88. public GUIStyle trackLockOverlay;
  89. public GUIStyle activation;
  90. public GUIStyle playrange;
  91. public GUIStyle timelineLockButton;
  92. public GUIStyle trackAvatarMaskButton;
  93. public GUIStyle markerWarning;
  94. public GUIStyle editModeBtn;
  95. public GUIStyle showMarkersBtn;
  96. public GUIStyle sequenceSwitcher;
  97. public GUIStyle inlineCurveHandle;
  98. public GUIStyle timeReferenceButton;
  99. public GUIStyle trackButtonSuite;
  100. public GUIStyle previewButtonDisabled;
  101. public GUIStyle markerHeaderMuteButton;
  102. static internal DirectorStyles s_Instance;
  103. DirectorNamedColor m_DarkSkinColors;
  104. DirectorNamedColor m_LightSkinColors;
  105. DirectorNamedColor m_DefaultSkinColors;
  106. const string k_DarkSkinPath = resourcesPath + "Timeline_DarkSkin.txt";
  107. const string k_LightSkinPath = resourcesPath + "Timeline_LightSkin.txt";
  108. static readonly GUIContent s_TempContent = new GUIContent();
  109. public static bool IsInitialized
  110. {
  111. get { return s_Instance != null; }
  112. }
  113. public static DirectorStyles Instance
  114. {
  115. get
  116. {
  117. if (s_Instance == null)
  118. {
  119. s_Instance = new DirectorStyles();
  120. s_Instance.Initialize();
  121. }
  122. return s_Instance;
  123. }
  124. }
  125. public static void ReloadStylesIfNeeded()
  126. {
  127. if (Instance.ShouldLoadStyles())
  128. {
  129. Instance.LoadStyles();
  130. if (!Instance.ShouldLoadStyles())
  131. Instance.Initialize();
  132. }
  133. }
  134. public DirectorNamedColor customSkin
  135. {
  136. get { return EditorGUIUtility.isProSkin ? m_DarkSkinColors : m_LightSkinColors; }
  137. internal set
  138. {
  139. if (EditorGUIUtility.isProSkin)
  140. m_DarkSkinColors = value;
  141. else
  142. m_LightSkinColors = value;
  143. }
  144. }
  145. DirectorNamedColor LoadColorSkin(string path)
  146. {
  147. var asset = EditorGUIUtility.LoadRequired(path) as TextAsset;
  148. if (asset != null && !string.IsNullOrEmpty(asset.text))
  149. {
  150. return DirectorNamedColor.CreateAndLoadFromText(asset.text);
  151. }
  152. return m_DefaultSkinColors;
  153. }
  154. static DirectorNamedColor CreateDefaultSkin()
  155. {
  156. var nc = ScriptableObject.CreateInstance<DirectorNamedColor>();
  157. nc.SetDefault();
  158. return nc;
  159. }
  160. public void ExportSkinToFile()
  161. {
  162. if (customSkin == m_DarkSkinColors)
  163. customSkin.ToText(k_DarkSkinPath);
  164. if (customSkin == m_LightSkinColors)
  165. customSkin.ToText(k_LightSkinPath);
  166. }
  167. public void ReloadSkin()
  168. {
  169. if (customSkin == m_DarkSkinColors)
  170. {
  171. m_DarkSkinColors = LoadColorSkin(k_DarkSkinPath);
  172. }
  173. else if (customSkin == m_LightSkinColors)
  174. {
  175. m_LightSkinColors = LoadColorSkin(k_LightSkinPath);
  176. }
  177. }
  178. public void Initialize()
  179. {
  180. m_DefaultSkinColors = CreateDefaultSkin();
  181. m_DarkSkinColors = LoadColorSkin(k_DarkSkinPath);
  182. m_LightSkinColors = LoadColorSkin(k_LightSkinPath);
  183. // add the built in colors (control track uses attribute)
  184. TrackResourceCache.ClearTrackColorCache();
  185. TrackResourceCache.SetTrackColor<AnimationTrack>(customSkin.colorAnimation);
  186. TrackResourceCache.SetTrackColor<PlayableTrack>(Color.white);
  187. TrackResourceCache.SetTrackColor<AudioTrack>(customSkin.colorAudio);
  188. TrackResourceCache.SetTrackColor<ActivationTrack>(customSkin.colorActivation);
  189. TrackResourceCache.SetTrackColor<GroupTrack>(customSkin.colorGroup);
  190. TrackResourceCache.SetTrackColor<ControlTrack>(customSkin.colorControl);
  191. // add default icons
  192. TrackResourceCache.ClearTrackIconCache();
  193. TrackResourceCache.SetTrackIcon<AnimationTrack>(animationTrackIcon);
  194. TrackResourceCache.SetTrackIcon<AudioTrack>(audioTrackIcon);
  195. TrackResourceCache.SetTrackIcon<PlayableTrack>(playableTrackIcon);
  196. TrackResourceCache.SetTrackIcon<ActivationTrack>(new GUIContent(GetBackgroundImage(activation)));
  197. TrackResourceCache.SetTrackIcon<SignalTrack>(signalTrackIcon);
  198. }
  199. DirectorStyles()
  200. {
  201. LoadStyles();
  202. }
  203. bool ShouldLoadStyles()
  204. {
  205. return endmarker == null ||
  206. endmarker.name == GUISkin.error.name;
  207. }
  208. void LoadStyles()
  209. {
  210. endmarker = GetGUIStyle("Icon-Endmarker");
  211. groupBackground = GetGUIStyle("groupBackground");
  212. displayBackground = GetGUIStyle("sequenceClip");
  213. fontClip = GetGUIStyle("Font-Clip");
  214. trackHeaderFont = GetGUIStyle("sequenceTrackHeaderFont");
  215. trackGroupAddButton = GetGUIStyle("sequenceTrackGroupAddButton");
  216. groupFont = GetGUIStyle("sequenceGroupFont");
  217. timeCursor = GetGUIStyle("Icon-TimeCursor");
  218. tinyFont = GetGUIStyle("tinyFont");
  219. foldout = GetGUIStyle("Icon-Foldout");
  220. trackMuteButton = GetGUIStyle("trackMuteButton");
  221. trackLockButton = GetGUIStyle("trackLockButton");
  222. trackRecordButton = GetGUIStyle("trackRecordButton");
  223. playTimeRangeStart = GetGUIStyle("Icon-PlayAreaStart");
  224. playTimeRangeEnd = GetGUIStyle("Icon-PlayAreaEnd");
  225. selectedStyle = GetGUIStyle("Color-Selected");
  226. trackSwatchStyle = GetGUIStyle("Icon-TrackHeaderSwatch");
  227. connector = GetGUIStyle("Icon-Connector");
  228. keyframe = GetGUIStyle("Icon-Keyframe");
  229. warning = GetGUIStyle("Icon-Warning");
  230. extrapolationHold = GetGUIStyle("Icon-ExtrapolationHold");
  231. extrapolationLoop = GetGUIStyle("Icon-ExtrapolationLoop");
  232. extrapolationPingPong = GetGUIStyle("Icon-ExtrapolationPingPong");
  233. extrapolationContinue = GetGUIStyle("Icon-ExtrapolationContinue");
  234. bottomShadow = GetGUIStyle("Icon-Shadow");
  235. trackOptions = GetGUIStyle("Icon-TrackOptions");
  236. infiniteTrack = GetGUIStyle("Icon-InfiniteTrack");
  237. clipOut = GetGUIStyle("Icon-ClipOut");
  238. clipIn = GetGUIStyle("Icon-ClipIn");
  239. trackCurvesButton = GetGUIStyle("trackCurvesButton");
  240. trackLockOverlay = GetGUIStyle("trackLockOverlay");
  241. activation = GetGUIStyle("Icon-Activation");
  242. playrange = GetGUIStyle("Icon-Playrange");
  243. timelineLockButton = GetGUIStyle("IN LockButton");
  244. trackAvatarMaskButton = GetGUIStyle("trackAvatarMaskButton");
  245. trackMarkerButton = GetGUIStyle("trackCollapseMarkerButton");
  246. markerMultiOverlay = GetGUIStyle("MarkerMultiOverlay");
  247. editModeBtn = GetGUIStyle("editModeBtn");
  248. showMarkersBtn = GetGUIStyle("showMarkerBtn");
  249. markerWarning = GetGUIStyle("markerWarningOverlay");
  250. sequenceSwitcher = GetGUIStyle("sequenceSwitcher");
  251. inlineCurveHandle = GetGUIStyle("RL DragHandle");
  252. timeReferenceButton = GetGUIStyle("timeReferenceButton");
  253. trackButtonSuite = GetGUIStyle("trackButtonSuite");
  254. previewButtonDisabled = GetGUIStyle("previewButtonDisabled");
  255. markerHeaderMuteButton = GetGUIStyle("markerHeaderMuteButton");
  256. playrangeContent = new GUIContent(GetBackgroundImage(playrange)) { tooltip = "Toggle play range markers." };
  257. fontClipLoop = new GUIStyle(fontClip) { fontStyle = FontStyle.Bold };
  258. }
  259. public static GUIStyle GetGUIStyle(string s)
  260. {
  261. return EditorStyles.FromUSS(s);
  262. }
  263. public static GUIContent TrIconContent(string iconName, string tooltip = null)
  264. {
  265. return EditorGUIUtility.TrIconContent(iconName == null ? null : ResolveIcon(iconName), tooltip);
  266. }
  267. public static GUIContent IconContent(string iconName)
  268. {
  269. return EditorGUIUtility.IconContent(iconName == null ? null : ResolveIcon(iconName));
  270. }
  271. public static GUIContent TrTextContentWithIcon(string text, string tooltip, string iconName)
  272. {
  273. return EditorGUIUtility.TrTextContentWithIcon(text, tooltip, iconName == null ? null : ResolveIcon(iconName));
  274. }
  275. public static GUIContent TrTextContent(string text, string tooltip = null)
  276. {
  277. return EditorGUIUtility.TrTextContent(text, tooltip);
  278. }
  279. public static Texture2D LoadIcon(string iconName)
  280. {
  281. return EditorGUIUtility.LoadIconRequired(iconName == null ? null : ResolveIcon(iconName));
  282. }
  283. static string ResolveIcon(string icon)
  284. {
  285. return string.Format(k_ImagePath, icon);
  286. }
  287. public static string Elipsify(string label, Rect rect, GUIStyle style)
  288. {
  289. var ret = label;
  290. if (label.Length == 0)
  291. return ret;
  292. s_TempContent.text = label;
  293. float neededWidth = style.CalcSize(s_TempContent).x;
  294. return Elipsify(label, rect.width, neededWidth);
  295. }
  296. public static string Elipsify(string label, float destinationWidth, float neededWidth)
  297. {
  298. var ret = label;
  299. if (label.Length == 0)
  300. return ret;
  301. if (destinationWidth < neededWidth)
  302. {
  303. float averageWidthOfOneChar = neededWidth / label.Length;
  304. int floor = Mathf.Max((int)Mathf.Floor(destinationWidth / averageWidthOfOneChar), 0);
  305. if (floor < k_Elipsis.Length)
  306. ret = string.Empty;
  307. else if (floor == k_Elipsis.Length)
  308. ret = k_Elipsis;
  309. else if (floor < label.Length)
  310. ret = label.Substring(0, floor - k_Elipsis.Length) + k_Elipsis;
  311. }
  312. return ret;
  313. }
  314. public static Texture2D GetBackgroundImage(GUIStyle style, StyleState state = StyleState.normal)
  315. {
  316. var blockName = GUIStyleExtensions.StyleNameToBlockName(style.name, false);
  317. var styleBlock = EditorResources.GetStyle(blockName, state);
  318. return styleBlock.GetTexture(StyleCatalogKeyword.backgroundImage);
  319. }
  320. }
  321. }