No internet connection
  1. Home
  2. How to

Show Only Lanes With Automation Across Multiple Tracks?

By Philip weinrobe @Philip_weinrobe
    2024-09-19 15:57:08.890Z

    Hi Geniuses
    The new pro tools native command "show lanes with automation" is amazing.
    i have assigned it to a key command and can click any single track and it works perfectly. great success.

    problem is: i want to be able to do this for my whole session in one click, but this native command seems to not work as soon as multiple tracks are connected.

    anyone wanna take a stab at how we can use soundflow to get around this functionality issue?

    Goal: show only lanes with automation across multiple selected tracks.

    thank you!
    Philip

    • 11 replies

    There are 11 replies. Estimated reading time: 14 minutes

    1. O

      Here's a template I saved ages ago from the forums for 'do for each track' pretty sure that will get you there?

      
      function action() {
      
      /// Code to repeat on every selected track goes here.
      
      
      
      }
      
      
      //Get selected tracks
      const originalTracks = sf.ui.proTools.selectedTrackNames;
      
      //Do for each track.
      sf.ui.proTools.selectedTracks.trackHeaders.slice().map(track => {
      
          //Select track
          track.trackSelect();
      
          //Scroll track into View
          track.trackScrollToView();
      
          action()
      });
      
      //Restore previously selected tracks
      sf.ui.proTools.trackSelectByName({ names: originalTracks });
      

      It might break because the function is changing the tracks every time? Try and see? I'm not in latest protools so I don't have that command yet, but dang that's cool! I know a lot of people here were trying to figure out how to do that with SF before it was native!

      Hmmm here's another version kicking around in my bins, might be a bit cleaner and more adaptable

      function doForAllSelectedTracks(action) {
          var originallySelectedTrackNames = sf.ui.proTools.selectedTrackNames;
      
          try {
              sf.ui.proTools.selectedTrackHeaders.forEach(track => {
                  track.trackSelect();
                  action(track);
              });
          }
          finally {
              sf.ui.proTools.trackSelectByName({ names: originallySelectedTrackNames });
          }
      }
      
      /**@param {AxPtTrackHeader} track */
      function trackFunc(track) {
      
          //Insert your code here
          log(track.normalizedTrackName);
      
      }
      
      doForAllSelectedTracks(trackFunc);
      
      1. Chad Wahlbrink @Chad2024-09-19 20:58:55.690Z

        Also, thanks for sharing the right direction on this, @Owen_Granich_Young!! The crux of my script is that selectedTrackHeaders.forEach() call

      2. In reply toPhilip_weinrobe:
        Chad Wahlbrink @Chad2024-09-19 18:20:47.722Z

        Hey @Philip_weinrobe,

        Try this one out.

        You can set options for the command at the top of the script.

        Options are 'lanes with automation', 'all automation lanes', 'lanes with automation within selection', or 'hide all automation lanes'

        By default, it will work on all selected tracks, but if you set allTracksOrSelectedTracks = 'All Tracks' - then it will try to do it for every track in the session.

        Performing on All Tracks is not especially fast, but it works. Grab a snack and let it roll.

        
        // Options are 'lanes with automation', 'all automation lanes', 'lanes with automation within selection', or 'hide all automation lanes'
        const automationLanesToShow = 'lanes with automation'
        
        // Options Are 'All Tracks' or 'Selected Tracks'
        let allTracksOrSelectedTracks = 'Selected Tracks';
        
        if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`;
        
        sf.ui.proTools.appActivateMainWindow();
        sf.ui.proTools.mainWindow.invalidate();
        
        const ptVersion = sf.ui.proTools.appVersion.split('.').map(Number).slice(0, 2).reduce((p, c, i) => p + Math.pow(100, 2 - i) * c, 0);
        
        // Test for older versions of PT
        // const ptVersion = 230600
        
        if (ptVersion < 240600) {
            alert('This command requires Pro Tools 2024.6+')
            throw 0;
        }
        
        function scrollToTrack({ trackName }) {
            let dlg = sf.ui.proTools.confirmationDialog;
            sf.ui.proTools.menuClick({ menuPath: ["Track", "Scroll to Track..."] })
            dlg.elementWaitFor();
            dlg.textFields.first.elementSetTextFieldWithAreaValue({
                value: trackName,
            });
            dlg.buttons.whoseTitle.is("OK").first.elementClick();
        }
        
        if (allTracksOrSelectedTracks == 'All Tracks') {
            let isTrackListShown = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Track List').isMenuChecked
        
            if (!isTrackListShown) {
                sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Track List'] });
                sf.ui.proTools.mainWindow.invalidate();
            }
        
            try {
                sf.ui.proTools.mainWindow.tables.whoseTitle.is("Group List").first.childrenByRole("AXRow").first.childrenByRole('AXCell').first.buttons.first.elementClick();
                sf.ui.proTools.mainWindow.invalidate();
            } catch (err) {
                throw `${err}: Could Not Click All Group in Group List`
            }
        }
        
        // Filter out all Basic Folder Tracks which don't have automation lanes. 
        let trackTypes = ['Basic Folder Track']
        
        const checker = x => trackTypes.some(element => !x.title.value.includes(element));
        
        let audioTracks = sf.ui.proTools.selectedTracks.invalidate().trackHeaders.filter(x => x).filter(checker).map(t => t.normalizedTrackName);
        
        sf.app.proTools.selectTracksByName({ trackNames: audioTracks, });
        
        let frameHeight = sf.ui.proTools.mainWindow.frame.h;
        
        sf.ui.proTools.selectedTracks.trackHeaders.forEach(
            (currentTrack) => {
                let currentTrackName = currentTrack.normalizedTrackName;
                sf.app.proTools.selectTracksByName({ trackNames: [currentTrackName] })
        
                if (sf.ui.proTools.selectedTrack.position.y < 0) {
                    scrollToTrack({ trackName: currentTrackName });
                    sf.ui.proTools.mainWindow.invalidate();
                }
        
                if ((frameHeight - sf.ui.proTools.selectedTrack.position.y) < 200) {
                    scrollToTrack({ trackName: currentTrackName });
                    sf.ui.proTools.mainWindow.invalidate();
                }
        
                currentTrack.children.whoseRole.is("AXDisclosureTriangle")
                    .whoseTitle.is("Show/hide automation lanes").first
                    .popupMenuSelect({
                        isRightClick: true,
                        menuPath: [automationLanesToShow],
                    })
            })
        
        1. Chad Wahlbrink @Chad2024-09-19 18:21:14.957Z

          Also, I put a user friendly template version of this in my CW Pro Tools Utilities Package if you want to check that out:

          1. Chad Wahlbrink @Chad2024-09-19 18:45:42.422Z

            I also added a command to toggle automation lanes for all selected tracks to my CW Pro Tools Utilities Package.

            Make sure the top-most selected track is visible before running. I prefer to keep it lean without messing with the "Scroll to Track" dialog.

            1. PPhilip weinrobe @Philip_weinrobe
                2024-09-20 15:44:35.118Z
                1. PPhilip weinrobe @Philip_weinrobe
                    2024-09-20 15:44:53.383Z

                    updated, then uninstalled and re-installed but still don't see the automation sub folder...

                    1. Chad Wahlbrink @Chad2024-09-20 16:06:25.366Z

                      That's quite strange! It's showing up correctly on my alt account. I would try entirely quitting SoundFlow from the menu bar and then re-opening SoundFlow from Finder to see if the 1.0.99 update is available.

                      If that doesn't work, ensure you are on the latest version of SoundFlow:
                      https://my.soundflow.org/install

                      1. PPhilip weinrobe @Philip_weinrobe
                          2024-09-20 16:35:30.704Z

                          quitting and re-opening made the latest update visible and now it works great
                          thanks!!

                2. In reply toChad:
                  PPhilip weinrobe @Philip_weinrobe
                    2024-09-20 15:48:42.519Z

                    script works well!
                    just have to select all tracks, confirm they are medium height, scroll to top...and let it roll.

                    yeah, not super speedy but not that bad.

                    would be amazing if someday this could be fast and not have to loop through...

                    1. Chad Wahlbrink @Chad2024-09-20 17:13:19.159Z2024-09-20 17:45:44.114Z

                      Yeah, I agree.

                      That would require further changes in Pro Tools. It would make more sense if Shift+Option+Select worked like it does for other functions.

                      There is an option to use the custom keyboard commands for each track INSTEAD of UI Automation selecting the menu.

                      DISCLAIMER: This would be less stable, but it works okay on my machine. The best practice is to avoid keyboard simulation when possible.

                      I'm finding this to work much more quickly, but I will leave my package version as is since it's the most stable approach.

                      // Use Keyboard Command Instead of Menu
                      // Modifiers in form ctrl, cmd, alt, shift 
                      // Ex: "ctrl+cmd+alt+shift+z"
                      let keyCommand = "ctrl+cmd+alt+shift+z";
                      
                      // Options Are 'All Tracks' or 'Selected Tracks'
                      let allTracksOrSelectedTracks = 'All Tracks';
                      
                      ////////////////////////////////////////////////
                      
                      if (!sf.ui.proTools.isRunning) throw `Pro Tools is not running`;
                      
                      sf.ui.proTools.appActivateMainWindow();
                      sf.ui.proTools.mainWindow.invalidate();
                      
                      const ptVersion = sf.ui.proTools.appVersion.split('.').map(Number).slice(0, 2).reduce((p, c, i) => p + Math.pow(100, 2 - i) * c, 0);
                      
                      // Test for older versions of PT
                      // const ptVersion = 230600
                      
                      if (ptVersion < 240600) {
                          alert('This command requires Pro Tools 2024.6+')
                          throw 0;
                      }
                      
                      function scrollToTrack({ trackName }) {
                          let dlg = sf.ui.proTools.confirmationDialog;
                          sf.ui.proTools.menuClick({ menuPath: ["Track", "Scroll to Track..."] })
                          dlg.elementWaitFor();
                          dlg.textFields.first.elementSetTextFieldWithAreaValue({
                              value: trackName,
                          });
                          dlg.buttons.whoseTitle.is("OK").first.elementClick();
                      }
                      
                      if (allTracksOrSelectedTracks == 'All Tracks') {
                          let isTrackListShown = sf.ui.proTools.getMenuItem('View', 'Other Displays', 'Track List').isMenuChecked
                      
                          if (!isTrackListShown) {
                              sf.ui.proTools.menuClick({ menuPath: ['View', 'Other Displays', 'Track List'] });
                              sf.ui.proTools.mainWindow.invalidate();
                          }
                      
                          try {
                              sf.ui.proTools.mainWindow.tables.whoseTitle.is("Group List").first.childrenByRole("AXRow").first.childrenByRole('AXCell').first.buttons.first.elementClick();
                              sf.ui.proTools.mainWindow.invalidate();
                          } catch (err) {
                              throw `${err}: Could Not Click All Group in Group List`
                          }
                      }
                      
                      // Filter out all Basic Folder Tracks which don't have automation lanes. 
                      let trackTypes = ['Basic Folder Track']
                      
                      const checker = x => trackTypes.some(element => !x.title.value.includes(element));
                      
                      let audioTracks = sf.ui.proTools.selectedTracks.invalidate().trackHeaders.filter(x => x).filter(checker).map(t => t.normalizedTrackName);
                      
                      sf.app.proTools.selectTracksByName({ trackNames: audioTracks, });
                      
                      let frameHeight = sf.ui.proTools.mainWindow.frame.h;
                      
                      sf.ui.proTools.selectedTracks.trackHeaders.forEach(
                          (currentTrack) => {
                              let currentTrackName = currentTrack.normalizedTrackName;
                              sf.app.proTools.selectTracksByName({ trackNames: [currentTrackName] })
                      
                              if (sf.ui.proTools.selectedTrack.position.y < 0) {
                                  scrollToTrack({ trackName: currentTrackName });
                                  sf.ui.proTools.mainWindow.invalidate();
                              }
                      
                              if ((frameHeight - sf.ui.proTools.selectedTrack.position.y) < 200) {
                                  scrollToTrack({ trackName: currentTrackName });
                                  sf.ui.proTools.mainWindow.invalidate();
                              }
                      
                              // Ensure Pro Tools is Focused Before Running Key Command
                              if (!sf.ui.proTools.isFocused) {
                                  sf.ui.proTools.appActivateMainWindow();
                              }
                      
                              sf.keyboard.press({
                                  keys: keyCommand,
                              });
                      
                          })