Wait for user ROI generation? (doprompt)

Hi,

I am attempting a rather basic GUI to let a user select to use cutoff values in an image or draw a ROI. However I can not figure out how to get the system to wait  for the user to draw a ROI.

As a test I just have a small routine attempting to let the user draw a ROI with different Versions of ShowTools (see below). It just does not work. Also, using different PauseForUSer attempts failed

Is there way to make it work with doprompt, or do I have to use another Interactionstyle e.g. with NewPannel; Button etc?

 

Thanks!

 

Ralf

 

 

display /k=1/n=img/w=(80,365,350,635); appendimage i1

    variable gui=3

    prompt gui, "gui", popup, " keep; none; poly ; rectangle"

    do
        if (gui>2)
            doprompt "gui", gui
        endif
        doupdate
        if (gui>1)
            SetDrawLayer /k progFront
        endif

        setdrawenv fillpat=0

        if (gui==2)
            ShowTools/A poly
            PauseForUser/C img, gui
        elseif (gui==3)
            ShowTools/A poly
            PauseForUser /C img, gui
        endif

        ImageGenerateROIMask i1
        duplicate /o M_ROIMask, Roi
        display /k=1/w=(80,0,350,260); appendimage M_ROIMask


    while(gui>2)

 

 

I struggled with something similar, here is what worked for me:

    string s_info=TraceInfo(S_graphName, S_traceName, 0)
    string s_Xax=StringByKey("XAXIS",s_info)
    string s_Yax=StringByKey("YAXIS",s_info)   

    KillWindow/Z EncirclePanel
    GetWindow/Z kwTopWin wsize
    variable gx0=(V_left+V_right)/2, gy0=(V_top+V_bottom)/2
    NewPanel/N=EncirclePanel/W=(gx0,gy0,gx0+130,gy0+90) as "ROI"
    SetDrawLayer UserBack
    SetDrawEnv textyjust= 2
    DrawText 5,5,"Click & drag to select,\rthen click continue"
    Button Done,pos={30,35},size={70,20},title="Continue", Proc=ButtonProc
    Button Cancel,pos={30,60},size={70,20},title="Cancel", Proc=ButtonProc
   
    // set hook to bring panel to front after drawing ROI
    SetWindow $S_graphName hook(encircleHook)=hookROI
   
    string s_flags=StringByKey("AXISFLAGS",s_info)
    variable flagBits=GrepString(s_flags, "/R")+2*GrepString(s_flags, "/T")
    switch (flagBits)
        case 0:
            GraphWaveDraw/W=$S_graphName/F/O/B=$s_Xax/L=$s_Yax yROI, xROI
            break
        case 1:
            GraphWaveDraw/W=$S_graphName/F/O/B=$s_Xax/R=$s_Yax yROI, xROI
            break
        case 2:
            GraphWaveDraw/W=$S_graphName/F/O/T=$s_Xax/L=$s_Yax yROI, xROI
            break
        case 3:
            GraphWaveDraw/W=$S_graphName/F/O/T=$s_Xax/R=$s_Yax yROI, xROI
            break
    endswitch
           
    PauseForUser EncirclePanel, $S_graphName
    SetWindow $S_graphName hook(encircleHook)=$""
   
    RemoveFromGraph/Z/W=$S_graphName yROI
    wave/Z xROI=xROI, yROI=yROI
    if (WaveExists(xROI)==0)
        return 0
    endif



// hook is active while drawing to select ROI
// brings panel to front when drawing is complete
// Couldn't figure out how to give a floating panel focus.
function hookROI(s)
    STRUCT WMWinHookStruct &s
   
    if (s.eventCode==8 || s.eventCode==5)
        DoWindow/F EncirclePanel
        return 1
    endif
    return 0
end

// deal with cancel and continue buttons for selection by drawing
function ButtonProc(STRUCT WMButtonAction &s)
       
    if (s.eventCode!=2)
        return 0
    endif
   
    if (stringmatch(s.ctrlName, "Cancel"))
        wave/Z xROI=xROI, yROI=yROI
        if (WaveExists(xROI))
            Redimension/N=0 xROI, yROI
        endif
    endif
   
    KillWindow/Z EncirclePanel
   
    return 0
end

 

In my case with Image Tools, I have a button to Start the draw action. Clicking the button changes the button's name and userdata for the button. It also puts userdata on the graph window.

usD = GetUserData(k_fullPanel,"buttonsetbckgrnd_tab21","")
strswitch(usD)
    case "start":
        switch(how)
            case 1:     // manual
                Button buttonsetbckgrnd_tab21,win=$k_fullpanel,userdata="end",title="End..."
                SetWindow $k_imgDisplay, userdata(draw)="active"
                SetDrawLayer/W=$k_imgDisplay ProgFront
                GraphWaveDraw/W=$k_imgDisplay/L/T/O imgT_bckgY,imgT_bckgX

The image window has a hook function with this code.

// image window hook function
Function Hf_imgTImageHook(iwH)      // WindowHookFunction
    STRUCT WMWinHookStruct &iwH
   
    variable hookResult = 0
    string wmode
   
    switch(iwH.eventCode)
        case 0:     // activate
            // reset axes if ever switched
            wmode = GetUserData(k_imgDisplay,"","draw")
            if (strlen(wmode) != 0)
                // drawing mode active, ignore active event
                hookResult = 0
            else
                hookResult = 1
            endif
            break
        case 2:     // image being killed
            ...
            hookResult = 1
            break
        case 5:     // mouseup
            wmode = GetUserData(k_imgDisplay,"","draw")
            if (strlen(wmode) != 0)
                // drawing mode active here
                ...
            else
                // drawing mode inactive here
                ...
            endif
            hookResult = 1
            break
    endswitch
   
    return hookResult
end

The End button code is as below.

    case "end":
        DoUpdate/W=$k_imgDisplay
        Button buttonsetbckgrnd_tab21,win=$k_fullpanel,userdata="start",title="Set"
        GraphWaveEdit/W=$k_imgDisplay/T=1 scalewy
        GraphNormal/W=$k_imgDisplay
        SetDrawLayer/W=$k_imgDisplay UserFront
        SetWindow $k_imgDisplay, userdata(draw)=""

The approach could likely be improved when GetWindow would have a flag to return the drawing mode state for a graph or image window, such as ...

GetWindow ... drawmode
0 - normal mode
1 - drawing mode active
2 - edit mode active