diff options
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs new file mode 100644 index 0000000..a3276bf --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Editor/Utilities/BreadcrumbDrawer.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Timeline; + +namespace UnityEditor.Timeline +{ + enum TitleMode + { + None, + DisabledComponent, + Prefab, + PrefabOutOfContext, + Asset, + GameObject + } + + struct BreadCrumbTitle + { + public string name; + public TitleMode mode; + } + + class BreadcrumbDrawer + { + static readonly GUIContent s_TextContent = new GUIContent(); + static readonly string k_DisabledComponentText = L10n.Tr("The PlayableDirector is disabled"); + static readonly string k_PrefabOutOfContext = L10n.Tr("Prefab Isolation not enabled. Click to Enable."); + + static readonly GUIStyle k_BreadCrumbLeft; + static readonly GUIStyle k_BreadCrumbMid; + static readonly GUIStyle k_BreadCrumbLeftBg; + static readonly GUIStyle k_BreadCrumbMidBg; + static readonly GUIStyle k_BreadCrumbMidSelected; + static readonly GUIStyle k_BreadCrumbMidBgSelected; + + static readonly Texture k_TimelineIcon; + + const string k_Elipsis = "…"; + + static BreadcrumbDrawer() + { + k_BreadCrumbLeft = new GUIStyle("GUIEditor.BreadcrumbLeft"); + k_BreadCrumbMid = new GUIStyle("GUIEditor.BreadcrumbMid"); + k_BreadCrumbLeftBg = new GUIStyle("GUIEditor.BreadcrumbLeftBackground"); + k_BreadCrumbMidBg = new GUIStyle("GUIEditor.BreadcrumbMidBackground"); + + k_BreadCrumbMidSelected = new GUIStyle(k_BreadCrumbMid); + k_BreadCrumbMidSelected.normal = k_BreadCrumbMidSelected.onNormal; + + k_BreadCrumbMidBgSelected = new GUIStyle(k_BreadCrumbMidBg); + k_BreadCrumbMidBgSelected.normal = k_BreadCrumbMidBgSelected.onNormal; + k_TimelineIcon = EditorGUIUtility.IconContent("TimelineAsset Icon").image; + } + + static string FitTextInArea(float areaWidth, string text, GUIStyle style) + { + var borderWidth = style.border.left + style.border.right; + var textWidth = style.CalcSize(EditorGUIUtility.TextContent(text)).x; + + if (borderWidth + textWidth < areaWidth) + return text; + + // Need to truncate the text to fit in the areaWidth + var textAreaWidth = areaWidth - borderWidth; + var pixByChar = textWidth / text.Length; + var charNeeded = (int)Mathf.Floor(textAreaWidth / pixByChar); + charNeeded -= k_Elipsis.Length; + + if (charNeeded <= 0) + return k_Elipsis; + + if (charNeeded <= text.Length) + return k_Elipsis + " " + text.Substring(text.Length - charNeeded); + + return k_Elipsis; + } + + public static void Draw(float breadcrumbAreaWidth, List<BreadCrumbTitle> labels, Action<int> navigateToBreadcrumbIndex) + { + GUILayout.BeginHorizontal(GUILayout.Width(breadcrumbAreaWidth)); + { + var labelWidth = (int)(breadcrumbAreaWidth / labels.Count); + + for (var i = 0; i < labels.Count; i++) + { + var label = labels[i]; + + var style = i == 0 ? k_BreadCrumbLeft : k_BreadCrumbMid; + var backgroundStyle = i == 0 ? k_BreadCrumbLeftBg : k_BreadCrumbMidBg; + + if (i == labels.Count - 1) + { + if (i > 0) + { + // Only tint last breadcrumb if we are dug-in + DrawBreadcrumbAsSelectedSubSequence(labelWidth, label, k_BreadCrumbMidSelected, k_BreadCrumbMidBgSelected); + } + else + { + DrawActiveBreadcrumb(labelWidth, label, style, backgroundStyle); + } + } + else + { + var previousContentColor = GUI.contentColor; + + GUI.contentColor = new Color(previousContentColor.r, + previousContentColor.g, + previousContentColor.b, + previousContentColor.a * 0.6f); + var content = GetTextContent(labelWidth, label, style); + var rect = GetBreadcrumbLayoutRect(content, style); + + if (Event.current.type == EventType.Repaint) + { + backgroundStyle.Draw(rect, GUIContent.none, 0); + } + + if (GUI.Button(rect, content, style)) + { + navigateToBreadcrumbIndex.Invoke(i); + } + GUI.contentColor = previousContentColor; + } + } + } + GUILayout.EndHorizontal(); + } + + static GUIContent GetTextContent(int width, BreadCrumbTitle text, GUIStyle style) + { + s_TextContent.tooltip = string.Empty; + s_TextContent.image = null; + if (text.mode == TitleMode.DisabledComponent) + { + s_TextContent.tooltip = k_DisabledComponentText; + s_TextContent.image = EditorGUIUtility.GetHelpIcon(MessageType.Warning); + } + else if (text.mode == TitleMode.Prefab) + s_TextContent.image = PrefabUtility.GameObjectStyles.prefabIcon; + else if (text.mode == TitleMode.GameObject) + s_TextContent.image = PrefabUtility.GameObjectStyles.gameObjectIcon; + else if (text.mode == TitleMode.Asset) + s_TextContent.image = k_TimelineIcon; + else if (text.mode == TitleMode.PrefabOutOfContext) + { + s_TextContent.image = PrefabUtility.GameObjectStyles.prefabIcon; + if (!TimelineWindow.instance.locked) + s_TextContent.tooltip = k_PrefabOutOfContext; + } + + if (s_TextContent.image != null) + width = Math.Max(0, width - s_TextContent.image.width); + s_TextContent.text = FitTextInArea(width, text.name, style); + + return s_TextContent; + } + + static void DrawBreadcrumbAsSelectedSubSequence(int width, BreadCrumbTitle label, GUIStyle style, GUIStyle backgroundStyle) + { + var rect = DrawActiveBreadcrumb(width, label, style, backgroundStyle); + const float underlineThickness = 2.0f; + const float underlineVerticalOffset = 0.0f; + var underlineHorizontalOffset = backgroundStyle.border.right * 0.333f; + var underlineRect = Rect.MinMaxRect( + rect.xMin - underlineHorizontalOffset, + rect.yMax - underlineThickness - underlineVerticalOffset, + rect.xMax - underlineHorizontalOffset, + rect.yMax - underlineVerticalOffset); + + EditorGUI.DrawRect(underlineRect, DirectorStyles.Instance.customSkin.colorSubSequenceDurationLine); + } + + static Rect GetBreadcrumbLayoutRect(GUIContent content, GUIStyle style) + { + // the image makes the button far too big compared to non-image versions + var image = content.image; + content.image = null; + var size = style.CalcSizeWithConstraints(content, Vector2.zero); + content.image = image; + if (image != null) + size.x += size.y; // assumes square image, constrained by height + + return GUILayoutUtility.GetRect(content, style, GUILayout.MaxWidth(size.x)); + } + + static Rect DrawActiveBreadcrumb(int width, BreadCrumbTitle label, GUIStyle style, GUIStyle backgroundStyle) + { + var content = GetTextContent(width, label, style); + var rect = GetBreadcrumbLayoutRect(content, style); + + if (Event.current.type == EventType.Repaint) + { + backgroundStyle.Draw(rect, GUIContent.none, 0); + } + + if (GUI.Button(rect, content, style)) + { + UnityEngine.Object target = TimelineEditor.inspectedDirector; + if (target == null) + target = TimelineEditor.inspectedAsset; + if (target != null) + { + bool ping = true; + if (label.mode == TitleMode.PrefabOutOfContext) + { + var gameObject = PrefabUtility.GetRootGameObject(target); + if (gameObject != null) + { + target = gameObject; // ping the prefab root if it's locked. + if (!TimelineWindow.instance.locked) + { + var assetPath = AssetDatabase.GetAssetPath(gameObject); + if (!string.IsNullOrEmpty(assetPath)) + { + var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.OpenPrefab(assetPath); + if (stage != null) + ping = false; + } + } + } + } + + if (ping) + { + EditorGUIUtility.PingObject(target); + } + } + } + + return rect; + } + } +} |
