PopupMenu or SetVariable in Control Panel
My Control Panel skills in Igor are pretty limited and I'm struggling with something which is pretty simple. I have made a GUI where the user can scroll through an image stack. There are features shown the user at specific slices and I am making a panel that the user will use to classify the features. There are 6 possibilities for classification (0-5) and these are stored in a numeric wave - there is a text definition for these possibilities. The panel has a line for each feature for the user to interact with.
My first attempt was to use SetVariable using the numeric wave to prefill the box. This was good, but it was possible for the user to pick values outside the range and they also would need a key to know what text definitions the values referred to.
I am now trying to use PopupMenu. Here I specify the value as a string list of my 6 text definitions. What I'd like to do is set the definition based on the numeric wave and also update the numeric wave when the user changes the value. As a bonus I'd like this selection to change the colour of a circle next to the PopupMenu
I have posted a MWE that shows where I am up to. Most of the features should show "Class 1" but they show the first item. I am also out of ideas on how to use this menu to interact with the numeric wave (ktCat). Thank you for reading. Any help would be appreciated!
Variable nKts = 45
Make/O/N=(nKts) ktCat = 1
ktCat[0,5] = p
Make/O/N=(6,4) colorWave={{0.5,1,0,0,1,0},{0.5,1,0,0,1,1},{0.5,1,0,0,0,1},{0.75,0.75,0,0,0.75,0.75}}
colorWave[][] = floor(65535*colorWave[p][q])
ktCategoryPanel(nKts)
End
/// @param nKts number of kinetochores
Function ktCategoryPanel(nKts)
Variable nKts
Variable nRow = 30
Variable nCol = ceil(nKts / nRow)
WAVE/Z colorWave, ktCat
KillWindow/Z ktCategory
NewPanel/N=ktCategory/K=1/W=(0,0,20+150*nCol,130+20*nRow)
// labelling of columns
DrawText/W=ktCategory 10,30,"Choose category"
// do it button
Button DoIt,pos={10,90+20*nRow},size={120,20},proc=CompleteButtonProc,title="Complete"
// insert rows
String boxName0
String popupStr = "Error;Class 1;Class 2;Class 3;Circle;Square;"
Variable ktVal
Variable i,j
for(i = 0; i < nKts; i += 1)
j = floor(i / nRow)
boxName0 = "box0_" + num2str(i)
DrawText/W=ktCategory 10+150*j,68+(mod(i,nRow)*20),num2str(i+1)
// SetVariable $boxName0,pos={30+150*j,53+(mod(i,nRow)*20)},size={50,14},value= ktCat[i], title=" "
PopUpMenu $boxName0,pos={30+150*j,53+(mod(i,nRow)*20)},size={50,14},value= "Error;Class 1;Class 2;Class 3;Circle;Square;", popvalue = StringFromList(ktCat[i],popupStr)
ktVal = ktCat[i]
SetDrawEnv fillfgc=(colorWave[ktVal][0],colorWave[ktVal][1],colorWave[ktVal][2],colorWave[ktVal][3])
DrawOval/W=ktCategory 120+150*j,50+(mod(i,nRow)*20),138+150*j,68+(mod(i,nRow)*20)
endfor
End
Maybe this:
Variable nKts = 45
Make/O/N=(nKts) ktCat = 1
ktCat[0,5] = p
Make/O/N=(6,4) colorWave={{0.5,1,0,0,1,0},{0.5,1,0,0,1,1},{0.5,1,0,0,0,1},{0.75,0.75,0,0,0.75,0.75}}
colorWave[][] = floor(65535*colorWave[p][q])
ktCategoryPanel(nKts)
End
/// @param nKts number of kinetochores
Function ktCategoryPanel(nKts)
Variable nKts
Variable nRow = 30
Variable nCol = ceil(nKts / nRow)
WAVE/Z colorWave, ktCat
KillWindow/Z ktCategory
NewPanel/N=ktCategory/K=1/W=(0,0,20+150*nCol,130+20*nRow)
// labelling of columns
DrawText/W=ktCategory 10,30,"Choose category"
// do it button
Button DoIt,pos={10,90+20*nRow},size={120,20},proc=CompleteButtonProc,title="Complete"
// insert rows
String boxName0
String list = "Error;Class 1;Class 2;Class 3;Circle;Square;"
String popupStr = "\""+list+"\""
Variable ktVal
Variable i,j
for(i = 0; i < nKts; i += 1)
j = floor(i / nRow)
boxName0 = "box0_" + num2str(i)
DrawText/W=ktCategory 10+150*j,68+(mod(i,nRow)*20),num2str(i+1)
String presetTo = StringFromList(ktCat[i],list)
Variable mode = 1 + WhichListItem(presetTo,list) // about the same as 1+ktCat[i]
PopUpMenu $boxName0,pos={30+150*j,53+(mod(i,nRow)*20)},size={50,14},value= #popupStr, popvalue = presetTo, mode=mode
ktVal = ktCat[i]
SetDrawEnv fillfgc=(colorWave[ktVal][0],colorWave[ktVal][1],colorWave[ktVal][2],colorWave[ktVal][3])
DrawOval/W=ktCategory 120+150*j,50+(mod(i,nRow)*20),138+150*j,68+(mod(i,nRow)*20)
endfor
End
December 19, 2019 at 12:46 pm - Permalink
In addition to Jim's modifications:
Variable nKts = 45
Make/O/N=(nKts) ktCat = 1
ktCat[0,5] = p
Make/O/N=(6,4) colorWave={{0.5,1,0,0,1,0},{0.5,1,0,0,1,1},{0.5,1,0,0,0,1},{0.75,0.75,0,0,0.75,0.75}}
colorWave[][] = floor(65535*colorWave[p][q])
ktCategoryPanel(nKts)
End
/// @param nKts number of kinetochores
Function ktCategoryPanel(nKts)
Variable nKts
Variable nRow = 30
Variable nCol = ceil(nKts / nRow)
WAVE/Z colorWave, ktCat
KillWindow/Z ktCategory
NewPanel/N=ktCategory/K=1/W=(0,0,20+150*nCol,130+20*nRow)
// labelling of columns
DrawText/W=ktCategory 10,30,"Choose category"
// do it button
Button DoIt,pos={10,90+20*nRow},size={120,20},proc=CompleteButtonProc,title="Complete"
// insert rows
String boxName0, valname0
String list = "Error;Class 1;Class 2;Class 3;Circle;Square;"
String popupStr = "\""+list+"\""
Variable ktVal
Variable i,j
for(i = 0; i < nKts; i += 1)
j = floor(i / nRow)
boxName0 = "box0_" + num2str(i)
DrawText/W=ktCategory 10+150*j,68+(mod(i,nRow)*20),num2str(i+1)
String presetTo = StringFromList(ktCat[i],list)
Variable mode = 1 + WhichListItem(presetTo,list) // about the same as 1+ktCat[i]
PopUpMenu $boxName0,pos={30+150*j,53+(mod(i,nRow)*20)},size={70,14}, bodywidth=70,value= #popupStr, popvalue = presetTo, mode=mode, proc=ktPopupHelper
ktVal = ktCat[i]
valName0 = "val0_" + num2str(i)
ValDisplay $valName0, pos={120+150*j,53+(mod(i,nRow)*20)}, size={18,18},bodyWidth=18,value=0,mode=1,barmisc={0,0}
ValDisplay $valName0, limits={-1,1,0}, frame=0, zeroColor=(colorWave[ktCat[i]][0],colorWave[ktCat[i]][1],colorWave[ktCat[i]][2],colorWave[ktCat[i]][3])
endfor
End
Function ktPopupHelper(s) : PopupMenuControl
STRUCT WMPopupAction &s
if (s.eventCode == 2) // mouse up
String name = s.ctrlName
Variable boxnum = str2num(name[5,inf]) // assumes the format to be box0_num
Variable sel = s.popNum-1 // 1-6 (popup) vs. 0-5 (wave)
WAVE/Z colorWave, ktCat
ktCat[boxnum] = sel
ValDisplay $("val0_" + num2str(boxnum)) ,win=ktCategory ,zeroColor=(colorWave[sel][0],colorWave[sel][1],colorWave[sel][2],colorWave[sel][3])
endif
return 0
End
I had to replace the circles with ValDisplays, otherwise it is indefinitely complicated to update the color for a specific position. There is some slight complication with that: Although the color is defined as semi-transparent (active alpha value) the ValDisplays do not seem to reflect that (at least here with Igor 8.04). Maybe this is a bug. One can probably fake the correct behavior with just RGB colors for now.
December 19, 2019 at 07:03 pm - Permalink
Thank you chozo (and Jim), this works great! I now see how to capture the value to the numeric wave. This is very useful because this wave dictates the display of markers in the image window that is part of this project.
I didn't notice that the alpha values were not being read in the panel. I can probably get rid of the alpha value with no consequence to the display window.
Thank you again.
December 20, 2019 at 04:04 am - Permalink