first commit

This commit is contained in:
SimonSayeBabu
2025-01-17 13:10:20 +01:00
commit bd1057cec0
16967 changed files with 1048699 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
using UnityEngine;
using UnityEngine.Timeline;
// Data sources for key overlays
namespace UnityEditor.Timeline
{
// Used for key overlays manipulators
class AnimationTrackKeyDataSource : BasePropertyKeyDataSource
{
readonly float m_TrackOffset;
protected override AnimationClip animationClip { get; }
public AnimationTrackKeyDataSource(AnimationTrack track)
{
animationClip = track != null ? track.infiniteClip : null;
m_TrackOffset = track != null ? (float)track.infiniteClipTimeOffset : 0.0f;
}
protected override float TransformKeyTime(float keyTime)
{
return keyTime + m_TrackOffset;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0b56195e00682b4594dfaeef9d5fa78
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace UnityEditor.Timeline
{
class Control
{
readonly List<Manipulator> m_Manipulators = new List<Manipulator>();
public bool HandleManipulatorsEvents(WindowState state)
{
var isHandled = false;
foreach (var manipulator in m_Manipulators)
{
isHandled = manipulator.HandleEvent(state);
if (isHandled)
break;
}
return isHandled;
}
public void AddManipulator(Manipulator m)
{
m_Manipulators.Add(m);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 077690d334440b044bdd51b26b3e9413
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d40a0edbdcdcf9747a420f3bbe0f18db
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,89 @@
using System;
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
[CustomTrackDrawer(typeof(AnimationTrack)), UsedImplicitly]
class AnimationTrackDrawer : TrackDrawer
{
static class Styles
{
public static readonly GUIContent AvatarMaskActiveTooltip = L10n.TextContent(string.Empty, "Enable Avatar Mask");
public static readonly GUIContent AvatarMaskInactiveTooltip = L10n.TextContent(string.Empty, "Disable Avatar Mask");
}
public override void DrawTrackHeaderButton(Rect rect, WindowState state)
{
var animTrack = track as AnimationTrack;
if (animTrack == null) return;
var style = DirectorStyles.Instance.trackAvatarMaskButton;
var tooltip = animTrack.applyAvatarMask ? Styles.AvatarMaskInactiveTooltip : Styles.AvatarMaskActiveTooltip;
using (var check = new EditorGUI.ChangeCheckScope())
{
var toggle = GUI.Toggle(rect, animTrack.applyAvatarMask, tooltip, style);
if (check.changed)
{
animTrack.applyAvatarMask = toggle;
if (state != null)
state.rebuildGraph = true;
}
}
}
public override void DrawRecordingBackground(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
{
base.DrawRecordingBackground(trackRect, trackAsset, visibleTime, state);
DrawBorderOfAddedRecordingClip(trackRect, trackAsset, visibleTime, (WindowState)state);
}
static void DrawBorderOfAddedRecordingClip(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
{
if (!state.IsArmedForRecord(trackAsset))
return;
AnimationTrack animTrack = trackAsset as AnimationTrack;
if (animTrack == null || !animTrack.inClipMode)
return;
// make sure there is no clip but we can add one
TimelineClip clip = null;
if (trackAsset.FindRecordingClipAtTime(state.editSequence.time, out clip) || clip != null)
return;
float yMax = trackRect.yMax;
float yMin = trackRect.yMin;
double startGap = 0;
double endGap = 0;
trackAsset.GetGapAtTime(state.editSequence.time, out startGap, out endGap);
if (double.IsInfinity(endGap))
endGap = visibleTime.y;
if (startGap > visibleTime.y || endGap < visibleTime.x)
return;
startGap = Math.Max(startGap, visibleTime.x);
endGap = Math.Min(endGap, visibleTime.y);
float xMin = state.TimeToPixel(startGap);
float xMax = state.TimeToPixel(endGap);
var r = Rect.MinMaxRect(xMin, yMin, xMax, yMax);
ClipDrawer.DrawClipSelectionBorder(r, ClipBorder.Recording(), ClipBlends.kNone);
}
public override bool HasCustomTrackHeaderButton()
{
var animTrack = track as AnimationTrack;
if (animTrack == null) return false;
return animTrack != null && animTrack.avatarMask != null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb281723220c9964094e6c52e0ece792
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 63118a0c9ee42ac46b7f30e793177a76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class InfiniteTrackDrawer : TrackDrawer
{
readonly IPropertyKeyDataSource m_DataSource;
Rect m_TrackRect;
public InfiniteTrackDrawer(IPropertyKeyDataSource dataSource)
{
m_DataSource = dataSource;
}
public bool CanDraw(TrackAsset track, WindowState state)
{
var keys = m_DataSource.GetKeys();
var isTrackEmpty = track.clips.Length == 0;
return keys != null || (state.IsArmedForRecord(track) && isTrackEmpty);
}
static void DrawRecordBackground(Rect trackRect)
{
var styles = DirectorStyles.Instance;
EditorGUI.DrawRect(trackRect, styles.customSkin.colorInfiniteTrackBackgroundRecording);
Graphics.ShadowLabel(trackRect,
DirectorStyles.Elipsify(DirectorStyles.recordingLabel.text, trackRect, styles.fontClip),
styles.fontClip, Color.white, Color.black);
}
public override bool DrawTrack(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
{
m_TrackRect = trackRect;
if (!CanDraw(trackAsset, state))
return true;
if (state.recording && state.IsArmedForRecord(trackAsset))
DrawRecordBackground(trackRect);
if (m_DataSource.GetKeys() != null && m_DataSource.GetKeys().Length > 0 || state.recording)
GUI.Box(trackRect, GUIContent.none, DirectorStyles.Instance.infiniteTrack);
var shadowRect = trackRect;
shadowRect.yMin = shadowRect.yMax;
shadowRect.height = 15.0f;
if (Event.current.type == EventType.Repaint)
DirectorStyles.Instance.bottomShadow.Draw(shadowRect, false, false, false, false);
var keys = m_DataSource.GetKeys();
if (keys != null && keys.Length > 0)
{
foreach (var k in keys)
DrawKeyFrame(k, state);
}
return true;
}
void DrawKeyFrame(float key, WindowState state)
{
var x = state.TimeToPixel(key);
var bounds = new Rect(x, m_TrackRect.yMin + 3.0f, 1.0f, m_TrackRect.height - 6.0f);
if (!m_TrackRect.Overlaps(bounds))
return;
var iconWidth = DirectorStyles.Instance.keyframe.fixedWidth;
var iconHeight = DirectorStyles.Instance.keyframe.fixedHeight;
var keyframeRect = bounds;
keyframeRect.width = iconWidth;
keyframeRect.height = iconHeight;
keyframeRect.xMin -= iconWidth / 2.0f;
keyframeRect.yMin = m_TrackRect.yMin + ((m_TrackRect.height - iconHeight) / 2.0f);
// case 890650 : Make sure to use GUI.Label and not GUI.Box since the number of key frames can vary while dragging keys in the inline curves causing hotControls to be desynchronized
GUI.Label(keyframeRect, GUIContent.none, DirectorStyles.Instance.keyframe);
EditorGUI.DrawRect(bounds, DirectorStyles.Instance.customSkin.colorInfiniteClipLine);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ea6a8a826704f743b3b0ce3e9d3c9a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 16388ae022a89264b84107f0c1b44680
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class ClipsLayer : ItemsLayer<TimelineClipGUI>
{
static readonly GUIStyle k_ConnectorIcon = DirectorStyles.Instance.connector;
public ClipsLayer(Layer layerOrder, IRowGUI parent) : base(layerOrder)
{
var track = parent.asset;
track.SortClips();
TimelineClipGUI previousClipGUI = null;
foreach (var clip in track.clips)
{
var oldClipGUI = ItemToItemGui.GetGuiForClip(clip);
var isInvalid = oldClipGUI != null && oldClipGUI.isInvalid; // HACK Make sure to carry invalidy state when refereshing the cache.
var currentClipGUI = new TimelineClipGUI(clip, parent, this) { isInvalid = isInvalid };
if (previousClipGUI != null) previousClipGUI.nextClip = currentClipGUI;
currentClipGUI.previousClip = previousClipGUI;
AddItem(currentClipGUI);
previousClipGUI = currentClipGUI;
}
//adjust zOrder based on current clip selection
foreach (var clipGUI in items)
{
if (clipGUI.IsSelected())
clipGUI.MoveToTop();
}
}
public override void Draw(Rect rect, WindowState state)
{
base.Draw(rect, state); //draw clips
DrawConnector(items);
}
static void DrawConnector(List<TimelineClipGUI> clips)
{
if (Event.current.type != EventType.Repaint)
return;
foreach (var clip in clips)
{
if (clip.previousClip != null && clip.visible && clip.treeViewRect.width > 14 &&
(DiscreteTime)clip.start == (DiscreteTime)clip.previousClip.end)
{
// draw little connector widget
var localRect = clip.treeViewRect;
localRect.x -= Mathf.Floor(k_ConnectorIcon.fixedWidth / 2.0f);
localRect.width = k_ConnectorIcon.fixedWidth;
localRect.height = k_ConnectorIcon.fixedHeight;
GUI.Label(localRect, GUIContent.none, k_ConnectorIcon);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a809a4b50addbf44b9023b5e7f9fd4d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
enum Layer : byte
{
Clips,
ClipHandles,
Markers,
MarkerHeaderTrack,
MarkersOnHeader
}
struct LayerZOrder : IComparable<LayerZOrder>
{
Layer m_Layer;
int m_ZOrder;
public LayerZOrder(Layer layer, int zOrder)
{
m_Layer = layer;
m_ZOrder = zOrder;
}
public int CompareTo(LayerZOrder other)
{
if (m_Layer == other.m_Layer)
return m_ZOrder.CompareTo(other.m_ZOrder);
return m_Layer.CompareTo(other.m_Layer);
}
public static LayerZOrder operator ++(LayerZOrder x)
{
return new LayerZOrder(x.m_Layer, x.m_ZOrder + 1);
}
public LayerZOrder ChangeLayer(Layer layer)
{
return new LayerZOrder(layer, m_ZOrder);
}
}
interface ILayerable
{
LayerZOrder zOrder { get; }
}
interface IZOrderProvider
{
LayerZOrder Next();
}
interface ILayer : IZOrderProvider
{
void Draw(Rect rect, WindowState state);
}
abstract class ItemsLayer<T> : ILayer where T : TimelineItemGUI
{
// provide a buffer for time-based culling to allow for UI that extends slightly beyond the time (e.g. markers)
// prevents popping of marker visibility.
const int kVisibilityBufferInPixels = 10;
int m_PreviousLayerStateHash = -1;
LayerZOrder m_LastZOrder;
public LayerZOrder Next()
{
m_NeedSort = true;
return m_LastZOrder++;
}
readonly List<T> m_Items = new List<T>();
bool m_NeedSort = true;
public virtual void Draw(Rect rect, WindowState state)
{
if (m_Items.Count <= 0) return;
Sort();
// buffer to prevent flickering of markers at boundaries
var onePixelTime = state.PixelDeltaToDeltaTime(kVisibilityBufferInPixels);
var visibleTime = state.timeAreaShownRange + new Vector2(-onePixelTime, onePixelTime);
var layerViewStateHasChanged = GetLayerViewStateChanged(rect, state);
foreach (var item in m_Items)
{
item.visible = item.end > visibleTime.x && item.start < visibleTime.y;
if (!item.visible)
continue;
item.Draw(rect, layerViewStateHasChanged, state);
}
}
public List<T> items => m_Items;
protected void AddItem(T item)
{
m_Items.Add(item);
m_NeedSort = true;
}
protected ItemsLayer(Layer layerOrder)
{
m_LastZOrder = new LayerZOrder(layerOrder, 0);
}
void Sort()
{
if (!m_NeedSort)
return;
m_Items.Sort((a, b) => a.zOrder.CompareTo(b.zOrder));
m_NeedSort = false;
}
bool GetLayerViewStateChanged(Rect rect, WindowState state)
{
var layerStateHash = rect.GetHashCode().CombineHash(state.viewStateHash);
var layerViewStateHasChanged = layerStateHash != m_PreviousLayerStateHash;
if (Event.current.type == EventType.Layout && layerViewStateHasChanged)
m_PreviousLayerStateHash = layerStateHash;
return layerViewStateHasChanged;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef97f39912c138b4cabdccedfb24093b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class MarkersLayer : ItemsLayer<TimelineItemGUI>
{
public MarkersLayer(Layer layerOrder, IRowGUI parent) : base(layerOrder)
{
CreateLists(parent);
}
void CreateLists(IRowGUI parent)
{
var markerCount = parent.asset.GetMarkerCount();
if (markerCount == 0) return;
var accumulator = new List<IMarker>();
var sortedMarkers = new List<IMarker>(parent.asset.GetMarkers());
var vm = TimelineWindowViewPrefs.GetTrackViewModelData(parent.asset);
sortedMarkers.Sort((lhs, rhs) =>
{
// Sort by time first
var timeComparison = lhs.time.CompareTo(rhs.time);
if (timeComparison != 0)
return timeComparison;
// If there's a collision, sort by edit timestamp
var lhsObject = lhs as object;
var rhsObject = rhs as object;
if (lhsObject.Equals(null) || rhsObject.Equals(null))
return 0;
var lhsHash = lhsObject.GetHashCode();
var rhsHash = rhsObject.GetHashCode();
if (vm.markerTimeStamps.ContainsKey(lhsHash) && vm.markerTimeStamps.ContainsKey(rhsHash))
return vm.markerTimeStamps[lhsHash].CompareTo(vm.markerTimeStamps[rhsHash]);
return 0;
});
foreach (var current in sortedMarkers)
{
// TODO: Take zoom factor into account?
if (accumulator.Count > 0 && Math.Abs(current.time - accumulator[accumulator.Count - 1].time) > TimeUtility.kTimeEpsilon)
ProcessAccumulator(accumulator, parent);
accumulator.Add(current);
}
ProcessAccumulator(accumulator, parent);
}
void ProcessAccumulator(List<IMarker> accumulator, IRowGUI parent)
{
if (accumulator.Count == 0) return;
if (accumulator.Count == 1)
{
AddItem(new TimelineMarkerGUI(accumulator[0], parent, this));
}
else
{
// Ensure that the cluster is always considered *below* the markers it contains.
var clusterZOrder = Next();
AddItem(
new TimelineMarkerClusterGUI(
accumulator.Select(m => new TimelineMarkerGUI(m, parent, this)).ToList(),
parent, this, clusterZOrder));
}
accumulator.Clear();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bea62e1faac8f9a48a4cb919ea05cb6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using System;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class TrackDrawer : GUIDrawer
{
internal WindowState sequencerState { get; set; }
public static TrackDrawer CreateInstance(TrackAsset trackAsset)
{
if (trackAsset == null)
return Activator.CreateInstance<TrackDrawer>();
TrackDrawer drawer;
try
{
drawer = (TrackDrawer)Activator.CreateInstance(TimelineHelpers.GetCustomDrawer(trackAsset.GetType()));
}
catch (Exception)
{
drawer = Activator.CreateInstance<TrackDrawer>();
}
drawer.track = trackAsset;
return drawer;
}
protected TrackAsset track { get; private set; }
public virtual bool HasCustomTrackHeaderButton()
{
return false;
}
public virtual void DrawTrackHeaderButton(Rect rect, WindowState state) { }
public virtual bool DrawTrack(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
{
return false;
}
public virtual void DrawRecordingBackground(Rect trackRect, TrackAsset trackAsset, Vector2 visibleTime, WindowState state)
{
EditorGUI.DrawRect(trackRect, DirectorStyles.Instance.customSkin.colorTrackBackgroundRecording);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a0f991b6c2f45b44b92e163f9969e8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Timeline
{
struct TrackItemsDrawer
{
List<ILayer> m_Layers;
ClipsLayer m_ClipsLayer;
public List<TimelineClipGUI> clips => m_ClipsLayer.items;
public TrackItemsDrawer(IRowGUI parent)
{
m_Layers = null;
m_ClipsLayer = null;
BuildGUICache(parent);
}
void BuildGUICache(IRowGUI parent)
{
m_ClipsLayer = new ClipsLayer(Layer.Clips, parent);
m_Layers = new List<ILayer>
{
m_ClipsLayer,
new MarkersLayer(Layer.Markers, parent)
};
}
public void Draw(Rect rect, WindowState state)
{
foreach (var layer in m_Layers)
{
layer.Draw(rect, state);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7137daaeb11e8647bf1ade9b7e9aa97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditorInternal;
using UnityEngine;
namespace UnityEditor.Timeline
{
interface IPropertyKeyDataSource
{
float[] GetKeys(); // Get the keys
Dictionary<float, string> GetDescriptions(); // Caches for descriptions
}
abstract class BasePropertyKeyDataSource : IPropertyKeyDataSource
{
static readonly StringBuilder k_StringBuilder = new StringBuilder();
protected abstract AnimationClip animationClip { get; }
public virtual float[] GetKeys()
{
if (animationClip == null)
return null;
var info = AnimationClipCurveCache.Instance.GetCurveInfo(animationClip);
return info.keyTimes.Select(TransformKeyTime).ToArray();
}
public virtual Dictionary<float, string> GetDescriptions()
{
var map = new Dictionary<float, string>();
var info = AnimationClipCurveCache.Instance.GetCurveInfo(animationClip);
var processed = new HashSet<string>();
foreach (var b in info.bindings)
{
var groupID = b.GetGroupID();
if (processed.Contains(groupID))
continue;
var group = info.GetGroupBinding(groupID);
var prefix = AnimationWindowUtility.GetNicePropertyGroupDisplayName(b.type, b.propertyName);
foreach (var t in info.keyTimes)
{
k_StringBuilder.Length = 0;
var key = TransformKeyTime(t);
if (map.ContainsKey(key))
k_StringBuilder.Append(map[key])
.Append('\n');
k_StringBuilder.Append(prefix)
.Append(" : ")
.Append(group.GetDescription(key));
map[key] = k_StringBuilder.ToString();
}
processed.Add(groupID);
}
return map;
}
protected virtual float TransformKeyTime(float keyTime)
{
return keyTime;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee83d5e1ad2ac4c9aa39e3a6f256062e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
interface IRowGUI
{
TrackAsset asset { get; }
Rect boundingRect { get; }
bool locked { get; }
bool showMarkers { get; }
bool muted { get; }
Rect ToWindowSpace(Rect treeViewRect);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ecec8cdc3ff99e4a9c65635d7e6b043
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9d816a6ab06c6834480f5f45f440e287
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using System;
namespace UnityEditor.Timeline
{
interface ISelectable : ILayerable
{
void Select();
bool IsSelected();
void Deselect();
bool CanSelect(UnityEngine.Event evt);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4acbfc0398bab674f922f693e58f4afc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3c01b61b3a6887c49a15276fd38be918
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using UnityEngine.Timeline;
using UnityEngine;
namespace UnityEditor.Timeline
{
static class ItemToItemGui
{
static Dictionary<object, TimelineItemGUI> s_ItemToItemGUI =
new Dictionary<object, TimelineItemGUI>();
public static void Add(TimelineClip clip, TimelineItemGUI gui)
{
s_ItemToItemGUI[clip] = gui;
}
public static void Add(IMarker marker, TimelineItemGUI gui)
{
s_ItemToItemGUI[marker] = gui;
}
public static TimelineClipGUI GetGuiForClip(TimelineClip clip)
{
return GetGuiForItem(clip) as TimelineClipGUI;
}
public static TimelineMarkerGUI GetGuiForMarker(IMarker marker)
{
return GetGuiForItem(marker) as TimelineMarkerGUI;
}
static TimelineItemGUI GetGuiForItem(object item)
{
if (item == null)
return null;
TimelineItemGUI gui;
s_ItemToItemGUI.TryGetValue(item, out gui);
return gui;
}
}
abstract class TimelineItemGUI : ISelectable
{
protected readonly DirectorStyles m_Styles;
public abstract ITimelineItem item { get; }
public abstract double start { get; }
public abstract double end { get; }
public abstract void Draw(Rect rect, bool rectChanged, WindowState state);
public abstract Rect RectToTimeline(Rect trackRect, WindowState state);
public virtual void Select() { }
public virtual bool IsSelected() { return false; }
public virtual void Deselect() { }
public virtual bool CanSelect(Event evt) { return true; }
public virtual void StartDrag() { }
public virtual void StopDrag() { }
public LayerZOrder zOrder { get; set; }
public bool visible { get; set; }
public bool isInvalid { get; set; }
public IRowGUI parent { get; }
public Rect rect
{
get { return parent.ToWindowSpace(treeViewRect); }
}
public Rect treeViewRect
{
get { return m_TreeViewRect; }
protected set
{
m_TreeViewRect = value;
if (value.width < 0.0f)
m_TreeViewRect.width = 1.0f;
}
}
Rect m_TreeViewRect;
protected TimelineItemGUI(IRowGUI parent)
{
this.parent = parent;
m_Styles = DirectorStyles.Instance;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6f515f8ecd3b6a546b90abaae2553f99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityObject = UnityEngine.Object;
namespace UnityEditor.Timeline
{
class TimelineMarkerClusterGUI : TimelineItemGUI
{
readonly List<TimelineMarkerGUI> m_MarkerGUIs;
readonly IZOrderProvider m_ZOrderProvider;
public TimelineMarkerGUI topMarker
{
get { return m_MarkerGUIs.LastOrDefault(); }
}
TimelineMarkerGUI m_ManipulatedMarker;
public TimelineMarkerClusterGUI(List<TimelineMarkerGUI> guis, IRowGUI parent,
IZOrderProvider zOrderProvider, LayerZOrder layerZOrder)
: base(parent)
{
m_MarkerGUIs = guis;
m_ZOrderProvider = zOrderProvider;
zOrder = layerZOrder;
SortMarkers();
topMarker.onStartDrag += OnDragTopMarker;
}
public override double start
{
get { return topMarker.start; }
}
public override double end
{
get { return topMarker.end; }
}
public override ITimelineItem item
{
get { return topMarker.item; }
}
public override void Select()
{
foreach (var marker in m_MarkerGUIs)
{
if (!marker.IsSelected())
marker.Select();
}
}
public override void Deselect()
{
foreach (var marker in m_MarkerGUIs)
{
if (marker.IsSelected())
marker.Deselect();
}
}
public override void Draw(Rect trackRect, bool trackRectChanged, WindowState state)
{
RegisterRect(state);
topMarker.Draw(trackRect, trackRectChanged, state);
if (m_MarkerGUIs.Count > 1)
GUI.Box(treeViewRect, String.Empty, DirectorStyles.Instance.markerMultiOverlay);
if (m_ManipulatedMarker != null)
m_ManipulatedMarker.Draw(trackRect, trackRectChanged, state);
}
public override Rect RectToTimeline(Rect trackRect, WindowState state)
{
return topMarker.RectToTimeline(trackRect, state);
}
public void CycleTop()
{
if (m_MarkerGUIs.Count < 2)
return;
topMarker.onStartDrag -= OnDragTopMarker;
var last = topMarker;
for (int i = 0; i < m_MarkerGUIs.Count; ++i)
{
var next = m_MarkerGUIs[i];
m_MarkerGUIs[i] = last;
last = next;
}
topMarker.zOrder = m_ZOrderProvider.Next();
topMarker.onStartDrag += OnDragTopMarker;
}
void OnDragTopMarker()
{
m_ManipulatedMarker = topMarker;
m_ManipulatedMarker.onStartDrag -= OnDragTopMarker;
m_MarkerGUIs.RemoveAt(m_MarkerGUIs.Count - 1);
}
void SortMarkers()
{
m_MarkerGUIs.Sort((lhs, rhs) => lhs.zOrder.CompareTo(rhs.zOrder));
}
void RegisterRect(WindowState state)
{
treeViewRect = topMarker.treeViewRect;
if (Event.current.type == EventType.Repaint && !parent.locked)
state.spacePartitioner.AddBounds(this, rect);
}
public static bool CanCycleMarkers()
{
if (!SelectionManager.SelectedMarkers().Any())
return false;
var cluster = PickerUtils.TopmostPickedItemOfType<TimelineMarkerClusterGUI>();
if (cluster == null)
return false;
// Only cycle if the marker is selected and nothing else is selected
return cluster.topMarker.IsSelected() && SelectionManager.Count() == 1;
}
public static void CycleMarkers()
{
var cluster = PickerUtils.TopmostPickedItemOfType<TimelineMarkerClusterGUI>();
if (cluster == null)
return;
cluster.topMarker.Deselect();
cluster.CycleTop();
cluster.topMarker.Select();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2c03ae9aa36a4fd44a983831f44654be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Timeline;
using UnityObject = UnityEngine.Object;
namespace UnityEditor.Timeline
{
class TimelineMarkerGUI : TimelineItemGUI, ISnappable, IAttractable
{
public event System.Action onStartDrag;
int m_ProjectedClipHash = -1;
int m_MarkerHash;
bool m_Selectable;
MarkerDrawOptions m_MarkerDrawOptions;
MarkerEditor m_Editor;
IMarker marker { get; }
bool selectable
{
get { return m_Selectable; }
}
public double time
{
get { return marker.time; }
}
public override double start
{
get { return time; }
}
public override double end
{
get { return time; }
}
public override void Select()
{
zOrder = zOrderProvider.Next();
SelectionManager.Add(marker);
TimelineWindowViewPrefs.GetTrackViewModelData(parent.asset).markerTimeStamps[m_MarkerHash] = DateTime.UtcNow.Ticks;
}
public override bool IsSelected()
{
return SelectionManager.Contains(marker);
}
public override void Deselect()
{
SelectionManager.Remove(marker);
}
public override ITimelineItem item
{
get { return ItemsUtils.ToItem(marker); }
}
IZOrderProvider zOrderProvider { get; }
public TimelineMarkerGUI(IMarker theMarker, IRowGUI parent, IZOrderProvider provider) : base(parent)
{
marker = theMarker;
m_Selectable = marker.GetType().IsSubclassOf(typeof(UnityObject));
m_MarkerHash = 0;
var o = marker as object;
if (!o.Equals(null))
m_MarkerHash = o.GetHashCode();
zOrderProvider = provider;
zOrder = zOrderProvider.Next();
ItemToItemGui.Add(marker, this);
m_Editor = CustomTimelineEditorCache.GetMarkerEditor(theMarker);
}
int ComputeDirtyHash()
{
return time.GetHashCode();
}
static void DrawMarker(Rect drawRect, Type type, bool isSelected, bool isCollapsed, MarkerDrawOptions options)
{
if (Event.current.type == EventType.Repaint)
{
bool hasError = !string.IsNullOrEmpty(options.errorText);
var style = StyleManager.UssStyleForType(type);
style.Draw(drawRect, GUIContent.none, false, false, !isCollapsed, isSelected);
// case1141836: Use of GUI.Box instead of GUI.Label causes desync in UI controlID
if (hasError)
GUI.Label(drawRect, String.Empty, DirectorStyles.Instance.markerWarning);
var tooltip = hasError ? options.errorText : options.tooltip;
if (!string.IsNullOrEmpty(tooltip) && drawRect.Contains(Event.current.mousePosition))
{
GUIStyle.SetMouseTooltip(tooltip, drawRect);
}
}
}
void UpdateDrawData()
{
if (Event.current.type == EventType.Layout)
{
try
{
m_MarkerDrawOptions = m_Editor.GetMarkerOptions(marker);
}
catch (Exception e)
{
Debug.LogException(e);
m_MarkerDrawOptions = CustomTimelineEditorCache.GetDefaultMarkerEditor().GetMarkerOptions(marker);
}
}
}
public override void Draw(Rect trackRect, bool trackRectChanged, WindowState state)
{
UpdateDrawData();
// compute marker hash
var currentMarkerHash = ComputeDirtyHash();
// update the clip projected rectangle on the timeline
CalculateClipRectangle(trackRect, state, currentMarkerHash, trackRectChanged);
var isSelected = selectable && SelectionManager.Contains(marker);
var showMarkers = parent.showMarkers;
QueueOverlay(treeViewRect, isSelected, !showMarkers);
DrawMarker(treeViewRect, marker.GetType(), isSelected, !showMarkers, m_MarkerDrawOptions);
if (Event.current.type == EventType.Repaint && showMarkers && !parent.locked)
state.spacePartitioner.AddBounds(this, rect);
}
public void QueueOverlay(Rect rect, bool isSelected, bool isCollapsed)
{
if (Event.current.type == EventType.Repaint && m_Editor.supportsDrawOverlay)
{
rect = GUIClip.Unclip(rect);
TimelineWindow.instance.AddUserOverlay(marker, rect, m_Editor, isCollapsed, isSelected);
}
}
public override void StartDrag()
{
if (onStartDrag != null)
onStartDrag.Invoke();
}
void CalculateClipRectangle(Rect trackRect, WindowState state, int projectedClipHash, bool trackRectChanged)
{
if (m_ProjectedClipHash == projectedClipHash && !trackRectChanged)
return;
m_ProjectedClipHash = projectedClipHash;
treeViewRect = RectToTimeline(trackRect, state);
}
public override Rect RectToTimeline(Rect trackRect, WindowState state)
{
var style = StyleManager.UssStyleForType(marker.GetType());
var width = style.fixedWidth;
var height = style.fixedHeight;
var x = ((float)marker.time * state.timeAreaScale.x) + state.timeAreaTranslation.x + trackRect.xMin;
x -= 0.5f * width;
return new Rect(x, trackRect.y, width, height);
}
public IEnumerable<Edge> SnappableEdgesFor(IAttractable attractable, ManipulateEdges manipulateEdges)
{
var edges = new List<Edge>();
var attractableGUI = attractable as TimelineMarkerGUI;
var canAddEdges = !(attractableGUI != null && attractableGUI.parent == parent);
if (canAddEdges)
edges.Add(new Edge(time));
return edges;
}
public bool ShouldSnapTo(ISnappable snappable)
{
return snappable != this;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d34348f8b97a334291f5cf31adc5d67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using UnityEditor.Timeline.Actions;
using UnityEngine;
namespace UnityEditor.Timeline
{
class DrillIntoClip : Manipulator
{
protected override bool DoubleClick(Event evt, WindowState state)
{
if (evt.button != 0)
return false;
var guiClip = PickerUtils.TopmostPickedItem() as TimelineClipGUI;
if (guiClip == null)
return false;
if (!TimelineWindow.instance.state.editSequence.isReadOnly && (guiClip.clip.curves != null || guiClip.clip.animationClip != null))
Invoker.Invoke<EditClipInAnimationWindow>(new[] { guiClip.clip });
if (guiClip.supportsSubTimelines)
Invoker.Invoke<EditSubTimeline>(new[] { guiClip.clip });
return true;
}
}
class ContextMenuManipulator : Manipulator
{
protected override bool MouseDown(Event evt, WindowState state)
{
if (evt.button == 1)
ItemSelection.HandleSingleSelection(evt);
return false;
}
protected override bool ContextClick(Event evt, WindowState state)
{
if (evt.alt)
return false;
var selectable = PickerUtils.TopmostPickedItem() as ISelectable;
if (selectable != null && selectable.IsSelected())
{
SequencerContextMenu.ShowItemContextMenu(evt.mousePosition);
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b222f61a1f7253e4d8e8cc82bfde9e42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,274 @@
using System;
using System.Linq;
using UnityEditor.ShortcutManagement;
using UnityEditor.Timeline.Actions;
using UnityEngine;
namespace UnityEditor.Timeline
{
class TimelinePanManipulator : Manipulator
{
const float k_MaxPanSpeed = 50.0f;
bool m_Active;
protected override bool MouseDown(Event evt, WindowState state)
{
if ((evt.button == 2 && evt.modifiers == EventModifiers.None) ||
(evt.button == 0 && evt.modifiers == EventModifiers.Alt))
{
TimelineCursors.SetCursor(TimelineCursors.CursorType.Pan);
m_Active = true;
return true;
}
return false;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (m_Active)
{
TimelineCursors.ClearCursor();
state.editorWindow.Repaint();
}
return false;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
// Note: Do not rely on evt.button here as some 3rd party automation
// software does not properly set the button data during drag.
if (!m_Active)
return false;
return Pan(evt, state);
}
protected override bool MouseWheel(Event evt, WindowState state)
{
if (Math.Abs(evt.delta.x) < 1e-5 || Math.Abs(evt.delta.x) <= Math.Abs(evt.delta.y))
return false;
TimelineZoomManipulator.InvalidateWheelZoom();
var panEvent = new Event(evt);
panEvent.delta = new Vector2(panEvent.delta.x * k_MaxPanSpeed * -1.0f, 0.0f);
return Pan(panEvent, state);
}
static bool Pan(Event evt, WindowState state)
{
var cursorRect = TimelineWindow.instance.sequenceContentRect;
cursorRect.xMax = TimelineWindow.instance.position.xMax;
cursorRect.yMax = TimelineWindow.instance.position.yMax;
if (state.GetWindow() != null && state.GetWindow().treeView != null)
{
var scroll = state.GetWindow().treeView.scrollPosition;
scroll.y -= evt.delta.y;
state.GetWindow().treeView.scrollPosition = scroll;
state.OffsetTimeArea((int)evt.delta.x);
return true;
}
return false;
}
}
class TimelineZoomManipulator : Manipulator
{
Vector2 m_MouseDownPos = Vector2.zero;
float m_FocalTime;
float m_LastMouseMoveX = -1;
bool m_WheelUsedLast;
TimelineZoomManipulator() { }
public static readonly TimelineZoomManipulator Instance = new TimelineZoomManipulator();
internal void DoZoom(float zoomFactor)
{
var refRange = TimelineEditor.visibleTimeRange;
DoZoom(zoomFactor, refRange, (refRange.x + refRange.y) / 2);
// Force resetting the reference zoom after a Framing operation
InvalidateWheelZoom();
}
static void DoZoom(float zoomFactor, Vector2 refRange, float focalTime)
{
const float kMinRange = 0.05f; // matches zoomable area.
if (zoomFactor <= 0)
return;
var t = Mathf.Max(focalTime, refRange.x);
var x = (refRange.x + t * (zoomFactor - 1)) / zoomFactor;
var y = (refRange.y + t * (zoomFactor - 1)) / zoomFactor;
var newRange = Mathf.Abs(x - y) < kMinRange ? refRange : new Vector2(
Mathf.Max(x, -WindowConstants.timeAreaShownRangePadding),
Mathf.Min(y, WindowState.kMaxShownTime));
if (newRange != refRange)
// Zoomable area does not protect 100% against crazy values
TimelineEditor.visibleTimeRange = newRange;
}
internal static void InvalidateWheelZoom()
{
Instance.m_WheelUsedLast = false;
}
protected override bool MouseDown(Event evt, WindowState state)
{
m_MouseDownPos = evt.mousePosition;
m_FocalTime = state.PixelToTime(m_MouseDownPos.x);
return false;
}
protected override bool MouseWheel(Event evt, WindowState state)
{
if (Math.Abs(evt.delta.y) < 1e-5)
return false;
var zoomRect = TimelineWindow.instance.sequenceContentRect;
zoomRect.yMax += TimelineWindow.instance.horizontalScrollbarHeight;
if (!zoomRect.Contains(evt.mousePosition))
return false;
if (!m_WheelUsedLast || Mathf.Abs(m_LastMouseMoveX - evt.mousePosition.x) > 1.0f)
{
m_LastMouseMoveX = evt.mousePosition.x;
m_FocalTime = state.PixelToTime(m_LastMouseMoveX);
}
var zoomFactor = -evt.delta.y * 0.02f + 1;
DoZoom(zoomFactor, state.timeAreaShownRange, m_FocalTime);
m_WheelUsedLast = true;
return true;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
// Fast zoom...
if (evt.modifiers != EventModifiers.Alt || evt.button != 1) return false;
var mouseMoveLength = Event.current.mousePosition - m_MouseDownPos;
var delta = Math.Abs(mouseMoveLength.x) > Math.Abs(mouseMoveLength.y)
? mouseMoveLength.x
: -mouseMoveLength.y;
var zoomFactor = PixelToZoom(delta);
DoZoom(zoomFactor, state.timeAreaShownRange, m_FocalTime);
m_WheelUsedLast = false;
return true;
}
static float PixelToZoom(float x)
{
const float pixel2Zoom = 1 / 300.0f;
x *= pixel2Zoom;
if (x < -0.75)
{
// Rational function that behaves like 1+x on [-0.75,inf) and asymptotically reaches zero on (-inf,-0.75]
// The coefficients were obtained by the following constraints:
//1) f(-0.75) = 0.25
//2) f'(-0.75) = 1 C1 continuity
//3) f(-3) = 0.001 (asymptotically zero)
return 1 / (98.6667f + 268.444f * x + 189.63f * x * x);
}
return 1 + x;
}
}
class TimelineShortcutManipulator : Manipulator
{
protected override bool ValidateCommand(Event evt, WindowState state)
{
return evt.commandName == EventCommandNames.Copy ||
evt.commandName == EventCommandNames.Paste ||
evt.commandName == EventCommandNames.Duplicate ||
evt.commandName == EventCommandNames.SelectAll ||
evt.commandName == EventCommandNames.Delete ||
evt.commandName == EventCommandNames.SoftDelete ||
evt.commandName == EventCommandNames.FrameSelected;
}
protected override bool ExecuteCommand(Event evt, WindowState state)
{
if (state.IsCurrentEditingASequencerTextField())
return false;
if (evt.commandName == EventCommandNames.SelectAll)
{
Invoker.InvokeWithSelected<SelectAllAction>();
return true;
}
if (evt.commandName == EventCommandNames.SoftDelete)
{
Invoker.InvokeWithSelected<DeleteAction>();
return true;
}
if (evt.commandName == EventCommandNames.FrameSelected)
{
Invoker.InvokeWithSelected<FrameSelectedAction>();
return true;
}
return ActionManager.HandleShortcut(evt);
}
}
class InlineCurvesShortcutManipulator : Manipulator
{
protected override bool ExecuteCommand(Event evt, WindowState state)
{
if (state.IsCurrentEditingASequencerTextField())
return false;
var inlineCurveEditor = SelectionManager.GetCurrentInlineEditorCurve();
if (inlineCurveEditor == null || !inlineCurveEditor.inlineCurvesSelected)
return false;
if (evt.commandName != EventCommandNames.FrameSelected)
return false;
Invoker.InvokeWithSelected<FrameSelectedAction>();
return true;
}
// CurveEditor uses an hardcoded shortcut to execute the FrameAll action, preventing the ShortcutManager from
// ever picking it up. We have to hijack it to ensure our code is being run when framing inline curves.
protected override bool KeyDown(Event evt, WindowState state)
{
var inlineCurveEditor = SelectionManager.GetCurrentInlineEditorCurve();
if (inlineCurveEditor == null || !inlineCurveEditor.inlineCurvesSelected)
return false;
// Not conflicting with the hardcoded value
if (evt.keyCode != KeyCode.A)
return false;
var combination = ShortcutManager.instance.GetShortcutBinding(Shortcuts.Timeline.frameAll)
.keyCombinationSequence.ToList();
var shortcutCombination = combination.First();
var currentCombination = KeyCombination.FromKeyboardInput(evt);
// User is not actually pressing the correct key combination for FrameAll
if (combination.Count == 1 && shortcutCombination.Equals(currentCombination))
Invoker.InvokeWithSelected<FrameAllAction>();
return true;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d029640460cf8ff47bbbfe69f49ddf29
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,196 @@
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Timeline.Actions;
using UnityEngine;
using UnityEngine.Timeline;
namespace UnityEditor.Timeline
{
class InlineCurveResize : Manipulator
{
bool m_Captured;
float m_CapturedHeight;
float m_CaptureMouseYPos;
InlineCurveResizeHandle m_Target;
protected override bool MouseDown(Event evt, WindowState state)
{
m_Target = PickerUtils.FirstPickedElementOfType<InlineCurveResizeHandle>();
if (m_Target == null)
return false;
m_Captured = true;
m_CapturedHeight = TimelineWindowViewPrefs.GetInlineCurveHeight(m_Target.trackGUI.track);
m_CaptureMouseYPos = GUIUtility.GUIToScreenPoint(Event.current.mousePosition).y;
state.AddCaptured(this);
return true;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (!m_Captured || m_Target == null)
return false;
var trackGUI = m_Target.trackGUI;
float inlineTrackHeight = m_CapturedHeight +
(GUIUtility.GUIToScreenPoint(Event.current.mousePosition).y - m_CaptureMouseYPos);
TimelineWindowViewPrefs.SetInlineCurveHeight(trackGUI.track, Mathf.Max(inlineTrackHeight, 60.0f));
state.GetWindow().treeView.CalculateRowRects();
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!m_Captured)
return false;
state.RemoveCaptured(this);
m_Captured = false;
return true;
}
public override void Overlay(Event evt, WindowState state)
{
var rect = state.GetWindow().sequenceRect;
EditorGUIUtility.AddCursorRect(rect, MouseCursor.SplitResizeUpDown);
}
}
class TrackResize : Manipulator
{
bool m_Captured;
int m_NumberOfContributingTracks;
TrackResizeHandle m_Target;
List<TimelineTrackGUI> m_TracksToResize;
protected override bool MouseDown(Event evt, WindowState state)
{
m_Target = PickerUtils.FirstPickedElementOfType<TrackResizeHandle>();
if (m_Target == null)
return false;
m_NumberOfContributingTracks = 1;
var selectedTracks = SelectionManager.SelectedTrackGUI().ToList();
if (selectedTracks.Any() && selectedTracks.Contains(m_Target.trackGUI)) //resize all selected tracks
{
var allTrackGui = state.GetWindow().treeView.allTrackGuis;
m_TracksToResize = allTrackGui.OfType<TimelineTrackGUI>().Where(i => SelectionManager.Contains(i.track)).ToList();
m_NumberOfContributingTracks += m_TracksToResize.IndexOf(m_Target.trackGUI);
}
else
m_TracksToResize = new List<TimelineTrackGUI> { m_Target.trackGUI };
m_Captured = true;
state.AddCaptured(this);
return true;
}
protected override bool MouseDrag(Event evt, WindowState state)
{
if (!m_Captured || m_Target == null)
return false;
var delta = evt.mousePosition.y - m_Target.boundingRect.center.y;
var extension = Mathf.RoundToInt(delta / m_NumberOfContributingTracks / state.trackScale);
foreach (var track in m_TracksToResize)
track.heightExtension += extension;
state.GetWindow().treeView.CalculateRowRects();
return true;
}
protected override bool MouseUp(Event evt, WindowState state)
{
if (!m_Captured)
return false;
foreach (var track in m_TracksToResize)
CommitExtension(track);
state.GetWindow().treeView.CalculateRowRects();
state.RemoveCaptured(this);
m_Captured = false;
return true;
}
public override void Overlay(Event evt, WindowState state)
{
var rect = state.GetWindow().sequenceRect;
EditorGUIUtility.AddCursorRect(rect, MouseCursor.SplitResizeUpDown);
}
static void CommitExtension(TimelineTrackGUI trackGUI)
{
if (trackGUI != null)
TimelineWindowViewPrefs.SetTrackHeightExtension(trackGUI.track, trackGUI.heightExtension);
}
}
class TrackDoubleClick : Manipulator
{
protected override bool DoubleClick(Event evt, WindowState state)
{
if (evt.button != 0)
return false;
var trackGUI = PickerUtils.FirstPickedElementOfType<TimelineTrackBaseGUI>();
if (trackGUI == null)
return false;
// Double-click is only available for AnimationTracks: it conflicts with selection mechanics on other tracks
if ((trackGUI.track as AnimationTrack) == null)
return false;
return EditTrackInAnimationWindow.Do(trackGUI.track);
}
}
class TrackShortcutManipulator : Manipulator
{
protected override bool KeyDown(Event evt, WindowState state)
{
return InternalExecute(evt, state);
}
protected override bool ExecuteCommand(Event evt, WindowState state)
{
return InternalExecute(evt, state);
}
static bool InternalExecute(Event evt, WindowState state)
{
if (state.IsCurrentEditingASequencerTextField())
return false;
var tracks = SelectionManager.SelectedTracks().ToList();
var items = SelectionManager.SelectedClipGUI();
foreach (var item in items)
{
var trackGUI = item.parent as TimelineTrackBaseGUI;
if (trackGUI == null)
continue;
if (!tracks.Contains(trackGUI.track))
tracks.Add(trackGUI.track);
}
return ActionManager.HandleShortcut(evt,
ActionManager.TrackActions,
x => ActionManager.ExecuteTrackAction(x, tracks));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5151708d47edd4344ba8e7bd469d966e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,103 @@
using UnityEngine;
namespace UnityEditor.Timeline
{
abstract class Manipulator
{
int m_Id;
protected virtual bool MouseDown(Event evt, WindowState state) { return false; }
protected virtual bool MouseDrag(Event evt, WindowState state) { return false; }
protected virtual bool MouseWheel(Event evt, WindowState state) { return false; }
protected virtual bool MouseUp(Event evt, WindowState state) { return false; }
protected virtual bool DoubleClick(Event evt, WindowState state) { return false; }
protected virtual bool KeyDown(Event evt, WindowState state) { return false; }
protected virtual bool KeyUp(Event evt, WindowState state) { return false; }
protected virtual bool ContextClick(Event evt, WindowState state) { return false; }
protected virtual bool ValidateCommand(Event evt, WindowState state) { return false; }
protected virtual bool ExecuteCommand(Event evt, WindowState state) { return false; }
public virtual void Overlay(Event evt, WindowState state) { }
public bool HandleEvent(WindowState state)
{
Event currentEvent = Event.current;
var type = currentEvent.GetTypeForControl(m_Id);
return HandleEvent(type, currentEvent, state);
}
public bool HandleEvent(EventType type, WindowState state)
{
Event currentEvent = Event.current;
return HandleEvent(type, currentEvent, state);
}
bool HandleEvent(EventType type, Event evt, WindowState state)
{
if (m_Id == 0)
m_Id = GUIUtility.GetPermanentControlID();
bool isHandled = false;
switch (type)
{
case EventType.ScrollWheel:
isHandled = MouseWheel(evt, state);
break;
case EventType.MouseUp:
{
if (GUIUtility.hotControl == m_Id)
{
isHandled = MouseUp(evt, state);
GUIUtility.hotControl = 0;
evt.Use();
}
}
break;
case EventType.MouseDown:
{
isHandled = evt.clickCount < 2 ? MouseDown(evt, state) : DoubleClick(evt, state);
if (isHandled)
GUIUtility.hotControl = m_Id;
}
break;
case EventType.MouseDrag:
{
if (GUIUtility.hotControl == m_Id)
isHandled = MouseDrag(evt, state);
}
break;
case EventType.KeyDown:
isHandled = KeyDown(evt, state);
break;
case EventType.KeyUp:
isHandled = KeyUp(evt, state);
break;
case EventType.ContextClick:
isHandled = ContextClick(evt, state);
break;
case EventType.ValidateCommand:
isHandled = ValidateCommand(evt, state);
break;
case EventType.ExecuteCommand:
isHandled = ExecuteCommand(evt, state);
break;
}
if (isHandled)
evt.Use();
return isHandled;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2bf68308f6cdff141ab98cd34174e4f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UnityEditor.Timeline
{
static class PickerUtils
{
public static List<object> pickedElements { get; private set; }
public static void DoPick(WindowState state, Vector2 mousePosition)
{
if (state.GetWindow().sequenceHeaderRect.Contains(mousePosition))
{
pickedElements = state.headerSpacePartitioner.GetItemsAtPosition<object>(mousePosition).ToList();
}
else if (state.GetWindow().sequenceContentRect.Contains(mousePosition))
{
pickedElements = state.spacePartitioner.GetItemsAtPosition<object>(mousePosition).ToList();
}
else
{
if (pickedElements != null)
pickedElements.Clear();
else
pickedElements = new List<object>();
}
}
public static ILayerable TopmostPickedItem()
{
return PickedItemsSortedByZOrderOfType<ILayerable>().FirstOrDefault();
}
public static T TopmostPickedItemOfType<T>() where T : class, ILayerable
{
return PickedItemsSortedByZOrderOfType<T>().FirstOrDefault();
}
public static T TopmostPickedItemOfType<T>(Func<T, bool> predicate) where T : class, ILayerable
{
return PickedItemsSortedByZOrderOfType<T>().FirstOrDefault(predicate);
}
static IEnumerable<T> PickedItemsSortedByZOrderOfType<T>() where T : class, ILayerable
{
return pickedElements.OfType<T>().OrderByDescending(x => x.zOrder);
}
public static T FirstPickedElementOfType<T>() where T : class, IBounds
{
return pickedElements.FirstOrDefault(e => e is T) as T;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16950289b516d6747868e0f7bf7b37a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 06ae1baf5524b314fa65b173b9eca869
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
namespace UnityEditor.Timeline
{
enum AttractedEdge
{
None,
Left,
Right
}
interface IAttractable
{
bool ShouldSnapTo(ISnappable snappable);
double start { get; }
double end { get; }
}
interface IAttractionHandler
{
void OnAttractedEdge(IAttractable attractable, ManipulateEdges manipulateEdges, AttractedEdge edge, double time);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6bfec54ce89b0b642a65d44def023b99
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More