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!

Function DoStuff()
    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:

Function DoStuff()
    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

 

In addition to Jim's modifications:

Function DoStuff()
    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.

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.