Unexpected Item ID Behavior in PopupMenu/ComboBox

I’m encountering an unexpected issue with item IDs when using a PopupMenu in a ComboBox and it’s ComboBox Attachment. Here is the function I’m using to add items and submenus:

void MyAudioProcessorEditor::addPopupForAlgorithmComboBox(juce::ComboBox& comboBox)
{
    juce::PopupMenu* menu = comboBox.getRootMenu();
    if (menu == nullptr)
        return;

    menu->addItem(1, "Default");

    juce::PopupMenu analogMenu;
    analogMenu.addItem(2, "Tube");
    analogMenu.addItem(3, "Tape");
    analogMenu.addItem(4, "Overdrive");
    analogMenu.addItem(5, "Diode");

    ... more sub menus

    menu->addSubMenu("Analog", analogMenu);
    .. add all sub menus

}

The issue:

  • For the “Diode” item (ID 5), the expected attachment value is item ID - 1. However, during debugging, it unexpectedly aligns with 5 instead. (IDs before are correct and “Overdrive” prints 3 with
    DBG(algorithmParameter->load());)
  • Additionally, the behavior changes further on, skipping IDs (e.g., jumping from ID 11 to ID 13). After “Diode” (ID 5), the IDs increment correctly (6, 7, etc.), but discrepancies still occur.

I’m curious about why this happens and how to fix it.
Thanks!

You might need to explain your use of ComboBoxAttachment here a bit more. Are you doing a single ComboBoxAttachment for the entire ComboBox& (in other words, do all these submenus control a single plugin parameter)? Or does each PopupMenu submenu get its own ComboBoxAttachment in order to control a different parameter?

Also, note this part in the ComboBoxAttachment docs:

Combobox items will be spaced linearly across the range of the parameter. For example if the range is specified by NormalisableRange (-0.5f, 0.5f, 0.5f) and you add three items then the first will be mapped to a value of -0.5, the second to 0, and the third to 0.5.

So calling PopupMenu::addItem as you are doing here, by manually specifying the itemResultID, may be part of the problem. That might be in conflict with how ComboBoxAttachment is trying to work.

Rather than specify the IDs myself, I have done something like this before to populate a ComboBox that is attached to a parameter:

RangedAudioParameter* param = apvts.getParameter (parameterID);
comboBox.clear();
comboBox.addItemList (param->getAllValueStrings(), 1);