Pop up menu

Hello,

I wanted to make a procedure of mine more interactive. So to do that I thought that I could create a Menu that when selected will pop up a window that will allow me to enter the parameters of my function.

I noticed that to create the menu I should use the Menu function:


Menu "Test"
"Function", /Q, my_function()
end



But how can I get the pop up window and fill in the function parameters? Instead of calling my function in the command window and filling up all parameters separated by commas I would like to have a window similar to the one in "Curve Fitting" on which in can fill the guesses and etc

Thanks in advance,

Gabriel
To create a simple pop-up window use the the DoPrompt environment. Just read about 'DoPrompt' in the command help window and look at the template there. For your purpose it may take only a few lines of code to make work much more convenient. If you are looking for a more complicated control environment (like the curve fitting dialoge) you should read more about panel creation (look for 'NewPanel' and the likes and/or build a new panel found in the windows menu by using the toolbox; ctrl+T).
Type this in Igor's command line to see the help for The Simple Input Dialog:

DisplayHelpTopic "The Simple Input Dialog"

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
Thank you for your response. I have managed to work with "Prompt" enviroment however some problems occured.

After selecting the waves with a pop up I get a string with the wave name but not the wave it self. How can I have the wave in my procedure? I tried using TraceNameToRef but didnt get it working.

And one more question, is it possible to have in the pop up menu, while entering the parameters, the last inputed values instead of zeros?

Thanks
You need a reference to the wave.

If sWaveName is a string variable from your prompt code with the name of the wave, then

Wave w = $sWaveName

will give you a local reference (w) that you can use to access that wave.

Copy DisplayHelpTopic "Wave References" to the command line to learn more.
Yes indeed I need reference to the wave. But I still can't get the wave.

Here's the piece of the code, can someone point to me what I'm doing wrong?
.
.
String test
Prompt test, "Example:", popup Wavelist("*_test", ";", "")
DoPrompt "Select waves", test
If (v_flag)
    return -1
endif

Wave u = $test
.
.

I can see with debugger that the string test has the right wave name associated but I can't get the contents of that wave to my "u" wave. I get the following error :
"While executing a wave read, the following error occurred: Attempt to operate on a null (missing) wave."

Thanks
So your wavename ends with "_test" but what does it start with?

If it starts with a number, or contains a space, the wavename will need single quotes around it. A not-so-obvious error made even more annoying in that some functions require the single quotes while others do not. Using the contents of the string Test, can you do wave commands (using exactly what test contains)?
Well the waves that I deal with always start with some letters then a underscore letters and a number in the end. Do I need the single quotes?

In the debugger, under the tab "WAVEs and STRUCTs" the wave u is displayed as "u < null >". So I guess that I can't do any wave related commands.

I have a string with the wave name and I would like to use it to initialize the corresponding wave in my procedure. How can I do that?
The following function works for me. Igor 6.23, Win7.
Function PromptTest()
    Make/O/N=10 w1_test, w2_test
    w1_test = p
    w2_test = 2*p
    String test
    Prompt test, "Example:", popup Wavelist("*_test", ";", "")
    DoPrompt "Select waves", test
    If (v_flag)
        return -1
    endif

    Wave u = $test
    print test
    print u
End


This is the output from the history window after running the function and selecting w1_test.
•prompttest()
  w1_test
  w1_test[0]= {0,1,2,3,4,5,6,7,8,9}


You might give this a try, if it works, then the problem may lie in the file name. By the way, your code doesn't change the data folder between the Prompt and the assignment of the wave, does it? Wavelist only acts on the current directory and doesn't give the full path to the waves that it finds.
jtigor wrote:
By the way, your code doesn't change the data folder between the Prompt and the assignment of the wave, does it? Wavelist only acts on the current directory and doesn't give the full path to the waves that it finds.


Yes it did change, I'm very sorry that I didn't mention that earlier. Without the directory change all works fine. Thank you very much jtigor.

However, I wanted to have the waves that I crate with this procedure in directory of their own. Should I create a directory in the end of the procedure and than move the waves? How can I finish with the waves in their own directory?

Thank you all for your patience.
gzvitiello wrote:
However, I wanted to have the waves that I crate with this procedure in directory of their own. Should I create a directory in the end of the procedure and than move the waves? How can I finish with the waves in their own directory?


It's a little hard to tell how to go about this without more details.

Once you create the wave reference it will be absolute; you can create a new directory and make it the current directory without affecting the wave reference. It's just that when creating a reference with "WAVE w = $wavename" Igor will look for the wave in the current directory if "wavename" does not include path information.

So, going on what you have said so far, I can suggest that you create the wave references before creating or changing directories, then you should be ok.
If I create the folder after getting the reference and making the waves they will be outside the folder in the end.

I guess that the easiest for me would be just to use the  MoveWave to get the waves into the data folder.

So what I did was this:

DFREF dfr = GetDataFolderDFR()

string folder
sprintf folder, "Waves round %d", round_number
NewDataFolder/O $folder

movewave u, dfr:$folder

Where u is the wave I referenced before and round is a variable created before. But I get the following error: "While executing MoveWwave, the following error occured: name already exists as a wave"
gzvitiello wrote:
Where u is the wave I referenced before and round is a variable created before. But I get the following error: "While executing MoveWwave, the following error occured: name already exists as a wave"


Unfortunately, NewDataFolder/O does not delete the waves in the currently existing data folder and MoveWave does not have an overwrite option (kinda wish it did). I would do this like so...

DFREF dfr = GetDataFolderDFR()

string folder
sprintf folder, "Waves round %d", round_number
NewDataFolder/s/O $folder

Killwaves/z u                        //   /z flag prevents error if wave does not exist yet.
movewave drf:u, :

setdatafolder ::


This is a little different but it's just because I tend to set the new folder as active so moving waves is a little easier.
gzvitiello wrote:
Where u is the wave I referenced before and round is a variable created before. But I get the following error: "While executing MoveWwave, the following error occured: name already exists as a wave"


In your code
movewave u, dfr:$folder
$folder is interpreted as the new file name, not a folder name. So your starting wave is moved to the data folder referenced by dfr but the name is changed to the contents of $folder.

To get the behavior that I think you want, you could modify your code by creating a second datafolder reference that includes $folder. (I've included an entire procedure for easier testing, but see the part at the end.)
Function PromptTest()
    Make/O/N=10 w1_test, w2_test
    w1_test = p
    w2_test = 2*p
    String test
    Prompt test, "Example:", popup Wavelist("*_test", ";", "")
    DoPrompt "Select waves", test
    If (v_flag)
        return -1
    endif
 
    Wave u = $test
    print test
    print u
   
    DFREF dfr = GetDataFolderDFR()
   
    Variable round_number = 8
    string folder
    sprintf folder, "Waves_round_%d", round_number
    NewDataFolder/O $folder
    DFREF newdfr = dfr:$folder
    movewave u, newdfr

End


By the way, I changed the white space in your new folder name to underscores. I tested the code both with white space and underscores and it works as expected in each case. However, I prefer I life without the heartaches that such blanks can cause.
Jtigor and Proland I thank you very much for your help. The new datafolder reference solved it all.

Everything is working as expected now, thanks again.
proland wrote:
So your wavename ends with "_test" but what does it start with?

If it starts with a number, or contains a space, the wavename will need single quotes around it. A not-so-obvious error made even more annoying in that some functions require the single quotes while others do not. Using the contents of the string Test, can you do wave commands (using exactly what test contains)?

As an aside, it is worth mentioning that in the particular case used here, the single quotes are not only not needed, but are actually not tolerated. When you use

Wave w = $mystringvariable

the entire contents of mystringvariable are taken as the wave name, and the single quotes cannot be present. The single quotes are necessary on the command line or any place where Igor needs them for parsing a string.

OK- that last gets you to a gotcha- if you include a *path* in a string variable, then you need single quotes around any liberal names in the path:
String myDFpath="root:nonliberalnamedfolder:'liberal named data folder':'liberal named wave'"
Wave w=$myDFpath


John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
Thank you for your comment johnweeks.

I was still working on the pop up window and I wanted to have a list of all folders and subfolders to choose from. I've put together a command,  ReplaceString(",",StringByKey("FOLDERS",DataFolderDir(1)),";") , that when runned from root it returns me all the data folders but I can't choose the subfolders. How can I do that?

This would be integrated in a prompt enviroment as:

Prompt dfolder, "Name of the Data Folder:", popup ReplaceString(",",StringByKey("FOLDERS",DataFolderDir(1)),";")
DoPrompt "Choose Data Folder:", dfolder
Setdatafolder dfolder
I think your needs have grown beyond the Simple Input Dialog and you need to create a control panel. I also see that Jim Prouty sent you a simple example of a control panel in response to a tech support query.

If you create a control panel, you can use the Wave Selector Widget to provide wave and data folder selections in your panel. It is implemented as a WaveMetrics procedure. To learn more about it, see the demo experiment: File->Example Experiments->Programming->WaveSelectorWidgetExample.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
I don't know what you want to achieve exactly, but it may be easier to do the selection in the data browser, which happens to list all waves and folders already, and then execute a function to do the work.
It can be done by adding buttons to the data browser via ModifyBrowser which executes a function on every selected wave, or via a menu entry + GetBrowserSelection to extract the selected elements. John's suggestion may be the best solution, but is also not all too easy to implement.