Left direction uses wrong logic.

Thiago_Sase wrote on 8/19/2024, 9:44 AM

@jetdv Could you help me again?
Please, I need the left direction behaviors as the same as the right direction logic.
The right direction does perfectly what it's supposed to do. But the left direction does not.
Where is my mistake?
 

public void Main(Vegas vegas, string direction, int duplicateCount)
        {
            myVegas = vegas;
            List<TrackEvent> selectedEvents = new List<TrackEvent>();
            Dictionary<TrackEvent, Track> eventTrackMap = new Dictionary<TrackEvent, Track>();

            // List to store the new duplicated events
            List<TrackEvent> newEvents = new List<TrackEvent>();

            // Find all selected events and their tracks
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvents.Add(evnt);
                        eventTrackMap[evnt] = track;
                    }
                }
            }

            // Check if any events are selected
            if (selectedEvents.Count > 0)
            {
                // Sort selected events by their start time to handle them in order
                selectedEvents.Sort((a, b) => a.Start.CompareTo(b.Start));

                // Find the maximum end time of all selected events manually
                Timecode lastGlobalEventEnd = new Timecode(0);
                foreach (TrackEvent evnt in selectedEvents)
                {
                    if (evnt.End > lastGlobalEventEnd)
                    {
                        lastGlobalEventEnd = evnt.End;
                    }
                }

                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;

                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = currentEvent.Start - Timecode.FromMilliseconds((i + 1) * eventLength.ToMilliseconds());
                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

                        // Duplicate the event with the calculated start time
                        if (direction == "Left" || direction == "Right")
                        {
                            if (myTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)myTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, newEventStart);
                            }
                            else if (myTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)myTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, newEventStart);
                            }

                            // Update the end position of the last duplicate event and the global tracker
                            lastEventEnd = newEvent.End;
                            lastGlobalEventEnd = lastEventEnd;
                        }
                        else if (direction == "Up" || direction == "Down")
                        {
                            Track targetTrack = null;
                            int trackIndex = myTrack.Index;

                            if (direction == "Up")
                            {
                                if (trackIndex > 0)
                                {
                                    targetTrack = myVegas.Project.Tracks[trackIndex - 1];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                            }
                            else if (direction == "Down")
                            {
                                if (trackIndex < myVegas.Project.Tracks.Count - 1)
                                {
                                    targetTrack = myVegas.Project.Tracks[trackIndex + 1];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                            }

                            if (myTrack.IsAudio() && targetTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)targetTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, currentEvent.Start);
                                myTrack = aTrack;
                            }
                            else if (myTrack.IsVideo() && targetTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)targetTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, currentEvent.Start);
                                myTrack = vTrack;
                            }
                        }

                        if (newEvent != null)
                        {
                            newEvents.Add(newEvent);
                        }

                        // Update lastGlobalEventEnd after each duplication to ensure proper spacing
                        lastGlobalEventEnd = newEvent.End;
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select events to duplicate.");
            }
        }

I think it is this section of the code where my mistake is:

if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = currentEvent.Start - Timecode.FromMilliseconds((i + 1) * eventLength.ToMilliseconds());
                        }

But I can't find a solution.

Comments

zzzzzz9125 wrote on 8/19/2024, 10:35 AM

@Thiago_Sase For me, this script works fine in all four directions:

What do you mean by wrong logic, could you provide a screenshot and explanation?

Last changed by zzzzzz9125 on 8/19/2024, 10:36 AM, changed a total of 1 times.

Using VEGAS Pro 22 build 248 & VEGAS Pro 21 build 208.

Information about my PC:
Brand Name: HP VICTUS Laptop
System: Windows 11.0 (64-bit) 10.00.22631
CPU: 12th Gen Intel(R) Core(TM) i7-12700H
GPU: NVIDIA GeForce RTX 3050 Laptop GPU
GPU Driver: NVIDIA Studio Driver 560.70

Thiago_Sase wrote on 8/19/2024, 10:49 AM

