controlP5 - adapting Range controller

edited February 2014 in Library Questions

hi, first of all thanks for the CP5 library it's great! i am still learning it along with processing and whole Java thing. my question is: Is there any way to 'register' a method to work with Range? just like in slider, so following code would work:

import controlP5.*;

ControlP5 cp5; 

float lowValue = 0;
float highValue = 15;
float value = 10;

void setup() {
  size(500,500);
  cp5 = new ControlP5(this);
  cp5.addRange("range", 0, 100, lowValue, highValue, 10, 10, 200, 20);
  cp5.addSlider("slider", 0, 100, value, 10, 50, 200, 20);
}

void draw() {}

 // this works nicely
void slider(float theValue) {
  value = theValue;
}

// this is not working
void range(float lValue, float hValue) {
  lowValue = lValue;
  highValue = hValue;

}

currently only method 'slider' is working. how best to adapt Range controller to react on what's in 'range' method? what's the rule of thumb here if I'd like to create new controller that would support this functionality?

alternatively, how would it be possible to link highValue and lowValue to those in Range ? (slider also provides this functionality if i name the slider the same as a public variable)

Answers

  • edited February 2014

    ps. i do not look for utilizing controlEvent(ControlEvent event) method:

                void controlEvent(ControlEvent event) {
                   if(event.isFrom("range")) {
                      Controller<?> r = event.getController();
                      range(r.getArrayValue(0), r.getArrayValue(1));
                   }
                }
    

    but to develop Range class code so the 'range' method will be available to use in sketch as in slider example.

  • Here is one way, not sure if there is a method-only solution as well...

    Code Example

    import controlP5.*;
    ControlP5 cp5;
    Range r;
    
    void setup() {
      size(500, 500);
      cp5 = new ControlP5(this);
      r = cp5.addRange("range", 0, 100, 10, 35, 10, 10, 200, 20);
    }
    
    void draw() {
      background(125);
    }
    
    void range() {
      println(r.getArrayValue());
    }
    
  • thanks, this works, but why I need to declare Range object but i don't need it in case of Slider object? My main question is rather on what should I do in a controller class (ie. Range) to register a method that works the same as slider() method.

  • Answer ✓

    Found a better way, where you don't need to declare a Range object.

    Adapted Code Example

    import controlP5.*;
    ControlP5 cp5;
    
    void setup() {
      size(500, 500);
      cp5 = new ControlP5(this);
      cp5.addRange("range", 0, 100, 10, 35, 10, 10, 200, 20);
    }
    
    void draw() {
      background(125);
    }
    
    void range(ControlEvent theEvent) {
      println(theEvent.getArrayValue());
    }
    

    See: http://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/Controller.java

    As long as you extend Controller (like Slider and all the other Controllers do), the behavior is inherited. In other words, ControlP5 will link the controller via it's name (and the magic of java reflection) to either a variable or a method in the main sketch. In addition, you can also implement custom ControlListener's and use addListener() to add them to Controllers. See the examples under use.

  • thanks Amnon, I will dig the topic further though, as it actually does not solve my case. I have created custom controller and want to create hundreds of controllers on screen (button-like). Due to large number of them and also because the name of each will not be known (data taken from a file) i cannot use dedicated method of controllerName(ControlEvent e) , nor the if(event.from(controllerName)) inside papplet controlEvent method.

  • Answer ✓

    All right, good luck. Don't know your exact project, but if you intend on creating hundreds of controllers of which you will only know the name during runtime, then I really think it would be most efficient to use a single control event method to handle all of the events.

    Code Example

    import controlP5.*;
    ControlP5 cp5;
    
    void setup() {
      size(800, 800);
      cp5 = new ControlP5(this);
    }
    
    void draw() {
      background(0);
    }
    
    void keyPressed() {
      if (key == 'b') {
        createRandomlyNamedButton("button_" + frameCount);
      }
    }
    
    void createRandomlyNamedButton(String name) {
      // optionally add the name to some arrayList or create an object
      // there are many options, depending on what you want exactly
      cp5.addButton(name)
        .setPosition(random(100, width-100), random(100, height-100))
        .setSize(90, 50);
    }
    
    public void controlEvent(ControlEvent theEvent) {
      println(theEvent.getController().getName());
      // or check it against an arrayList of names/objects
    }
    
  • edited February 2014 Answer ✓

    Is there a particular reason you can't use the controlEvent() method? I did this yesterday, it produces a list of sliders on screen and sends their value through DMX. It might be good for inspiration (stripped down):

    void setup()
    {
      nrOfChannels = (width-10)/15;
    
      //Create a number of sliders, depending on the width of the frame:
      for (int i = 1; i < nrOfChannels; i++)
      {
        cp5.addSlider("channel" + i)
          .setPosition(5 + 15*i, 220)
            .setSize(10, 150)
              .setLabel(str(i))
                .setRange(0, 255)
                  .getValueLabel().setVisible(false);
      }
    }
    
    void controlEvent(ControlEvent theEvent) {
    
      for (int i = 1; i < nrOfChannels; i++)
      {
        if (theEvent.isFrom("channel" + i))
        {
          //Set the DMX output to the value from the slider
          int value = (int) cp5.getController("channel" + i).getValue();
          dmxOutput.set(i, value);
        }
      }
    }
    
  • edited February 2014

    .

Sign In or Register to comment.