I want multiple (let’s say 4) ofParameter boolean in my GUI (I’m using ofxGui) which can be checked in order to draw different circles (e.g. first bool is for drawing a red filled circle, second bool is for drawing a blue filled circle, etc.).
in ofApp.h
There is a default checkbox when launching the application (e.g. blue circle). When clicking on a new checkbox (e.g. red circle), I want the previous checkbox to go to false. Also, when clicking on a checkbox that is already to true (which means it will go to false), the default checkbox should come back as the only checkbox set to true. What would be the best approach the create this behavior with checkboxes?
Hi,
I usually use ofxButton, instead of ofParameter.
I tried to simulate what your’e doing with ofParameter, but didn’t get it right to add a listener to the ofParameter-bool.
So I suggest to use an ofxButton, and add a listener function to each of them (not the best solution… But if there aren’t too many buttons, it might be ok) so you know which button is clicked.
I usually use ofxDatGui, which sends a pointer of the clicked button to the listener, so you can use one listener-function :), anyway:
In each listener function you should check:
If all buttons are false: set default button to true;
Else: set all to false, except the one clicked (you know which, because every button calls its own function).
Well. Some quick thoughts to get it working. Good luck!
heyho, sorry i did not test this, so i probably missed something. But i think a lambda function could be very useful here. Hope that works and helps. thomas
_firstBoolParam.newListener([this](bool & value){if(value){ofLogNotice() << "TODO: unset the other parameters";};});
_secondBoolParam.newListener([this](bool & value){if(value){ofLogNotice() << "TODO: unset the other parameters";};});
Thank you, this does work. I just have do declare a lot of circleColor.set(false). It would be nice if I could specify a group of checkboxes to go to false instead of setting them individually.
Yes, putting all the ofParameters in a std::vector would be nice.
Haven’t tested this, but think it should look something like this.
In this example I’m using the newListener-function @thomasgeissl mentioned, which I didn’t get working last time, but he already mentioned that it was untested.
for(int i=0; i<params.size(); i++){ // Add listener functions to all ofParameters
params[i].newListener([this](bool & value){
bool bAllFalse = true;
for(int j=0; j<params.size(); j++){ // Check if all ofParameters are set to false
if(params[j] == true)
bAllFalse = false;
}
if(bAllFalse){ // If all set to false: set the default button
params[0].set(true);
}
if(value){
// Set all to false, except self
for(int j=0; j<params.size(); j++){
if(params[j] != params[i])
params[j].set(false);
}
};
});
}
So not really complete, but hopefully you can use it
I love using .newListener() with lambdas. I delcare an ofEventListener object for each ofParameter that I’m listening to. I’m not sure, but I think this is might be the only way that .newListener() works (with an ofEventListener object). Since the listener is an object, it gets destroyed when it goes out of scope. @arturo wrote a nice blog post about this, and @roymacdonald has included it in a draft chapter of ofBook on ofEvents.
The ofParamter and ofEventListener can be put together in a struct or class too if needed, and instances of struct/class can be added to a vector or other container.
You can of course generalize that to multiple parameters in a vector by checking in a for loop that the current parameter in the for loop is not the same as the sender.
Hi, @Jildert the code that you shared is wrong as you need to store the result of the newListener function in an ofEventListener object.
there is also the ofEventListeners class (notice the s at the end of the name) which is a collection of ofEventListener objects. In arturo’s post that just before this one he makes use of it.
I personally use both lambdas and pointers to functions. It really depends on the use case.