Cabbage Logo
Back to Cabbage Site

Radiogroup - chnset one button ON doesn't turn other buttons OFF

When I use chnset on a selected button channel (member of a radiogroup) to change button state to 1, the states of other buttons remain unchanged. Shouldn’t other buttons automatically change to 0 when they are members of the same radiogroup?
The radiogroup behaves as expected when clicking on button widgets though.
Please let me know if I’m doing something wrong.

<Cabbage>
form caption("test radiogroup") size(200, 100), pluginid("trg1") style("legacy")

button bounds(80, 8, 50, 40) latched(1) channel("button0") identchannel("button0_ID") text("0") value(1)  radiogroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(134, 8, 50, 40) latched(1) channel("button1") identchannel("button1_ID") text("1") value(0)  radiogroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(80, 52, 50, 40) latched(1) channel("button2") identchannel("button2_ID") text("2") value(0)  radiogroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(134, 52, 50, 40) latched(1) channel("button3") identchannel("button3_ID") text("3") value(0)  radiogroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -m0d -+rtmidi=NULL 
</CsOptions>
<CsInstruments>

ksmps = 16
nchnls = 2
0dbfs = 1

instr 1

kcnt init 0
if metro(1)==1 then
    ksel = kcnt % 4
    /* 
    chnset k(0), "button0" ; adding this block resolves the problem
    chnset k(0), "button1"
    chnset k(0), "button2"
    chnset k(0), "button3"
    */    
    Ssel sprintfk  "button%d", ksel
    chnset k(1), Ssel 
    kcnt += 1
endif

k0 chnget "button0"
k1 chnget "button1"
k2 chnget "button2"
k3 chnget "button3"

Sout sprintfk "%d, %d, %d, %d \n", k0, k1, k2, k3
printks Sout,1

endin

</CsInstruments>
<CsScore>
f0 z
i 1 0 [3600*24*7]
</CsScore>
</CsoundSynthesizer>

Thanks. It works fine when you manually select the button values, but not when you try to programmatically change them in your code. It’s safe to call this a bug. I’ll add it to the list. :wink:

Just tried to remove some workarounds I had to resolve the above issue one+ year later and it seems this still persists in 2.7.8 (also in queue mode). I hope this is solvable?

This one is causing me some grief. Leave it with me. It’s a little complex because of how this is implemented…

I have pushed a fix for this now. Can you test it? Here is the instrument I tested with.

instr 1

    kcnt init 0
    kMetro metro 1
    if kMetro==1 then
        ksel = kcnt % 4  
        Ssel sprintfk  "button%d", ksel
        cabbageSetValue Ssel, k(1) 
        kcnt += 1
    endif

    k0 chnget "button0"
    k1 chnget "button1"
    k2 chnget "button2"
    k3 chnget "button3"

    Sout sprintfk "%d, %d, %d, %d \n", k0, k1, k2, k3
    printf Sout, kMetro

endin

There is a slight issue when first changing, it looks like one of the buttons holds its value a little longer than a single k-cycle. But it quickly regains its composure. I just hop the changes I’ve made don’t screw up other aspects of buttons and checkboxes. I tested a few of the examples and they seem to work fine. :crossed_fingers:

This seems to work for me too! Thanks! I’ll let you know in case of any issues when I use the mechanism in practice.

Do you expect any specific side effects? Did you then fix this holding of value with unknown side effects or is this “latency” an artefact of your fix?

Your questions are many, but my answers are few :rofl: Tbh, I applied some sticky tape and hoped for the best! It comes down to juggling the two different gui modes. If I could drop one entirely I could make these kind of things more streamlined. Perhaps something for Cabbage v3 :wink:

Sure, sticky tape :smile: I’m just trying to pull out of your mystery box anything that could help anticipate where issues could show up, but I can also let myself be surprised with a reassuring Rory’s safety tape :slight_smile:

And I’d just like to mention again that the GUI mode seems essential to me - to be able to position widgets with a mouse. But I’m of course open to learn if there is a more clever way of doing things. Surely there are different use cases but I have in mind audio plugin design.

Oh no, I wasn’t talking about that, I was talking about support both guiMode(“queue”) and guiMode(“polling”), that’s the route of the pain!

That’s a relieve! Now I see your “madness” even more :laughing:
Maybe it would be easier to have a magic button like with the camelCase to convert all widget channels - or maybe not… but yeah I see that is a temporary sticky situation. Looking forward to v3!

