No internet connection
  1. Home
  2. How to

How to convert a "Flat Menu Item" into an array?

By Kitch Membery @Kitch2020-06-06 07:59:59.587Z2020-06-06 11:20:35.839Z

Desired Workflow

Id like to be able to compare the current "H/W Buffer Size" with an array of fetched items from the "H/W Buffer Size" popup menu in the Pro Tools Playback Engine window.

Question

The attached script seems to be correct but the "indexOf" is returning "-1" implying that it does not exist in the array which it does.

The bufferSizeMenuItems however does not say that it is an array but a "Flat Menu Item". How can I convert the "Flat Menu Item" to an array, so the "indexOf" returns the correct result.

Thanks in advance!

Command Info

ID: user:ck9fdwh1a0000wd10vnffuiou:ckb3ayvjr0000hz10zg0srcfg
Name: Test

Source

//Activate Protools
sf.ui.proTools.appActivateMainWindow();

//Open Playback Engine
sf.ui.proTools.getMenuItem('Setup', 'Playback Engine...').elementClick();

//H/W Buffer Size popup menu
const popupMenu = sf.ui.proTools.windows.whoseTitle.is('Playback Engine').first.popupButtons.allItems[1];

//Current Buffer Size
const currentBufferSize = popupMenu.value.invalidate().value;

//Array from H/W Buffer Size popup menu
const bufferSizeMenuItems = popupMenu.popupMenuFetchAllItems().menuItems;

//H/W Buffer Size popup menu items length 
const popupMenuItemsLength = bufferSizeMenuItems.length;

//The following line logs "-1" and I'm not sure why?
log(bufferSizeMenuItems.indexOf(currentBufferSize));

log(bufferSizeMenuItems.indexOf('32 Samples'));

Links

User UID: uOwKfD26NbWKAWotin3dmnSne7B3

Feedback Key: sffeedback:uOwKfD26NbWKAWotin3dmnSne7B3:-M97dBDVhIecUFhm0fMG

Feedback ZIP

Solved in post #3, click to view
  • 7 replies
  1. Your variable bufferSizeMenuItems is an array of objects (of type FlatMenuItem). You're thus trying to compare a string (currentBufferSize) to a FlatMenuItem`.

    Instead, you should probably say something like:

    const bufferSizeMenuPathStrings = popupMenu.popupMenuFetchAllItems().menuItems.map(mi => mi.path.join(' -> '));
    

    And then do

    log(bufferSizeMenuPathStrings.indexOf(currentBufferSize));
    

    Note, this wouldn't work very well for any menu with nested content. For that, you'd need to instead check the checked status of the menu items (which overall would work better actually).

    I would recommend something like this:

    const bufferSizeMenuItems = sf.ui.proTools.popupMenuFetchAllItems().menuItems;
    
    const checkedIndex = bufferSizeMenuItems.map((mi, i) => ({ menuItem: mi, index: i })).filter(m => m.menuItem.element.isMenuChecked)[0].index;
    
    1. You can then combine it to something like this if you want to select the next/previous item:

      
      /**
       * @param {FlatMenuItem[]} menuItems
       * @param {number} delta
       * @return {FlatMenuItem}
       */
      function getDeltaMenuItem(menuItems, delta) {
        const checkedIndex = menuItems.map((mi, i) => ({ menuItem: mi, index: i })).filter(m => m.menuItem.element.isMenuChecked)[0].index;
        let newIndex = checkedIndex + delta;
        if (newIndex >= menuItems.length) newIndex = 0;
        else if (newIndex < 0) newIndex = menuItems.length - 1;
        return menuItems[newIndex];
      }
      
      const bufferSizeMenuItems = popupMenu.popupMenuFetchAllItems().menuItems;
      
      const nextMenuItem = getDeltaMenuItem(bufferSizeMenuItems, 1); //1 for next, -1 for previous
      
      popupMenu.popupMenuSelect({ menuPath: nextMenuItem.path });
      
      ReplySolution
      1. Kitch Membery @Kitch2020-06-06 19:27:47.922Z

        Amazing. Thanks Christian :-)

      2. In reply tochrscheuer:
        Dustin Harris @Dustin_Harris
          2020-06-11 01:46:41.576Z

          I have a basic question... this separator in join below, what is this actually doing? (a quick test function reveals that mi.path is System.String[], so I'm totally stumped)

          ...menuItems.map(mi => mi.path.join(' -> '));
          
          1. It joins elements of an array to form a string.

            System.String[] is an array of strings, the [] means array.

            In this case the path would contain the path to the menu item (think parent menu, sub menu) as an array - ie. ["Parent menu", "Sub menu"].
            We want an easy way to compare that to a single string so in this case I just ask to join the array with a delimiter so it becomes "Parent menu -> Sub menu"

            1. Note that the code is generally flawed since the value shown by Pro Tools would not actually look like that which is why I went on to provide a better solution in the follow up posts.

              1. In reply tochrscheuer:
                Dustin Harris @Dustin_Harris
                  2020-06-11 01:59:01.895Z

                  The explanation makes complete sense! Thank you :)