@zzzzzz9125 I mean, if I duplicate multiple selected events to the right direction, everything works fine without overlapping. But if I do the same for the left direction, the overlap will happen. 

jetdv wrote on 8/19/2024, 10:50 AM

What's the purpose of this in the left?

Timecode.FromMilliseconds((i + 1)

Instead of this:

Timecode.FromMilliseconds((i + 1) * eventLength.ToMilliseconds())

Why wouldn't you just use?

eventLength

 

Thiago_Sase wrote on 8/19/2024, 10:51 AM

@jetdv @zzzzzz9125 Sorry, I need to show the complete script for a better understanding.

 

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
using ScriptPortal.Vegas;

namespace DuplicateEventLeftRightUp
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas, string direction, int duplicateCount)
        {
            myVegas = vegas;
            List<TrackEvent> selectedEvents = new List<TrackEvent>();
            Dictionary<TrackEvent, Track> eventTrackMap = new Dictionary<TrackEvent, Track>();

            // List to store the new duplicated events
            List<TrackEvent> newEvents = new List<TrackEvent>();

            // Find all selected events and their tracks
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvents.Add(evnt);
                        eventTrackMap[evnt] = track;
                    }
                }
            }

            // Check if any events are selected
            if (selectedEvents.Count > 0)
            {
                // Sort selected events by their start time to handle them in order
                selectedEvents.Sort((a, b) => a.Start.CompareTo(b.Start));

                // Find the maximum end time of all selected events manually
                Timecode lastGlobalEventEnd = new Timecode(0);
                foreach (TrackEvent evnt in selectedEvents)
                {
                    if (evnt.End > lastGlobalEventEnd)
                    {
                        lastGlobalEventEnd = evnt.End;
                    }
                }

                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;

                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = currentEvent.Start - Timecode.FromMilliseconds((i + 1) * eventLength.ToMilliseconds());
                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

                        // Duplicate the event with the calculated start time
                        if (direction == "Left" || direction == "Right")
                        {
                            if (myTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)myTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, newEventStart);
                            }
                            else if (myTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)myTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, newEventStart);
                            }

                            // Update the end position of the last duplicate event and the global tracker
                            lastEventEnd = newEvent.End;
                            lastGlobalEventEnd = lastEventEnd;
                        }
                        else if (direction == "Up" || direction == "Down")
                        {
                            Track targetTrack = null;
                            int trackIndex = myTrack.Index;

                            if (direction == "Up")
                            {
                                if (trackIndex > 0)
                                {
                                    targetTrack = myVegas.Project.Tracks[trackIndex - 1];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                            }
                            else if (direction == "Down")
                            {
                                if (trackIndex < myVegas.Project.Tracks.Count - 1)
                                {
                                    targetTrack = myVegas.Project.Tracks[trackIndex + 1];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                            }

                            if (myTrack.IsAudio() && targetTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)targetTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, currentEvent.Start);
                                myTrack = aTrack;
                            }
                            else if (myTrack.IsVideo() && targetTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)targetTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, currentEvent.Start);
                                myTrack = vTrack;
                            }
                        }

                        if (newEvent != null)
                        {
                            newEvents.Add(newEvent);
                        }

                        // Update lastGlobalEventEnd after each duplication to ensure proper spacing
                        lastGlobalEventEnd = newEvent.End;
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select events to duplicate.");
            }
        }




    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            // Create the form
            Form form = new Form();
            form.Text = "Duplicate Events";
            form.StartPosition = FormStartPosition.CenterScreen;
            form.BackColor = Color.FromArgb(45, 45, 48);
            form.ForeColor = Color.White;
            form.FormBorderStyle = FormBorderStyle.FixedDialog;
            form.MaximizeBox = false;
            form.MinimizeBox = false;
            form.Size = new Size(300, 300);
            form.Font = new Font("Segoe UI", 10, FontStyle.Regular);

            // Create a label for the duplicate count
            Label duplicateCountLabel = new Label();
            duplicateCountLabel.Text = "Number of Duplicates:";
            duplicateCountLabel.Location = new Point(20, 20);
            duplicateCountLabel.Size = new Size(150, 30);

            // Create a numeric up-down control for duplicate count
            NumericUpDown duplicateCountUpDown = new NumericUpDown();
            duplicateCountUpDown.Minimum = 1;
            duplicateCountUpDown.Maximum = 100;
            duplicateCountUpDown.Value = 1;
            duplicateCountUpDown.Location = new Point(180, 20);
            duplicateCountUpDown.Size = new Size(60, 30);

            // Create panel to hold the buttons
            Panel buttonPanel = new Panel();
            buttonPanel.Size = new Size(200, 150);
            buttonPanel.Location = new Point(50, 70);
            buttonPanel.BackColor = Color.FromArgb(37, 37, 38);

            // Create the "Duplicate Up" button with an arrow
            Button duplicateUpButton = new Button();
            duplicateUpButton.Text = "↑";
            duplicateUpButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateUpButton.Size = new Size(50, 50);
            duplicateUpButton.Location = new Point(75, 10);
            duplicateUpButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateUpButton.FlatStyle = FlatStyle.Flat;
            duplicateUpButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Down" button with an arrow
            Button duplicateDownButton = new Button();
            duplicateDownButton.Text = "↓";
            duplicateDownButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateDownButton.Size = new Size(50, 50);
            duplicateDownButton.Location = new Point(75, 90);
            duplicateDownButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateDownButton.FlatStyle = FlatStyle.Flat;
            duplicateDownButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Left" button with an arrow
            Button duplicateLeftButton = new Button();
            duplicateLeftButton.Text = "←";
            duplicateLeftButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateLeftButton.Size = new Size(50, 50);
            duplicateLeftButton.Location = new Point(10, 50);
            duplicateLeftButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateLeftButton.FlatStyle = FlatStyle.Flat;
            duplicateLeftButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Right" button with an arrow
            Button duplicateRightButton = new Button();
            duplicateRightButton.Text = "→";
            duplicateRightButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateRightButton.Size = new Size(50, 50);
            duplicateRightButton.Location = new Point(140, 50);
            duplicateRightButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateRightButton.FlatStyle = FlatStyle.Flat;
            duplicateRightButton.FlatAppearance.BorderSize = 0;

            // Add buttons to the panel
            buttonPanel.Controls.Add(duplicateUpButton);
            buttonPanel.Controls.Add(duplicateDownButton);
            buttonPanel.Controls.Add(duplicateLeftButton);
            buttonPanel.Controls.Add(duplicateRightButton);

            // Event handler for "Duplicate Left" button
            duplicateLeftButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Left", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Right" button
            duplicateRightButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Right", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Up" button
            duplicateUpButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Up", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Down" button
            duplicateDownButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Down", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Add the controls to the form
            form.Controls.Add(duplicateCountLabel);
            form.Controls.Add(duplicateCountUpDown);
            form.Controls.Add(buttonPanel);

            // Show the form
            form.ShowDialog();
        }
    }
}

