How can we have a drop-down list for set variable option in Igor ?

I have the set of around 30 graphs and I want to create a panel. So that I can select a single wave/ graph and display it in a sub Window to study it. I know about the set variable option which has the facility of up and down scroll buttons. I wonder if one can have his list as an option in set-variable rather than just numbers.

Have a look at:

DisplayHelpTopic "PopupMenu"

with e.g.

value = WinList( "*" , ";" , "WIN:1")

to create a popup that reports all graphs.

It sounds to me like ChrLie is correct and a PopupMenu control is the best solution for you. But are you trying to get a control that works like a Windows editable combobox? That is, a drop-down list that can set a variety of pre-set strings, but you can also edit the string to get some custom something or other? For that, I would pair a SetVariable with a PopupMenu.

You can use two SetVariable controls. One to show the graph window name and another to have the up/down arrows. This would in effect give you the ability to move up/down through the list of windows, which appears as text. Maybe this is close to what you wanted?

For example, try this:

Function DoStuff()
	// make some graph windows
	Display
	Display
	Display
	Display
	// make list of all graph windows
	String sWinList = WinList( "*" , ";" , "WIN:1")
	// make text wave of graph window names
	Make/O/T/N=(ItemsInList(sWinList)) wWinNames
	wWinNames[] = StringFromList(p, sWinList)
	
	// Make Panel
	NewPanel
	Setvariable setvarWinName, pos={10, 10}, size={145,16}, title="Choose"
	Setvariable setvarWinName, value=wWinNames[0], noedit=1
	
	SetVariable setvarWinIndex, pos={157,10},size={10,16}
	SetVariable setvarWinIndex, limits={0,ItemsInList(sWinList)-1,1},value= _NUM:0
	SetVariable setvarWinIndex, proc=SetVarProc
End

Function SetVarProc(sva) : SetVariableControl
	STRUCT WMSetVariableAction &sva
	
	strswitch(sva.ctrlName)
		case "setvarWinIndex":
			switch( sva.eventCode )
				case 1: // mouse up
				case 2: // Enter key
				case 3: // Live update
					Variable dval = sva.dval
					String sval = sva.sval
					ControlInfo setvarWinIndex
					Setvariable setvarWinName, value=wWinNames[V_Value]
					break
				case -1: // control being killed
					break
			endswitch
	
	endswitch

	return 0
End

I leave it as an exercise to make the code robust, etc.

 

I didn't read the OP closely enough, I think. Are you trying to create a panel in which you can select a graph, and then select a trace from that graph?

Well, I created the procedure to accomplish the task thanks to Kurt but the issue that I am facing right now with the code is that the code create a panel and a host panel for the preview but when I click on the host window and then directly click on the "setvariable" up and down scroll button it yields to the action desired but it previews only wave 0 while the wave output should change to WAve10 or some other wave number.

 I am attaching the code

