Wait for user ROI generation? (doprompt)
Ralf Schmauder
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)
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_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
March 20, 2023 at 09:09 am - Permalink
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.
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.
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.
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 ...
0 - normal mode
1 - drawing mode active
2 - edit mode active
March 21, 2023 at 08:10 am - Permalink