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.