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   /$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.