private void EventPitchChange(IEnumerable <TrackEvent> Events, decimal Semitones) { using (var undo = new UndoBlock("Pitch " + Semitones.ToString())) { var rateChangeFactor = (decimal)Math.Pow((double)MagicRatio, (double)Semitones); foreach (var ev in Events) { decimal newRate = Math.Round((decimal)ev.PlaybackRate * rateChangeFactor, 6); Timecode newLength = Timecode.FromNanos((long)(ev.Length.Nanos / rateChangeFactor)); // boundary checks / clamps if (newRate < 0.0m) { return; } if ((Math.Round(newRate, 3) > 4.0m) || (Math.Round(newRate, 3) < 0.25m)) { return; } ev.AdjustPlaybackRate((double)newRate, true); ev.Length = newLength; } } }
/// <summary> /// Ensures that the active scene has a MARS Session /// </summary> /// <returns>Thew newly created MARSSession, or null if a session previously exists</returns> public static MARSSession EnsureSessionInActiveScene() { var session = GameObjectUtils.GetComponentInActiveScene <MARSSession>(); if (SessionConfigured(session)) { return(null); } using (var undoBlock = new UndoBlock("Ensure Session in Active Scene", TestMode)) { if (!session) { var marsBehaviorsInScene = MarsRuntimeUtils.HasMarsBehaviors(SceneManager.GetActiveScene()); session = CreateSession(undoBlock, marsBehaviorsInScene); var userRef = GameObjectUtils.Instantiate(MARSRuntimePrefabs.instance.UserPrefab).transform; userRef.name = k_UserName; userRef.parent = session.m_CameraReference.transform; userRef.localPosition = Vector3.zero; userRef.localRotation = Quaternion.identity; userRef.localScale = Vector3.one; undoBlock.RegisterCreatedObject(userRef.gameObject); session.m_UserReference = userRef; DirtySimulatableSceneIfNeeded(); return(session); } EnsureSessionConfigured(session, undoBlock); } return(null); }
/// <summary> /// Indent the active selection one step. /// </summary> public void Indent() { if (!IsValid) { return; } Row xtr = null; var ActionGroup = new UndoBlockCollection(); for (int i = LogicalBounds.FirstRow; i <= LogicalBounds.LastRow; i++) { xtr = Control.Document[i]; xtr.Text = "\t" + xtr.Text; var b = new UndoBlock(); b.Action = UndoAction.InsertRange; b.Text = "\t"; b.Position.X = 0; b.Position.Y = i; ActionGroup.Add(b); } if (ActionGroup.Count > 0) { Control.Document.AddToUndoList(ActionGroup); } Bounds = LogicalBounds; Bounds.FirstColumn = 0; Bounds.LastColumn = xtr.Text.Length; Control.Caret.Position.X = LogicalBounds.LastColumn; Control.Caret.Position.Y = LogicalBounds.LastRow; }
public void Indent(string Pattern) { if (!this.IsValid) { return; } Row xtr = null; UndoBlockCollection ActionGroup = new UndoBlockCollection(); for (int i = this.LogicalBounds.FirstRow; i <= this.LogicalBounds.LastRow; i++) { xtr = Control.Document[i]; xtr.Text = Pattern + xtr.Text; UndoBlock b = new UndoBlock(); b.Action = UndoAction.InsertRange; b.Text = Pattern; b.Position.X = 0; b.Position.Y = i; ActionGroup.Add(b); } if (ActionGroup.Count > 0) { Control.Document.AddToUndoList(ActionGroup); } this.Bounds = this.LogicalBounds; this.Bounds.FirstColumn = 0; this.Bounds.LastColumn = xtr.Text.Length; Control.Caret.Position.X = this.LogicalBounds.LastColumn; Control.Caret.Position.Y = this.LogicalBounds.LastRow; }
private void PerformReplace() { if (SearchResults.Count == 0) { PerformSearch(); } if (SearchResults.Count == 0) { return; } string ReplaceString = tbReplace.Text; using (var undo = new UndoBlock("Search / replace")) { foreach (SearchReplaceResult rslt in SearchResults) { if (!rslt.Include) { continue; } rslt.Replace(ReplaceString); } } MyVegas.UpdateUI(); // a bit dirty, but we want to update the search results. PerformSearch(); }
public static void Execute(Vegas vegas) { Marker fistMarker = null; var markersToRemove = new List <Marker>(); var proj = vegas.Project; using (var undo = new UndoBlock("Convert Markers To Regions")) { foreach (var marker in VegasHelper.GetMarkersByTimecode(proj)) { if (fistMarker == null) { fistMarker = marker; } else { markersToRemove.Add(fistMarker); markersToRemove.Add(marker); Region currentRegion = new Region(fistMarker.Position, marker.Position - fistMarker.Position); proj.Regions.Add(currentRegion); fistMarker = null; } } foreach (var marker in markersToRemove) { proj.Markers.Remove(marker); } } }
public void SavePlanesFromSimulation(GameObject environmentRoot) { using (var undoBlock = new UndoBlock("Save Planes From Simulation")) { k_Planes.Clear(); this.GetPlanes(k_Planes); if (k_Planes.Count == 0) { EditorUtility.DisplayDialog(k_SavePlanesDialogTitle, k_NoPlanesDialogMessage, k_NoPlanesDialogOk); return; } if (!TryDestroyPreviousPlanes(environmentRoot, k_SavePlanesDialogTitle, undoBlock)) { return; } var newPlanesRoot = CreateGeneratedPlanesRoot(environmentRoot.transform, undoBlock); var simPlanePrefab = MarsObjectCreationResources.instance.GeneratedSimulatedPlanePrefab; foreach (var plane in k_Planes) { var synthPlane = Object.Instantiate(simPlanePrefab, newPlanesRoot); synthPlane.transform.SetWorldPose(plane.pose); synthPlane.SetMRPlaneData(plane.vertices, plane.center, plane.extents); } newPlanesRoot.gameObject.SetLayerRecursively(SimulationConstants.SimulatedEnvironmentLayerIndex); } }
public static void Execute(Vegas vegas) { var videoTracks = VegasHelper.GetTracks <VideoTrack>(vegas, 1); var selectedTrackEvents = VegasHelper.GetTrackEvents(videoTracks); var currentPosition = selectedTrackEvents[0].Start; //order the list selectedTrackEvents.Sort(new TrackEventsNameTimeComparer()); using (var undo = new UndoBlock("Order Events By Name And Time")) { //update order of the events foreach (var selectedTrackEvent in selectedTrackEvents) { if (selectedTrackEvent.IsGrouped) { foreach (var groupedTrackEvents in selectedTrackEvent.Group) { groupedTrackEvents.Start = currentPosition; } } else { selectedTrackEvent.Start = currentPosition; } currentPosition += selectedTrackEvent.Length; } } }
public static void Execute(Vegas vegas) { var configData = new WallBuilderConfiguration(); if (!GetConfigurationFromUser(configData)) { return; } var wallTracks = WallBuilder.BuildWall(vegas.Project.Video.Width, vegas.Project.Video.Height, configData); using (var undo = new UndoBlock("Insert Video Wall")) { var trackNumber = 0; var videoTracks = VegasHelper.GetTracks <VideoTrack>(vegas); foreach (var track in wallTracks) { var videoTrack = SelectOrInsertVideoTrack(vegas, videoTracks, trackNumber); trackNumber += 1; SetTrackKeyFrames(videoTrack, track); } } }
private void PosAlignByMarkers() { var selectedByTrack = myVegas.Project.GetSelectedEvents().GroupBy(item => item.Track); if (selectedByTrack.Count() < 2) { return; } var guideEvents = selectedByTrack.First(); var punchpoints = (guideEvents.Select(Ev => new { Ev, mmk = Ev.FindCurrentMetaMarker() }).Select(T => T.Ev.Start + T.mmk.GlobalMarkerOffset)).ToList(); selectedByTrack = selectedByTrack.Skip(1); // don't adjust the guide track using (var undo = new UndoBlock("Align by markers")) { foreach (var group in selectedByTrack) { var events = new List <TrackEvent>(); events.AddRange(group); for (int i = 0; i <= events.Count - 1; i++) { if (i > punchpoints.Count - 1) { break; } TrackEvent ev = events[i]; MetaMarker mmk = ev.FindCurrentMetaMarker(); Timecode newMkPos = punchpoints[i]; ev.Start = newMkPos - mmk.GlobalMarkerOffset; } } } }
/// <summary> /// Sets the default camera settings based on the current scene view camera /// </summary> /// <param name="sceneView">Scene view that we are getting the camera from</param> /// <param name="isSimView">Is the scene view a simulation view</param> public void SetDefaultEnvironmentCamera(SceneView sceneView, bool isSimView) { MARSSession.EnsureRuntimeState(); var simCamera = sceneView.camera; var cameraTransform = simCamera.transform; using (var undoBlock = new UndoBlock("Set Default Environment Camera")) { undoBlock.RecordObject(this); if (isSimView) { var cameraScale = MARSSession.GetWorldScale(); var camPose = new Pose(cameraTransform.position / cameraScale, cameraTransform.rotation); m_EnvironmentInfo.DefaultCameraWorldPose = camPose; m_EnvironmentInfo.DefaultCameraPivot = sceneView.pivot / cameraScale; m_EnvironmentInfo.DefaultCameraSize = sceneView.size / cameraScale; } else { m_EnvironmentInfo.DefaultCameraWorldPose = cameraTransform.GetWorldPose(); m_EnvironmentInfo.DefaultCameraPivot = sceneView.pivot; m_EnvironmentInfo.DefaultCameraSize = sceneView.size; } } }
public List <TrackEvent> CutFirstGroup() { List <TrackEvent> trackEvents = new List <TrackEvent>(); List <TrackEvent> trackEventsInGroup = new List <TrackEvent>(); foreach (TrackEvent trackEvent in group1) { trackEventsInGroup.Add(trackEvent); } foreach (TrackEvent trackEvent in trackEventsInGroup) { Timecode offset = trackEvent.Length - new Timecode(Config.splitOffset); TrackEvent cut = null; using (UndoBlock undo = new UndoBlock("Cut first group track events")) { cut = trackEvent.Split(offset); } if (cut != null) { trackEvents.Add(cut); } } return(trackEvents); }
internal static void ExtractPlanes(PlaneExtractionSettings settings) { using (var undoBlock = new UndoBlock("Extract Planes")) { var prefabRoot = settings.gameObject; undoBlock.RecordObject(prefabRoot); var voxelGenerationParams = settings.VoxelGenerationParams; var planeExtractionParams = settings.PlaneFindingParams; var voxelSize = voxelGenerationParams.voxelSize; if ((int)(planeExtractionParams.minPointsPerSqMeter * (voxelSize * voxelSize)) <= 0) { Debug.LogWarning("Minimum points per voxel is not greater than 0. " + "Increase either the voxel size or the minimum points per square meter."); return; } if (!PlaneGenerationModule.TryDestroyPreviousPlanes(prefabRoot, "Extracting Planes", undoBlock)) { return; } GenerateVoxelGrids(prefabRoot, voxelGenerationParams, planeExtractionParams); FindPlanesInGrids(prefabRoot, undoBlock); } }
private void SplitEvent() { List <TrackEvent> Events = myVegas.Project.GetSelectedEvents(); if (Events.Count == 0) { return; } using (var undo = new UndoBlock("Split Events by MetaTakes")) { foreach (TrackEvent ev in Events) { TrackEvent curEv = ev; foreach (MediaMarker mk in ev.ActiveTake.Media.Markers) { if (curEv == null) { break; // dun goofed } var mmk = new MetaMarker(mk, curEv); if (!mmk.IsWithinEventBounds) { continue; } curEv = curEv.Split(mmk.GlobalMarkerOffset); } } } }
public static void Execute(Vegas vegas) { var selectedTracks = VegasHelper.GetTracks <VideoTrack>(vegas, 1, onlySelected: true); var framerate = (int)Math.Round(vegas.Project.Video.FrameRate, 0, MidpointRounding.AwayFromZero); var config = GetConfig(selectedTracks, framerate); var points = BezierMotion.GetPoints(config); var startingFrame = vegas.Transport.CursorPosition.FrameCount; var width = vegas.Project.Video.Width; var height = vegas.Project.Video.Height; var framesPerStep = (framerate / config.StepsPerSecond); using (var undo = new UndoBlock("Track Along Bezier")) { for (var trackIndex = 0; trackIndex < config.NumberOfTracks; trackIndex++) { var currentFrame = startingFrame + (long)(trackIndex * config.SecondsBetweenTracks * 24); var selectedTrack = selectedTracks[config.NumberOfTracks - trackIndex - 1]; selectedTrack.TrackMotion.MotionKeyframes.Clear(); foreach (var point in points) { SetTrackMotionKeyFrame(currentFrame, selectedTrack, width, point, height); currentFrame += framesPerStep; } } } }
public static void Execute(Vegas vegas) { var videoTracks = VegasHelper.GetTracks <VideoTrack>(vegas, 1); var selectedTrackEvents = VegasHelper.GetTrackEvents(videoTracks); var currentPosition = selectedTrackEvents[0].Start; //order the list ListHelpers.Shuffle(selectedTrackEvents, new Random()); using (var undo = new UndoBlock("Randomize Events")) { //update order of the events foreach (var selectedTrackEvent in selectedTrackEvents) { if (selectedTrackEvent.IsGrouped) { foreach (var groupedTrackEvents in selectedTrackEvent.Group) { groupedTrackEvents.Start = currentPosition; } } else { selectedTrackEvent.Start = currentPosition; } currentPosition += selectedTrackEvent.Length; } } }
private void RegionNameFromEvents(IEnumerable<RegionGroup> Groups) { using (var undo = new UndoBlock("Name regions")) { foreach (RegionGroup Group in Groups) { var Names = new Dictionary<string, int>(); var Best = new KeyValuePair<string, int>(); foreach (TrackEvent Evt in Group.Events) { if (Names.ContainsKey(Evt.ActiveTake.Name)) Names[Evt.ActiveTake.Name] += 1; else Names.Add(Evt.ActiveTake.Name, 1); } foreach (var Pair in Names) { if (Pair.Value > Best.Value) Best = Pair; } Group.Region.Label = Best.Key; } } }
private void RegionNameFromEvents(IEnumerable <RegionGroup> Groups) { using (var undo = new UndoBlock("Name regions")) { foreach (RegionGroup Group in Groups) { var Names = new Dictionary <string, int>(); var Best = new KeyValuePair <string, int>(); foreach (TrackEvent Evt in Group.Events) { if (Names.ContainsKey(Evt.ActiveTake.Name)) { Names[Evt.ActiveTake.Name] += 1; } else { Names.Add(Evt.ActiveTake.Name, 1); } } foreach (var Pair in Names) { if (Pair.Value > Best.Value) { Best = Pair; } } Group.Region.Label = Best.Key; } } }
private void EventPropertiesTakeOffline_Invoked(object sender, EventArgs e) { List <TrackEvent> selected = myVegas.Project.GetSelectedEvents(); if (selected.Count == 0) { return; } using (var undo = new UndoBlock("Set takes offline")) { foreach (TrackEvent ev in selected) { Media offlineMedia = myVegas.Project.MediaPool.AddMedia(""); if (ev.IsAudio()) { //offlineMedia.CreateOfflineStream(MediaType.Audio); ev.AddTake(offlineMedia.GetAudioStreamByIndex(0), true); } if (ev.IsVideo()) { //offlineMedia.CreateOfflineStream(MediaType.Video); ev.AddTake(offlineMedia.GetVideoStreamByIndex(0), true); } } } }
internal static Transform CreateGeneratedPlanesRoot(Transform parent, UndoBlock undoBlock) { var planesRoot = new GameObject(GeneratedPlanesRoot.PlanesRootName, typeof(GeneratedPlanesRoot)).transform; planesRoot.SetParent(parent); undoBlock.RegisterCreatedObject(planesRoot.gameObject); return(planesRoot); }
private void NumericUpDownValueChanged(Object sender, EventArgs args) { using (UndoBlock undo = new UndoBlock("NumericUpDown value changed")) { NumericUpDown obj1 = sender as NumericUpDown; animationTrack = (int)obj1.Value - 1; } }
private void ExecuteScript_Click(object sender, EventArgs e) { VEGASPythonManager.mVegasPythonManager.ShowDebugMessage("Execute Script"); using (UndoBlock undo = new UndoBlock("Execute Python Script")) { VEGASPythonManager.mVegasPythonManager.ShowDebugMessage("Execute Script Step 2"); VEGASPythonManager.mVegasPythonManager.Execute_VPython_CMD(); } }
private void EventPropertiesMarkersPaste_Invoked(object sender, EventArgs e) { object cbMarkers = Clipboard.GetData(Strings.ClipboardMarkersTag); if (cbMarkers == null) { return; } var markers = (Dictionary <double, string>)cbMarkers; List <TrackEvent> selected = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Add markers to files (don't undo this)")) { foreach (TrackEvent ev in selected) { string dir = Path.GetDirectoryName(ev.ActiveTake.Media.FilePath) + Path.DirectorySeparatorChar; string filename = Path.GetFileName(ev.ActiveTake.Media.FilePath); if (filename != null && (!ev.IsAudio() || !filename.Contains(".wav"))) // wav files only, right now { continue; } string tempFileName = dir + Path.GetFileNameWithoutExtension(filename) + "_take02" + Path.GetExtension(filename); uint counter = 2; while (File.Exists(tempFileName)) { tempFileName = dir + Path.GetFileNameWithoutExtension(filename) + "_take" + counter++.ToString().PadLeft(2, '0') + Path.GetExtension(filename); } string fullpath = dir + filename; File.Copy(fullpath, tempFileName); ev.ActiveTake.Media.ReplaceWith(new Media(tempFileName)); myVegas.Project.MediaPool.Remove(fullpath); try { var fileReader = new BinaryReader(new FileStream(fullpath, FileMode.Open), Encoding.ASCII); fileReader.Close(); } catch { MessageBox.Show("File could not be opened. Try reloading Vegas."); undo.Cancel = true; return; } WaveFile.AddMarkers(fullpath, markers); ev.ActiveTake.Media.ReplaceWith(new Media(fullpath)); myVegas.Project.MediaPool.Remove(tempFileName); File.Delete(tempFileName); } } }
private void ProjectFileNewVersionCommand_Invoked(object sender, EventArgs e) { var selected = (from currentTrack in myVegas.Project.Tracks from ev in currentTrack.Events where ev.Selected select ev) .ToList(); var files = selected.GroupBy(p => p.ActiveTake.MediaPath); using (var undo = new UndoBlock("Create new file")) { foreach (var file in files) { string fnOrig = file.Key; string fnBase = Path.GetDirectoryName(fnOrig) + Path.DirectorySeparatorChar; string fnFile = Path.GetFileNameWithoutExtension(fnOrig); if (fnFile == null) { throw new ArgumentNullException("fnFile"); } string fnExt = Path.GetExtension(fnOrig); string newfilename; int counter = 1; int numDigits = 3; // check if we're already part of a sequence var fileEndingRegex = new Regex(@"_(?<counter>\d+)$"); var m = fileEndingRegex.Match(Path.GetFileNameWithoutExtension(fnFile)); if (m.Success) { string prevCtr = m.Groups["counter"].Value; counter = Convert.ToInt16(prevCtr); numDigits = prevCtr.Length; fnFile = fnFile.Substring(0, fnFile.Length - numDigits); } else { fnFile = fnFile + "_"; } do { string tail = counter++.ToString().PadLeft(numDigits, '0'); newfilename = fnBase + fnFile + tail + fnExt; } while (File.Exists(newfilename)); File.Copy(fnOrig, newfilename); Media newMedia = myVegas.Project.MediaPool.AddMedia(newfilename); foreach (TrackEvent ev in file) { ev.ActiveTake.Media.ReplaceWith(newMedia); } } } }
private void SetMarkerOffset() { using (var undo = new UndoBlock("Set Marker Offset")) { Timecode ofs = FormTimeEntry.GetUserTime(); foreach (TrackEvent ev in myVegas.Project.GetSelectedEvents()) { SetCurrentMarkerOffset(ev, ofs); } } }
public static void PanFromCenterToLeft(Vegas vegas, VideoEvent videoEvent) { using (UndoBlock undo = new UndoBlock("Add pan/crop")) { VideoMotionKeyframe key0 = videoEvent.VideoMotion.Keyframes[0]; int videoWidth = vegas.Project.Video.Width; VideoMotionKeyframe key1 = new VideoMotionKeyframe(Timecode.FromMilliseconds(Config.splitOffset)); videoEvent.VideoMotion.Keyframes.Add(key1); key1.MoveBy(new VideoMotionVertex(videoWidth, 0)); } }
private void RegionNameSequential(IEnumerable <RegionGroup> Groups) { int CurrentIndex = 1; using (var undo = new UndoBlock("Name regions sequentially")) { foreach (RegionGroup Grp in Groups) { Grp.Region.Label = String.Format(Strings.SequentialNamingString, CurrentIndex++); } } }
private void RegionsResize(Timecode Time) { var groups = myVegas.GetRegionGroups(); using (var undo = new UndoBlock("Resize regions by " + Time)) { foreach (RegionGroup Group in groups) { Group.AdjustRegionLength(Group.Region.Length + Time); } } }
private void EventEdgeRgtAuto_Invoked(object sender, EventArgs e) { List<TrackEvent> events = myVegas.Project.GetSelectedEvents(true); using (var undo = new UndoBlock("Automatically adjust right edges")) { for (int i = 0; i < events.Count - 1; i++) // don't adjust last event { Timecode distToNext = events[i + 1].Start - events[i].End; events[i].Length += distToNext; } } }
private void RegionNameSequential(IEnumerable<RegionGroup> Groups) { int CurrentIndex = 1; using (var undo = new UndoBlock("Name regions sequentially")) { foreach (RegionGroup Grp in Groups) { Grp.Region.Label = String.Format(Strings.SequentialNamingString, CurrentIndex++); } } }
private void EventPropertiesGainReset_Invoked(object sender, EventArgs e) { List <TrackEvent> selected = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Reset Gain")) { foreach (TrackEvent ev in selected) { ev.SetGain(1.0f); } } }
private void EventEdgeRgtAuto_Invoked(object sender, EventArgs e) { List <TrackEvent> events = myVegas.Project.GetSelectedEvents(true); using (var undo = new UndoBlock("Automatically adjust right edges")) { for (int i = 0; i < events.Count - 1; i++) // don't adjust last event { Timecode distToNext = events[i + 1].Start - events[i].End; events[i].Length += distToNext; } } }
private void EventPitchChangeSet(IEnumerable <TrackEvent> Events, decimal Semitones) { using (var undo = new UndoBlock("Set pitch to " + Semitones.ToString())) { foreach (var ev in Events) { var rateChangeFactor = Math.Pow((double)MagicRatio, (double)Semitones); var oldRate = ev.PlaybackRate; ev.AdjustPlaybackRate(rateChangeFactor, true); ev.Length = Timecode.FromNanos((long)(ev.Length.Nanos / (ev.PlaybackRate / oldRate))); } } }
private void ProjectFileNewVersionCommand_Invoked(object sender, EventArgs e) { var selected = (from currentTrack in myVegas.Project.Tracks from ev in currentTrack.Events where ev.Selected select ev) .ToList(); var files = selected.GroupBy(p => p.ActiveTake.MediaPath); using (var undo = new UndoBlock("Create new file")) { foreach (var file in files) { string fnOrig = file.Key; string fnBase = Path.GetDirectoryName(fnOrig) + Path.DirectorySeparatorChar; string fnFile = Path.GetFileNameWithoutExtension(fnOrig); if (fnFile == null) throw new ArgumentNullException("fnFile"); string fnExt = Path.GetExtension(fnOrig); string newfilename; int counter = 1; int numDigits = 3; // check if we're already part of a sequence var fileEndingRegex = new Regex(@"_(?<counter>\d+)$"); var m = fileEndingRegex.Match(Path.GetFileNameWithoutExtension(fnFile)); if (m.Success) { string prevCtr = m.Groups["counter"].Value; counter = Convert.ToInt16(prevCtr); numDigits = prevCtr.Length; fnFile = fnFile.Substring(0, fnFile.Length - numDigits); } else fnFile = fnFile + "_"; do { string tail = counter++.ToString().PadLeft(numDigits, '0'); newfilename = fnBase + fnFile + tail + fnExt; } while (File.Exists(newfilename)); File.Copy(fnOrig, newfilename); Media newMedia = myVegas.Project.MediaPool.AddMedia(newfilename); foreach (TrackEvent ev in file) { ev.ActiveTake.Media.ReplaceWith(newMedia); } } } }
/// /// Implementation /// internal void RegionCreateFromEvents_Invoked(object sender, EventArgs e) { var eventgroups = myVegas.Project.GetEventGroups(); var regions = (myVegas.Project.Regions.Count != 0) ? new List<Sony.Vegas.Region>(myVegas.Project.Regions) : new List<Sony.Vegas.Region>(); bool selectionSet = false; if (myVegas.SelectionLength != Timecode.FromMilliseconds(0)) if (myVegas.Cursor == myVegas.SelectionStart || myVegas.Cursor == myVegas.SelectionStart + myVegas.SelectionLength) selectionSet = true; using (var undo = new UndoBlock("Create regions")) { foreach (var egrp in eventgroups) { Timecode groupStart = null; Timecode groupEnd = null; foreach (var ev in egrp) { if (groupStart == null || ev.Start < groupStart) groupStart = ev.Start; if (groupEnd == null || ev.End > groupEnd) groupEnd = ev.End; } // skip outside seletion if (selectionSet) if (groupEnd >= (myVegas.SelectionStart + myVegas.SelectionLength) || groupStart <= myVegas.SelectionStart) continue; // don't write inside existing regions if (regions.Any(reg => reg.ContainsTime(groupStart, (groupEnd - groupStart)))) continue; // don't surround existing regions if (regions.HasInside(groupStart, groupEnd)) continue; var NewRegion = new Sony.Vegas.Region(groupStart, (groupEnd - groupStart)); myVegas.Project.Regions.Add(NewRegion); } } }
private void MarkerCreateMultiCommand_Invoked(object sender, EventArgs e) { KeyValuePair<int, Timecode>? data = FormMarkerCreate.GetAmountAndTime(); if (data == null) return; int num = data.Value.Key; Timecode interval = data.Value.Value; using (var undo = new UndoBlock("Create multiple markers")) { for (int i = 0; i < num; i++) { Timecode pos = Timecode.FromNanos(myVegas.Transport.CursorPosition.Nanos + (interval.Nanos * i)); myVegas.Project.Markers.Add(new Marker(pos)); } } }
private void MarkerSetIntervalCommand_Invoked(object sender, EventArgs e) { if (myVegas.Project.Markers.Count <= 0) return; var selectedMks = myVegas.GetSelectedMarkers(); if (selectedMks.Count == 0 && myVegas.Project.Markers.Count != 0) { MessageBox.Show("Select a range of markers using the loop selection."); return; } Timecode time = FormTimeEntry.GetUserTime(); if (time == null) { MessageBox.Show("You must enter a valid time."); return; } Timecode inc = null; using (var undo = new UndoBlock("Set marker interval")) { foreach (Marker mk in selectedMks) { if (inc == null) { inc = mk.Position; } mk.Position = inc; inc += time; } } }
private void ResetMarkerOffset() { List<TrackEvent> selected = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Reset marker offset")) { foreach (TrackEvent ev in selected) { MetaMarker mmk = ev.FindCurrentMetaMarker(); if (mmk == null) continue; ev.ActiveTake.Offset = mmk.GlobalMarkerPosition; } } }
private void EventPropertiesTakeOffline_Invoked(object sender, EventArgs e) { List<TrackEvent> selected = myVegas.Project.GetSelectedEvents(); if (selected.Count == 0) return; using (var undo = new UndoBlock("Set takes offline")) { foreach (TrackEvent ev in selected) { Media offlineMedia = myVegas.Project.MediaPool.AddMedia(""); if (ev.IsAudio()) { //offlineMedia.CreateOfflineStream(MediaType.Audio); ev.AddTake(offlineMedia.GetAudioStreamByIndex(0), true); } if (ev.IsVideo()) { //offlineMedia.CreateOfflineStream(MediaType.Video); ev.AddTake(offlineMedia.GetVideoStreamByIndex(0), true); } } } }
private void EventPropertiesGainReset_Invoked(object sender, EventArgs e) { List<TrackEvent> selected = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Reset Gain")) { foreach (TrackEvent ev in selected) { ev.SetGain(1.0f); } } }
private void EventEdgeLftAuto_Invoked(object sender, EventArgs e) { List<TrackEvent> events = myVegas.Project.GetSelectedEvents(true); using (var undo = new UndoBlock("Automatically adjust left edges")) { for (int i = events.Count - 1; i > 0; i--) // don't adjust first event { Timecode distToNext = events[i].Start - events[i - 1].End; events[i].Start -= distToNext; events[i].Length += distToNext; foreach (Take take in events[i].Takes) { take.Offset -= distToNext; } } } }
/// Implementation /// /// private void RegionsNudge(Timecode Time, bool Cumulative) { Timecode ZeroTime = myVegas.Project.Ruler.StartTime; Timecode Adjustment = Time; if (Cumulative) Adjustment = Timecode.FromSeconds(0); var Groups = myVegas.GetRegionGroups(); using (var undo = new UndoBlock("Nudge regions by " + Time)) { foreach (var group in Groups) { Timecode newTime = group.Region.Position + Adjustment; Timecode localAdjustment = Timecode.FromSeconds(0); // zero time detection if (newTime < ZeroTime) { if (ScriptOptions.GetValue(Strings.ScriptName, "ShowZeroTimeWarning", true)) { myVegas.ShowError("Cannot move beyond start of timeline", "Your operation was aborted to avoid moving events outside the timeline"); } return; } // collision detection foreach (var grp in Groups) { if (!grp.Equals(@group)) { if (newTime <= grp.Region.End && newTime >= grp.Region.Position) { localAdjustment = newTime - grp.Region.End; break; } } } group.MoveTo(newTime - localAdjustment); if (Cumulative) Adjustment += Time; } } }
private void EventPitchChangeSet(IEnumerable<TrackEvent> Events, decimal Semitones) { using (var undo = new UndoBlock("Set pitch to " + Semitones.ToString())) { foreach (var ev in Events) { var rateChangeFactor = Math.Pow((double)MagicRatio, (double)Semitones); var oldRate = ev.PlaybackRate; ev.AdjustPlaybackRate(rateChangeFactor, true); ev.Length = Timecode.FromNanos((long)(ev.Length.Nanos / (ev.PlaybackRate / oldRate))); } } }
private void Distribute(SequenceMode sequenceMode) { List<TrackEvent> events = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Distribute: " + sequenceMode.ToString())) { if (sequenceMode == SequenceMode.Reset) { foreach (TrackEvent ev in events) { if (ev.ActiveTake.Media.Markers.Count > 0) SetMetaTake(ev, 0); } } else if (sequenceMode == SequenceMode.First) { foreach (TrackEvent ev in events) { Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; List<Marker> siblings = ev.ActiveTake.Media.Markers.Cast<Marker>().Where( mk => mkCur.Label.ToLowerInvariant() == mk.Label.ToLowerInvariant()).ToList(); if (siblings.Count <= 1 || mkCur == siblings[0]) continue; SetMetaTake(ev, siblings[0]); } } else if (sequenceMode == SequenceMode.Sequential) { var used = new List<Marker>(); foreach (TrackEvent ev in events) { Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; List<Marker> siblings = ev.ActiveTake.Media.Markers.Cast<Marker>().Where( mk => mkCur.Label.ToLowerInvariant() == mk.Label.ToLowerInvariant()).ToList(); if (siblings.Count <= 1) continue; List<Marker> usedSiblings = used.FindAll(item => item.Label.ToLowerInvariant() == mkCur.Label.ToLowerInvariant()); // reset when full if (usedSiblings.Count >= siblings.Count) { used.RemoveAll(item => item.Label.ToLowerInvariant() == mkCur.Label.ToLowerInvariant()); usedSiblings.Clear(); } bool done = false; Marker next = null; int curid = siblings.FindIndex(item => item.Position == mkCur.Position); int offset = 0; while (!done) { next = siblings[(curid + offset++) % siblings.Count]; if (usedSiblings.Find(item => item.Position == next.Position) == null) { done = true; } } if (next != null) { SetMetaTake(ev, next); used.Add(next); } } } else if (sequenceMode == SequenceMode.Reverse) { List<int> seq = (from ev in events select ev.FindCurrentMarker() into curMk where curMk != null select curMk.Index).ToList(); int i = seq.Count - 1; foreach (TrackEvent ev in events) { SetMetaTake(ev, seq[i--]); } } else if (sequenceMode == SequenceMode.Random) { var rnd = new Random(); int last = 0; int next = 0; foreach (TrackEvent ev in events) { Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; List<Marker> siblings = ev.ActiveTake.Media.Markers.Cast<Marker>().Where( mk => mkCur.Label.ToLowerInvariant() == mk.Label.ToLowerInvariant()).ToList(); while (next == last) { next = rnd.Next(0, ev.ActiveTake.Media.Markers.Count); if (siblings.Count > 1) { Marker trg = ev.ActiveTake.Media.Markers[next]; if (mkCur.Label.ToLowerInvariant() != trg.Label.ToLowerInvariant()) { next = last; // force the loop to run once more } } else // we have only one variation { next = -1; break; } } if (next > 0) SetMetaTake(ev, next); last = next; } } else if (sequenceMode == SequenceMode.Next) { foreach (TrackEvent ev in events) { Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; List<int> siblings = (from Marker mk in ev.ActiveTake.Media.Markers where mkCur.Label != null && mkCur.Label.ToLowerInvariant() == mk.Label.ToLowerInvariant() select mk.Index).ToList(); int curMkSibID = siblings.IndexOf(mkCur.Index); int nextMkID = (curMkSibID + 1) % siblings.Count; Marker nextMk = ev.ActiveTake.Media.Markers[siblings[nextMkID]]; SetMetaTake(ev, nextMk); } } else if (sequenceMode == SequenceMode.Prev) { foreach (TrackEvent ev in events) { Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; List<int> siblings = (from Marker mk in ev.ActiveTake.Media.Markers where mkCur.Label != null && mkCur.Label.ToLowerInvariant() == mk.Label.ToLowerInvariant() select mk.Index).ToList(); int curMkSibID = siblings.IndexOf(mkCur.Index); int nextMkID = (curMkSibID - 1) % siblings.Count; if (nextMkID < 0) nextMkID += siblings.Count; Marker nextMk = ev.ActiveTake.Media.Markers[siblings[nextMkID]]; SetMetaTake(ev, nextMk); } } else if (sequenceMode == SequenceMode.NextGroup || sequenceMode == SequenceMode.PrevGroup) { int groupJumpDirection = 1; if (sequenceMode == SequenceMode.PrevGroup) { groupJumpDirection = -1; } foreach (TrackEvent ev in events) { var groups = new List<string>(); Marker mkCur = ev.FindCurrentMarker(); if (mkCur == null) continue; foreach (MediaMarker mk in ev.ActiveTake.Media.Markers) { if (mk.Label != null && !groups.Contains(mk.Label.ToLowerInvariant())) { groups.Add(mk.Label.ToLowerInvariant()); } } string grpNext = string.Empty; for (int i = 0; i < groups.Count; i++) { if (groups[i] == mkCur.Label.ToLowerInvariant()) { grpNext = groups[(groups.Count + i + groupJumpDirection) % (groups.Count)]; break; } } Marker mkNext = ev.ActiveTake.Media.Markers.FirstOrDefault( mk => mk.Label != null && mk.Label.ToLowerInvariant() == grpNext.ToLowerInvariant()); if (mkNext == null) return; SetMetaTake(ev, mkNext); } } } }
private void EventEdgeChange(EventEdgeAdjustMethod Method) { var userAmount = FormTimeEntry.GetUserTime(String.Format("Adjust {0} edge by", Method.ToString())); if (userAmount == null || userAmount.Nanos == 0) return; using (var undo = new UndoBlock("Adjust Event Edge")) { var events = myVegas.Project.GetSelectedEvents(); switch (Method) { case EventEdgeAdjustMethod.Left: foreach (var ev in events.Where(e => e.End + userAmount >= e.Start && e.Start - userAmount <= e.End)) // don't 'wrap' events { ev.End -= userAmount; foreach (Take take in ev.Takes) { take.Offset += userAmount; } ev.Start += userAmount; } break; case EventEdgeAdjustMethod.Right: foreach (var ev in events.Where(e => e.End + userAmount >= e.Start && e.Start - userAmount <= e.End)) { ev.End += userAmount; } break; } } }
private void renameToolStripMenuItem_Click(object sender, EventArgs e) { List<Media> selectedMedia = GetSelectedMedia(); using (var undo = new UndoBlock("Rename media")) { foreach (Media media in selectedMedia) { var MovePrompt = new FormSimplePrompt("Enter destination", "Enter the target filename", "Note: you can enter an existing file.") { tbUserData = { Text = Path.GetFileName(media.FilePath) } }; DialogResult rslt = MovePrompt.ShowDialog(); if (rslt != DialogResult.OK) continue; string target = MovePrompt.tbUserData.Text; if (File.Exists(target)) { DialogResult RetargetRslt = MessageBox.Show( "Re-target this media to the specified file? If the file content differs, this may destabilize your project.", "Target file exists", MessageBoxButtons.YesNo); if (RetargetRslt != DialogResult.Yes) { continue; } } target = ResolveFilePath(media.FilePath, target); #if DEBUG DialogResult go = MessageBox.Show(String.Format("RENAME:\n{0}\nTO\n{1}", media.FilePath, target), "Do it?", MessageBoxButtons.YesNo); if (go != DialogResult.Yes) continue; #endif RenameMedia(media, target); } } PopulateMediaListItems(); }
private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { if (e.Row.DataBoundItem == null) return; var view = e.Row.DataBoundItem as RegionView; if (view != null) { Region reg = view.Region; // ReSharper disable UnusedVariable using (var undo = new UndoBlock("Remove region")) // ReSharper restore UnusedVariable { myVegas.Project.Regions.Remove(reg); } } }
private void MarkerCreateFromEventsCommand_Invoked(object sender, EventArgs e) { List<TrackEvent> events = myVegas.Project.GetSelectedEvents(); if (events.Count <= 0) return; using (var undo = new UndoBlock("Create Markers from events")) { foreach (TrackEvent ev in events) { myVegas.Project.Markers.Add(new Marker(ev.Start)); } } }
private void PerformReplace() { if (SearchResults.Count == 0) PerformSearch(); if (SearchResults.Count == 0) return; string ReplaceString = tbReplace.Text; using (var undo = new UndoBlock("Search / replace")) { foreach (SearchReplaceResult rslt in SearchResults) { if (!rslt.Include) continue; rslt.Replace(ReplaceString); } } MyVegas.UpdateUI(); // a bit dirty, but we want to update the search results. PerformSearch(); }
private void RegionsAutoSize(Timecode Headroom) { var Groups = myVegas.GetRegionGroups(); // check overlapping groups var Overlaps = new List<RegionGroup>(); Timecode LastEnd = null; foreach (RegionGroup Grp in Groups) { if (LastEnd != null && Grp.Region.Position < LastEnd) { Overlaps.Add(Grp); } LastEnd = Grp.Region.End; } if (Overlaps.Count != 0) { if (MessageBox.Show( "This project contains overlapping / duplicate regions. Autosize would likely screw everything up. Continue anyway?", "Overlaps detected", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } } using (var undo = new UndoBlock("Fit regions to events")) { foreach (RegionGroup Grp in Groups) { if (Grp.Events.Count == 0) continue; Grp.Region.Position = Grp.Start - Headroom; Grp.Region.End = Grp.End + Headroom; } } }
private void SplitEvent() { List<TrackEvent> Events = myVegas.Project.GetSelectedEvents(); if (Events.Count == 0) return; using (var undo = new UndoBlock("Split Events by MetaTakes")) { foreach (TrackEvent ev in Events) { TrackEvent curEv = ev; foreach (MediaMarker mk in ev.ActiveTake.Media.Markers) { if (curEv == null) break; // dun goofed var mmk = new MetaMarker(mk, curEv); if (!mmk.IsWithinEventBounds) continue; curEv = curEv.Split(mmk.GlobalMarkerOffset); } } } }
private void EventPropertiesChangePaste(IEnumerable<TrackEvent> TargetEvents, EventPropertiesFlags Flags) { object clipboardData = Clipboard.GetData(Strings.ClipboardTemplateTag); if (clipboardData == null) return; var bytes = clipboardData as Byte[]; var str = new MemoryStream(bytes); var fmt = new BinaryFormatter { Binder = new EventPropertiesTemplateBinder() }; var tpl = (EventPropertiesTemplate)fmt.Deserialize(str); using (var undo = new UndoBlock("Paste event properties")) { foreach (TrackEvent ev in TargetEvents) { if (Flags.IsSet(EventPropertiesFlags.FadeIn)) ev.FadeIn.Length = Timecode.FromNanos(tpl.FadeIn.LengthNanos); if (Flags.IsSet(EventPropertiesFlags.FadeOut)) ev.FadeOut.Length = Timecode.FromNanos(tpl.FadeOut.LengthNanos); if (Flags.IsSet(EventPropertiesFlags.FadeInCurve)) ev.FadeIn.Curve = (CurveType)Enum.Parse(typeof(CurveType), tpl.FadeIn.CurveType); if (Flags.IsSet(EventPropertiesFlags.FadeOutCurve)) ev.FadeOut.Curve = (CurveType)Enum.Parse(typeof(CurveType), tpl.FadeOut.CurveType); if (Flags.IsSet(EventPropertiesFlags.Gain)) ev.FadeIn.Gain = tpl.FadeIn.Gain; if (Flags.IsSet(EventPropertiesFlags.Loop)) ev.Loop = tpl.Loop; if (Flags.IsSet(EventPropertiesFlags.Length)) ev.Length = Timecode.FromNanos(tpl.LengthNanos); if (Flags.IsSet(EventPropertiesFlags.PitchAmount)) ev.AdjustPlaybackRate(tpl.PlaybackRate, true); if (Flags.IsSet(EventPropertiesFlags.PitchMethod)) { // Not supported by Vegas API yet } // broken, too unintuitive /*if (Flags.IsSet(EventPropertiesFlags.RegionOffset)) { Region r = myVegas.FindSurroundingRegion(ev); // workaround to make sure we don't stack events within the same region if (r == null || r == LastSurroundingRegion) continue; ev.Start.Nanos = r.Position.Nanos + tpl.RegionOffsetNanos; LastSurroundingRegion = r; }*/ } } }
private void btnResetProject_Click(object sender, EventArgs e) { if (DialogResult.Yes != MessageBox.Show("This will clear all render markers from your project. Really reset?", "Really reset project?", MessageBoxButtons.YesNo)) return; var killSheet = new List<CommandMarker>(); using (UndoBlock undo = new UndoBlock("Clear project render markers")) { killSheet.AddRange(myVegas.Project.CommandMarkers.Where(cmk => cmk.CommandType.ToString().ContainsRenderTag(false))); foreach (var cmk in killSheet) { myVegas.Project.CommandMarkers.Remove(cmk); } } _renderParams.ResetToDefault(); SetInitialValues(); UpdateNamingPreview(); HighlightDefaultValues(); }
private void EventPitchChange(IEnumerable<TrackEvent> Events, decimal Semitones) { using (var undo = new UndoBlock("Pitch " + Semitones.ToString())) { var rateChangeFactor = (decimal)Math.Pow((double)MagicRatio, (double)Semitones); foreach (var ev in Events) { decimal newRate = Math.Round((decimal)ev.PlaybackRate * rateChangeFactor, 6); Timecode newLength = Timecode.FromNanos((long)(ev.Length.Nanos / rateChangeFactor)); // boundary checks / clamps if (newRate < 0.0m) return; if ((Math.Round(newRate, 3) > 4.0m) || (Math.Round(newRate, 3) < 0.25m)) return; ev.AdjustPlaybackRate((double)newRate, true); ev.Length = newLength; } } }
private void EventPropertiesNormGainSet_Invoked(object sender, EventArgs e) { List<TrackEvent> selected = myVegas.Project.GetSelectedEvents(); if (selected.Count == 0) return; using (var undo = new UndoBlock("Set Normalization Gain")) { var dlg = new FormSimplePrompt("Enter gain", "Enter the gain in decibels", "Enter a valid decimal number."); dlg.OnEvalInput += delegate(String Text) { float tryGain; if (float.TryParse(Text, out tryGain)) return tryGain.ToString(); return "Enter a valid decimal number."; }; DialogResult rslt = dlg.ShowDialog(); if (rslt != DialogResult.OK) return; float gain; if (!float.TryParse(dlg.tbUserData.Text, out gain)) return; foreach (TrackEvent ev in selected) { if (ev.IsAudio()) { var aev = ev as AudioEvent; aev.SetNormalizationGain(gain); } } } }
private void deleteToolStripMenuItem_Click(object sender, EventArgs e) { MediaPool pool = MyVegas.Project.MediaPool; List<Media> selectedMedia = GetSelectedMedia(); using (var undo = new UndoBlock("Delete media")) { foreach (Media media in selectedMedia) { var killsheet = new List<TrackEvent>(); if (media.UseCount != 0) { DialogResult rslt = MessageBox.Show("Really remove this media? All associated events or takes will be removed.", "Media still in use", MessageBoxButtons.YesNo); { if (rslt != DialogResult.Yes) continue; foreach (TrackEvent ev in MyVegas.Project.GetAllEvents()) { if (ev.Takes.Count == 1 && ev.ActiveTake.Media == media) { killsheet.Add(ev); continue; } foreach (Take take in ev.Takes) { if (take.Media == media) { ev.Takes.Remove(take); } } } } foreach (TrackEvent ev in killsheet) { var parentTrack = ev.Track; parentTrack.Events.Remove(ev); } } string mediaKey = media.KeyString; pool.Remove(mediaKey); } } PopulateMediaListItems(); }
private void EventPropertiesMarkersPaste_Invoked(object sender, EventArgs e) { object cbMarkers = Clipboard.GetData(Strings.ClipboardMarkersTag); if (cbMarkers == null) return; var markers = (Dictionary<double, string>)cbMarkers; List<TrackEvent> selected = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Add markers to files (don't undo this)")) { foreach (TrackEvent ev in selected) { string dir = Path.GetDirectoryName(ev.ActiveTake.Media.FilePath) + Path.DirectorySeparatorChar; string filename = Path.GetFileName(ev.ActiveTake.Media.FilePath); if (filename != null && (!ev.IsAudio() || !filename.Contains(".wav"))) // wav files only, right now continue; string tempFileName = dir + Path.GetFileNameWithoutExtension(filename) + "_take02" + Path.GetExtension(filename); uint counter = 2; while (File.Exists(tempFileName)) { tempFileName = dir + Path.GetFileNameWithoutExtension(filename) + "_take" + counter++.ToString().PadLeft(2, '0') + Path.GetExtension(filename); } string fullpath = dir + filename; File.Copy(fullpath, tempFileName); ev.ActiveTake.Media.ReplaceWith(new Media(tempFileName)); myVegas.Project.MediaPool.Remove(fullpath); try { var fileReader = new BinaryReader(new FileStream(fullpath, FileMode.Open), Encoding.ASCII); fileReader.Close(); } catch { MessageBox.Show("File could not be opened. Try reloading Vegas."); undo.Cancel = true; return; } WaveFile.AddMarkers(fullpath, markers); ev.ActiveTake.Media.ReplaceWith(new Media(fullpath)); myVegas.Project.MediaPool.Remove(tempFileName); File.Delete(tempFileName); } } }
private void EventEdgeTrim(EventEdgeAdjustMethod edgeAdjustMethod, Timecode Position) { List<TrackEvent> events = myVegas.Project.GetSelectedEvents(); using (var undo = new UndoBlock("Set Event Edge")) { switch (edgeAdjustMethod) { case EventEdgeAdjustMethod.Left: foreach (var ev in events) { if (ev.Loop == false && Position <= ev.Start) // can't wrap non-looping continue; var amount = Position - ev.Start; if (Position <= ev.End) { ev.Start = ev.Start + amount; ev.End -= amount; foreach (var take in ev.Takes) take.Offset += amount; } else // wraparoo { var oldEnd = ev.End; var oldLength = ev.Length; ev.Start = oldEnd; ev.End = Position; foreach (var take in ev.Takes) take.Offset += oldLength; } } break; case EventEdgeAdjustMethod.Right: foreach (var ev in events) { if (ev.Loop == false && Position >= ev.End) continue; var amount = ev.End - Position; if (Position >= ev.Start) { ev.End -= amount; } else // wraparoo { var oldStart = ev.Start; var oldEnd = ev.End; ev.Start = Position; ev.End = oldStart; foreach (var take in ev.Takes) take.Offset -= ev.End - Position; } } break; } } }