How to detect which CheckBox was toggled to keep at least one switch 'ON'

Hello,
I am quite new in Processing. I am working on a project where I use a CheckBox from ControlP5 library to control random rotation of a shape. I have 4 switches each for one angle (0/90/180/270 degrees) and I need to detect which switch was toggled and caused an event to keep at least one ‘ON’.
Is there any other simple way how to detect it? Currently I store last state of all switches and compare it with new state in case of the event.

Here is simple example of my code

// Test of swich toggle detection
import controlP5.*;

ControlP5 cp5;
CheckBox checkbox;
float b[] = new float [4];

void setup() {
  size(500, 280);
  background(0);
  cp5 = new ControlP5(this);
  checkbox = cp5.addCheckBox("checkBox")
                .setPosition(100, 100)
                .setSize(20, 20)
                .setItemsPerRow(2)
                .setSpacingColumn(35)
                .setSpacingRow(25)
                .addItem("0", 0)
                .addItem("90", 1)
                .addItem("180", 2)
                .addItem("270", 3)
                ;
}

void draw() {
}

void checkBox(float[] a) {
  for (int i=0; i<4; i++) {
    if (a[i]!=b[i]) {
      println("Switch ",i*90," was toggled");
      break;
    }
  }
  arrayCopy(a,b);
}

is it possible that you actually want a option group ( one of N selected ) only?

PDE / File / Examples / ControlP5 / controllers / ControlP5radioButton /

but you might stay with it and code the "if one selected deselect all others "

The shape can be in 1 to 4 different positions (determined by activated checkboxes), so I need to detect all the combinations. The reason is to avoid the case when user wants to deactivate the last “ON” checkbox, so I need to detect it and toggle it back “ON”.

sorry for ask for confirm:
can there more than one be selected?


did you play the example i told you?

Yes. The valid combination is any of 1 to 4 checkboxes “ON”.

To get the state of particular checkbox in the radioButton example you have to check all of them one by one (like I do now in my sketch). I want to know if there is more simple way like to get an index of the checkbox which caused the event when user toggled it.

good question, meanwhile could try workaround:

import controlP5.*;

ControlP5 cp5;
CheckBox c0,c1,c2,c3;

void setup() {
  size(500, 280);
  background(0);
  cp5 = new ControlP5(this);
  c0 = cp5.addCheckBox("checkBox_0")
                .setPosition(100, 100)
                .setSize(20, 20)
                .addItem("0", 0)
                ;
  c1 = cp5.addCheckBox("checkBox_90")
                .setPosition(150, 100)
                .setSize(20, 20)
                .addItem("90", 0)
                ;
  c2 = cp5.addCheckBox("checkBox_180")
                .setPosition(150, 150)
                .setSize(20, 20)
                .addItem("180", 0)
                ;
  c3 = cp5.addCheckBox("checkBox_270")
                .setPosition(100, 150)
                .setSize(20, 20)
                .addItem("270", 0)
                ;
}

void draw() {
}

void checkBox_0(float[] a) {
  println(a);
}
void checkBox_90(float[] a) {
  println(a);
}
void checkBox_180(float[] a) {
  println(a);
}
void checkBox_270(float[] a) {
  println(a);
}

This is my workaround. I am wondering if exists more elegant way how to keep at least one switch ‘ON’.

// At least one switch 'ON'
import controlP5.*;

ControlP5 cp5;
CheckBox rotation;
float[] r = {1,0,0,0};
int nRot = 1;

void setup() {
  size(500, 280);
  background(0);
  cp5 = new ControlP5(this);
  rotation = cp5.addCheckBox("rotation")
                .setPosition(100, 100)
                .setSize(20, 20)
                .setItemsPerRow(2)
                .setSpacingColumn(35)
                .setSpacingRow(25)
                .addItem("0", 0)
                .addItem("90", 1)
                .addItem("180", 2)
                .addItem("270", 3)
                .activate(0)
                ;
}

void draw() {
}

void rotation(float a[]) {
  int tgd = 0;  
  
  for (int i=0; i<4; i++) {
    if (int(a[i])!=r[i]) {
      println("Switch ",i*90," was toggled");
      tgd = i;
      break;
    }
  }
  nRot = 0;
  for (int i = 0; i<4; i++) {
    if (int(a[i])!= 0) nRot = nRot + 1;
  }
  if (nRot == 0) {
    nRot=1;
    rotation.toggle(tgd);
  }
    else arrayCopy(a,r);
}
1 Like
/**
 * ControlP5 Checkbox
 * an example demonstrating the use of a checkbox in controlP5. 
 * by Andreas Schlegel, 2012
 * www.sojamo.de/libraries/controlP5
 *
 */


import controlP5.*;
ControlP5 cp5;
CheckBox checkbox;

int sum, sumold=1;

void setup() {
  size(400, 400);

  cp5 = new ControlP5(this);
  checkbox = cp5.addCheckBox("checkBox")
    .setPosition(100, 100)
    .setSize(20, 20)
    .setItemsPerRow(2)
    .setSpacingColumn(35)
    .setSpacingRow(25)
    .addItem("0", 1)
    .addItem("90", 2)
    .addItem("180", 3)
    .addItem("270", 4)
    .activate(0)
    ;
}

void keyPressed() {
  if (key==' ') {
    checkbox.deactivateAll();
  } else {
    for (int i=1; i<5; i++) { // check if key 1-4 have been pressed and toggle
      if (keyCode==(48 + i)) { 
        checkbox.toggle(i-1);
        println("key " +i+ " toggle "+checkbox.getItem(i-1).getName());
      }
    }
  }
}

void draw() {
}

void controlEvent(ControlEvent theEvent) {
  if (theEvent.isFrom(checkbox)) {
    //print("got an event from "+checkbox.getName()+"\t\n");
    //println(checkbox.getArrayValue());
    sum = 0;
    for (int i=0; i<checkbox.getArrayValue().length; i++) {
      int n = (int)checkbox.getArrayValue()[i];
      // print(n);
      if (n==1) {
        int k = (int)checkbox.getItem(i).internalValue();
        sum += k;
        //println("\ni ", i, " k ", k, " sum ", sum);
      }
    }
    int dsum = sum - sumold;
    println( dsum );
    sumold = sum;
    println();
  }
}

void checkBox(float[] a) {
  //println(a);
}

from the examples and using kind of sum,
if delta prints -3 button 3 was deactivated…


still no idea about a real library function for a button related event info…
UPPER LEVEL? write own event controller ?