Last changed by Thiago_Sase on 8/19/2024, 10:52 AM, changed a total of 1 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files

Thiago_Sase wrote on 8/19/2024, 11:42 AM

@jetdv @zzzzzz9125 I made a video trying to explain better;

jetdv wrote on 8/19/2024, 11:58 AM

In your video, you had TWO events selected going "left". What if you only have ONE event selected?

When you're going left, your "start" position is not changing so when it does the second one, it's starting to the left of the second one which is where the first one was located. You're not keeping track of the "beginning" point.

Try this and see if it helps:
 

                Timecode beginning = null;

                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;
                    if (beginning == null)
                    {
                        beginning = selectedEvent.Start;
                    }


                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = beginning - eventLength;
                            beginning = newEventStart;

                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

 

Thiago_Sase wrote on 8/19/2024, 12:30 PM

@jetdv Thank you very much. It worked.

Is it correct to name (or thinking about) the solution you gave me of "Reverse logic of the right direction"?

Thiago_Sase wrote on 8/19/2024, 2:24 PM

@jetdv Please, one last question about this, if the up and down directions behaviors do the same as the solution you showed me, how that could be?

Last changed by Thiago_Sase on 8/19/2024, 2:25 PM, changed a total of 1 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files

jetdv wrote on 8/19/2024, 4:45 PM

