///Inline curve editor box static void DoCurveBox(AnimatedParameter animParam, IKeyable keyable, bool isRecording) { var e = Event.current; var keyableLength = keyable.GetLength(); var keyableTime = keyable.RootTimeToLocalTime(); GUILayout.Label("INVISIBLE TEXT", GUILayout.Height(0)); var lastRect = GUILayoutUtility.GetLastRect(); GUILayout.Space(250); var timeRect = new Rect(0, 0, keyableLength, 0); var posRect = new Rect(); if (e.type == EventType.Repaint || !fixedCurveRects.TryGetValue(animParam, out posRect)) { posRect = new Rect(lastRect.x, lastRect.yMax + 5, lastRect.width, 240); fixedCurveRects[animParam] = posRect; } GUI.color = EditorGUIUtility.isProSkin ? new Color(0, 0, 0, 0.5f) : new Color(0, 0, 0, 0.3f); GUI.Box(posRect, "", (GUIStyle)"textfield"); GUI.color = Color.white; var dragTimeRect = new Rect(posRect.x, posRect.y + 1, posRect.width, 10); GUI.Box(dragTimeRect, ""); if (dragTimeRect.Contains(e.mousePosition)) { EditorGUIUtility.AddCursorRect(dragTimeRect, MouseCursor.SplitResizeLeftRight); if (e.type == EventType.MouseDown && e.button == 0) { isDraggingTime = true; e.Use(); } } if (isDraggingTime) { var iLerp = Mathf.InverseLerp(posRect.x, posRect.xMax, e.mousePosition.x); keyable.root.currentTime = Mathf.Lerp(keyable.startTime, keyable.endTime, iLerp); } if (e.rawType == EventType.MouseUp) { isDraggingTime = false; } if (e.type == EventType.KeyDown && posRect.Contains(e.mousePosition)) { if (e.keyCode == KeyCode.Comma) { GUIUtility.keyboardControl = 0; keyable.root.currentTime = animParam.GetKeyPrevious(keyableTime) + keyable.startTime; e.Use(); } if (e.keyCode == KeyCode.Period) { GUIUtility.keyboardControl = 0; keyable.root.currentTime = animParam.GetKeyNext(keyableTime) + keyable.startTime; Event.current.Use(); } } var dopeRect = new Rect(posRect.x, dragTimeRect.yMax + 1, posRect.width, 16); Handles.color = Color.black.WithAlpha(0.2f); Handles.DrawLine(new Vector2(dopeRect.xMin, dopeRect.yMin), new Vector2(dopeRect.xMax, dopeRect.yMin)); Handles.DrawLine(new Vector2(dopeRect.xMin, dopeRect.yMax), new Vector2(dopeRect.xMax, dopeRect.yMax)); Handles.color = Color.white; DopeSheetEditor.DrawDopeSheet(animParam, keyable, dopeRect, 0, keyableLength); var curvesRect = new Rect(posRect.x, dopeRect.yMax, posRect.width, posRect.height - dopeRect.height - dragTimeRect.height); CurveEditor.DrawCurves(animParam, keyable, curvesRect, timeRect); if (isRecording) { var iLerp = Mathf.InverseLerp(keyable.startTime, keyable.endTime, keyable.root.currentTime); var lerp = Mathf.Lerp(posRect.x, posRect.xMax, iLerp); var a = new Vector3(lerp, posRect.y, 0); var b = new Vector3(lerp, posRect.yMax, 0); Handles.color = EditorGUIUtility.isProSkin ? Slate.Styles.recordingColor : Color.red; Handles.DrawAAPolyLine(a, b); Handles.color = Color.white; } }
///Display an AnimatedParameter GUI public static void ShowParameter(AnimatedParameter animParam, IKeyable keyable, SerializedProperty serializedProperty = null) { //Calling this through a PropertyDrawer (thus serialized property != null), seems to have some mambo jumbo spacing. //This fixes that spacing so that both field and property parameter editors looks the same. GUILayout.Space(serializedProperty != null ? 0 : 2); if (!animParam.isValid) { GUILayout.Label("Animatable Parameter is invalid"); return; } var e = Event.current; var keyableLength = keyable.GetLength(); var keyableTime = keyable.RootTimeToLocalTime(); var isRecording = keyable.IsRootTimeWithinClip(); var foldOut = EditorTools.GetObjectFoldOut(animParam); var hasAnyKey = animParam.HasAnyKey(); var hasKeyNow = animParam.HasKey(keyableTime); var hasChanged = animParam.HasChanged(); var parameterEnabled = animParam.enabled; var lastRect = new Rect(); GUI.backgroundColor = new Color(0, 0.4f, 0.4f, 0.5f); GUILayout.BeginVertical(Slate.Styles.headerBoxStyle); GUI.backgroundColor = Color.white; GUILayout.BeginHorizontal(); var sFold = foldOut ? "▼" : "▶"; var sName = animParam.ToString(); GUILayout.Label(sFold, GUILayout.Width(13)); lastRect = GUILayoutUtility.GetLastRect(); GUI.enabled = !animParam.isExternal || isRecording; GUI.backgroundColor = hasAnyKey && parameterEnabled ? new Color(1, 0.6f, 0.6f) : Color.white; GUI.backgroundColor = hasAnyKey && parameterEnabled && isRecording ? Slate.Styles.recordingColor : GUI.backgroundColor; DoParameterField(string.Format("<b>{0}</b>", sName), animParam, keyableTime); GUI.enabled = true; GUI.backgroundColor = Color.white; EditorGUIUtility.AddCursorRect(lastRect, MouseCursor.Link); if (e.type == EventType.MouseDown && e.button == 0 && lastRect.Contains(e.mousePosition)) { EditorTools.SetObjectFoldOut(animParam, !foldOut); e.Use(); } GUI.enabled = hasAnyKey && parameterEnabled; if (GUILayout.Button(Slate.Styles.previousKeyIcon, GUIStyle.none, GUILayout.Height(20), GUILayout.Width(16))) { keyable.root.currentTime = animParam.GetKeyPrevious(keyableTime) + keyable.startTime; } EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); GUI.enabled = parameterEnabled; GUI.color = hasKeyNow && parameterEnabled ? new Color(1, 0.3f, 0.3f) : Color.white; GUI.color = hasAnyKey && hasChanged ? Color.green : GUI.color; if (GUILayout.Button(Slate.Styles.keyIcon, GUIStyle.none, GUILayout.Height(20), GUILayout.Width(16))) { if (e.alt) //temporary solution { animParam.scriptExpression = "value"; EditorTools.SetObjectFoldOut(animParam, true); } else { if (!hasKeyNow || hasChanged) { animParam.SetKeyCurrent(keyableTime); } else { animParam.RemoveKey(keyableTime); } } } GUI.color = Color.white; EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); GUI.enabled = hasAnyKey && parameterEnabled; if (GUILayout.Button(Slate.Styles.nextKeyIcon, GUIStyle.none, GUILayout.Height(20), GUILayout.Width(16))) { keyable.root.currentTime = animParam.GetKeyNext(keyableTime) + keyable.startTime; } EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); GUILayout.Space(2); GUI.enabled = true; GUI.color = Color.white.WithAlpha(animParam.enabled ? 1 : 0.5f); if (GUILayout.Button(Slate.Styles.gearIcon, GUIStyle.none, GUILayout.Height(20), GUILayout.Width(16))) { DoParamGearContextMenu(animParam, keyable); } GUI.color = Color.white; EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); GUI.enabled = true; GUILayout.EndHorizontal(); //... GUILayout.Space(3); GUILayout.EndVertical(); // var fade = EditorTools.GetObjectFoldOutFaded(animParam); if (EditorTools.GetObjectFoldOut(animParam)) { var hasExpression = animParam.hasActiveExpression; GUI.color = new Color(0.5f, 0.5f, 0.5f, 0.3f); GUILayout.BeginVertical(Slate.Styles.clipBoxFooterStyle); GUI.color = Color.white; #if SLATE_USE_EXPRESSIONS GUILayout.BeginHorizontal(); if (hasExpression) { if (GUILayout.Button(Styles.expressionIcon, GUI.skin.label, GUILayout.Width(18))) { var menu = Slate.Expressions.ExpressionsMenuGenerator.GetExpressionEnvironmentMenu(animParam.GetExpressionEnvironment(), (template) => { animParam.scriptExpression = template; }); menu.ShowAsContext(); } EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link); animParam.scriptExpression = EditorGUILayout.DelayedTextField(animParam.scriptExpression); } GUILayout.EndHorizontal(); if (hasExpression && animParam.compileException != null) { EditorGUILayout.HelpBox(animParam.compileException.Message, MessageType.Error); } #endif string info = null; if (!parameterEnabled) { info = "Parameter is disabled or overriden."; } if (info == null && !hasAnyKey && !hasExpression) { info = "Parameter is not yet animated. You can make it so by creating the first key."; } if (info == null && keyableLength == 0 && hasAnyKey) { info = "Length of Clip is zero. Can not display Curve Editor."; } if (info == null && animParam.isExternal && !isRecording) { info = "This Parameter can only be edited when time is within the clip range."; } if (info != null) { GUILayout.Label(info); } else { DoCurveBox(animParam, keyable, isRecording); } GUILayout.EndVertical(); GUILayout.Space(5); } else { #if SLATE_USE_EXPRESSIONS if (animParam.hasActiveExpression) { GUI.color = new Color(0.5f, 0.5f, 0.5f, 0.3f); GUILayout.BeginHorizontal(Styles.clipBoxFooterStyle); GUI.color = Color.white; GUILayout.Space(10); GUILayout.Label(string.Format("<b>= </b><size=9>{0}</size>", animParam.scriptExpression)); GUILayout.EndHorizontal(); } #endif } // EditorGUILayout.EndFadeGroup(); }