186 lines
7.8 KiB
C#
186 lines
7.8 KiB
C#
|
using System;
|
||
|
using UnityEditor.IMGUI.Controls;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Playables;
|
||
|
|
||
|
namespace UnityEditor.Timeline
|
||
|
{
|
||
|
class TimelineTrackErrorGUI : TimelineTrackBaseGUI
|
||
|
{
|
||
|
static class Styles
|
||
|
{
|
||
|
public static readonly GUIContent ErrorText = L10n.TextContent("Track cannot be loaded.", "Please fix any compile errors in the script for this track");
|
||
|
public static readonly Texture2D IconWarn = EditorGUIUtility.LoadIconRequired("console.warnicon.inactive.sml");
|
||
|
public static readonly GUIContent RemoveTrack = L10n.TextContent("Delete");
|
||
|
|
||
|
public static readonly Color WarningBoxBackgroundColor = new Color(115.0f / 255.0f, 115.0f / 255.0f, 115.0f / 255.0f); // approved for both skins
|
||
|
public static readonly Color WarningBoxHighlightColor = new Color(229 / 255.0f, 208 / 255.0f, 54 / 255.0f); // brigher than standard warning color for contrast
|
||
|
}
|
||
|
|
||
|
Rect m_TrackRect;
|
||
|
ScriptableObject m_ScriptableObject;
|
||
|
PlayableAsset m_Owner;
|
||
|
static GUIContent s_GUIContent = new GUIContent();
|
||
|
|
||
|
public TimelineTrackErrorGUI(TreeViewController treeview, TimelineTreeViewGUI treeviewGUI, int id, int depth, TreeViewItem parent, string displayName, ScriptableObject track, PlayableAsset owner)
|
||
|
: base(id, depth, parent, displayName, null, treeview, treeviewGUI)
|
||
|
{
|
||
|
m_ScriptableObject = track;
|
||
|
m_Owner = owner;
|
||
|
}
|
||
|
|
||
|
public override Rect boundingRect
|
||
|
{
|
||
|
get { return m_TrackRect; }
|
||
|
}
|
||
|
|
||
|
public override bool expandable
|
||
|
{
|
||
|
get { return false; }
|
||
|
}
|
||
|
|
||
|
public override void Draw(Rect headerRect, Rect contentRect, WindowState state)
|
||
|
{
|
||
|
m_TrackRect = contentRect;
|
||
|
|
||
|
DrawMissingTrackHeader(headerRect, state);
|
||
|
DrawMissingTrackBody(contentRect);
|
||
|
}
|
||
|
|
||
|
void DrawMissingTrackHeader(Rect headerRect, WindowState state)
|
||
|
{
|
||
|
var styles = DirectorStyles.Instance;
|
||
|
|
||
|
// Draw a header
|
||
|
Color backgroundColor = styles.customSkin.colorTrackHeaderBackground;
|
||
|
var bgRect = headerRect;
|
||
|
bgRect.x += styles.trackSwatchStyle.fixedWidth;
|
||
|
bgRect.width -= styles.trackSwatchStyle.fixedWidth;
|
||
|
EditorGUI.DrawRect(bgRect, backgroundColor);
|
||
|
|
||
|
// draw the warning icon
|
||
|
var errorIcon = Styles.IconWarn;
|
||
|
Rect iconRect = new Rect(headerRect.xMin + styles.trackSwatchStyle.fixedWidth, headerRect.yMin + 0.5f * (headerRect.height - errorIcon.height), errorIcon.width, errorIcon.height);
|
||
|
if (iconRect.width > 0 && iconRect.height > 0)
|
||
|
{
|
||
|
GUI.DrawTexture(iconRect, errorIcon, ScaleMode.ScaleAndCrop, true, 0, DirectorStyles.kClipErrorColor, 0, 0);
|
||
|
}
|
||
|
|
||
|
// Draw the name
|
||
|
|
||
|
// m_ScriptableObject == null will return true because the script can't be loaded. so this checks
|
||
|
// to make sure it is actually not null so we can grab the name
|
||
|
object o = m_ScriptableObject;
|
||
|
if (o != null)
|
||
|
{
|
||
|
s_GUIContent.text = m_ScriptableObject.name;
|
||
|
var textStyle = styles.trackHeaderFont;
|
||
|
textStyle.normal.textColor = styles.customSkin.colorTrackFont; // TODO -- we shouldn't modify the style like this. track header does it though :(
|
||
|
Rect textRect = headerRect;
|
||
|
textRect.xMin = iconRect.xMax + 1;
|
||
|
textRect.xMax = Math.Min(textRect.xMin + styles.trackHeaderFont.CalcSize(s_GUIContent).x, headerRect.xMax - 1);
|
||
|
EditorGUI.LabelField(textRect, s_GUIContent, textStyle);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Draw the color swatch to the left of the track, darkened by the mute
|
||
|
var color = Color.Lerp(DirectorStyles.kClipErrorColor, styles.customSkin.colorTrackDarken, styles.customSkin.colorTrackDarken.a);
|
||
|
color.a = 1;
|
||
|
using (new GUIColorOverride(color))
|
||
|
{
|
||
|
var colorSwatchRect = headerRect;
|
||
|
colorSwatchRect.width = styles.trackSwatchStyle.fixedWidth;
|
||
|
GUI.Label(colorSwatchRect, GUIContent.none, styles.trackSwatchStyle);
|
||
|
}
|
||
|
|
||
|
// draw darken overlay
|
||
|
EditorGUI.DrawRect(bgRect, styles.customSkin.colorTrackDarken);
|
||
|
|
||
|
DrawRemoveMenu(headerRect, state);
|
||
|
}
|
||
|
|
||
|
void DrawRemoveMenu(Rect headerRect, WindowState state)
|
||
|
{
|
||
|
const float pad = 3;
|
||
|
const float buttonSize = 16;
|
||
|
var buttonRect = new Rect(headerRect.xMax - buttonSize - pad, headerRect.y + ((headerRect.height - buttonSize) / 2f) + 2, buttonSize, buttonSize);
|
||
|
|
||
|
if (GUI.Button(buttonRect, GUIContent.none, DirectorStyles.Instance.trackOptions))
|
||
|
{
|
||
|
GenericMenu menu = new GenericMenu();
|
||
|
|
||
|
var owner = m_Owner;
|
||
|
var scriptableObject = m_ScriptableObject;
|
||
|
|
||
|
menu.AddItem(Styles.RemoveTrack, false, () =>
|
||
|
{
|
||
|
if (TrackExtensions.RemoveBrokenTrack(owner, scriptableObject))
|
||
|
state.Refresh();
|
||
|
}
|
||
|
);
|
||
|
|
||
|
menu.ShowAsContext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void DrawMissingTrackBody(Rect contentRect)
|
||
|
{
|
||
|
if (contentRect.width < 0)
|
||
|
return;
|
||
|
|
||
|
var styles = DirectorStyles.Instance;
|
||
|
|
||
|
// draw a track rectangle
|
||
|
EditorGUI.DrawRect(contentRect, styles.customSkin.colorTrackDarken);
|
||
|
// draw the warning box
|
||
|
DrawScriptWarningBox(contentRect, Styles.ErrorText);
|
||
|
}
|
||
|
|
||
|
static void DrawScriptWarningBox(Rect trackRect, GUIContent content)
|
||
|
{
|
||
|
var styles = DirectorStyles.Instance;
|
||
|
const float kTextPadding = 52f;
|
||
|
|
||
|
var errorIcon = Styles.IconWarn;
|
||
|
float textWidth = styles.fontClip.CalcSize(content).x;
|
||
|
|
||
|
var outerRect = trackRect;
|
||
|
outerRect.width = textWidth + kTextPadding + errorIcon.width;
|
||
|
outerRect.x += (trackRect.width - outerRect.width) / 2f;
|
||
|
outerRect.height -= 4f;
|
||
|
outerRect.y += 1f;
|
||
|
|
||
|
bool drawText = true;
|
||
|
if (outerRect.width > trackRect.width)
|
||
|
{
|
||
|
outerRect.x = trackRect.x;
|
||
|
outerRect.width = trackRect.width;
|
||
|
drawText = false;
|
||
|
}
|
||
|
|
||
|
var innerRect = new Rect(outerRect.x + 2, outerRect.y + 2, outerRect.width - 4, outerRect.height - 4);
|
||
|
using (new GUIColorOverride(Styles.WarningBoxHighlightColor))
|
||
|
GUI.Box(outerRect, GUIContent.none, styles.displayBackground);
|
||
|
using (new GUIColorOverride(Styles.WarningBoxBackgroundColor))
|
||
|
GUI.Box(innerRect, GUIContent.none, styles.displayBackground);
|
||
|
|
||
|
|
||
|
if (drawText)
|
||
|
{
|
||
|
var iconRect = new Rect(outerRect.x + kTextPadding / 2.0f - 4.0f, outerRect.y + (outerRect.height - errorIcon.height) / 2.0f, errorIcon.width, errorIcon.height);
|
||
|
var textRect = new Rect(iconRect.xMax + 4.0f, outerRect.y, textWidth, outerRect.height);
|
||
|
|
||
|
GUI.DrawTexture(iconRect, errorIcon, ScaleMode.ScaleAndCrop, true, 0, Styles.WarningBoxHighlightColor, 0, 0);
|
||
|
Graphics.ShadowLabel(textRect, content, styles.fontClip, Color.white, Color.black);
|
||
|
}
|
||
|
else if (errorIcon.width > innerRect.width)
|
||
|
{
|
||
|
var iconRect = new Rect(outerRect.x + (outerRect.width - errorIcon.width) / 2.0f, outerRect.y + (outerRect.height - errorIcon.height) / 2.0f, errorIcon.width, errorIcon.height);
|
||
|
GUI.DrawTexture(iconRect, errorIcon, ScaleMode.ScaleAndCrop, true, 0, Styles.WarningBoxHighlightColor, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void OnGraphRebuilt() { }
|
||
|
}
|
||
|
}
|