SetVar waveselector popup not working?

I am trying to make the popup menu for setvars work outside of the WaveSelectorWidgetExample. If I open up the example .pxp and open the Popup Wave Selector Panel from the macros menu, all of the SetVars work fine.

However, in my own panel, the setvars seem to not be initiating..the popup itself is not working and the variable text simply shows "" when I start up the panel.

Here's the code, mostly copy/pasted from the example.pxp which is why this is so confusing that it does not seem to work (obviously just trying to get it to work at all before I do anything with the panel)

#pragma rtGlobals=1     // Use modern global access method

#include <WaveSelectorWidget>
#include <PopupWaveSelector>

Function testpanel()
    NewPanel/K=1/W=(150,50,560,360) as "Demo Popup Wave Selector"
    RenameWindow $S_name, DemoPopupWaveSelectorPanel
    SetVariable testvar,pos={41,350},size={270,15},title="Smallest Size (suggested 60-80 nm)"
    SetVariable testvar,bodyWidth= 150
    MakeSetVarIntoWSPopupButton("DemoPopupWaveSelectorPanel", "testvar", "DemoPopupWaveSelectorNotify", "root:",  options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
   
    Button PopupWaveSelectorB1,pos={111,159},size={150,20}
    MakeButtonIntoWSPopupButton("DemoPopupWaveSelectorPanel", "PopupWaveSelectorB1", "DemoPopupWaveSelectorNotify", options=PopupWS_OptionFloat)
    TitleBox WSPopupTitle1,pos={46,145},size={115,12},title="Button, selection as title:"
    TitleBox WSPopupTitle1,frame=0


Function DemoPopupWaveSelectorNotify(event, wavepath, windowName, ctrlName)
    Variable event
    String wavepath
    String windowName
    String ctrlName
   
    print "Selected wave:",wavepath, " using control", ctrlName
end

End


What am I doing wrong?
mike_g wrote:
What am I doing wrong?


The code does not compile for me - do not embed one function inside another. What version of Igor are you using?
This appears to work:
#include <WaveSelectorWidget>
#include <PopupWaveSelector>
Function testpanel()
    NewPanel/K=1/W=(150,50,560,360) as "Demo Popup Wave Selector"
    RenameWindow $S_name, DemoPopupWaveSelectorPanel
    SetVariable testvar,pos={41,350},size={270,15},title="Smallest Size (suggested 60-80 nm)"
    SetVariable testvar,bodyWidth= 150
    MakeSetVarIntoWSPopupButton("DemoPopupWaveSelectorPanel", "testvar", "DemoPopupWaveSelectorNotify", "root:",  options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
 
    Button PopupWaveSelectorB1,pos={111,159},size={150,20}
    MakeButtonIntoWSPopupButton("DemoPopupWaveSelectorPanel", "PopupWaveSelectorB1", "DemoPopupWaveSelectorNotify", options=PopupWS_OptionFloat)
    TitleBox WSPopupTitle1,pos={46,145},size={115,12},title="Button, selection as title:"
    TitleBox WSPopupTitle1,frame=0
 
End
Function DemoPopupWaveSelectorNotify(event, wavepath, windowName, ctrlName)
    Variable event
    String wavepath
    String windowName
    String ctrlName
 
    print "Selected wave:",wavepath, " using control", ctrlName
end

Cheers,
Kurt
Sorry, my original snippet of code was missing the 1 "end" statement. My code is just as yours is, 2 different functions.

Even copy/pasting your code into a new pxp, however, yields the same issue. The button has no problem being a popup, the setvar (hidden because the sizing of the window/positioning of the setvar is off) just says "no value> or "no variable> and does not become a popup.

Using 6.37


It seems that the issue is the variable not initializing...i.e. copy/pasting your code into a new pxp and running testpanel() creates a directory root:Packages:WM_waveselectorlist but the directory is left empty (as opposed to how it populates in the wave selector widget example pxp)
You are passing "root:" as the name of the global string variable to be associated with that popup. The function returns an error code, but you haven't used the return value. This works:
Function testpanel()
    NewPanel/K=1/W=(150,50,560,360) as "Demo Popup Wave Selector"
    RenameWindow $S_name, DemoPopupWaveSelectorPanel
    SetVariable testvar,pos={41,350},size={270,15},title="Smallest Size (suggested 60-80 nm)"
    SetVariable testvar,bodyWidth= 150
    String/G root:myGlobalString=""
    MakeSetVarIntoWSPopupButton("DemoPopupWaveSelectorPanel", "testvar", "DemoPopupWaveSelectorNotify", "root:myGlobalString",  options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
 
    Button PopupWaveSelectorB1,pos={111,159},size={150,20}
    MakeButtonIntoWSPopupButton("DemoPopupWaveSelectorPanel", "PopupWaveSelectorB1", "DemoPopupWaveSelectorNotify", options=PopupWS_OptionFloat)
    TitleBox WSPopupTitle1,pos={46,145},size={115,12},title="Button, selection as title:"
    TitleBox WSPopupTitle1,frame=0
 
End


John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
You are passing "root:" as the name of the global string variable to be associated with that popup. The function returns an error code, but you haven't used the return value. This works:
Function testpanel()
    NewPanel/K=1/W=(150,50,560,360) as "Demo Popup Wave Selector"
    RenameWindow $S_name, DemoPopupWaveSelectorPanel
    SetVariable testvar,pos={41,350},size={270,15},title="Smallest Size (suggested 60-80 nm)"
    SetVariable testvar,bodyWidth= 150
    String/G root:myGlobalString=""
    MakeSetVarIntoWSPopupButton("DemoPopupWaveSelectorPanel", "testvar", "DemoPopupWaveSelectorNotify", "root:myGlobalString",  options=PopupWS_OptionFloat+PopupWS_OptionSVFramed)
 
    Button PopupWaveSelectorB1,pos={111,159},size={150,20}
    MakeButtonIntoWSPopupButton("DemoPopupWaveSelectorPanel", "PopupWaveSelectorB1", "DemoPopupWaveSelectorNotify", options=PopupWS_OptionFloat)
    TitleBox WSPopupTitle1,pos={46,145},size={115,12},title="Button, selection as title:"
    TitleBox WSPopupTitle1,frame=0
 
End


John Weeks
WaveMetrics, Inc.
support@wavemetrics.com


Thanks John, that did it. It was not immediately clear to me that simply making a setvar via panel or code did not automatically initiate/create a variable. I thought the root: call in the popupbutton function was to point the function to a directory to create the setvar.

Followup question: What I would like to do is allow a user to select a wave that I then operate on and pass into other functions. Programatically, what would be the best method to preserve the full path for a selected wave from the popup selectors?

My first thought is to do something simple like using the DemoPopupWaveSelectorNotify function from the Waveselectorwidget example like so:
Function DemoPopupWaveSelectorNotify(event, wavepath, windowName, ctrlName)
    Variable event
    String wavepath
    String windowName
    String ctrlName
   
    print "Selected wave:",wavepath, " using control", ctrlName
   
    string/G tempstr = wavepath
   
    rename tempstr, $ctrlname
   
    //print PopupWS_GetSelectionFullPath(windowName, ctrlName)
end


EDIT: I also see that using rename on a string is silly because one can not /O with rename...It also seems that simply calling exists() would return a value of 2 for both a string and a SVAR so I couldn't even write a check to see if I need to KillVariables or not...I guess I could store tempstr in a new directory to set it apart from the original SVAR but again, clunky...


This seems a little clunky to me though...calling a function to set a SetVar then making a new string with the info I want so that I can use that info later...


I also see that there is the function PopupWS_GetSelectionFullPath() which also returns a string for path. It seems like this is the better option? Is it possible to use events(? or something else?) to call PopupWS_GetSelectionFullPath() when a user actually makes a selection from the popup box and then rewrite the SetVar with the string output from PopupWS_GetSelectionFullPath() ? I'm pretty new to using panels and such in igor, so even just pointing me to the documentation I should read would be helpful.

Thanks!
The notify function IS the way to use events for this purpose. What is expected is that you will write your own notify function that calls your analysis code. You would pass the selected wave as an input to your analysis code, something like this (warning: I haven't tried to compile or run this):
Function Mike_G_WaveSelectorNotify(event, wavepath, windowName, ctrlName)
    Variable event
    String wavepath
    String windowName
    String ctrlName
 
    if (event == WMWS_SelectionChanged)
        WAVE/Z selectedWave = $wavepath
        if (!WaveExists(selectedWave))
            print "This is a bug"
            return 0
        endif

        Mike_G_AnalysisFunction(selectedWave)
    endif
end

If your solution involves global variables, you should immediately ask if there is another way to do it. Global variables make code that is difficult to write and debug, with behavior that depends on the history of previous runs. Sometimes that history is the whole point, in which case a global may be the solution, but most uses can be avoided.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
So this post is related to my other one in that the next step is to display the user-selected waves on a graph, preferably on a different tab in the same panel.


I guess the solution is to simply throw the appendtograph call in the nofication function. This seems to work!

Thanks again for the help.