Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,346 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Timeline;
|
||||
|
||||
namespace UnityEditor.Timeline
|
||||
{
|
||||
[Flags]
|
||||
enum InputEvent
|
||||
{
|
||||
None = 0,
|
||||
DragEnter = 1,
|
||||
DragExit = 2,
|
||||
Drag = 4,
|
||||
KeyboardInput = 8
|
||||
}
|
||||
|
||||
static class InputEventMethods
|
||||
{
|
||||
public static bool InputHasBegun(this InputEvent evt)
|
||||
{
|
||||
return evt == InputEvent.DragEnter || evt == InputEvent.KeyboardInput;
|
||||
}
|
||||
}
|
||||
|
||||
static class TimelineInspectorUtility
|
||||
{
|
||||
internal static class Styles
|
||||
{
|
||||
public static readonly GUIContent SecondsPrefix = L10n.TextContent("s", "Seconds");
|
||||
public static readonly GUIContent FramesPrefix = L10n.TextContent("f", "Frames");
|
||||
}
|
||||
|
||||
public static void TimeField(SerializedProperty property, GUIContent label, bool readOnly, double frameRate, double minValue, double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
var rect = EditorGUILayout.GetControlRect();
|
||||
TimeField(rect, property, label, readOnly, frameRate, minValue, maxValue, ref inputEvent);
|
||||
}
|
||||
|
||||
// Display Time related properties in frames and seconds
|
||||
public static void TimeField(Rect rect, SerializedProperty property, GUIContent label, bool readOnly, double frameRate, double minValue, double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
using (var propertyScope = new PropertyScope(rect, label, property))
|
||||
{
|
||||
GUIContent title = propertyScope.content;
|
||||
rect = EditorGUI.PrefixLabel(rect, title);
|
||||
|
||||
using (new IndentLevelScope(0))
|
||||
using (new LabelWidthScope((int)EditorGUI.kMiniLabelW))
|
||||
using (new GUIMixedValueScope(property.hasMultipleDifferentValues))
|
||||
{
|
||||
var secondsRect = new Rect(rect.xMin, rect.yMin, rect.width / 2 - EditorGUI.kSpacingSubLabel, rect.height);
|
||||
var framesRect = new Rect(rect.xMin + rect.width / 2, rect.yMin, rect.width / 2, rect.height);
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
EditorGUI.FloatField(secondsRect, Styles.SecondsPrefix, (float)property.doubleValue, EditorStyles.label);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DelayedAndDraggableDoubleField(secondsRect, Styles.SecondsPrefix, property, ref inputEvent);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.doubleValue = Clamp(property.doubleValue, minValue, maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (frameRate > TimeUtility.kTimeEpsilon)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
double time = property.doubleValue;
|
||||
int frames = TimeUtility.ToFrames(time, frameRate);
|
||||
double exactFrames = TimeUtility.ToExactFrames(time, frameRate);
|
||||
bool useIntField = TimeUtility.OnFrameBoundary(time, frameRate);
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
if (useIntField)
|
||||
EditorGUI.IntField(framesRect, Styles.FramesPrefix, frames, EditorStyles.label);
|
||||
else
|
||||
EditorGUI.DoubleField(framesRect, Styles.FramesPrefix, exactFrames, EditorStyles.label);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (useIntField)
|
||||
{
|
||||
int newFrames = DelayedAndDraggableIntField(framesRect, Styles.FramesPrefix, frames, ref inputEvent);
|
||||
time = Math.Max(0, TimeUtility.FromFrames(newFrames, frameRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
double newExactFrames = DelayedAndDraggableDoubleField(framesRect, Styles.FramesPrefix, exactFrames, ref inputEvent);
|
||||
time = Math.Max(0, TimeUtility.FromFrames((int)Math.Floor(newExactFrames), frameRate));
|
||||
}
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
property.doubleValue = Clamp(time, minValue, maxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static double TimeFieldUsingTimeReference(
|
||||
GUIContent label, double time, bool readOnly, bool showMixed, double frameRate, double minValue,
|
||||
double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
var state = TimelineWindow.instance.state;
|
||||
var needsTimeConversion = state != null && state.timeReferenceMode == TimeReferenceMode.Global;
|
||||
|
||||
if (needsTimeConversion)
|
||||
time = state.editSequence.ToGlobalTime(time);
|
||||
|
||||
var t = TimeField(label, time, readOnly, showMixed, frameRate, minValue, maxValue, ref inputEvent);
|
||||
|
||||
if (needsTimeConversion)
|
||||
t = state.editSequence.ToLocalTime(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
public static double DurationFieldUsingTimeReference(
|
||||
GUIContent label, double start, double end, bool readOnly, bool showMixed, double frameRate,
|
||||
double minValue, double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
var state = TimelineWindow.instance.state;
|
||||
var needsTimeConversion = state != null && state.timeReferenceMode == TimeReferenceMode.Global;
|
||||
|
||||
if (needsTimeConversion)
|
||||
{
|
||||
start = state.editSequence.ToGlobalTime(start);
|
||||
end = state.editSequence.ToGlobalTime(end);
|
||||
}
|
||||
|
||||
var duration = end - start;
|
||||
|
||||
var t = TimeField(label, duration, readOnly, showMixed, frameRate, minValue, maxValue, ref inputEvent);
|
||||
|
||||
end = start + t;
|
||||
|
||||
if (needsTimeConversion)
|
||||
{
|
||||
start = state.editSequence.ToLocalTime(start);
|
||||
end = state.editSequence.ToLocalTime(end);
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
public static double TimeField(Rect rect, GUIContent label, double time, bool readOnly, bool showMixed, double frameRate, double minValue, double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
using (new HorizontalScope(label, GUIStyle.none))
|
||||
{
|
||||
rect = EditorGUI.PrefixLabel(rect, label);
|
||||
|
||||
using (new IndentLevelScope(0))
|
||||
using (new LabelWidthScope((int)EditorGUI.kMiniLabelW))
|
||||
using (new GUIMixedValueScope(showMixed))
|
||||
{
|
||||
var secondsRect = new Rect(rect.xMin, rect.yMin, rect.width / 2 - EditorGUI.kSpacingSubLabel, rect.height);
|
||||
var framesRect = new Rect(rect.xMin + rect.width / 2, rect.yMin, rect.width / 2, rect.height);
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
EditorGUI.FloatField(secondsRect, Styles.SecondsPrefix, (float)time, EditorStyles.label);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = DelayedAndDraggableDoubleField(secondsRect, Styles.SecondsPrefix, time, ref inputEvent);
|
||||
}
|
||||
|
||||
if (frameRate > TimeUtility.kTimeEpsilon)
|
||||
{
|
||||
int frames = TimeUtility.ToFrames(time, frameRate);
|
||||
double exactFrames = TimeUtility.ToExactFrames(time, frameRate);
|
||||
bool useIntField = TimeUtility.OnFrameBoundary(time, frameRate);
|
||||
if (readOnly)
|
||||
{
|
||||
if (useIntField)
|
||||
EditorGUI.IntField(framesRect, Styles.FramesPrefix, frames, EditorStyles.label);
|
||||
else
|
||||
EditorGUI.FloatField(framesRect, Styles.FramesPrefix, (float)exactFrames, EditorStyles.label);
|
||||
}
|
||||
else
|
||||
{
|
||||
double newTime;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (useIntField)
|
||||
{
|
||||
int newFrames = DelayedAndDraggableIntField(framesRect, Styles.FramesPrefix, frames, ref inputEvent);
|
||||
newTime = Math.Max(0, TimeUtility.FromFrames(newFrames, frameRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
double newExactFrames = DelayedAndDraggableDoubleField(framesRect, Styles.FramesPrefix, exactFrames, ref inputEvent);
|
||||
newTime = Math.Max(0, TimeUtility.FromFrames((int)Math.Floor(newExactFrames), frameRate));
|
||||
}
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
time = newTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Clamp(time, minValue, maxValue);
|
||||
}
|
||||
|
||||
public static double TimeField(GUIContent label, double time, bool readOnly, bool showMixed, double frameRate, double minValue, double maxValue, ref InputEvent inputEvent)
|
||||
{
|
||||
var rect = EditorGUILayout.GetControlRect();
|
||||
return TimeField(rect, label, time, readOnly, showMixed, frameRate, minValue, maxValue, ref inputEvent);
|
||||
}
|
||||
|
||||
static InputEvent InputEventType(Rect rect, int id)
|
||||
{
|
||||
var evt = Event.current;
|
||||
switch (evt.GetTypeForControl(id))
|
||||
{
|
||||
case EventType.MouseDown:
|
||||
if (rect.Contains(evt.mousePosition) && evt.button == 0)
|
||||
{
|
||||
return InputEvent.DragEnter;
|
||||
}
|
||||
break;
|
||||
case EventType.MouseUp:
|
||||
if (GUIUtility.hotControl == id)
|
||||
{
|
||||
return InputEvent.DragExit;
|
||||
}
|
||||
break;
|
||||
case EventType.MouseDrag:
|
||||
if (GUIUtility.hotControl == id)
|
||||
{
|
||||
return InputEvent.Drag;
|
||||
}
|
||||
break;
|
||||
case EventType.KeyDown:
|
||||
if (GUIUtility.hotControl == id && evt.keyCode == KeyCode.Escape)
|
||||
{
|
||||
return InputEvent.DragExit;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return InputEvent.None;
|
||||
}
|
||||
|
||||
static double DelayedAndDraggableDoubleField(Rect rect, GUIContent label, double value, ref InputEvent inputEvent, double dragSensitivity)
|
||||
{
|
||||
var id = GUIUtility.GetControlID(FocusType.Keyboard);
|
||||
var fieldRect = EditorGUI.PrefixLabel(rect, id, label);
|
||||
rect.xMax = fieldRect.x;
|
||||
|
||||
double refValue = value;
|
||||
long dummy = 0;
|
||||
|
||||
inputEvent |= InputEventType(rect, id);
|
||||
|
||||
EditorGUI.DragNumberValue(rect, id, true, ref refValue, ref dummy, dragSensitivity);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var result = EditorGUI.DelayedDoubleFieldInternal(fieldRect, GUIContent.none, refValue, EditorStyles.numberField);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
inputEvent |= InputEvent.KeyboardInput;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int DelayedAndDraggableIntField(Rect rect, GUIContent label, int value, ref InputEvent inputEvent, long dragSensitivity)
|
||||
{
|
||||
var id = GUIUtility.GetControlID(FocusType.Keyboard);
|
||||
var fieldRect = EditorGUI.PrefixLabel(rect, id, label);
|
||||
rect.xMax = fieldRect.x;
|
||||
|
||||
double dummy = 0.0;
|
||||
long refValue = value;
|
||||
|
||||
inputEvent |= InputEventType(rect, id);
|
||||
|
||||
EditorGUI.DragNumberValue(rect, id, false, ref dummy, ref refValue, dragSensitivity);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var result = EditorGUI.DelayedIntFieldInternal(fieldRect, GUIContent.none, (int)refValue, EditorStyles.numberField);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
inputEvent |= InputEvent.KeyboardInput;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static double DelayedAndDraggableDoubleField(GUIContent label, double value, ref InputEvent action, double dragSensitivity)
|
||||
{
|
||||
var r = EditorGUILayout.s_LastRect = EditorGUILayout.GetControlRect(false, EditorGUI.kSingleLineHeight);
|
||||
return DelayedAndDraggableDoubleField(r, label, value, ref action, dragSensitivity);
|
||||
}
|
||||
|
||||
static void DelayedAndDraggableDoubleField(Rect rect, GUIContent label, SerializedProperty property, ref InputEvent inputEvent)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newValue = DelayedAndDraggableDoubleField(rect, label, property.doubleValue, ref inputEvent);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
property.doubleValue = newValue;
|
||||
}
|
||||
|
||||
static double DelayedAndDraggableDoubleField(Rect rect, GUIContent label, double value, ref InputEvent inputEvent)
|
||||
{
|
||||
var dragSensitivity = NumericFieldDraggerUtility.CalculateFloatDragSensitivity(value);
|
||||
return DelayedAndDraggableDoubleField(rect, label, value, ref inputEvent, dragSensitivity);
|
||||
}
|
||||
|
||||
static int DelayedAndDraggableIntField(Rect rect, GUIContent label, int value, ref InputEvent inputEvent)
|
||||
{
|
||||
var dragSensitivity = NumericFieldDraggerUtility.CalculateIntDragSensitivity(value);
|
||||
return DelayedAndDraggableIntField(rect, label, value, ref inputEvent, dragSensitivity);
|
||||
}
|
||||
|
||||
internal static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
|
||||
{
|
||||
if (val.CompareTo(min) < 0) return min;
|
||||
if (val.CompareTo(max) > 0) return max;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static Editor GetInspectorForObjects(UnityEngine.Object[] objects)
|
||||
{
|
||||
// create cached editor throws on assembly reload...
|
||||
try
|
||||
{
|
||||
if (objects.Any(x => x != null))
|
||||
{
|
||||
var director = TimelineWindow.instance.state.editSequence.director;
|
||||
return Editor.CreateEditorWithContext(objects, director, null);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue