controlP5: mousePressed only if (mouseButton == LEFT) ?

edited May 2014 in Library Questions

hi there, i am completly new to this forum, so hello and if this is not the right category, please move my post and forgive me^^ :/

i wonder if it is possible to override the updateInternalEvents() function in a way, that controlP5 only reacts on /forExample/ (mouseButton == LEFT).

or maybe i think to complicated about it and there is simpler way to make controlP5 only react to leftMouse... if so, well... thanks in advance.

Answers

  • edited June 2014

    I've found a "potential" solution for hacking the ControlP5 by overriding its init() method:
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlP5.java

    Another P5 lib class called ControlWindow:
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlWindow.java

    is the 1 responsible to get all input from Processing's Event class:
    https://github.com/processing/processing/blob/master/core/src/processing/event/Event.java

    Seems like ControlWindow doesn't care about which mouse button was pressed,
    since it doesn't bother to call MouseEvent's getButton() method at any time!

    My idea was to override ControlWindow's mouseEvent() method so it acts only when getButton() == PApplet.LEFT.

    But alas, the ControlP5's author PAndreas Schlegel AKA @sojamo, had the (I might add: disappointingly sad) idea of
    declaring his class ControlWindow final! :o3 Therefore, we can't hack ControlWindow class at all! ~X(

    I'll leave ya w/ my useless attempt. Perhaps there's another way. Good luck: %%-

    // forum.processing.org/two/discussion/5422/
    // controlp5-mousepressed-only-if-mousebutton-left-
    
    import controlP5.*;
    
    static final ControlP5 InstantiateHackedControlP5(final PApplet p) {
      return new ControlP5(p) {
        @ Override protected void init() {
          super.init();
    
          controlWindow = new ControlWindow(this, p) {
            @ Override public void mouseEvent(final MouseEvent e) {
              if (e.getButton() == PApplet.LEFT)  super.mouseEvent();
              else getPointer().set(e.getX(), e.getY());
            }
          };
        }
      };
    }
    
  • edited May 2014

    thx for the fast respond :)

    after thinking a while about your answer... i tried something like this:

        import processing.core.PApplet;
        import processing.event.MouseEvent;
        import controlP5.ControlP5;
                
        public class ChangedCp5 extends ControlP5 {
                
              public ChangedCp5(PApplet arg0) {
                    super(arg0);
              }
        
             @ Override
             public void mouseEvent(MouseEvent e) {
                        PApplet.println(e.getButton());
                    if (e.getButton() == PApplet.LEFT) {
                        getWindow().mouseEvent(e);
                    }
                }
        }
    

    but it doesnt do what i expected or print anything if i click araund, so i guess it is not working. and if i get you right, thats because the controlWindow is "protected" ?

    is there always a contolWindow? i never looked at the inner structure of cp5, i just did something like this:

        public ControlP5 cp5;
        
        public void setup(){
                size(1350,725);
                background(0);
                        cp5 = new ControlP5(this);
    

    and then i everywhere use controllers like this^^

    bngReloadMidi = cp5.addBang("reloadMidiKeyboard")
                                    .setPosition(370,1)
                                    .setTab(tabNames[4])
                                    .setSize(30,13);
    

    but i didnt initialize a controlWindow manually.

  • edited May 2014

    ... so i guess it is not working.

    More likely it's not internally being used by the library at all. Just a sitting-duck method! (~~)

    ... that's because the controlWindow is protected?

    Actually, field controlWindow is public:
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlP5.java#65

    And it receives an instantiated ControlWindow reference inside init() method:
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlP5.java#213

    Is there always a controlWindow?

    I guess you've meant the class ControlWindow rather than the ControlP5's field controlWindow?
    Don't mix up a field's name and its datatype! 8-X

    I've never looked at the inner structure of cp5,...

    Well, I've been leaving lotsa links to the ControlP5 library's sources above!
    You can click at and study them for yourself! :-B

    Now I just wanna highlight that the overriding attempts on mouseEvent() aren't the same in our versions!

    In my version, I'm trying to override the ControlWindow's mouseEvent():
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlWindow.java#469

    Yours is for the ControlP5's!
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlP5.java#711

    And as you've seen for yourself already, the ControlP5's mouseEvent() aren't called back inside the library!
    Neither PApplet's registerMethod() is called to make mouseEvent() effective inside that class!

    In my case, I can't override the ControlWindow's own mouseEvent() b/c the whole class was declared final! :-L
    It's a pity 'cause Class ControlWindow seems to be the real deal, as it indeed calls PApplet's registerMethod() below:
    https://code.google.com/p/controlp5/source/browse/trunk/src/controlP5/ControlWindow.java#160

  • edited May 2014

    _ I've never looked at the inner structure of cp5,...

    Well, I've been leaving lotsa links to the ControlP5 library's sources above! You can click at and study them for yourself!

    ofcourse i studied the links. i ment never before lol but to be serious, i didnt understand everything, what you are doing there. changing methodes in this way is new to me.

    i noticed that i did something else. i tested both... but i thougth, as it would be ok in my case, if everything inside cp5 only listen to the left mouseBtn, i simply replace the part of the code that (looked to me like it did...) communicates with the PApplet mouseListen thing :/ ...well. class ControlWindow seems to be that part and i think at least i understod the problem^^

  • Answer ✓

    Hi, you can use controlP5's pointer to customise mouse events:

    import controlP5.*;
    
    ControlP5 cp5;
    
    void setup() { 
      size(400, 600); 
      cp5 = new ControlP5(this);
    
      // register mouseEvent for your sketch
      registerMethod("mouseEvent", this);
      // enable cp5's pointer to override default mouseX,mouseY, mousePressed handling 
      cp5.getPointer().enable();  
    
      cp5.addButton("button") 
         .setPosition(100, 100) 
         .setSize(200, 19);
    
      cp5.addSlider("slider")
         .setPosition(100, 150)
         .setSize(200, 19);
    
      cp5.addNumberbox("nb")
         .setPosition(100, 200)
         .setSize(200, 19)
         .setValue(0)
         .setRange(0, 100);
    }
    
    void draw() { 
      background(220);
    }
    
    public void mouseEvent(MouseEvent theEvent) { 
      // catch mouseEvents and only update cp5's pointer if 
      // LEFT mouse button is pressed.
      if (theEvent.getButton()!=RIGHT && theEvent.getButton()!=CENTER) { 
        if (theEvent.getAction()==MouseEvent.PRESS) { 
          cp5.getPointer().pressed();
        } 
        else if (theEvent.getAction()==MouseEvent.RELEASE) { 
          cp5.getPointer().released();
        } 
        // update the mouse location
        cp5.getPointer().set( mouseX, mouseY);
      } 
      else { 
        println("the", (theEvent.getButton()==RIGHT ? "right":"center"), "button has been pressed, no action.");
      }
    }
    
  • edited June 2014

    Oh! So an inner class was the "official" way to override ControlWindow's mouseEvent()? @-)
    Nevertheless, I've tried once more to hack ControlP5. And almost got it! However my new mouseEvent() callback is failing! :((
    It throws IllegalAccessException for each MouseEvent! But gonna leave my 2nd failed attempt for reference: :O)

    // forum.processing.org/two/discussion/5422/
    // controlp5-mousepressed-only-if-mousebutton-left-
    
    import controlP5.*;
    ControlP5 cp5;
    
    void setup() { 
      size(400, 600, JAVA2D);
      frameRate(30);
      smooth(4);
    
      //cp5 = new ControlP5(this);
      cp5 = InstantiateCrackedControlP5(this);
    
      cp5.addButton("button")
        .setPosition(100, 100)
          .setSize(200, 19);
    
      cp5.addSlider("slider")
        .setPosition(100, 150)
          .setSize(200, 19);
    
      cp5.addNumberbox("nb")
        .setPosition(100, 200)
          .setSize(200, 19)
            .setValue(0)
              .setRange(0, 100);
    }
    
    void draw() {
      background(0300);
    }
    
    static final ControlP5 InstantiateCrackedControlP5(final PApplet p) {
      return new ControlP5(p) {
        @ Override protected void init() {
          super.init();
    
          p.unregisterMethod("mouseEvent", controlWindow);
          p.registerMethod("mouseEvent", this);
        }
    
        @ Override public void mouseEvent(final MouseEvent e) {
          if (e.getButton() == PApplet.LEFT)  controlWindow.mouseEvent(e);
          else controlWindow.getPointer().set(e.getX(), e.getY());
        }
      };
    }
    
  • edited June 2014

    Yeepee! Made it at last! ControlP5 was successfully hacked! \m/
    I had to make a formal subclass of it though! Seems like registerMethod() fails on anonymous classes! [..]

    P.S.: I had to declare the inner class CrackedControlP5 as public for it to work.
    Maybe that's the reason an anonymous instantiation doesn't work for registerMethod()? :-/
    I wonder what is the default access level (if any) for anonymous classes...

    /**
     * CrackedControlP5 (v3.0)
     * by GoToLoop (2014/Jun)
     *
     * forum.processing.org/two/discussion/5422/
     * controlp5-mousepressed-only-if-mousebutton-left-
     */
    
    import controlP5.*;
    ControlP5 cp5;
    
    void setup() { 
      size(400, 300, JAVA2D);
      frameRate(30);
      smooth(4);
    
      //cp5 = new ControlP5(this);
      cp5 = new CrackedControlP5(this);
    
      cp5.addButton("button")
        .setPosition(100, 100)
          .setSize(200, 19);
    
      cp5.addSlider("slider")
        .setPosition(100, 150)
          .setSize(200, 19);
    
      cp5.addNumberbox("nb")
        .setPosition(100, 200)
          .setSize(200, 19)
            .setValue(0)
              .setRange(0, 100);
    }
    
    void draw() {
      background(0300);
    }
    
    public class CrackedControlP5 extends ControlP5 {
      public CrackedControlP5(final PApplet p) {
        super(p);
    
        p.unregisterMethod("mouseEvent", controlWindow);
        p.registerMethod("mouseEvent", this);
      }
    
      @ Override public void mouseEvent(final MouseEvent e) {
        if (e.getButton() == PApplet.LEFT)  controlWindow.mouseEvent(e);
        else controlWindow.getPointer().set(e.getX(), e.getY());
      }
    }
    
  • edited June 2014

    thanks alot :D

Sign In or Register to comment.