#pragma rtGlobals=3		// Use modern global access method and strict wave access.
#pragma	version=0.6	//This	is	the	second	function	with	the	functionality	of	looking	
//into	the	data	folder	root:ARPESExperiment
//with additional print statements
//Including the functionalities of loading the waves in the form of list for default folder
//If Default folder does not exists setting the data folder to the root and looking for the waves in root
//Yet we had to include the provision to call HDF5Load
//Adding button and its functionality to plot graph
//Looking for the functionality to have the graph plot as an expandable window
Function DoStuff()
	variable	revert=0, lengthoflist
	SetDataFolder root:
      if(DataFolderExists("ARPESExperiment"))
 	   setDataFolder	root:ARPESExperiment
 	   print"Data Folder ARPESExperiment Exists"
    else
 	   setDataFolder	root:
    	Print	"The Data-Folder root:ARPESEXperiment doesnot exists"
    	DoAlert	/T="The DATAFOLDER does not exists" 2,"Do You Want to Call the ARPESLoad	Function"
    	if( V_Flag==1)
    		//call HDF5LoadFunction
    		HDF5Load()
    		setDataFolder	root:ARPESExperiment
    		//HDF5Load Functionality
    	elseif(V_FLAG==2)
    		DoAlert/T="Setting the Data Folder to root:" 0,"Setting the Data Folder to root: and loading the waves from	 root folder"
    		Print	"Setting	 Data-Folder to root:"
    		revert=1
 	//Will call the same functionalities of the DoStuff
    	else
    		return	0
    	endif
   endif
   
   
    String sWinList = WaveList("*",";","")	//WinList( "*" , ";" , "WIN:1")
    // make text wave of graph window names
    if(revert==1)
    	NewDataFolder/O root:Lists
    	SetDataFolder root:Lists
    else
    	NewDataFolder/O root:ARPESExperiment:Lists	//this will show error as long as HDF5Load() functionality is not fixed	
    	SetDataFolder	root:ARPESExperiment:Lists
    endif
	Make/O/T/N=(ItemsInList(sWinList)) wWinNames
 	wWinNames[] = StringFromList(p, sWinList)
  	lengthoflist= numpnts(wWinNames)
   if (lengthoflist==0)
  	 //Don't	Create a panel
	   DoAlert/T="Closing the Panel " 0, "There is no wave to plot or show"
	   SetDataFolder root:
    return 0 
    //Make Panel
   endif
   DoWindow/K Graphcoordination
   NewPanel /N= Graphcoordination
    
   print	"Panel Created"
   print	"It has ",ItemsinList(sWinList),"number of graphs"
   Setvariable setvarWinName, pos={10, 10}, size={145,16}, title="Choose"
   Setvariable setvarWinName, value=wWinNames[0], noedit=1
  
   SetVariable setvarWinIndex, pos= {157,10},size={10,16}
   SetVariable setvarWinIndex, limits= {0,ItemsInList(sWinList)-1,1},value= _NUM:0
   SetVariable setvarWinIndex, proc= SetVarProc
   
  //  Button	plotit,pos={165,10},size={45,16},proc=ButtonProc_Plotit	,Title="Plot!",	Font="Arial"
    //FirstGraph()
End

Function SetVarProc(sva) : SetVariableControl
    STRUCT WMSetVariableAction &sva
   
    strswitch(sva.ctrlName)
        case "setvarWinIndex":
            switch( sva.eventCode )
                case 1: // mouse up
                case 2: // Enter key
                case 3: // Live update
                    Variable dval = sva.dval
                    String sval = sva.sval
                    ControlInfo setvarWinIndex
                    Setvariable setvarWinName, value=wWinNames[V_Value]
                    DoUpdate
                    String Filename,Preview	 //ba.hold
			Filename= "wave"+num2Str(V_Value)
			print	Filename
			//hold=wWinNames[V_Value]	
			//print	hold
			String cwd,cwd1 //ba.cwd
			setdatafolder	::
			cwd=GetDataFolder(1)
			cwd1=cwd+Filename
			NewPanel /Host=$sva.win/EXT=0/W=(10,30,340,430)
			ModifyPanel Fixedsize=0
			//NewImage/F	$cwd1
			//KillWindow	Preview0
			Display /K=1/W=(10,30,340,430) /FG= (FL,FT,FR,FB) /HOST=#
			//Preview=UniqueName("Preview",1,0)
			RenameWindow #,Preview
			AppendImage $cwd1	
			ModifyImage $Filename ctab= {*,*,Terrain256,0},ctabAutoscale=1
			//Modify Graph margin(top)=14,frameStyle=5,tick=2,mirror=1,swapXY=1,minor=1,standoff=0
			DoWindow/F Graphcoordination
			DoUpdate
			Setdatafolder $cwd
			Setdatafolder Lists
		break
                   
                case -1: // control being killed
                    break
            endswitch
           
   
    endswitch
    //setdatafolder	root:

    return 0
End

Function ButtonProc_Plotit(ba): ButtonControl
	STRUCT	WMButtonAction &ba
	switch(ba.eventCode)
	case 2:
		//Plot the graph	 command
		ControlInfo setvarWinIndex
		String hold
		String Filename,Preview	 //ba.hold
		Filename= "wave"+num2Str(V_Value)
		print	Filename
		//hold=wWinNames[V_Value]	
		//print	hold
		String cwd,cwd1 //ba.cwd
		setdatafolder	::
		cwd=GetDataFolder(1)
		cwd1=cwd+Filename
		NewPanel /Host=$ba.win/EXT=0/W=(10,30,340,430)
		ModifyPanel Fixedsize=0
		//NewImage/F	$cwd1
		//KillWindow	Preview0
		Display /K=1/W=(10,30,340,430) /FG= (FL,FT,FR,FB) /HOST=#
		//Preview=UniqueName("Preview",1,0)
		RenameWindow #,Preview
		AppendImage $cwd1	
		ModifyImage $Filename ctab= {*,*,Terrain256,0},ctabAutoscale=1
		//Modify Graph margin(top)=14,frameStyle=5,tick=2,mirror=1,swapXY=1,minor=1,standoff=0
		DoWindow/F Graphcoordination
		DoUpdate
		Setdatafolder $cwd
		Setdatafolder Lists
		break
	
	endswitch
	return	0
