Logic not behaving in Button

Hello all,

I have made this button to reverse the playback of a buffer, by having the rate change from 1 to -1. So far so good.

~button = Button.new(w, Rect.new(10, 50, 30, 35))
.states_([
            ["Fwd", Color.black, Color.white],
            ["Bwd", Color.black, Color.white],
        ])
.action_({ arg state;
	       var rate;
	       state.value.postln;
	       rate = if (state == 0,{ 1 },{ -1 });
	       rate.postln;
	       x.set(\rate, rate);
        });

Then logic seems to breakdown as I get these server messages.

1
-1

0
-1

After an hour of staring at the screen bewildered I found this short video by the wonderful Eli Fieldsteel, which describes the same behaviour, however in the context of Synthdefs (my guess is the problem is the same in nature - the server getting confused with Boolean logic).

I also found this decade old wiki on using ifs in Synthdefs If statements in a SynthDef - SuperCollider wiki

The problem is although I think the diagnosis of the problem is probably accurate, the solution Eli proposes of using SelectX.ar does work for me when I use it in the ¨.action_¨ of the button. I get the error ¨ERROR: can’t set a control to a UGen¨.

If anyone is able to help guide me out of this strange problem I´d be most grateful. I have to admit I also find the solution Eli proposes - while it clearly works in his case - strikes me as aesthetically unpleasant and a bit of a hack (and it’s the first time I’ve felt that sensation while using SC - it’s not a criticism of Eli). My understanding is that this kind of logic represents the rudiments of programming, and yet like some weird quantum physics experiment basic logic seems to melt down in the face of the server / language relationship.

Many thanks in advance for any illumination on this subject.

What is x in your example?

GUI actions do not run in the server so server-side Boolean solutions are totally irrelevant to GUI functions. This is why Eli’s solution didn’t apply to your case.

hjh

Oh, and here’s your problem: the argument to the action function is the view (the Button object), not the value. Thus state will never be 0 here (but state.value should be, half the time).

hjh

Hi Jamshark,

the x is a SynthDef. Thanks for the clarification - misdiagnosis on my part!

Forgive my ignorance here but this statement:

the argument to the action function is the view (the Button object), not the value.

I’m struggling to discern the distinction? I´ll test the solution later, which is to correct state to state.value if I understand correctly.

Hi Jamshark,

I tried your solution and it worked. Reading your message multiple times I have wrapped my head around the distinction that you made.

Thanks so much for your patient help - it’s greatly appreciated!