Sticky button in ControlP5

edited November 2014 in Library Questions

Hello, I have some problem with controlP5 library. There are two buttons, visible and hidden. If you click one, it will be hidden and visible other. The problem is that the second button stuck. Here is a simple code to demonstrate:

import controlP5.*;

ControlP5 cp5;
Button button1, button2;

int i = 0;

void setup() {
  size(200, 200);
  cp5 = new ControlP5(this);
  button1 = cp5.addButton("BUTTON 1")
    .setPosition((width - 70) / 2, 50);
  button2 = cp5.addButton("BUTTON 2")
    .setPosition((width - 70) / 2, height - 70)
      .setVisible(false);
}

void controlEvent(ControlEvent theEvent) {
  if (theEvent.getName() == "BUTTON 1") {
    i = 1;
    println("BUTTON 1 was pressed.");
  }
  if (theEvent.getName() == "BUTTON 2") {
    i = 2;
    println("BUTTON 2 was pressed.");
  }
}

void draw() {
  background(128);
  if (i == 1) {
    button1.setVisible(false);
    button2.setVisible(true);
    i = 0;
  }
  if (i == 2) {
    button1.setVisible(true);
    button2.setVisible(false);
    i = 0;
  }
}

And if you press buttons alternately, you can see this in the log:

... BUTTON 2 was pressed. BUTTON 2 was pressed. BUTTON 1 was pressed. BUTTON 2 was pressed. BUTTON 2 was pressed. BUTTON 1 was pressed. ...

How can I fix it?

Tagged:

Answers

  • Your code can be simplified and made more efficiently. Only change the visibility at the moment the button is pressed. See the adapted example below...

    Adapted Code

    import controlP5.*;
    ControlP5 cp5;
    
    Button button1, button2;
    
    void setup() {
      size(200, 200);
      cp5 = new ControlP5(this);
      button1 = cp5.addButton("BUTTON 1").setPosition((width - 70) / 2, 50);
      button2 = cp5.addButton("BUTTON 2").setPosition((width - 70) / 2, height - 70).setVisible(false);
    }
    
    void controlEvent(ControlEvent theEvent) {
      if (theEvent.getName() == "BUTTON 1") {
        button1.setVisible(false);
        button2.setVisible(true);
      } else if (theEvent.getName() == "BUTTON 2") {
        button1.setVisible(true);
        button2.setVisible(false);
      }
    }
    
    void draw() {
      background(128);
    }
    
  • Unfortunately I cannot change the visibility at the moment of pressing. In my actual code after pressing the command is processed on the Arduino. And the answer Arduino will determine whether to change the visibility of buttons.

  • Answer ✓

    When you use setVisibility() or show() / hide() outside of controlEvent, it apparantly does not work correctly. When you click anywhere in the window, it seems to repeat the last controlEvent or something. This may be an issue than you can file for the library. For now, a workaround that does work, is using the position of the buttons to 'show' and 'hide' them. The example below shows this technique...

    Adapted Example

    import controlP5.*;
    ControlP5 cp5;
    
    Button button1, button2;
    
    int i = 0;
    
    void setup() {
      size(200, 200);
      cp5 = new ControlP5(this);
      button1 = cp5.addButton("BUTTON 1").setPosition(75, 50);
      button2 = cp5.addButton("BUTTON 2").setPosition(width + 75, 130);
    }
    
    void draw() {
      background(128);
      if (i == 1) {
        button1.setPosition(width + 75, 50);
        button2.setPosition(75, 130);
        i = 0;
      } else if (i == 2) {
        button1.setPosition(75, 50);
        button2.setPosition(width + 75, 130);
        i = 0;
      }
    }
    
    void controlEvent(ControlEvent theEvent) {
      if (theEvent.getName() == "BUTTON 1") {
        i = 1;
        println("BUTTON 1 was pressed.");
      } else if (theEvent.getName() == "BUTTON 2") {
        i = 2;
        println("BUTTON 2 was pressed.");
      }
    }
    
  • edited November 2014

    Same technique, multiple buttons, no hardcoded positions...

    import controlP5.*;
    ControlP5 cp5;
    
    Button[] buttons = new Button[7];
    int i = -1;
    
    void setup() {
      size(200, 400);
      cp5 = new ControlP5(this);
      for (int i=0; i<buttons.length; i++) {
        buttons[i] = cp5.addButton("BUTTON " + i).setPosition((width - 70) / 2 + (i == 0 ? 0 : width), 50 + i * 50).setValue(i);
      }
    }
    
    void draw() {
      background(128);
      if (i > -1) {
        for (int j=0; j<buttons.length; j++) {
          PVector loc = buttons[j].getPosition();
          if ((i+1)%buttons.length == j) {
            loc.x = loc.x % width;
          } else if (loc.x < width) {
            loc.x += width;
          }
          buttons[j].setPosition(loc);
        }
        i = -1;
      }
    }
    
    void controlEvent(ControlEvent theEvent) {
      i = int(cp5.getController(theEvent.getName()).getValue());
    }
    
  • setPosition() method is not the most elegant, but it seems appropriate for my code. Thank you.

Sign In or Register to comment.