Popup menu with human-readable entries to select wave

I have several dozen waves whose names are formatted like type_S_P_D, where "type" is the name of a machine, and S, P, and D are numbers corresponding to test conditions. I would like to populate a Popup menu such that the user sees something human-readable. For example, if the wave is named "Mod1_150_2_20", I would like the popup menu entry to be something like "Mod1, 150 m/s, P=2, D=20". Once selected, the routine would then proceed with analysis of the mod1_150_2_20 wave.

Furthermore, I would like to be able to build this entire human-readable list based on the contents of the data folder when the panel is created. How would I go about this?

> How would I go about this?

With some care.

* Generate a list of waves in the folder: LoWaves
* Translate the text of each list item into human-readable format, generating a new list LoNames
* Use LoNames for the popup selections
* Obtain the wave name by the returned pop value to select from LoWaves

Since you want to do this only once, you can save some effort by storing LoWaves and LoNames as global strings, generated before the panel control uses them. Otherwise, you can create string function to return either case.

Function/S create_list(variable whichone)

    string rstr = ... (get list of waves in current data folder)
    switch(whichone)
        case 0:   // return LoWaves
            break
        case 1:   // return LoNames
            ... manipulate the rstr into "human readable" format
            break
    endswitch
    return rstr
end

You may want to test this first by including a DO IT button on your panel rather than by having a change in the pop up cause the action to happen. Once you are happy with the approach, you could remove the DO IT button and have the action triggered when the pop value changes.

The following should work:

function/S parsePopList()
    string name, sVal, pVal, dVal, list = ""
    for (string str : ListToTextWave(WaveList("*",";",""),";"))
        SplitString/E=("([^_]*)_([0-9]*)_([0-9]*)_([0-9]*)") str, name, sVal, pVal, dVal
        if (strlen(sVal) && strlen(pVal) && strlen(dVal))
            list += name+", "+sVal+" m/s, P="+pVal+", D="+dVal+";"
        else
            list += str+";"
        endif
    endfor
    return list
end

function executePopup(STRUCT WMPopupAction &s) : PopupMenuControl
    if (s.eventCode != 2)
        return 0
    endif
    string select = s.popStr
    if (StringMatch(select,"* m/s, P=*"))   // is special selection
        string name, sVal, pVal, dVal
        SplitString/E=("(.*?), ([0-9]*) m\/s, P=([0-9]*), D=([0-9]*)") select, name, sVal, pVal, dVal
        select = name+"_"+sVal+"_"+pVal+"_"+dVal
    endif
    wave/z data = $select
    if (WaveExists(data))
        print "Working on: "+NameOfWave(data)
    endif
    return 0
end

NOTE: Your 'type' should not contain a underscore character. If it does sometimes, then the parsing needs to be done more carefully (I didn't bother for now).

Try it out:

function testPanel()
    NewPanel
    PopupMenu myWaveSelector ,value=parsePopList()  ,proc=executePopup
end

If you really want to have a static selection upon panel creation instead of a dynamic menu, you can simply save the output of parsePopList() into a string and plug this into PopupMenu upon creation.