Grrr: A SuperCollider UI lib for grid based controllers

I guess you’re interested in what individual monome button within the GRButton’s bounds triggered the change of GRButton value to true and thus starts playing the pattern? You can use the lastPressed() method GRButton inherits from GRView for that.

~drone = GRButton(a, 0@4, 4, 3);
~drone.action = {|view, value|
			var pressedButton;
			pressedButton = view.lastPressed;
			pressedButton.postln; // a Point representing x, y
			pressedButton.x.postln; // x position, an Integer
			pressedButton.y.postln; // y position, an Integer
			Pbindef(\gran, \sndBuf, b[\cuts][rrand(0, ~ssize)], \bpWet, 0.1).play;

Note that above x, y is only posted when the GRButton is changed from unlit to lit since the postln calls are in the GRButton action function and the first if clause. A GRButton is handled as a whole so pressing two monome buttons within a GRButton bounds after each other without releasing in between will not trigger the GRButton action twice. This is by design.

Triggering something every time a monome button of a GRButton is pressed regardless of whether it changes the value (leds) is also possible but then you need to use another action. Let me know if I should elaborate on that.

That’s exactly what I wanted, thanks! I’m using this to build something to improvise with soundscapes and dancers on Tuesday. If you’re interested I can post the code and samples so you or others can see what all these questions were about.

1 Like

Very happy to hear you’re using Grrr for a performance. I’d love to see what you’re building.

This makes me motivated to finalize docs too.

Still working on the code. Another question:

How would you turn off an LED when a pattern is done.

    \droneMix, msg[1],
    \warpRate, msg[2].linlin(0.0, 1.0, 0.1, 1.0),
    \lpffreq, msg[3].linlin(0.0, 1.0, 100, 400),
    \wdrop, msg[4].linlin(0.0, 1.0, 1, 35),
    \wmode, msg[5].linlin(0, 1, 1, 2),
    \dur, Pseq([msg[6].linlin(0, 1, 1, 20)], 1),
    \count, Prout({
        var n = msg[6].linlin(0, 1, 1, 20);
  {    n = n-1;

            if(n == 0,
                {~klank.value = false}
).play(quant: 0)

This was an attempt but it isn’t working. I also tried polling .isPlaying which didn’t work for this pattern either. Any ideas? Thanks again.

I believe there are several ways of doing this but the one that comes to my mind is to listen to updates from the EventStreamPlayer that is spawned on pattern-play. Simple example code using a coupled GRButton:

a = Pbind(*[
  degree: Pseq([0, 3, 2, 5], 4),
  dur: 0.1
b =;
c =, 0@0);
c.action = { |button, value|
  if (value) {
    d =;
    d.addDependant { |what, state|
      if (state == \stopped) { c.value = false }
  } {

I have never used Pbindef so I’m not sure how it works but I guess this is applicable for Pbindef too.


Hey, just wanted to say thanks for sharing this. Grrr made it super easy to prototype the grid interface for this arpeggiator in supercollider.