Interesting, thanks Jason. I’ve been thinking a lot about how to integrate ofParameter into ofxDatGui lately as it’s the #1 feature people have been asking for.
One of issues though that I see with its design is that it doesn’t look like the payload passed to the an event handler function carries any information about the parameter object itself that dispatched the event.
For example, looking at the guiFromParametersExample
circleResolution.addListener(this, &ofApp::circleResolutionChanged);
void ofApp::circleResolutionChanged(int & circleResolution){
ofSetCircleResolution(circleResolution);
}
The circleResolutionChanged event handler just receives a reference to the integer that the circleResolution parameter wraps. So if I understand the design correctly every ofParameter requires its own unique event handler to listen for when its underlying value has changed?
It seems to me that this could get unwieldy very quickly say if I had a Gui with 20 sliders in it as each slider would require its own unique event handler method to detect when its value had changed?
Or am I totally missing something here?
The way ofxDatGui currently handles variable binding is you create say a slider component by passing in a label (which every component requires) and then a min, max, and optional initial value (which can be a reference to a variable).
float myNumber = 50.0f;
ofxDatGui* gui = new ofxDatGui();
gui->addSlider("slider 1", 0, 100, &myNumber);
// listen for interactions //
gui->onSliderEvent(this, &ofApp::onSliderEvent);
Alternatively you can bind a variable to a component after it’s been constructed.
ofxDatGuiSlider* mySlider = gui->addSlider("slider 1", 0, 100);
mySlider->bind(&myNumber, minValue, maxValue);
The onSliderEvent event handler receives an ofxDatGuiSliderEvent object that contains not only a reference to the underlying float variable but also a pointer to the slider itself that dispatched the event. The advantage of this is that you only need one slider event handler on your entire gui because you can easily inspect the incoming event object to find out which slider dispatched the event.
void ofApp::onSliderEvent(ofxDatGuiSliderEvent e){
if(e.target == mySlider) // pointer comparison
// or
if(e.target.is("slider 1")) // name comparison
// do something with e.value (current value of the slider)
// do something with e.scale (current position of the value between min & max)
Not having to write an event handler for every variable I want to watch seems like the simpler solution to me but someone please correct me if I’m missing a feature of ofParameter that negates this need.
Regardless I do plan on adding ofParameter support to ofxDatGui soon, likely in a way that is similar to how it works with ofxGui via gui.add
methods to keep it consistent for people.
I just want to make sure I fully understand ofParameter’s design and what folks really like about it so that I can support it in ofxDatGui in the best way possible.