Flow control question: how best to wait for user input from within a loop

I've been struggling with flow control in a program I am developing. Briefly, the user needs to classify some structures in a series of images. I have a master function that gets a list of all the images in a directory and then we will process them using a loop. For each iteration, an image window and panel are shown and the user interacts with them*. What I am struggling with is how to get the loop to wait for user input.

I have tried two things:

1. using return statements to tell the loop that the user has finished. I couldn't get this to work. It seems like my functions that generate the window and panel pop on and off the stack and I can't communicate down to the original loop.

2. using a global variable (a modification of the background task example in the Help). This feels close to working. I set a running variable to 1 and test for 0 status in the loop using do-while. However, it is not possible for the user to interact with the panel is this state (spinning black and white disk).

What am I missing? Is it better to approach this another way? Any help very much appreciated!

* this part works fine and concludes with the user clicking OK in the panel which saves the classification to disk.

I figured a MWE would make it easier to understand my question. Running MWE() redraws the window and panel ten times without waiting for user input.

Ideally I wouldn't use a global variable and would just control everything using return statements. I can't see how to communicate back to the loop in MWE().

Function MWE()
    Variable i
    for(i = 0 ; i < 10; i += 1)
        Print "Image", i
        MakeWindowAndPanel()
    endfor
End

Function MakeWindowAndPanel()
    KillWindow/Z myWindow
    Display/N=myWindow
    FunctionToMakePanel()
End

Function FunctionToMakePanel()
    KillWindow/Z myPanel
    NewPanel/N=myPanel/K=1/W=(0,0,100,100)/HOST=myWindow/EXT=0
    Button Complete,pos={10,40},size={80,20},proc=CompleteButtonProc,title="Complete"
End

Function CompleteButtonProc(ctrlName) : ButtonControl
    String ctrlName
   
    strswitch(ctrlName)
        case "Complete" :
            //Save/J/P=txtDiskFolder/W XW,XW,YW,ktCat as txtName
            KillWindow/Z myWindow
            KillWindow/Z myPanel
            Print "I'm finished"
            return 1
    endswitch
End

 

maybe PauseForUser?

I don't find many uses for PauseForUser nowadays, but if I've understood correctly it would seem to fit your task.

Use PauseForUser after building windows to restrict user activity to panel and plot until user clicks on 'Complete'.

Thanks. Ah yes, PauseForUser. I thought this was deprecated, but according to the Help it still works in IP8. I think this might solve my problem.

Not deprecated. I put in a lot of effort to shoehorn that feature into the Igor Qt-based rewrite at Igor 7.

Not deprecated, but not recommended if you can find a different way to write the user interface. It's conceptually easier than writing a control panel, which involves mastering non-sequential programming.

One possible interface would be a listbox showing the available images. Have the user select a line and click a button to commence the analysis of the given image. Disable a selection when it is done.

You could also use a popup menu control and the user would initiate an analysis by selecting an item. Remove items that have been done.

A scheme like that allows a user to take a lunch break without messing up the loop.

Thanks for the input John. I added PauseForUser and it works in preliminary testing, but it feels too precarious. There's a lot of images to process and the user may not want to sit there and work through them all. So I'm going to try your suggestions for alternative interfaces.

Based on what I am doing in the Image Tools package, I would propose the approach in the attached example experiment.

mweforsjr51.pxp (5.67 KB)

Thank you. That is nice! For anyone following (or finding) this thread, the idea here is to build the image and panel and then use the complete button to move to the next image in the series. So control is handed to the panel rather than leaving a loop hanging around.

I think I could use this. In my case, the images are large stacks and the user needs to move around with a slider to classify a bunch of features, i.e. I would need to load the images on demand (for memory reasons) and rebuild the window and panel each time. I'm actually almost finished with a version using John's suggestion, but thank you very much for this example.