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); } 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); }
static bool ProcessPlayableAssetRecording(UndoPropertyModification mod, WindowState state, ICurvesOwner curvesOwner) { if (mod.currentValue == null) { return(false); } if (!curvesOwner.IsParameterAnimatable(mod.currentValue.propertyPath)) { return(false); } var localTime = state.editSequence.time; var timelineClip = curvesOwner as TimelineClip; if (timelineClip != null) { // don't use time global to local since it will possibly loop. localTime = timelineClip.ToLocalTimeUnbound(state.editSequence.time); } if (localTime < 0) { return(false); } // grab the value from the current modification float fValue; if (!ExpressionEvaluator.Evaluate(mod.currentValue.value, out fValue)) { // case 916913 -- 'Add Key' menu item will passes 'True' or 'False' (instead of 1, 0) // so we need a special case to parse the boolean string bool bValue; if (!bool.TryParse(mod.currentValue.value, out bValue)) { Debug.Assert(false, "Invalid type in PlayableAsset recording"); return(false); } fValue = bValue ? 1 : 0; } var added = curvesOwner.AddAnimatedParameterValueAt(mod.currentValue.propertyPath, fValue, (float)localTime); if (added && AnimationMode.InAnimationMode()) { EditorCurveBinding binding = curvesOwner.GetCurveBinding(mod.previousValue.propertyPath); AnimationMode.AddPropertyModification(binding, mod.previousValue, true); curvesOwner.targetTrack.SetShowInlineCurves(true); if (state.GetWindow() != null && state.GetWindow().treeView != null) { state.GetWindow().treeView.CalculateRowRects(); } } return(added); }
static bool IsMouseOverMarkerHeader(Vector2 mousePosition, WindowState state) { if (!state.showMarkerHeader) { return(false); } return(state.GetWindow().markerHeaderRect.Contains(mousePosition) || state.GetWindow().markerContentRect.Contains(mousePosition)); }
protected override bool ContextClick(Event evt, WindowState state) { if (!(state.GetWindow().markerHeaderRect.Contains(evt.mousePosition) || state.GetWindow().markerContentRect.Contains(evt.mousePosition))) { return(false); } ShowMenu(evt.mousePosition, state); return(true); }
// This is called when performing Undo operations. // It needs to be called here since some operations are not // allowed (EditorUtility.InstanceIDToObject, for example) // during the ISerializationCallbackReceiver methods. void OnValidate() { if (m_SerializedPath == null || m_WindowState == null || m_WindowState.GetWindow() == null) { return; } bool hasDifferentRoot = m_WindowState.GetCurrentSequencePath().selectionRoot != m_SerializedPath.selectionRoot; if (m_WindowState.GetWindow().locked&& hasDifferentRoot) { return; } m_WindowState.SetCurrentSequencePath(m_SerializedPath, true); }
internal static UndoPropertyModification[] ProcessPlayableAssetModification(UndoPropertyModification[] modifications, WindowState state) { // can't record without a director since the asset being modified might be a scene instance if (state == null || state.editSequence.director == null) { return(modifications); } var remaining = new List <UndoPropertyModification>(); foreach (UndoPropertyModification mod in modifications) { var clip = FindClipWithAsset(state.editSequence.asset, TimelineRecording.GetTarget(mod) as IPlayableAsset, state.editSequence.director); if (clip == null || !IsRecording(clip, state) || !ProcessPlayableAssetRecording(mod, state, clip)) { remaining.Add(mod); } } if (remaining.Count() != modifications.Length) { state.rebuildGraph = true; state.GetWindow().Repaint(); } return(remaining.ToArray()); }
internal static UndoPropertyModification[] ProcessPlayableAssetModification(UndoPropertyModification[] modifications, WindowState state) { // can't record without a director since the asset being modified might be a scene instance if (state == null || state.editSequence.director == null) { return(modifications); } var remaining = new List <UndoPropertyModification>(); foreach (UndoPropertyModification mod in modifications) { if (!ProcessPlayableAssetModification(mod, state)) { remaining.Add(mod); } } if (remaining.Count != modifications.Length) { state.rebuildGraph = true; state.GetWindow().Repaint(); } return(remaining.ToArray()); }
void DrawTrackBinding(Rect rect, Rect headerRect, WindowState state) { if (showSceneReference && state.editSequence.director != null && state.GetWindow().currentMode.ShouldShowTrackBindings(state)) { DoTrackBindingGUI(rect, headerRect, state); return; } var textStyle = m_Styles.trackHeaderFont; textStyle.normal.textColor = SelectionManager.Contains(track) ? Color.white : m_Styles.customSkin.colorTrackFont; string trackName = track.name; EditorGUI.BeginChangeCheck(); // by default the size is just the width of the string (for selection purposes) rect.width = m_Styles.trackHeaderFont.CalcSize(new GUIContent(trackName)).x; // if we are editing, supply the entire width of the header if (GUIUtility.keyboardControl == track.GetInstanceID()) { rect.width = (headerRect.xMax - rect.xMin) - (5 * WindowConstants.trackHeaderButtonSize); } trackName = EditorGUI.DelayedTextField(rect, GUIContent.none, track.GetInstanceID(), track.name, textStyle); if (EditorGUI.EndChangeCheck()) { TimelineUndo.PushUndo(track, "Rename Track"); track.name = trackName; } }
float DrawLockMarkersButton(Rect rect, WindowState state) { if (track.GetMarkerCount() == 0) { return(0.0f); } var markersShown = showMarkers; var style = TimelineWindow.styles.collapseMarkers; if (Event.current.type == EventType.Repaint) { style.Draw(rect, GUIContent.none, false, false, markersShown, false); } // Override enable state to display "Show Marker" button in disabled state. bool prevEnabledState = GUI.enabled; GUI.enabled = true; if (GUI.Button(rect, DirectorStyles.markerCollapseButton, GUIStyle.none)) { state.GetWindow().SetShowTrackMarkers(track, !markersShown); } GUI.enabled = prevEnabledState; return(WindowConstants.trackHeaderButtonSize); }
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); }
float DrawInlineCurveButton(Rect rect, WindowState state) { if (!CanDrawInlineCurve()) { return(0.0f); } // Override enable state to display "Show Inline Curves" button in disabled state. bool prevEnabledState = GUI.enabled; GUI.enabled = true; var newValue = GUI.Toggle(rect, track.GetShowInlineCurves(), GUIContent.none, DirectorStyles.Instance.curves); GUI.enabled = prevEnabledState; if (newValue != track.GetShowInlineCurves()) { if (!state.editSequence.isReadOnly) { TimelineUndo.PushUndo(track, newValue ? "Show Inline Curves" : "Hide Inline Curves"); } track.SetShowInlineCurves(newValue); state.GetWindow().treeView.CalculateRowRects(); } return(WindowConstants.trackHeaderButtonSize); }
void SelectionChangedCallback(int[] ids) { if (Event.current.button == 1) { var selectableItem = PickerUtils.PickedSelectable(); if (selectableItem != null) { return; } } if (Event.current.command || Event.current.control || Event.current.shift) { SelectionManager.UnSelectTracks(); } else { SelectionManager.Clear(); } foreach (var id in ids) { var trackGUI = (TimelineTrackBaseGUI)m_TreeView.FindItem(id); SelectionManager.Add(trackGUI.track); } m_State.GetWindow().Repaint(); }
void DrawNoSequenceGUI(WindowState windowState) { bool showCreateButton = false; var currentlySelectedGo = UnityEditor.Selection.activeObject != null ? UnityEditor.Selection.activeObject as GameObject : null; var textContent = DirectorStyles.noTimelineAssetSelected; var existingDirector = currentlySelectedGo != null?currentlySelectedGo.GetComponent <PlayableDirector>() : null; var existingAsset = existingDirector != null ? existingDirector.playableAsset : null; if (currentlySelectedGo != null && !TimelineUtility.IsPrefabOrAsset(currentlySelectedGo) && existingAsset == null) { showCreateButton = true; textContent = new GUIContent(String.Format(DirectorStyles.createTimelineOnSelection.text, currentlySelectedGo.name, "a Director component and a Timeline asset")); } GUILayout.FlexibleSpace(); GUILayout.BeginVertical(); GUILayout.FlexibleSpace(); GUILayout.Label(textContent); if (showCreateButton) { GUILayout.BeginHorizontal(); var textSize = GUI.skin.label.CalcSize(textContent); GUILayout.Space((textSize.x / 2.0f) - (WindowConstants.createButtonWidth / 2.0f)); if (GUILayout.Button("Create", GUILayout.Width(WindowConstants.createButtonWidth))) { var message = DirectorStyles.createNewTimelineText.text + " '" + currentlySelectedGo.name + "'"; string newSequencePath = EditorUtility.SaveFilePanelInProject(DirectorStyles.createNewTimelineText.text, currentlySelectedGo.name + "Timeline", "playable", message, ProjectWindowUtil.GetActiveFolderPath()); if (!string.IsNullOrEmpty(newSequencePath)) { var newAsset = CreateInstance <TimelineAsset>(); AssetDatabase.CreateAsset(newAsset, newSequencePath); Undo.IncrementCurrentGroup(); if (existingDirector == null) { existingDirector = Undo.AddComponent <PlayableDirector>(currentlySelectedGo); } existingDirector.playableAsset = newAsset; SetCurrentTimeline(existingDirector); var newTrack = windowState.GetWindow().AddTrack(typeof(AnimationTrack)); windowState.previewMode = false; TimelineUtility.SetSceneGameObject(windowState.editSequence.director, newTrack, currentlySelectedGo); } // If we reach this point, the state of the pannel has changed; skip the rest of this GUI phase // Fixes: case 955831 - [OSX] NullReferenceException when creating a timeline on a selected object GUIUtility.ExitGUI(); } GUILayout.EndHorizontal(); } GUILayout.FlexibleSpace(); GUILayout.EndVertical(); GUILayout.FlexibleSpace(); }
public override bool Execute(WindowState state) { // otherwise select all tracks. SelectionManager.Clear(); state.GetWindow().allTracks.ForEach(x => SelectionManager.Add(x.track)); return(true); }
public override bool Execute(WindowState state) { var inlineCurveEditor = SelectionManager.GetCurrentInlineEditorCurve(); if (inlineCurveEditor != null && inlineCurveEditor.inlineCurvesSelected) { FrameSelectedAction.FrameInlineCurves(inlineCurveEditor, state, false); return(true); } if (state.IsEditingASubItem()) { return(false); } var w = state.GetWindow(); if (w == null || w.treeView == null) { return(false); } var visibleTracks = w.treeView.visibleTracks.ToList(); if (state.editSequence.asset != null && state.editSequence.asset.markerTrack != null) { visibleTracks.Add(state.editSequence.asset.markerTrack); } if (visibleTracks.Count == 0) { return(false); } var startTime = float.MaxValue; var endTime = float.MinValue; foreach (var t in visibleTracks) { if (t == null) { continue; } double trackStart, trackEnd; t.GetItemRange(out trackStart, out trackEnd); startTime = Mathf.Min(startTime, (float)trackStart); endTime = Mathf.Max(endTime, (float)(trackEnd)); } if (startTime != float.MinValue) { FrameSelectedAction.FrameRange(startTime, endTime, state); return(true); } return(false); }
public TimelinePoint(WindowState state, Vector2 mousePosition) { m_State = state; m_TreeViewGUI = state.GetWindow().treeView; m_Time = m_State.PixelToTime(mousePosition.x); m_YPos = mousePosition.y; m_YScrollPos = m_TreeViewGUI.scrollPosition.y; }
// This is called when performing Undo operations. // It needs to be called here since some operations are not // allowed (EditorUtility.InstanceIDToObject, for example) // during the ISerializationCallbackReceiver methods. void OnValidate() { if (m_SerializedPath == null || m_WindowState == null || m_WindowState.GetWindow() == null) { return; } m_WindowState.SetCurrentSequencePath(m_SerializedPath, true); }
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); }
public void FinalizeRecording(WindowState state) { // rebuild the graph if we add/remove a clip. Rebuild the graph with an evaluation immediately // so previews and scene position is maintained. if (m_CurveCount != GetCurveCount(m_TargetClip)) { state.rebuildGraph = true; state.GetWindow().RebuildGraphIfNecessary(true); } }
public TimeAreaAutoPanner(WindowState state) { m_State = state; m_Window = m_State.GetWindow(); var shownRange = m_State.timeAreaShownRange; var trackViewBounds = m_Window.sequenceRect; m_ViewRect = Rect.MinMaxRect(m_State.TimeToPixel(shownRange.x), trackViewBounds.yMin, m_State.TimeToPixel(shownRange.y), trackViewBounds.yMax); }
protected override bool MouseDown(Event evt, WindowState state) { Rect headerSplitterRect = state.GetWindow().headerSplitterRect; if (headerSplitterRect.Contains(evt.mousePosition)) { m_Captured = true; state.AddCaptured(this); return(true); } return(false); }
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>(); } } }
static void ShowHide(WindowState state, TrackAsset[] tracks, bool shouldLock) { if (tracks.Length == 0) { return; } var window = state.GetWindow(); foreach (var track in tracks) { window.SetShowTrackMarkers(track, shouldLock); } }
static void AddNewTrackMenuCommand(GenericMenu menu, TrackAsset parentTrack, TimelineGroupGUI parentGroup, Type type, WindowState state) { GenericMenu.MenuFunction2 lastMethod = trackType => { SelectionManager.Clear(); if (parentTrack is GroupTrack) { parentTrack.SetCollapsed(false); } var track = state.GetWindow().AddTrack((Type)trackType, parentGroup == null ? null : parentGroup.track); if (parentGroup != null) { state.GetWindow().treeView.data.SetExpanded(parentGroup, true); } if (track.GetType() == typeof(ActivationTrack)) { var clip = track.CreateClip(0); clip.displayName = ActivationTrackDrawer.Styles.ClipText.text; state.Refresh(); } }; var category = TimelineHelpers.GetTrackCategoryName(type); if (!string.IsNullOrEmpty(category)) { category += "/"; } var name = category + TimelineHelpers.GetTrackMenuName(type); var disabled = parentTrack != null && parentTrack.lockedInHierarchy; AddCommandToMenu(menu, name, lastMethod, type, !disabled); }
static void ShowHide(WindowState state, TrackAsset[] tracks, bool shouldLock) { if (tracks.Length == 0) { return; } var window = state.GetWindow(); foreach (var track in tracks) { window.SetShowTrackMarkers(track, shouldLock); } TimelineEditor.Refresh(RefreshReason.WindowNeedsRedraw); }
public void FinalizeRecording(WindowState state) { // rebuild the graph if we add/remove a clip. Rebuild the graph with an evaluation immediately // so previews and scene position is maintained. if (m_CurveCount != GetCurveCount(m_TargetClip)) { state.rebuildGraph = true; state.GetWindow().RebuildGraphIfNecessary(true); } else if (m_TrackHasPreviewComponents) { // Track with preview components potentially has modifications impacting other properties that need // to be refreshed before inspector or scene view to not interfere with manipulation. state.EvaluateImmediate(); } }
void UpdateDrawData(WindowState state) { if (Event.current.type == EventType.Layout) { m_TrackDrawData.m_ShowTrackBindings = false; m_TrackDrawData.m_TrackBinding = null; if (state.editSequence.director != null && showSceneReference) { m_TrackDrawData.m_ShowTrackBindings = state.GetWindow().currentMode.ShouldShowTrackBindings(state); m_TrackDrawData.m_TrackBinding = state.editSequence.director.GetGenericBinding(track); } var lastError = m_TrackDrawOptions.errorText; var lastHeight = m_TrackDrawOptions.minimumHeight; try { m_TrackDrawOptions = m_TrackEditor.GetTrackOptions(track, m_TrackDrawData.m_TrackBinding); } catch (Exception e) { Debug.LogException(e); m_TrackDrawOptions = CustomTimelineEditorCache.GetDefaultTrackEditor().GetTrackOptions(track, m_TrackDrawData.m_TrackBinding); } m_TrackDrawData.m_AllowsRecording = DoesTrackAllowsRecording(track); m_TrackDrawData.m_TrackIcon = m_TrackDrawOptions.icon; if (m_TrackDrawData.m_TrackIcon == null) { m_TrackDrawData.m_TrackIcon = m_DefaultTrackIcon.image; } // if the problem state has changed, it may be due to external bindings // in that case, we need to tell the graph to rebuild. // there is no notification from the engine for some markers that invalidate the graph (addcomponent) if (m_TrackDrawData.m_ShowTrackBindings && lastError != null && !lastError.Equals(m_TrackDrawOptions.errorText) && !state.playing) { state.rebuildGraph = true; } // track height has changed. need to update gui if (!Mathf.Approximately(lastHeight, m_TrackDrawOptions.minimumHeight)) { state.Refresh(); } } }
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); }
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); }