Show me what's happening and ask again in about 24 hours

jetdv wrote on 8/20/2024, 6:57 PM

@Thiago_Sase, My version just makes sure that the "beginning" of the copied event is always at the "beginning" - not the beginning of the original event - x times the current event I'm copying.

Show me what's happening on the up/down and I'll see what we can do there as well.

Thiago_Sase wrote on 8/20/2024, 7:57 PM

@jetdv Thank you again for still trying to help. I did another video trying to explain.

jetdv wrote on 8/21/2024, 9:01 AM

It's basically the same issue you had going left. You're going "up one" but the second event then gets placed on top of the first event. You can try this - I haven't tested it.
 

                Timecode beginning = null;
                int UpTrack = -2;
                int DownTrack = 0;
                if (direction == "Down")
 //This new section is to find "below the bottom selected event"
                {
                    foreach (TrackEvent selectedEvent in selectedEvents)
                    {
                        if (selectedEvent.Track.Index + 1 > DownTrack)
                        {
                            DownTrack = selectedEvent.Track.Index + 1;
                        }
                    }
                }

                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;
                    if (beginning == null)
                    {
                        beginning = selectedEvent.Start;
                    }
                    if (UpTrack < -1)
                    {
                        UpTrack = selectedEvent.Track.Index - 1;
                    }



                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = beginning - eventLength;
                            beginning = newEventStart;
                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

                        // Duplicate the event with the calculated start time
                        if (direction == "Left" || direction == "Right")
                        {
                            if (myTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)myTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, newEventStart);
                            }
                            else if (myTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)myTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, newEventStart);
                            }

                            // Update the end position of the last duplicate event and the global tracker
                            lastEventEnd = newEvent.End;
                            lastGlobalEventEnd = lastEventEnd;
                        }
                        else if (direction == "Up" || direction == "Down")
                        {
                            Track targetTrack = null;
                            int trackIndex = UpTrack;

                            if (direction == "Up")
                            {
                                if (UpTrack > 0)
                                {
                                    targetTrack = myVegas.Project.Tracks[UpTrack];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    UpTrack = 0;
                                    trackIndex = 0;
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                                UpTrack = UpTrack - 1;

                            }
                            else if (direction == "Down")
                            {
                                if (DownTrack < myVegas.Project.Tracks.Count)
                                {
                                    targetTrack = myVegas.Project.Tracks[DownTrack];
                                }
                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    trackIndex = DownTrack;
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(trackIndex + 1);
 //I believe "+1" should not be needed but it won't hurt either
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(trackIndex + 1);
 //I believe "+1" should not be needed but it won't hurt either
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                }
                                DownTrack = DownTrack + 1;

                            }

                            if (myTrack.IsAudio() && targetTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)targetTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, currentEvent.Start);
                                myTrack = aTrack;
                            }
                            else if (myTrack.IsVideo() && targetTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)targetTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, currentEvent.Start);
                                myTrack = vTrack;
                            }
                        }

                        if (newEvent != null)
                        {
                            newEvents.Add(newEvent);
                        }

                        // Update lastGlobalEventEnd after each duplication to ensure proper spacing
                        lastGlobalEventEnd = newEvent.End;
                    }
                }
            }
            else

 

Thiago_Sase wrote on 8/21/2024, 9:51 AM

@jetdv Thank you. This update resolves the down direction perfectly. But the Up direction still has one overlap.

Right Direction = Everything Perfect!
Left Direction = Everything Perfect!
Down Direction = Everything Perfect!
Up Direction = Now, only the first duplicate will overlap.

jetdv wrote on 8/21/2024, 10:03 AM

Well... it's a LOT closer!!! 😁