end
//Function	FirstGraph()
//Display	 /W=(10,30,340,430)
//RenameWindow #,Preview0
//End
Static	StrConstant	NewFold="root:ARPESExperiment"
Function	HDF5Load()
		
		String	PathStr//,NewFold
		Variable	FileId
		//NewFold=UniqueName("ARPESExperiment",11,0)
		NewDataFolder	/O	$NewFold
		SetDataFolder	$NewFold
		DFREF	InitialFolder=GetDataFolderDFR()
		DFREF	tempFolder=NewFreeDataFolder()
		KillWaves/A
		HDF5OpenFile/R	FileId	as	""
		if(V_Flag)
			abort	//User	Cancelled
		endif
		PathStr=	S_Path
		Print	PathStr
		HDF5ListGroup/F/R=1/TYPE=2	FileId,"/"
		variable	i,j,scanMode,hv
		String	wName,noteStr,NoteStrClean
		for(i=0;i<ItemsInList(S_HDF5ListGroup);i+=1)
			SetDataFolder	tempFolder
			HDF5LoadData/IGOR=-1/N=W_temp/O/Q	FileId,StringFromList(i,S_HDF5ListGroup)
			Wave	W_temp
			SetDataFolder	initialFolder
			noteStr=	ReplaceString("\n",note(W_temp),"\r")
			noteStrClean=	ReplaceString(" ",noteStr,"")	
			if(WaveDims(W_temp)==2)
				wName=		UniqueName("Wave",1,0)
				Make/D/N=	(DimSize(W_temp,1),DimSize(W_temp,0))	$wName
				WAVE	w=	$wName
				w=	W_temp[p][q]
				SetScale/P	x,DimOffset(W_temp,1),DimDelta(W_temp,1),WaveUnits(W_temp,1),w
				SetScale/P	y,DimOffset(W_temp,0),DimDelta(W_temp,0),WaveUnits(W_temp,0),w
				//NewImage	/HIDE=0	$wName			
			elseif(WaveDims(W_temp)==3)
				
			for(j=0;j<DimSize(W_temp,2);j+=1)
				wName=UniqueName("wave",1,0)
				Make/D/N=(DimSize(W_temp,1),DimSize(W_temp,0))$wName
				//NewImage	/HIDE=0	$wName
				Wave	w=	$wName
				w=	W_temp[q][p][j]
				SetScale/P	x,DimOffset(W_temp,1),DimDelta(W_temp,1),WaveUnits(W_temp,1),w
				SetScale/P	y,DimOffset(W_temp,0),DimDelta(W_temp,0),WaveUnits(W_temp,0),w
			endfor
		endif
	endfor
	SetDataFolder	root:		
End

 

In reply to by coltblaze

Can you create a minimal, self-contained example that illustrates the problem. Posting a large amount of code, that includes a lot of irrelevant code, is unhelpful to those who would try to help you.

I have often found that the exercise in creating such a minimal example enables me to solve the issue as it removes clutter as allows one to focus on the core issue.

Function SetVarProc(sva) : SetVariableControl
    STRUCT WMSetVariableAction &sva
   
    strswitch(sva.ctrlName)
        case "setvarWinIndex":
            switch( sva.eventCode )
                case 1: // mouse up
                case 2: // Enter key
                case 3: // Live update
                    Variable dval = sva.dval
                    String sval = sva.sval
                    ControlInfo setvarWinIndex
                    Setvariable setvarWinName, value=wWinNames[V_Value]
                     
                     NewPanel /HOST=$sva.win/EXT=0
                     Display /K=1/W=(10,30,340,430) /FG= (FL,FT,FR,FB) /HOST=#

                     Append image wWinNames[V_value]

                     break
                case -1: // control being killed
                    break
            endswitch
   
    endswitch

    return 0
End

Let us say i click on the scroll button of the set variable for  the first time it should display me Wave0

then let us say in order to analyze the image i clicked on the hosted panel

now I click on the scroll button again it should have shown me the Wave1 in the new panel hosted corresponding to the control panel but i still get the Wave0

