mouseReleased in ofxGui

Is there a way to find out if the mouse has been released after having changed something in ofxGui. I don’t want to know when a specific parameter has changed just whether any parameter has changed and only after the mouse is released (otherwise the program will crash with too much drawing required).

Peter Mc

Hmm. Good thought. I could make use of this as well. I’ve found that the standard mouseReleased functions will only trigger when NOT clicking on an ofParameter (header or group name, for example).

An example where this would be useful:

a video player with an ofxFloatSlider that indicates the current playback time, and allows jumping to any time in the video by clicking on the control.

//.h
ofxFloatSlider time;

//.cpp
void ofApp::setup() {
...
    gui.add(time.setup("time", 0, 0, video.getDuration()));
...
}
void ofApp::update() {
    time = video.getPosition() * video.getDuration();
}

shows the time correctly, but how could I make it jump to a new position on the movie when clicking?

If I add

void ofApp::setup() {
    time.addListener(this, &ofApp::onTimeChanged);
}

the onTimeChanged function is called each time I change time inside update (30 or 60 fps), not just when I click on the gui, so I can’t use that event to call video.setPosition(...).

ofxBaseGui.h has the following:

                virtual bool mouseMoved(ofMouseEventArgs & args) = 0;
                virtual bool mousePressed(ofMouseEventArgs & args) = 0;
                virtual bool mouseDragged(ofMouseEventArgs & args) = 0;
                virtual bool mouseReleased(ofMouseEventArgs & args) = 0;
                virtual bool mouseScrolled(ofMouseEventArgs & args) = 0;
                virtual void mouseEntered(ofMouseEventArgs &){}
                virtual void mouseExited(ofMouseEventArgs &){}

Can we tap into them to detect when the mouse is released on a specific gui item?

the easiest way to do this is to use ofParameter instead of directly the slider:

ofParameter<float> time;


//.cpp
void ofApp::setup() {
...
    gui.add(time.set("time", 0, 0, video.getDuration()));
    time.addListener(this, &ofApp::onTimeChanged);
...
}
void ofApp::update() {
    time.setWithoutEventNotifications(video.getPosition() * video.getDuration());
}
1 Like

Thank you, that sounds like what I need!

But I noticed that then the GUI (the “progress bar”) does not get updated unless I drag the panel around. Maybe the GUI needs the notification to update the component?

oh yeah didn’t realize the gui also relies on the events to update the visualization. you can just set a flag whenever updating the time through code and return right away from the callback that sets the position like:

ofParameter<float> time;
bool settingTime;

//.cpp
void ofApp::setup() {
...
    gui.add(time.set("time", 0, 0, video.getDuration()));
    time.addListener(this, &ofApp::onTimeChanged);
...
}

void ofApp::update() {
    settingTime = true;
    time = video.getPosition() * video.getDuration();
    settingTime = false;
}

void ofApp::onTimeChange(float & t){
    if(settingTime) return;
    ....
}
1 Like