I think it's because you are "sorting" the events so the "first" one might not be the "top" one. I've changed the initial "look for bottom" loop to now also "look for top". So see if this change makes a difference:
 

                Timecode beginning = null;
                int UpTrack = myVegas.Project.Tracks.Count;
                int DownTrack = 0;
                if (direction == "Up" || direction == "Down")
                {
                    foreach (TrackEvent selectedEvent in selectedEvents)
                    {
                        if (selectedEvent.Track.Index + 1 > DownTrack)
                        {
                            DownTrack = selectedEvent.Track.Index + 1;
                        }
                        if (selectedEvent.Track.Index - 1 < UpTrack)
                        {
                            UpTrack = selectedEvent.Track.Index - 1;
                        }

                    }
                }
                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;
//Removed "UpTrack" from being changed here
                    if (beginning == null)
                    {
                        beginning = selectedEvent.Start;
                    }

                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = beginning - eventLength;
                            beginning = newEventStart;
                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

 

Thiago_Sase wrote on 8/21/2024, 10:41 AM

@jetdv Yes, that change made the difference. Thank you for the lessons. It was a lot of new interpretations to learn. This script is possible now because of the guidance of yours tutorials videos on YouTube and the lessons you post in this forum. Thank you, Sir. 

Thiago_Sase wrote on 8/21/2024, 10:43 AM

Here is the complete code;

 

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
using ScriptPortal.Vegas;

namespace DuplicateEventLeftRightUp
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas, string direction, int duplicateCount)
        {
            myVegas = vegas;
            List<TrackEvent> selectedEvents = new List<TrackEvent>();
            Dictionary<TrackEvent, Track> eventTrackMap = new Dictionary<TrackEvent, Track>();

            // List to store the new duplicated events
            List<TrackEvent> newEvents = new List<TrackEvent>();

            // Find all selected events and their tracks
            foreach (Track track in myVegas.Project.Tracks)
            {
                foreach (TrackEvent evnt in track.Events)
                {
                    if (evnt.Selected)
                    {
                        selectedEvents.Add(evnt);
                        eventTrackMap[evnt] = track;
                    }
                }
            }

            // Check if any events are selected
            if (selectedEvents.Count > 0)
            {
                // Sort selected events by their start time to handle them in order
                selectedEvents.Sort((a, b) => a.Start.CompareTo(b.Start));

                // Find the maximum end time of all selected events manually
                Timecode lastGlobalEventEnd = new Timecode(0);
                foreach (TrackEvent evnt in selectedEvents)
                {
                    if (evnt.End > lastGlobalEventEnd)
                    {
                        lastGlobalEventEnd = evnt.End;
                    }
                }

                Timecode beginning = null;
                int UpTrack = myVegas.Project.Tracks.Count;
                int DownTrack = 0;

                if (direction == "Up" || direction == "Down")
                {
                    foreach (TrackEvent selectedEvent in selectedEvents)
                    {
                        if (selectedEvent.Track.Index + 1 > DownTrack)
                        {
                            DownTrack = selectedEvent.Track.Index + 1;
                        }
                        if (selectedEvent.Track.Index - 1 < UpTrack)
                        {
                            UpTrack = selectedEvent.Track.Index - 1;
                        }
                    }
                }

                foreach (TrackEvent selectedEvent in selectedEvents)
                {
                    Track myTrack = eventTrackMap[selectedEvent];
                    TrackEvent currentEvent = selectedEvent;
                    Timecode eventLength = selectedEvent.Length;

                    if (beginning == null)
                    {
                        beginning = selectedEvent.Start;
                    }

                    // Reset the position for the current event's duplicates
                    Timecode lastEventEnd = currentEvent.End > lastGlobalEventEnd ? currentEvent.End : lastGlobalEventEnd;

                    for (int i = 0; i < duplicateCount; i++)
                    {
                        TrackEvent newEvent = null;
                        Timecode newEventStart = currentEvent.Start; // Initialize to avoid unassigned error

                        if (direction == "Left")
                        {
                            newEventStart = beginning - eventLength;
                            beginning = newEventStart;
                        }
                        else if (direction == "Right")
                        {
                            // Calculate the start time for the next duplicate to avoid overlap
                            newEventStart = lastEventEnd;
                        }

                        // Duplicate the event with the calculated start time
                        if (direction == "Left" || direction == "Right")
                        {
                            if (myTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)myTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, newEventStart);
                            }
                            else if (myTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)myTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, newEventStart);
                            }

                            // Update the end position of the last duplicate event and the global tracker
                            lastEventEnd = newEvent.End;
                            lastGlobalEventEnd = lastEventEnd;
                        }
                        else if (direction == "Up" || direction == "Down")
                        {
                            Track targetTrack = null;

                            if (direction == "Up")
                            {
                                if (UpTrack >= 0 && UpTrack < myVegas.Project.Tracks.Count)
                                {
                                    targetTrack = myVegas.Project.Tracks[UpTrack];
                                }

                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(0);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(0);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    UpTrack = 0; // Reset to the topmost track after adding a new one
                                }
                                else
                                {
                                    UpTrack--;
                                }
                            }
                            else if (direction == "Down")
                            {
                                if (DownTrack < myVegas.Project.Tracks.Count)
                                {
                                    targetTrack = myVegas.Project.Tracks[DownTrack];
                                }

                                if (targetTrack == null || (myTrack.IsAudio() && !targetTrack.IsAudio()) || (myTrack.IsVideo() && !targetTrack.IsVideo()))
                                {
                                    if (myTrack.IsAudio())
                                    {
                                        targetTrack = new AudioTrack(DownTrack + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    else if (myTrack.IsVideo())
                                    {
                                        targetTrack = new VideoTrack(DownTrack + 1);
                                        myVegas.Project.Tracks.Add(targetTrack);
                                    }
                                    DownTrack++;
                                }
                                else
                                {
                                    DownTrack++;
                                }
                            }

                            if (myTrack.IsAudio() && targetTrack.IsAudio())
                            {
                                AudioTrack aTrack = (AudioTrack)targetTrack;
                                newEvent = (AudioEvent)currentEvent.Copy(aTrack, currentEvent.Start);
                                myTrack = aTrack;
                            }
                            else if (myTrack.IsVideo() && targetTrack.IsVideo())
                            {
                                VideoTrack vTrack = (VideoTrack)targetTrack;
                                newEvent = (VideoEvent)currentEvent.Copy(vTrack, currentEvent.Start);
                                myTrack = vTrack;
                            }
                        }

                        if (newEvent != null)
                        {
                            newEvents.Add(newEvent);
                        }

                        // Update lastGlobalEventEnd after each duplication to ensure proper spacing
                        lastGlobalEventEnd = newEvent.End;
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select events to duplicate.");
            }
        }
    }

    public class EntryPoint
    {
        public void FromVegas(Vegas vegas)
        {
            // Create the form
            Form form = new Form();
            form.Text = "Duplicate Events";
            form.StartPosition = FormStartPosition.CenterScreen;
            form.BackColor = Color.FromArgb(45, 45, 48);
            form.ForeColor = Color.White;
            form.FormBorderStyle = FormBorderStyle.FixedDialog;
            form.MaximizeBox = false;
            form.MinimizeBox = false;
            form.Size = new Size(300, 300);
            form.Font = new Font("Segoe UI", 10, FontStyle.Regular);

            // Create a label for the duplicate count
            Label duplicateCountLabel = new Label();
            duplicateCountLabel.Text = "Number of Duplicates:";
            duplicateCountLabel.Location = new Point(20, 20);
            duplicateCountLabel.Size = new Size(150, 30);

            // Create a numeric up-down control for duplicate count
            NumericUpDown duplicateCountUpDown = new NumericUpDown();
            duplicateCountUpDown.Minimum = 1;
            duplicateCountUpDown.Maximum = 100;
            duplicateCountUpDown.Value = 1;
            duplicateCountUpDown.Location = new Point(180, 20);
            duplicateCountUpDown.Size = new Size(60, 30);

            // Create panel to hold the buttons
            Panel buttonPanel = new Panel();
            buttonPanel.Size = new Size(200, 150);
            buttonPanel.Location = new Point(50, 70);
            buttonPanel.BackColor = Color.FromArgb(37, 37, 38);

            // Create the "Duplicate Up" button with an arrow
            Button duplicateUpButton = new Button();
            duplicateUpButton.Text = "↑";
            duplicateUpButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateUpButton.Size = new Size(50, 50);
            duplicateUpButton.Location = new Point(75, 10);
            duplicateUpButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateUpButton.FlatStyle = FlatStyle.Flat;
            duplicateUpButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Down" button with an arrow
            Button duplicateDownButton = new Button();
            duplicateDownButton.Text = "↓";
            duplicateDownButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateDownButton.Size = new Size(50, 50);
            duplicateDownButton.Location = new Point(75, 90);
            duplicateDownButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateDownButton.FlatStyle = FlatStyle.Flat;
            duplicateDownButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Left" button with an arrow
            Button duplicateLeftButton = new Button();
            duplicateLeftButton.Text = "←";
            duplicateLeftButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateLeftButton.Size = new Size(50, 50);
            duplicateLeftButton.Location = new Point(10, 50);
            duplicateLeftButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateLeftButton.FlatStyle = FlatStyle.Flat;
            duplicateLeftButton.FlatAppearance.BorderSize = 0;

            // Create the "Duplicate Right" button with an arrow
            Button duplicateRightButton = new Button();
            duplicateRightButton.Text = "→";
            duplicateRightButton.Font = new Font("Segoe UI", 16, FontStyle.Bold);
            duplicateRightButton.Size = new Size(50, 50);
            duplicateRightButton.Location = new Point(140, 50);
            duplicateRightButton.BackColor = Color.FromArgb(28, 151, 234);
            duplicateRightButton.FlatStyle = FlatStyle.Flat;
            duplicateRightButton.FlatAppearance.BorderSize = 0;

            // Add buttons to the panel
            buttonPanel.Controls.Add(duplicateUpButton);
            buttonPanel.Controls.Add(duplicateDownButton);
            buttonPanel.Controls.Add(duplicateLeftButton);
            buttonPanel.Controls.Add(duplicateRightButton);

            // Event handler for "Duplicate Left" button
            duplicateLeftButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Left", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Right" button
            duplicateRightButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Right", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Up" button
            duplicateUpButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Up", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Event handler for "Duplicate Down" button
            duplicateDownButton.Click += (sender, args) =>
            {
                DuplicateEventLeftRightUp.Class1 duplicateEvent = new DuplicateEventLeftRightUp.Class1();
                duplicateEvent.Main(vegas, "Down", (int)duplicateCountUpDown.Value);
                form.Close();
            };

            // Add the controls to the form
            form.Controls.Add(duplicateCountLabel);
            form.Controls.Add(duplicateCountUpDown);
            form.Controls.Add(buttonPanel);

            // Show the form
            form.ShowDialog();
        }
    }
}

 

jetdv wrote on 8/21/2024, 10:47 AM

Glad to help. In this case, it's a matter of making sure that you're really looking at where the new one needs to go which is not always "just above/below the current one." when you have multiple ones selected. That's why I created a new variable which was "where the new one needs to go" and then that variable is what's updated (and also used to see if new tracks need to be added.)

Thiago_Sase wrote on 8/21/2024, 11:01 AM

@jetdv I'll practice more exercises about multiple events. I consider myself on the basic level of scripting for Vegas (I only started a few months ago), and these subjects about multiple selected events I need to understand better, I feel it's like for intermediate knowledge of scripting for Vegas. Maybe in a few years I'll understand better, more advanced tasks. Thank you.

Last changed by Thiago_Sase on 8/21/2024, 11:06 AM, changed a total of 1 times.

OS: Windows 10 22H2
CPU: Intel Core I7 12700
MEMORY: 32GB DDR4 3200MHz
GHAPHIC CARD: RTX 3060 8GB
HARD DRIVES: SSD for System and M.2 for Media Files