public override void ShowManipulationLabel() { m_ManipulateStartLabel.text = TimelineUtility.GetTimeString(Timeline.ViewMode, m_StartTime, (int)Timeline.TaggedClip.SampleRate); m_ManipulateStartLabel.style.visibility = Visibility.Visible; float estimatedTextSize = TimelineUtility.EstimateTextSize(m_ManipulateStartLabel); float controlWidth = Math.Max(float.IsNaN(estimatedTextSize) ? m_ManipulateStartLabel.layout.width : estimatedTextSize, 8) + 6; m_ManipulateStartLabel.style.left = -controlWidth; m_ManipulateEndLabel.text = TimelineUtility.GetTimeString(Timeline.ViewMode, m_EndTime, (int)Timeline.TaggedClip.SampleRate); m_ManipulateEndLabel.style.left = style.width.value.value + 8f; m_ManipulateEndLabel.style.visibility = Visibility.Visible; }
public AnnotationsTrack(Timeline owner) : base(owner) { m_TracksContextManipulator = new ContextualMenuManipulator(evt => { string timeStr = TimelineUtility.GetTimeString(m_Owner.ViewMode, m_Owner.ActiveTime, (int)Clip.SampleRate); evt.menu.AppendAction($"Add Annotation at {timeStr}", null, DropdownMenuAction.Status.Disabled); evt.menu.AppendSeparator(); AddTagMenu(evt, action => OnAddAnnotationSelection(action.userData as Type), EditorApplication.isPlaying ? DropdownMenuAction.Status.Disabled : DropdownMenuAction.Status.Normal); evt.menu.AppendSeparator(); AddMarkerMenu(evt, action => OnAddAnnotationSelection(action.userData as Type), EditorApplication.isPlaying ? DropdownMenuAction.Status.Disabled : DropdownMenuAction.Status.Normal); }); }
public TimeRange(float minimumTime, float maximumTime, float minimumRange, float frameRate) { m_FrameRate = frameRate; minimumTime = (float)TimelineUtility.RoundToFrame(minimumTime, frameRate); maximumTime = (float)TimelineUtility.RoundToFrame(maximumTime, frameRate); minimumRange = (float)TimelineUtility.RoundToFrame(minimumRange, frameRate); m_StartTime = minimumTime; m_EndTime = maximumTime; m_ActiveTime = m_StartTime; m_DebugTime = m_StartTime; m_MinimumRange = minimumRange; m_MinimumTime = minimumTime; m_MaximumTime = maximumTime; }
public void OnAddTagSelection(Type tagType, float startTime, float duration = -1f) { if (m_Mode == TimelineViewMode.frames) { startTime = (float)TimelineUtility.RoundToFrame(startTime, TaggedClip.SampleRate); if (duration >= 0) { duration = (float)TimelineUtility.RoundToFrame(duration, TaggedClip.SampleRate); } } TaggedClip.AddTag(tagType, startTime, duration); TargetAsset.MarkDirty(); }
public override void ShowManipulationLabel() { TaggedAnimationClip clip = Track.Clip; float sampleRate = clip.SampleRate; string start = TimelineUtility.GetTimeString(Timeline.ViewMode, m_Tag.startTime, (int)sampleRate); m_ManipulateStartLabel.text = start; string end = TimelineUtility.GetTimeString(Timeline.ViewMode, m_Tag.EndTime, (int)sampleRate); float estimatedTextSize = TimelineUtility.EstimateTextSize(m_ManipulateStartLabel); float controlWidth = Math.Max(float.IsNaN(estimatedTextSize) ? m_ManipulateStartLabel.layout.width : estimatedTextSize, 8) + 6; m_ManipulateStartLabel.style.left = -controlWidth; m_ManipulateEndLabel.text = end; m_ManipulateStartLabel.style.visibility = Visibility.Visible; m_ManipulateEndLabel.style.visibility = Visibility.Visible; }
protected bool TryToSnap(float dragPosition, MouseDirection direction, float framerate, out float newTime, bool snapToClipStart = true, bool snapToClipDuration = true, bool snapToPlayhead = true) { Timeline timeline = m_Target.Timeline; if (SnappingEnabled) { m_Target.UnSnap(); SnappingElement snapTarget = FindSnapTarget(dragPosition, direction); if (snapTarget != null) { newTime = timeline.WorldPositionToTime(snapTarget.GetSnapPosition(dragPosition)); m_Target.SnapTo(snapTarget); if (timeline.TimelineUnits == TimelineViewMode.frames) { newTime = (float)TimelineUtility.RoundToFrame(newTime, framerate); } timeline.ShowSnap(newTime); return(true); } float zeroPos = timeline.TimeToWorldPos(0f); float duration = m_Target.Track.Clip.DurationInSeconds; float endPos = timeline.TimeToWorldPos(duration); if (snapToClipStart && Mathf.Abs(dragPosition - zeroPos) < k_SnapMoveDelta) { timeline.ShowSnap(0f); newTime = 0f; return(true); } if (snapToClipDuration && Mathf.Abs(dragPosition - endPos) < k_SnapMoveDelta) { newTime = duration; timeline.ShowSnap(newTime); return(true); } float activeTimePos = timeline.TimeToWorldPos(timeline.ActiveTime); if (snapToPlayhead && Mathf.Abs(dragPosition - activeTimePos) < k_SnapMoveDelta) { newTime = timeline.ActiveTime; timeline.ShowSnap(timeline.ActiveTime); return(true); } } newTime = timeline.WorldPositionToTime(dragPosition); if (timeline.TimelineUnits == TimelineViewMode.frames) { newTime = (float)TimelineUtility.RoundToFrame(newTime, framerate); } m_Target.UnSnap(); timeline.HideSnap(); return(false); }
void DrawRuler( Rect position, float frameRate, TimelineViewMode timeFormat) { if (float.IsNaN(position.x) || float.IsNaN(position.xMax) || float.IsNaN(worldBound.x) || float.IsNaN(worldBound.xMax)) { return; } Rect shownArea = new Rect(m_DrawInfo.layout.startTime, -90f, m_DrawInfo.layout.Duration, .05f); Color backupCol = GUI.color; GUI.BeginGroup(position); Color tempBackgroundColor = GUI.backgroundColor; m_TickHandler.SetRanges(m_DrawInfo.layout.startTime, m_DrawInfo.layout.endTime, worldBound.x, worldBound.xMax); m_TickHandler.SetTickStrengths(kTickRulerDistMin, kTickRulerDistFull, true); int labelLevel = m_TickHandler.GetLevelWithMinSeparation(kTickRulerDistLabel); if (Event.current.type == EventType.Repaint) { var originalColor = GUI.color; // Draw tick markers of various sizes for (int tickLevel = 0; tickLevel < m_TickHandler.tickLevels; tickLevel++) { float strength = m_TickHandler.GetStrengthOfLevel(tickLevel) * .9f; m_TickCache.Clear(); m_TickHandler.GetTicksAtLevel(tickLevel, true, m_TickCache); for (int i = 0; i < m_TickCache.Count; i++) { if (m_TickCache[i] < k_RangeMin || m_TickCache[i] > k_RangeMax) { continue; } float frame = Mathf.Round(m_TickCache[i] * frameRate); float height = position.height * Mathf.Min(1, strength) * kTickRulerHeightMax; float x = FrameToPixel(frame, frameRate, position, shownArea); // Draw line float minY = position.height - height + 0.5f; float maxY = position.height - 0.5f; GUI.color = tickLevel >= labelLevel ? TimelineWidget.k_MajorTickColor : TimelineWidget.k_MinorTickColor; Rect r = new Rect(new Vector2(x - .5f, minY), new Vector2(1, maxY - minY) ); GUI.DrawTexture(r, EditorGUIUtility.whiteTexture); } } GUI.color = originalColor; } // Draw tick labels m_TickCache.Clear(); m_TickHandler.GetTicksAtLevel(labelLevel, false, m_TickCache); for (int i = 0; i < m_TickCache.Count; i++) { if (m_TickCache[i] < k_RangeMin || m_TickCache[i] > k_RangeMax) { continue; } float frame = Mathf.Round(m_TickCache[i] * frameRate); // Important to take floor of positions of GUI stuff to get pixel correct alignment of // stuff drawn with both GUI and Handles/GL. Otherwise things are off by one pixel half the time. float labelPos = FrameToPixel(frame, frameRate, position, shownArea); string label = TimelineUtility.GetTimeString(timeFormat, m_TickCache[i], (int)frameRate); var labelSize = GUI.skin.GetStyle("label").CalcSize(new GUIContent(label)); float x = labelPos + 3; float y = -1; float w = labelSize.x + 2; float h = labelSize.y; GUI.Label(new Rect(x, y, w, h), label, TimeAreaStyles.timelineTick); } GUI.EndGroup(); GUI.backgroundColor = tempBackgroundColor; GUI.color = backupCol; }
float RoundValue(float value) { return((float)TimelineUtility.RoundToFrame(value, m_FrameRate)); }
protected override void OnMouseMoveEvent(MouseMoveEvent evt) { Timeline timeline = TagElement.Timeline; TaggedAnimationClip taggedAnimationClip = timeline.TaggedClip; if (!m_Active || !target.HasMouseCapture() || !taggedAnimationClip.Valid || EditorApplication.isPlaying) { return; } if (Math.Abs(m_MousePreviousPosition.x - evt.mousePosition.x) < k_MinDistanceForTagCreation) { if (Math.Abs(m_MouseDownPosition.y - evt.mousePosition.y) >= k_MinDistanceForTagCreation) { OnMouseMoveReorderEvent(evt); } return; } Vector2 position = evt.mousePosition; MouseDirection direction = GetMouseDirection(position); m_MousePreviousPosition = position; float framerate = taggedAnimationClip.SampleRate; TagAnnotation tag = TagElement.m_Tag; Asset asset = taggedAnimationClip.Asset; Mode mode = m_Mode; if (m_OverrideMode == Mode.None) { float mousePos = evt.mousePosition.x; float fromStart = Math.Abs(mousePos - TagElement.worldBound.x); float fromEnd = Math.Abs(mousePos - TagElement.worldBound.xMax); // If the tag element is this small it will be too difficult to accurately grab the center and even accurately pick either end // we'll figure out which side of the tag is closest and assume the user meant to click that side. if (TagElement.layout.width <= 14f) { if (fromStart <= fromEnd) { mode = Mode.StartTime; } else { mode = Mode.Duration; } m_OverrideMode = mode; } } else { mode = m_OverrideMode; } float newTime = float.NaN; float dragPosition = position.x; bool canPreview = timeline.CanPreview(); // when we're dragging the entire tag we need to snap the edges of the tag, not the mouse position so we'll handle that inside its switch case if (mode != Mode.Body) { if (m_Target.SnapValid(dragPosition)) { return; } TryToSnap(dragPosition, direction, taggedAnimationClip.SampleRate, out newTime, snapToPlayhead: !canPreview); } float previewTime = -1f; switch (mode) { case Mode.StartTime: float endTime = tag.startTime + tag.duration; Undo.RecordObject(asset, "Drag Tag start"); float delta = newTime - tag.startTime; if (tag.duration - delta < TagElement.MinTagDuration) { tag.startTime = endTime - TagElement.MinTagDuration; tag.duration = TagElement.MinTagDuration; } else { tag.startTime = newTime; tag.duration = endTime - tag.startTime; } TagElement.Timeline.ShowStartGuideline(tag.startTime); previewTime = newTime; break; case Mode.Duration: Undo.RecordObject(asset, "Drag Tag Duration"); float newDuration = newTime - tag.startTime; if (newDuration <= TagElement.MinTagDuration) { tag.duration = TagElement.MinTagDuration; } else { tag.duration = newDuration; } TagElement.Timeline.ShowEndGuideline(tag.EndTime); previewTime = tag.EndTime; break; case Mode.Body: Undo.RecordObject(asset, "Drag Tag"); newTime = m_Target.Timeline.WorldPositionToTime(position.x); if (TagElement.Timeline.TimelineUnits == TimelineViewMode.frames) { newTime = (float)TimelineUtility.RoundToFrame(newTime - m_TimeOffsetAtMouseDown, framerate); } else { newTime -= m_TimeOffsetAtMouseDown; } if (!m_Target.SnapValid(newTime) && !m_Target.SnapValid(newTime + tag.duration)) { float mouseOffset = TagElement.Timeline.TimeToWorldPos(newTime); if (!TryToSnap(mouseOffset, direction, taggedAnimationClip.SampleRate, out newTime, snapToPlayhead: !canPreview)) { float durationPos = TagElement.Timeline.TimeToWorldPos(newTime + tag.duration); //Try to snap via the end of the current tag if (TryToSnap(durationPos, direction, taggedAnimationClip.SampleRate, out float candidateEndTime, snapToPlayhead: !canPreview)) { newTime = candidateEndTime - tag.duration; } } tag.startTime = newTime; TagElement.Timeline.ShowGuidelines(tag.startTime, tag.EndTime); } previewTime = tag.EndTime; break; } if (canPreview && previewTime >= 0f) { TagElement.Timeline.SetActiveTime(previewTime); } tag.NotifyChanged(); TagElement.Timeline.SendTagModified(); evt.StopPropagation(); TagElement.ShowManipulationLabel(); }