123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor.IMGUI.Controls;
- using UnityEditor.Timeline;
- using UnityEngine;
- using UnityEngine.Timeline;
- using UnityEngine.Playables;
- using UnityObject = UnityEngine.Object;
- namespace UnityEditor
- {
- class TimelineDragging : TreeViewDragging
- {
- public delegate bool TypeResolver(IEnumerable<Type> types, Action<Type> onComplete, string format);
- private static readonly string k_SelectTrackWithBinding = LocalizationDatabase.GetLocalizedString("Add {0}");
- private static readonly string k_SelectTrackWithClip = LocalizationDatabase.GetLocalizedString("Add Clip With {0}");
- private static readonly string k_SelectClip = LocalizationDatabase.GetLocalizedString("Add {0}");
- const string k_GenericDragId = "TimelineDragging";
- readonly int kDragSensitivity = 2;
- readonly TimelineAsset m_Timeline;
- readonly TimelineWindow m_Window;
- class TimelineDragData
- {
- public TimelineDragData(List<TreeViewItem> draggedItems)
- {
- this.draggedItems = draggedItems;
- }
- public readonly List<TreeViewItem> draggedItems;
- }
- public TimelineDragging(TreeViewController treeView, TimelineWindow window, TimelineAsset data)
- : base(treeView)
- {
- m_Timeline = data;
- m_Window = window;
- }
- public override bool CanStartDrag(TreeViewItem targetItem, List<int> draggedItemIDs, Vector2 mouseDownPosition)
- {
- if (Event.current.modifiers != EventModifiers.None)
- return false;
- // Can only drag when starting in the track header area
- if (mouseDownPosition.x > m_Window.sequenceHeaderRect.xMax)
- return false;
- var trackBaseGUI = targetItem as TimelineTrackBaseGUI;
- if (trackBaseGUI == null || trackBaseGUI.track == null)
- return false;
- if (trackBaseGUI.track.lockedInHierarchy)
- return false;
- if (Event.current.type == EventType.MouseDrag && Mathf.Abs(Event.current.delta.y) < kDragSensitivity)
- return false;
- // Make sure dragged items are selected
- // TODO Use similar system than the SceneHierarchyWindow in order to handle selection between treeView and tracks.
- SelectionManager.Clear();
- var draggedTrackGUIs = m_Window.allTracks.Where(t => draggedItemIDs.Contains(t.id));
- foreach (var trackGUI in draggedTrackGUIs)
- SelectionManager.Add(trackGUI.track);
- return true;
- }
- public override void StartDrag(TreeViewItem draggedNode, List<int> draggedItemIDs)
- {
- DragAndDrop.PrepareStartDrag();
- var tvItems = SelectionManager.SelectedTrackGUI().Cast<TreeViewItem>().ToList();
- DragAndDrop.SetGenericData(k_GenericDragId, new TimelineDragData(tvItems));
- DragAndDrop.objectReferences = new UnityObject[] {}; // this IS required for dragging to work
- string title = draggedItemIDs.Count + (draggedItemIDs.Count > 1 ? "s" : ""); // title is only shown on OSX (at the cursor)
- TimelineGroupGUI groupGui = draggedNode as TimelineGroupGUI;
- if (groupGui != null)
- {
- title = groupGui.displayName;
- }
- DragAndDrop.StartDrag(title);
- }
- public static bool IsDraggingEvent()
- {
- return Event.current.type == EventType.DragUpdated ||
- Event.current.type == EventType.DragExited ||
- Event.current.type == EventType.DragPerform;
- }
- public static bool ResolveType(IEnumerable<System.Type> types, Action<Type> onComplete, string formatString)
- {
- if (!types.Any() || onComplete == null)
- return false;
- if (types.Count() == 1)
- {
- onComplete(types.First());
- return true;
- }
- var menu = new GenericMenu();
- var builtInTypes = types.Where(TypeUtility.IsBuiltIn).OrderBy(TypeUtility.GetDisplayName).ToArray();
- var customTypes = types.Where(x => !TypeUtility.IsBuiltIn(x)).OrderBy(TypeUtility.GetDisplayName).ToArray();
- foreach (var t in builtInTypes)
- {
- menu.AddItem(new GUIContent(string.Format(formatString, TypeUtility.GetDisplayName(t))), false, s => onComplete((System.Type)s), t);
- }
- if (builtInTypes.Length != 0 && customTypes.Length != 0)
- menu.AddSeparator(string.Empty);
- foreach (var t in customTypes)
- {
- menu.AddItem(new GUIContent(string.Format(formatString, TypeUtility.GetDisplayName(t))), false, s => onComplete((System.Type)s), t);
- }
- menu.ShowAsContext();
- return true;
- }
- public override bool DragElement(TreeViewItem targetItem, Rect targetItemRect, int row)
- {
- if (TimelineWindow.instance.state.editSequence.isReadOnly)
- return false;
- // the drop rect contains the row rect plus additional spacing. The base drag element overlaps 1/2 the height of the next track
- // which interferes with track bindings
- var targetTrack = targetItem as TimelineGroupGUI;
- if (row > 0 && targetTrack != null && !targetTrack.dropRect.Contains(Event.current.mousePosition))
- return false;
- return base.DragElement(targetItem, targetItemRect, row);
- }
- TreeViewItem GetNextItem(TreeViewItem item)
- {
- if (item == null)
- return null;
- if (item.parent == null)
- {
- int row = m_Window.treeView.data.GetRow(item.id);
- var items = m_Window.treeView.data.GetRows();
- if (items.Count > row + 1)
- return items[row + 1];
- return null;
- }
- var children = item.parent.children;
- if (children == null)
- return null;
- for (int i = 0; i < children.Count - 1; i++)
- {
- if (children[i] == item)
- return children[i + 1];
- }
- return null;
- }
- private static TrackAsset GetTrack(TreeViewItem item)
- {
- TimelineTrackBaseGUI baseGui = item as TimelineTrackBaseGUI;
- if (baseGui == null)
- return null;
- return baseGui.track;
- }
- // The drag and drop may be over an expanded group but might be between tracks
- private void HandleNestedItemGUI(ref TreeViewItem parentItem, ref TreeViewItem targetItem, ref TreeViewItem insertBefore)
- {
- const float kTopPad = 5;
- const float kBottomPad = 5;
- insertBefore = null;
- if (!ShouldUseHierarchyDragAndDrop())
- return;
- var targetTrack = targetItem as TimelineGroupGUI;
- if (targetTrack == null)
- return;
- var mousePosition = Event.current.mousePosition;
- var dropBefore = targetTrack.rowRect.yMin + kTopPad > mousePosition.y;
- var dropAfter = !(targetTrack.track is GroupTrack) && (targetTrack.rowRect.yMax - kBottomPad < mousePosition.y);
- targetTrack.drawInsertionMarkerBefore = dropBefore;
- targetTrack.drawInsertionMarkerAfter = dropAfter;
- if (dropBefore)
- {
- targetItem = parentItem;
- parentItem = targetItem != null ? targetItem.parent : null;
- insertBefore = targetTrack;
- }
- else if (dropAfter)
- {
- targetItem = parentItem;
- parentItem = targetItem != null ? targetItem.parent : null;
- insertBefore = GetNextItem(targetTrack);
- }
- else if (targetTrack.track is GroupTrack)
- {
- targetTrack.isDropTarget = true;
- }
- }
- public override DragAndDropVisualMode DoDrag(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPos)
- {
- m_Window.isDragging = false;
- var retMode = DragAndDropVisualMode.None;
- var trackDragData = DragAndDrop.GetGenericData(k_GenericDragId) as TimelineDragData;
- if (trackDragData != null)
- {
- retMode = HandleTrackDrop(parentItem, targetItem, perform, dropPos);
- if (retMode == DragAndDropVisualMode.Copy && targetItem != null && Event.current.type == EventType.DragUpdated)
- {
- var targetActor = targetItem as TimelineGroupGUI;
- if (targetActor != null)
- targetActor.isDropTarget = true;
- }
- }
- else if (DragAndDrop.objectReferences.Any())
- {
- var objectsBeingDropped = DragAndDrop.objectReferences.OfType<UnityObject>();
- var director = m_Window.state.editSequence.director;
- if (ShouldUseHierarchyDragAndDrop())
- {
- // for object drawing
- var originalTarget = targetItem;
- TreeViewItem insertBeforeItem = null;
- HandleNestedItemGUI(ref parentItem, ref targetItem, ref insertBeforeItem);
- var track = GetTrack(targetItem);
- var parent = GetTrack(parentItem);
- var insertBefore = GetTrack(insertBeforeItem);
- retMode = HandleHierarchyPaneDragAndDrop(objectsBeingDropped, track, perform, m_Timeline, director, ResolveType, insertBefore);
- // fallback to old clip behaviour
- if (retMode == DragAndDropVisualMode.None)
- {
- retMode = HandleClipPaneObjectDragAndDrop(objectsBeingDropped, track, perform, m_Timeline, parent, director, m_Window.state.timeAreaShownRange.x, ResolveType, insertBefore);
- }
- // if we are rejected, clear any drop markers
- if (retMode == DragAndDropVisualMode.Rejected && targetItem != null)
- {
- ClearInsertionMarkers(originalTarget);
- ClearInsertionMarkers(targetItem);
- ClearInsertionMarkers(parentItem);
- ClearInsertionMarkers(insertBeforeItem);
- }
- }
- else
- {
- var candidateTime = TimelineHelpers.GetCandidateTime(m_Window.state, Event.current.mousePosition);
- retMode = HandleClipPaneObjectDragAndDrop(objectsBeingDropped, GetTrack(targetItem), perform, m_Timeline, GetTrack(parentItem), director, candidateTime, ResolveType);
- }
- }
- m_Window.isDragging = false;
- return retMode;
- }
- void ClearInsertionMarkers(TreeViewItem item)
- {
- var trackGUI = item as TimelineTrackBaseGUI;
- if (trackGUI != null)
- {
- trackGUI.drawInsertionMarkerAfter = false;
- trackGUI.drawInsertionMarkerBefore = false;
- trackGUI.isDropTarget = false;
- }
- }
- bool ShouldUseHierarchyDragAndDrop()
- {
- return m_Window.state.IsEditingAnEmptyTimeline() || m_Window.state.sequencerHeaderWidth > Event.current.mousePosition.x;
- }
- public static DragAndDropVisualMode HandleHierarchyPaneDragAndDrop(IEnumerable<UnityObject> objectsBeingDropped, TrackAsset targetTrack, bool perform, TimelineAsset timeline, PlayableDirector director, TypeResolver typeResolver, TrackAsset insertBefore = null)
- {
- if (timeline == null)
- return DragAndDropVisualMode.Rejected;
- // if we are over a target track, defer to track binding system (implemented in TrackGUIs), unless we are a groupTrack
- if (targetTrack != null && (targetTrack as GroupTrack) == null)
- return DragAndDropVisualMode.None;
- if (targetTrack != null && targetTrack.lockedInHierarchy)
- return DragAndDropVisualMode.Rejected;
- var tracksWithBinding = objectsBeingDropped.SelectMany(TypeUtility.GetTracksCreatableFromObject).Distinct();
- if (!tracksWithBinding.Any())
- return DragAndDropVisualMode.None;
- if (perform)
- {
- System.Action<Type> onResolve = trackType =>
- {
- foreach (var obj in objectsBeingDropped)
- {
- if (!obj.IsPrefab() && TypeUtility.IsTrackCreatableFromObject(obj, trackType))
- {
- var newTrack = TimelineHelpers.CreateTrack(timeline, trackType, targetTrack, string.Empty);
- if (insertBefore != null)
- {
- if (targetTrack != null)
- targetTrack.MoveLastTrackBefore(insertBefore);
- else
- timeline.MoveLastTrackBefore(insertBefore);
- }
- TimelineHelpers.Bind(newTrack, obj, director);
- }
- }
- TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
- };
- typeResolver(tracksWithBinding, onResolve, k_SelectTrackWithBinding);
- }
- return DragAndDropVisualMode.Copy;
- }
- public static DragAndDropVisualMode HandleClipPaneObjectDragAndDrop(IEnumerable<UnityObject> objectsBeingDropped, TrackAsset targetTrack, bool perform, TimelineAsset timeline, TrackAsset parent, PlayableDirector director, double candidateTime, TypeResolver typeResolver, TrackAsset insertBefore = null)
- {
- if (timeline == null)
- return DragAndDropVisualMode.Rejected;
- // locked tracks always reject
- if (targetTrack != null && targetTrack.lockedInHierarchy)
- return DragAndDropVisualMode.Rejected;
- // treat group tracks as having no track
- if (targetTrack is GroupTrack)
- {
- parent = targetTrack;
- targetTrack = null;
- }
- // Special case for monoscripts, since they describe the type
- if (objectsBeingDropped.Any(o => o is MonoScript))
- return HandleClipPaneMonoScriptDragAndDrop(objectsBeingDropped.OfType<MonoScript>(), targetTrack, perform, timeline, parent, director, candidateTime);
- // no unity objects, or explicit exceptions
- if (!objectsBeingDropped.Any() || objectsBeingDropped.Any(o => !ValidateObjectDrop(o)))
- return DragAndDropVisualMode.Rejected;
- // reject scene references if we have no context
- if (director == null && objectsBeingDropped.Any(o => o.IsSceneObject()))
- return DragAndDropVisualMode.Rejected;
- var validTrackTypes = objectsBeingDropped.SelectMany(o => TypeUtility.GetTrackTypesForObject(o)).Distinct().ToList();
- // special case for playable assets
- if (objectsBeingDropped.Any(o => TypeUtility.IsConcretePlayableAsset(o.GetType())))
- {
- var playableAssets = objectsBeingDropped.OfType<IPlayableAsset>().Where(o => TypeUtility.IsConcretePlayableAsset(o.GetType()));
- return HandleClipPanePlayableAssetDragAndDrop(playableAssets, targetTrack, perform, timeline, parent, director, candidateTime, typeResolver);
- }
- var markerTypes = objectsBeingDropped.SelectMany(o => TypeUtility.MarkerTypesWithFieldForObject(o)).Distinct();
- // Markers support all tracks
- if (!markerTypes.Any())
- {
- // No tracks support this object
- if (!validTrackTypes.Any())
- return DragAndDropVisualMode.Rejected;
- // no tracks for this object
- if (targetTrack != null && !validTrackTypes.Contains(targetTrack.GetType()))
- return DragAndDropVisualMode.Rejected;
- }
- // there is no target track, dropping to empty space, or onto a group
- if (perform)
- {
- // choose track and then clip
- if (targetTrack == null)
- {
- var createdTrack = HandleTrackAndItemCreation(objectsBeingDropped, candidateTime, typeResolver, timeline, parent, validTrackTypes, insertBefore);
- if (!createdTrack)
- {
- timeline.CreateMarkerTrack();
- HandleItemCreation(objectsBeingDropped, timeline.markerTrack, candidateTime, typeResolver, true); // menu is always popped if ambiguous choice
- }
- }
- // just choose clip/marker
- else
- {
- HandleItemCreation(objectsBeingDropped, targetTrack, candidateTime, typeResolver, true); // menu is always popped if ambiguous choice
- }
- }
- return DragAndDropVisualMode.Copy;
- }
- static bool HandleTrackAndItemCreation(IEnumerable<UnityEngine.Object> objectsBeingDropped, double candidateTime, TypeResolver typeResolver, TimelineAsset timeline, TrackAsset parent, IEnumerable<Type> validTrackTypes, TrackAsset insertBefore = null)
- {
- Action<Type> onResolved = t =>
- {
- var newTrack = TimelineHelpers.CreateTrack(timeline, t, parent, string.Empty);
- if (insertBefore != null)
- {
- if (parent != null)
- parent.MoveLastTrackBefore(insertBefore);
- else
- timeline.MoveLastTrackBefore(insertBefore);
- }
- HandleItemCreation(objectsBeingDropped, newTrack, candidateTime, typeResolver, validTrackTypes.Count() == 1); // menu is popped if ambiguous clip choice and unambiguous track choice
- };
- return typeResolver(validTrackTypes, t => onResolved(t), k_SelectTrackWithClip); // Did it create a track
- }
- static void HandleItemCreation(IEnumerable<UnityEngine.Object> objectsBeingDropped, TrackAsset targetTrack, double candidateTime, TypeResolver typeResolver, bool allowMenu)
- {
- var assetTypes = objectsBeingDropped.Select(o =>
- TypeUtility.GetAssetTypesForObject(targetTrack.GetType(), o)
- .Union(TypeUtility.MarkerTypesWithFieldForObject(o))).ToList();
- Action<Type> onCreateItem = assetType =>
- {
- if (typeof(PlayableAsset).IsAssignableFrom(assetType))
- {
- TimelineHelpers.CreateClipsFromObjects(assetType, targetTrack, candidateTime,
- objectsBeingDropped);
- }
- else
- {
- TimelineHelpers.CreateMarkersFromObjects(assetType, targetTrack, candidateTime, objectsBeingDropped);
- }
- };
- var flatAssetTypes = assetTypes.SelectMany(x => x).Distinct();
- // If there is a one to one mapping between assets and timeline types, no need to go through the type resolution, not ambiguous.
- if (assetTypes.All(x => x.Count() <= 1))
- {
- foreach (var type in flatAssetTypes)
- {
- onCreateItem(type);
- }
- }
- else
- {
- if (!allowMenu) // If we already popped a menu, and are presented with an ambiguous choice, take the first entry
- {
- flatAssetTypes = new[] {flatAssetTypes.First()};
- }
- typeResolver(flatAssetTypes, onCreateItem, k_SelectClip);
- }
- }
- /// Handles drag and drop of a mono script.
- public static DragAndDropVisualMode HandleClipPaneMonoScriptDragAndDrop(IEnumerable<MonoScript> scriptsBeingDropped, TrackAsset targetTrack, bool perform, TimelineAsset timeline, TrackAsset parent, PlayableDirector director, double candidateTime)
- {
- var playableAssetTypes = scriptsBeingDropped.Select(s => s.GetClass()).Where(TypeUtility.IsConcretePlayableAsset).Distinct();
- if (!playableAssetTypes.Any())
- return DragAndDropVisualMode.Rejected;
- var targetTrackType = typeof(PlayableTrack);
- if (targetTrack != null)
- targetTrackType = targetTrack.GetType();
- var trackAssetsTypes = TypeUtility.GetPlayableAssetsHandledByTrack(targetTrackType);
- var supportedTypes = trackAssetsTypes.Intersect(playableAssetTypes);
- if (!supportedTypes.Any())
- return DragAndDropVisualMode.Rejected;
- if (perform)
- {
- if (targetTrack == null)
- targetTrack = TimelineHelpers.CreateTrack(timeline, targetTrackType, parent, string.Empty);
- TimelineHelpers.CreateClipsFromTypes(supportedTypes, targetTrack, candidateTime);
- }
- return DragAndDropVisualMode.Copy;
- }
- public static DragAndDropVisualMode HandleClipPanePlayableAssetDragAndDrop(IEnumerable<IPlayableAsset> assetsBeingDropped, TrackAsset targetTrack, bool perform, TimelineAsset timeline, TrackAsset parent, PlayableDirector director, double candidateTime, TypeResolver typeResolver)
- {
- // get the list of supported track types
- var assetTypes = assetsBeingDropped.Select(x => x.GetType()).Distinct();
- IEnumerable<Type> supportedTypes = null;
- if (targetTrack == null)
- {
- supportedTypes = TypeUtility.AllTrackTypes().Where(t => TypeUtility.GetPlayableAssetsHandledByTrack(t).Intersect(assetTypes).Any()).ToList();
- }
- else
- {
- supportedTypes = Enumerable.Empty<Type>();
- var trackAssetTypes = TypeUtility.GetPlayableAssetsHandledByTrack(targetTrack.GetType());
- if (trackAssetTypes.Intersect(assetTypes).Any())
- supportedTypes = new[] {targetTrack.GetType()};
- }
- if (!supportedTypes.Any())
- return DragAndDropVisualMode.Rejected;
- if (perform)
- {
- Action<Type> onResolved = (t) =>
- {
- if (targetTrack == null)
- targetTrack = TimelineHelpers.CreateTrack(timeline, t, parent, string.Empty);
- var clipTypes = TypeUtility.GetPlayableAssetsHandledByTrack(targetTrack.GetType());
- foreach (var asset in assetsBeingDropped)
- {
- if (clipTypes.Contains(asset.GetType()))
- TimelineHelpers.CreateClipOnTrackFromPlayableAsset(asset, targetTrack, candidateTime);
- }
- };
- typeResolver(supportedTypes, onResolved, k_SelectTrackWithClip);
- }
- return DragAndDropVisualMode.Copy;
- }
- static bool ValidateObjectDrop(UnityObject obj)
- {
- // legacy animation clips are not supported at all
- AnimationClip clip = obj as AnimationClip;
- if (clip != null && clip.legacy)
- return false;
- return !(obj is TimelineAsset);
- }
- public DragAndDropVisualMode HandleTrackDrop(TreeViewItem parentItem, TreeViewItem targetItem, bool perform, DropPosition dropPos)
- {
- ((TimelineTreeView)m_Window.treeView.gui).showInsertionMarker = false;
- var trackDragData = (TimelineDragData)DragAndDrop.GetGenericData(k_GenericDragId);
- bool validDrag = ValidDrag(targetItem, trackDragData.draggedItems);
- if (!validDrag)
- return DragAndDropVisualMode.None;
- var draggedTracks = trackDragData.draggedItems.OfType<TimelineGroupGUI>().Select(x => x.track).ToList();
- if (draggedTracks.Count == 0)
- return DragAndDropVisualMode.None;
- if (parentItem != null)
- {
- var parentActor = parentItem as TimelineGroupGUI;
- if (parentActor != null && parentActor.track != null)
- {
- if (parentActor.track.lockedInHierarchy)
- return DragAndDropVisualMode.Rejected;
- if (draggedTracks.Any(x => !TimelineCreateUtilities.ValidateParentTrack(parentActor.track, x.GetType())))
- return DragAndDropVisualMode.Rejected;
- }
- }
- var insertAfterItem = targetItem as TimelineGroupGUI;
- if (insertAfterItem != null && insertAfterItem.track != null)
- {
- ((TimelineTreeView)m_Window.treeView.gui).showInsertionMarker = true;
- }
- if (dropPos == DropPosition.Upon)
- {
- var groupGUI = targetItem as TimelineGroupGUI;
- if (groupGUI != null)
- groupGUI.isDropTarget = true;
- }
- if (perform)
- {
- PlayableAsset targetParent = m_Timeline;
- var parentActor = parentItem as TimelineGroupGUI;
- if (parentActor != null && parentActor.track != null)
- targetParent = parentActor.track;
- TrackAsset siblingTrack = insertAfterItem != null ? insertAfterItem.track : null;
- // where the user drops after the last track, make sure to place it after all the tracks
- if (targetParent == m_Timeline && dropPos == DropPosition.Below && siblingTrack == null)
- {
- siblingTrack = m_Timeline.GetRootTracks().LastOrDefault(x => !draggedTracks.Contains(x));
- }
- if (TrackExtensions.ReparentTracks(TrackExtensions.FilterTracks(draggedTracks).ToList(), targetParent, siblingTrack, dropPos == DropPosition.Above))
- {
- m_Window.state.Refresh();
- }
- }
- return DragAndDropVisualMode.Move;
- }
- public static void HandleBindingDragAndDrop(TrackAsset dropTarget, Type requiredBindingType)
- {
- var objectBeingDragged = DragAndDrop.objectReferences[0];
- var action = BindingUtility.GetBindingAction(requiredBindingType, objectBeingDragged);
- DragAndDrop.visualMode = action == BindingAction.DoNotBind
- ? DragAndDropVisualMode.Rejected
- : DragAndDropVisualMode.Link;
- if (action == BindingAction.DoNotBind || Event.current.type != EventType.DragPerform)
- return;
- var director = TimelineEditor.inspectedDirector;
- switch (action)
- {
- case BindingAction.BindDirectly:
- {
- BindingUtility.Bind(director, dropTarget, objectBeingDragged);
- break;
- }
- case BindingAction.BindToExistingComponent:
- {
- var gameObjectBeingDragged = objectBeingDragged as GameObject;
- Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
- BindingUtility.Bind(director, dropTarget, gameObjectBeingDragged.GetComponent(requiredBindingType));
- break;
- }
- case BindingAction.BindToMissingComponent:
- {
- var gameObjectBeingDragged = objectBeingDragged as GameObject;
- Debug.Assert(gameObjectBeingDragged != null, "The object being dragged was detected as being a GameObject");
- var typeNameOfComponent = requiredBindingType.ToString().Split(".".ToCharArray()).Last();
- var bindMenu = new GenericMenu();
- bindMenu.AddItem(
- EditorGUIUtility.TextContent("Create " + typeNameOfComponent + " on " + gameObjectBeingDragged.name),
- false,
- nullParam => BindingUtility.Bind(director, dropTarget, Undo.AddComponent(gameObjectBeingDragged, requiredBindingType)),
- null);
- bindMenu.AddSeparator("");
- bindMenu.AddItem(EditorGUIUtility.TrTextContent("Cancel"), false, userData => {}, null);
- bindMenu.ShowAsContext();
- break;
- }
- default:
- {
- //no-op
- return;
- }
- }
- DragAndDrop.AcceptDrag();
- }
- static bool ValidDrag(TreeViewItem target, List<TreeViewItem> draggedItems)
- {
- TreeViewItem currentParent = target;
- while (currentParent != null)
- {
- if (draggedItems.Contains(currentParent))
- return false;
- currentParent = currentParent.parent;
- }
- // dragging into the sequence itself
- return true;
- }
- }
- }
|