Because this didn’t work in the polling mode (see beginning of this topic), I just tried it now (with my code above) and it seems that the buttons flicker to 1 and back to 0 (just visually looking at the lights). I’m using the gui mode, so no problem for me, but you might want to check if it works in the polling mode.

That’s exactly the kind of problem I was expected :grimacing:

This or some other fix resulted now is some other serious issue.
In 2.7.8 this works fine but no more in 2.7.11 and 2.7.12:

<Cabbage>
form caption("test radioGroup") size(200, 100), pluginId("trg1") guiMode("queue")

button bounds(80, 8, 50, 40) latched(1) channel("button0")  text("0") value(1)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontColour:0(0, 0, 0, 255) fontColour:1(160, 0, 0, 255)
button bounds(134, 8, 50, 40) latched(1) channel("button1")  text("1") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontColour:0(0, 0, 0, 255) fontColour:1(160, 0, 0, 255)
button bounds(80, 52, 50, 40) latched(1) channel("button2")  text("2") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontColour:0(0, 0, 0, 255) fontColour:1(160, 0, 0, 255)
button bounds(134, 52, 50, 40) latched(1) channel("button3") text("3") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontColour:0(0, 0, 0, 255) fontColour:1(160, 0, 0, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -m0d -+rtmidi=NULL 
</CsOptions>
<CsInstruments>

ksmps = 16

instr 1

kTrig[] fillarray \
trigger(cabbageGetValue:k("button0"),0.5,0),\
trigger(cabbageGetValue:k("button1"),0.5,0),\
trigger(cabbageGetValue:k("button2"),0.5,0),\
trigger(cabbageGetValue:k("button3"),0.5,0)

kind = 0
until kind == 4 do
if kTrig[kind] == 1 then
    printk 0, kind
endif
kind += 1
od

endin

</CsInstruments>
<CsScore>
f0 z
i 1 0 [3600*24*7]
</CsScore>
</CsoundSynthesizer>

I’m guessing that this issue is again related to the dualism between the guiModes. So now trigger seem to become dysfunctional. I hope this could be fixed or at least substituted with some cabbageTriggerMagic opcode, but the missing trigger might (very likely) cause confusion in debugging older code.

Dang it. I’ll need to revert back those changes. The radiogroup mechanism is very much a GUI feature tied to an actual mouse press. Trying to add it programmatically is proving a little more trickier than I thought.

If you manually reset the other channels each time you update the current value of a widget in a radiogroup it works fine:

<Cabbage>
form caption("test radiogroup") size(200, 100), pluginid("trg1") style("legacy")

button bounds(80, 8, 50, 40) channel("button0") text("0") value(1)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(134, 8, 50, 40) channel("button1")  text("1") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(80, 52, 50, 40) channel("button2")  text("2") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(134, 52, 50, 40) channel("button3")  text("3") value(0)  radioGroup("group1") corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -m0d -+rtmidi=NULL 
</CsOptions>
<CsInstruments>

ksmps = 16
nchnls = 2
0dbfs = 1

instr 1
kInner = 0
kcnt init 0

if metro(1)==1 then
    ksel = kcnt % 4
    Ssel sprintfk  "button%d", ksel
    
    while kInner < 4 do
        Ssel sprintfk  "button%d", kInner
        if kInner == ksel then
            chnset k(1), Ssel 
        else            
            chnset k(0), Ssel 
        endif
        kInner+=1
    od
    
    kcnt += 1
endif

k0 chnget "button0"
k1 chnget "button1"
k2 chnget "button2"
k3 chnget "button3"

Sout sprintfk "%d, %d, %d, %d \n", k0, k1, k2, k3
printks Sout,1

endin

But the whole point of a radiogroup is to avoid this…

Yes, I knew that.

And this too :slight_smile:

So I guess we shall keep banging all the buttons all the time :slight_smile:

I think I have this working now. :crossed_fingers: Your latest csd works as I would expect, and your first one also. Note that at times two of the buttons might have the same value for a single k-cycle. There isn’t much I can do about this as I need to traverse the list of components in the radioGroup to disable them. When Cabbage turns off button 1, so that it can enable button 2, all buttons will off for a split second before it enables button 2. It’s kind of annoying, but I’m not sure it can be addressed without completely rewriting the radioGroup system from the ground up. :confounded:

Fantastic! My cabbages seem healthy now :slight_smile:
Thank you!!!

1 Like