then let us say i again click on the scroll button this happens again while now it should have shown me Wave2 but still it shows me Wave 0 in the new panel

let us say now  say if I click anywhere on the control panel and then click the scroll button it shows me Wave3 while my Wave2, Wave 1 are just lost.

well how about this:

#pragma rtGlobals=3		// Use modern global access method and strict wave access.
Function DoStuff()
    // make some graph windows
 
    // make list of all graph windows
    String sWinList = WaveList( "*" , ";" , "")
    // make text wave of graph window names
    Make/O/T/N=(ItemsInList(sWinList)) wWinNames
    wWinNames[] = StringFromList(p, sWinList)
   
    // Make Panel
    NewPanel
    Setvariable setvarWinName, pos={10, 10}, size={145,16}, title="Choose"
    Setvariable setvarWinName, value=wWinNames[0], noedit=1
   
    SetVariable setvarWinIndex, pos={157,10},size={10,16}
    SetVariable setvarWinIndex, limits={0,ItemsInList(sWinList)-1,1},value= _NUM:0
    SetVariable setvarWinIndex, proc=SetVarProc
End

Function SetVarProc(sva) : SetVariableControl
    STRUCT WMSetVariableAction &sva
   
    strswitch(sva.ctrlName)
        case "setvarWinIndex":
            switch( sva.eventCode )
                case 1: // mouse up
                case 2: // Enter key
                case 3: // Live update
                    Variable dval = sva.dval
                    String sval = sva.sval
                    ControlInfo setvarWinIndex
                    Setvariable setvarWinName, value=wWinNames[V_Value]
                   
                    Wave/T	internalwave=wWinNames
                    print	internalwave[V_Value]
                    String	Filename,cwd,cwd1
                    Filename=internalwave[V_Value]
                    print	Filename
                    cwd=GetDataFolder(1)
                    cwd1=cwd+Filename //It is just get the name from list wWinNames
                   	NewPanel/Host=$sva.win	/Ext=0/W=(10,30,340,430)
                  	ModifyPanel	Fixedsize=0
                   	Display/W=(20,25,320,400) /FG= (FL,FT,FR,FB) /HOST=#//If you delete /FG you will understand more
			RenameWindow #,Preview
			appendImage		$cwd1
                    break
                case -1: // control being killed
                    break
            endswitch
   
    endswitch

    return 0
End

well the waves and list shall be in the same folder.

Have you tried testing what you have posted?

I opened a new experiment and pasted in your code. Running DoStuff() makes the wave wWinNames and makes a panel.

But, for example, ... 

// make list of all graph windows
    String sWinList = WaveList( "*" , ";" , "")

Makes a list of waves (that do not exist as they have not yet been created) from the top window (that has not been created yet). In addition, the comment above implies that you are trying to make a list of all graph windows.

Within the SetVarProc you have not declared a reference to wWinNames, although it works provided you are in the same datafolder as wWinNames (you do not control this in your code). 

You have a string called Filename, but this is set to a wave (or window) name.

I suggest you run the code with the debugger, put a breakpoint in the SetVarProc, and step through one line at a time.

Please take time to make the example code meaningful, understand what the issue is and try to resolve it yourself. Then come back with further questions.

 

 

In reply to by coltblaze

It isn't clear what the intended behaviour is. You seem to want to select a wave from a list of waves and create an image plot. A popup control is usually the best way to select an item from a list. I assume that there's some reason you want to plot in a graph subwindow of a panel subwindow, rather than simply plotting in a graph window (or subwindow). Do you want the selected wave to be plotted in the same subwindow each time you make a selection? If that's what you're trying to do you should remove any image traces from the plot and append the selected image in a named subwindow.

The following code is from your SetVarProc, with some comments added:


NewPanel/Host=$sva.win  /Ext=0/W=(10,30,340,430)

   // creates a new panel to the right of the panel with the setvar
   // the new panel is $(sva.win)#P0 if it's the first panel subwindow of sva.win
   // every time an item is selected a new subwindow panel is created

ModifyPanel Fixedsize=0
Display/W=(20,25,320,400) /FG= (FL,FT,FR,FB) /HOST=#

   // create a graph subwindow inside active panel
   // graph subwindow is $(sva.win)#P0#G0

RenameWindow #,Preview

   // graph subwindow is now $(sva.win)#P0#Preview

appendImage     $cwd1

   // image is plotted in the newly created graph subwindow

You should check to see if this is what you intend to do.