Beginner questions about events

I subclass ofxButton and then I want to call a xbutton class’ function if the user clicks on an instance of this button:

xbutton.h:

class xbutton : public ofxButton 
{

  public:

    bool mouseMoved(ofMouseEventArgs & args);
    bool mouseDragged(ofMouseEventArgs & args);
    bool mousePressed(ofMouseEventArgs & args);
    bool mouseReleased(ofMouseEventArgs & args);
    bool mouseScrolled(ofMouseEventArgs & args);
    void mouseEntered(ofMouseEventArgs & args);
    void mouseExited(ofMouseEventArgs & args);

    
    void mousepressedj();

}

in ofApp.h:

ofxButton edit[10];
xbutton editb;

In ofApp.cpp:

void setup()
{
 editb.addListener(this,&ofApp::editPressed);  
 edit[0].addListener(this,&ofApp::editPressed);
}

When I click on edit[0] button, it calls ofApp::editPressed function without problem.But when I click on editd button, it doesn’t call ofApp::editPressed function.Why?

Also, how can I call the function xbutton::mousepressedj when the user clicks on editb button?When I write in ofApp.cpp:

editb.addListener(this,&xbutton(or &edit0)::mousepressedj);

it gives the error:

C:\openframeworks\addons\ofxGui\src\ofxButton.h:21: error: no matching function for call to 'ofAddListener(ofEvent<void>&, ofApp*&, void (xbutton::*&)())'
   ofAddListener(triggerEvent,listener,method);
            ^

Hi,
I might guess that when you subclassed ofxButton you didn’t implement correctly the mouse callbacks, which is making it not to trigger the event, hence your listener will not react.
the implementation of the mouse callbacks should look something like

bool xbutton::mouseMoved(ofMouseEventArgs & args){
    ofxButton::mouseMoved(args);//this is calling the superclass implementation for this method
    //here just add whatever else you might need.
}

as for the second question, there are two problems.
first, the callback function you pass in addListener(...) MUST have as argument a reference to an instance of the same kind as the event that triggers the event. In the case of ofxButton that is a bool.
So, your method declaration should look more like

void mousepressedj(bool & b);

And you must implement it accordingly.

As for:

the use of this is completely wrong.
the add listener expects a pointer to an instance of the class that has the callback function, hence xbutton. As you placed that line in ofApp, the this keyword is a pointer to the instance of the class where it is written, so in this case a pointer to the instance of ofApp. So, change this line to

editb.addListener(&editb, &xbutton::mousepressedj);

hope this helps.

best

1 Like

Thanks for your answer.

Changing just :

editb.addListener(this, &xbutton::mousepressedj);

to

editb.addListener(&editb, &xbutton::mousepressedj);

did the trick like you said but I have a question.I want that when user clicks on an instance of xbutton, it should call a function I created.If I try to call a function like xbutton::mousepressedJ which expects no argument/parameter, using the above addlistener function works without problem.But if I try to call a function which expects arguments/parameters , I am not able to use it with addListener function, it gives error.How can I use addListener function to call a function(when user clicks on the instance of xbutton) which expects arguments/parameters?

Hi,
you need call this function with arguments from inside the one you pass to addListener.
it is the easiest way.

best

Thanks for your answer.

It is working but I noticed that I have to click two times on an instance of xbutton for app to call mousePressedJ(my own function) function.If I click on it just one time, it doesn’t work,if I click on it again then it works.But when I click on an instance of ofxButton , it calls mousePressedJ function as it should.

edit0.addListener(&edit0,&xbutton::mousePressedJ);
//edit0 is an xbutton object(I inherited if from ofxButton using “class xbutton : public //ofxButton”

How can I solve this “two times click” problem?

I solved the last problem by removing all the functions like:

bool mousePressed(ofMouseEventArgs & args);

from the xbutton class…

I have another problem,cause my pressedJ function can’t get parameters/arguments , it can’t be able to seperate right mouse click from left mouse clicks, so even if the user right clicks(instead of a left click)on an instance of xbutton it still calls mousePressedJ function and I don’t know how I can check if the user clicked on left mouse button or right mouse button…

It probably has to do with how you are implementing your xbutton class.
Why are you subclassing ofxButton?
best

Thanks for your answer.

I thought again about why I subclassed the ofxButton and it seems there is no need to do it but I still have the problem in my last post , how can I seperate a right click on a button from left click and left click from right click?

I think that ofxButton makes no difference between buttons.
the ofMouseEventArgs object passed to the mouse callback functions has a parameter called button, which stores which button was pressed.

void mouseReleased(ofMouseEventArgs & args){
     if(args.button == OF_MOUSE_BUTTON_LEFT){
         //left button pressed
     }else if(args.button == OF_MOUSE_BUTTON_RIGHT){
        //right button pressed
     }
}

Thanks for your answer.

Should I modify ofxButton.cpp for using this?I actually subclassed ofxButton for not to modify ofxButton.cpp but if I should do it I will do…

I’d say it is not a good idea to modify the source code if you can handle the problem by subclassing.
Just remember to override only what you need and to call the super class overiden function from within the subclass over-riding function if you don’t want to break anything.
On the other hand, which might be at the end less of a head ache, copy ofxButton .h and .cpp files into your project files, give em a different name and modify the class name accordingly where ever it appears in these new files (use the search and replace function of your IDE for this, it will be very easy and fast). Then just modify this one to suit your needs and instance it instead of ofxButton. It might sound a little bit overkill but it might help you getting rid of subclassing issues as well as understanding how the ofxGui widgets work, so you can make your custom ones in the future. :slight_smile:
best

Thanks for your help :slight_smile: