Refactor ofxGui with extended features and controls #31

Open
wants to merge 1,710 commits into
from

Conversation

Projects
None yet
@frauzufall

I am creating this pull request to have a starting point for the discussion about this.

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 3, 2015

You cleared out a lot of inherited functions in your PR, we should do the same here.

This PR also has unresolved layout issues - the positioning and sizing is not that good. I was not sure how spacingNextElement and spacingFirstElement were used and how to apply that to the vertical layout. There were also issues of ofxGuiGroup in the core addon when the container gets resized before or after adding controls, that's why I could not always keep the original positioning.

We should apply your PR and the newer commits to this branch with this PR and then ping the people who wanted to help - roymacdonald and thomasgeissl - to do testing and discuss the rest? Like if we keep the rotary slider and the graphics and things like that. I also would have suggested to put the master slave controls into a separate addon. But I could not yet get them to work with the new ofxGui so it could still affect this branch.

And then there are some additional suggestions - slider controlled by arrow keys (https://github.com/roymacdonald/ofxGuiPlus) and the wish to disable controls. This would be another variable in ofxBaseGui.

You cleared out a lot of inherited functions in your PR, we should do the same here.

This PR also has unresolved layout issues - the positioning and sizing is not that good. I was not sure how spacingNextElement and spacingFirstElement were used and how to apply that to the vertical layout. There were also issues of ofxGuiGroup in the core addon when the container gets resized before or after adding controls, that's why I could not always keep the original positioning.

We should apply your PR and the newer commits to this branch with this PR and then ping the people who wanted to help - roymacdonald and thomasgeissl - to do testing and discuss the rest? Like if we keep the rotary slider and the graphics and things like that. I also would have suggested to put the master slave controls into a separate addon. But I could not yet get them to work with the new ofxGui so it could still affect this branch.

And then there are some additional suggestions - slider controlled by arrow keys (https://github.com/roymacdonald/ofxGuiPlus) and the wish to disable controls. This would be another variable in ofxBaseGui.

addons/ofxGui/src/ofxBaseGui.cpp
@@ -225,22 +227,28 @@ void ofxBaseGui::setPosition(float x, float y){
setNeedsRedraw();
}
-void ofxBaseGui::setSize(float w, float h){
+void ofxBaseGui::setSize(float w, float h, bool callback){
b.width = w;

This comment has been minimized.

@arturoc

arturoc Aug 4, 2015

Owner

let's remove this callbacks parameters, it's a pattern that we use sometimes in OF and it's really confusing to read.

this:

gui.sizeChangedE.disable()
gui.setSize(40,40)
gui.sizeChangedE.enable()

is more verbose but it's clear what it means, but this:

gui.setSize(40,40,false);

it's really cryptic and forces you to go to the original headers to see the meaning of that parameter, another possibility would be something like:

gui.setSizeWithoutEvent(40,40);

but it would need to be public and since it's something we only need internally to avoid recursive calls i think the first syntax is ok

@arturoc

arturoc Aug 4, 2015

Owner

let's remove this callbacks parameters, it's a pattern that we use sometimes in OF and it's really confusing to read.

this:

gui.sizeChangedE.disable()
gui.setSize(40,40)
gui.sizeChangedE.enable()

is more verbose but it's clear what it means, but this:

gui.setSize(40,40,false);

it's really cryptic and forces you to go to the original headers to see the meaning of that parameter, another possibility would be something like:

gui.setSizeWithoutEvent(40,40);

but it would need to be public and since it's something we only need internally to avoid recursive calls i think the first syntax is ok

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 4, 2015

Owner

also not completely sure but we might want to join the sliders in one class only, i added a Layout enum and variable in ofxBaseGui, we could switch on that to generate the slider as vertical or horizontal instead of having 2 classes. then a horizontal gui group will generate sliders with vertical layout and a vertical gui group horizontal sliders by default but we can configure that through the config.

other controls could switch on that too to render differently depending on the layout.

what do you think?

in any case i think adding back that layout variable and enum in the base class and removing bVertical from ofxGuiGroup is more flexible

Owner

arturoc commented Aug 4, 2015

also not completely sure but we might want to join the sliders in one class only, i added a Layout enum and variable in ofxBaseGui, we could switch on that to generate the slider as vertical or horizontal instead of having 2 classes. then a horizontal gui group will generate sliders with vertical layout and a vertical gui group horizontal sliders by default but we can configure that through the config.

other controls could switch on that too to render differently depending on the layout.

what do you think?

in any case i think adding back that layout variable and enum in the base class and removing bVertical from ofxGuiGroup is more flexible

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 4, 2015

Yes all these suggestions make sense to me. Who wants to rewrite? I can do it, just making sure we are not doing the same thing again :-)

Any idea on how to set the child's config to the config of the parent but also keeping the ability to set certain values in the child's constructor? (see last commit)

Yes all these suggestions make sense to me. Who wants to rewrite? I can do it, just making sure we are not doing the same thing again :-)

Any idea on how to set the child's config to the config of the parent but also keeping the ability to set certain values in the child's constructor? (see last commit)

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 4, 2015

Owner

go for it, let me know if you need help with something.

i saw your latest commit before, it's definitely better than before, i thought about removing it but finally forgot. the config in the guigroup doesn't make much sense, i added only to do this and it's not even kept up to date internally. the only things i finally needed to set up were the layout and a flag to tell the created gui that it lives inside a container since some gui elements render slightly different depending if they are contained or not:

https://github.com/arturoc/openFrameworks/blob/refactor-gui/addons/ofxGui/src/ofxGuiGroup.h#L220

if you can add back those 2 flags in ofxBaseGui and set them to children in those methods in ofxGuiGroup i think that should be enough

Owner

arturoc commented Aug 4, 2015

go for it, let me know if you need help with something.

i saw your latest commit before, it's definitely better than before, i thought about removing it but finally forgot. the config in the guigroup doesn't make much sense, i added only to do this and it's not even kept up to date internally. the only things i finally needed to set up were the layout and a flag to tell the created gui that it lives inside a container since some gui elements render slightly different depending if they are contained or not:

https://github.com/arturoc/openFrameworks/blob/refactor-gui/addons/ofxGui/src/ofxGuiGroup.h#L220

if you can add back those 2 flags in ofxBaseGui and set them to children in those methods in ofxGuiGroup i think that should be enough

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 4, 2015

Do I have to do this:

ofxFpsPlotter::ofxFpsPlotter(const ofxValuePlotter::Config & c)

I should be able to just use Config & c or did you add the class for better readability?

Do I have to do this:

ofxFpsPlotter::ofxFpsPlotter(const ofxValuePlotter::Config & c)

I should be able to just use Config & c or did you add the class for better readability?

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 4, 2015

and while I am at this point - why did you remove the empty constructor and setup function of ofxValuePlotter? To force one to use a parameter with the plotted value? I like the idea of using only the parameter, I just ask if we shouldn't keep the other option. We have this approach:

//.h
ofParameter<float> value;
//.cpp setup
add<ofxValuePlotter>(value);
//.cpp update
value.set(0.5);

and this one:

//.h
ofxValuePlotter plotter;
//.cpp setup
add(plotter.setup());
//.cpp update
plotter.update(0.5)

You think we should remove the second one? I am fine with that, I just want to clarify.

and while I am at this point - why did you remove the empty constructor and setup function of ofxValuePlotter? To force one to use a parameter with the plotted value? I like the idea of using only the parameter, I just ask if we shouldn't keep the other option. We have this approach:

//.h
ofParameter<float> value;
//.cpp setup
add<ofxValuePlotter>(value);
//.cpp update
value.set(0.5);

and this one:

//.h
ofxValuePlotter plotter;
//.cpp setup
add(plotter.setup());
//.cpp update
plotter.update(0.5)

You think we should remove the second one? I am fine with that, I just want to clarify.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 4, 2015

Owner

i'm not 100% sure but i think we should deprecate the setup option and having gui elements directly in user code in favor of creating parameters and adding them to a gui group. i've kept the older setup methods so old code keeps working but though that for new elements we could just remove them from the beginning. On the other hand if this is going to be part of ofxGui it will be kind of not very uniform so not very sure.

if you already adapted the setup methods to return a reference let's leave them in by now

Owner

arturoc commented Aug 4, 2015

i'm not 100% sure but i think we should deprecate the setup option and having gui elements directly in user code in favor of creating parameters and adding them to a gui group. i've kept the older setup methods so old code keeps working but though that for new elements we could just remove them from the beginning. On the other hand if this is going to be part of ofxGui it will be kind of not very uniform so not very sure.

if you already adapted the setup methods to return a reference let's leave them in by now

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 4, 2015

Owner
ofxFpsPlotter::ofxFpsPlotter(const ofxValuePlotter::Config & c)

because i'm using the config struct from the parent class, thinking of it we could add a config struct in this one too even if it's empty just for uniformity sake

Owner

arturoc commented Aug 4, 2015

ofxFpsPlotter::ofxFpsPlotter(const ofxValuePlotter::Config & c)

because i'm using the config struct from the parent class, thinking of it we could add a config struct in this one too even if it's empty just for uniformity sake

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 4, 2015

Alright sorry. I didn't read the fps plotter constructor carefully.

I like the idea of making ofxGui solely parameter based. I would leave the setup functions in and mark them all deprecated. But what about buttons? Should the button-pressed-event also be changed to a parameter-changed-event? That's probably not the most intuitive way?

Alright sorry. I didn't read the fps plotter constructor carefully.

I like the idea of making ofxGui solely parameter based. I would leave the setup functions in and mark them all deprecated. But what about buttons? Should the button-pressed-event also be changed to a parameter-changed-event? That's probably not the most intuitive way?

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 5, 2015

Another question: Why don't the groups get configs and config constructors? Couldn't they also be used without a global variable or is the getControl-function going to be gone because it can be misused?

ofxGuiGroup::Config config;
config.alignment = OfxBaseGui::Horizontal;
add<ofxGuiGroup>("mygroup",config);
getControl("mygroup")->add(parameter1);
getControl("mygroup")->add(parameter2);
getControl("mygroup")->add(parameter3);

I am not completely happy with this because there is no check if the names are unique and there can be typos without the compiler noticing etc. but I like to be able to get rid of the gobal gui control variables. What do you think?

Another question: Why don't the groups get configs and config constructors? Couldn't they also be used without a global variable or is the getControl-function going to be gone because it can be misused?

ofxGuiGroup::Config config;
config.alignment = OfxBaseGui::Horizontal;
add<ofxGuiGroup>("mygroup",config);
getControl("mygroup")->add(parameter1);
getControl("mygroup")->add(parameter2);
getControl("mygroup")->add(parameter3);

I am not completely happy with this because there is no check if the names are unique and there can be typos without the compiler noticing etc. but I like to be able to get rid of the gobal gui control variables. What do you think?

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 6, 2015

Owner

yes i was doubting on groups because they are the only case where you probably want to use them after creation and i don't like the getControl() method much either. it's using pointers which i'm trying to avoid, it can fail without compiler warning as you say and in that case it'll return null and crash the program.

I'll give this a try at some point but let's leave them as they are by now. Having a config object though makes sense but keeping the setup methods so they can be initialized with the old style makes sense by now too.

In general i think the guidelines might be:

  • avoid pointers, the syntax is strange for beginners but also the ownership is never clear ( we could use shared_ptr though)
  • most controls don't need to be modified after initialization so the config object allows to pass any parameters from the beginning
  • make the syntax as easy to use as possible.
Owner

arturoc commented Aug 6, 2015

yes i was doubting on groups because they are the only case where you probably want to use them after creation and i don't like the getControl() method much either. it's using pointers which i'm trying to avoid, it can fail without compiler warning as you say and in that case it'll return null and crash the program.

I'll give this a try at some point but let's leave them as they are by now. Having a config object though makes sense but keeping the setup methods so they can be initialized with the old style makes sense by now too.

In general i think the guidelines might be:

  • avoid pointers, the syntax is strange for beginners but also the ownership is never clear ( we could use shared_ptr though)
  • most controls don't need to be modified after initialization so the config object allows to pass any parameters from the beginning
  • make the syntax as easy to use as possible.
@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 9, 2015

Yes, I keep that in mind.
One minor thing - why do we need the two generateText-functions with identical content in the slider class? What do we need the one with the unsigned char type for?

template<typename Type>
void ofxSlider<Type>::generateText()

template<>
void ofxSlider<unsigned char>::generateText()

Yes, I keep that in mind.
One minor thing - why do we need the two generateText-functions with identical content in the slider class? What do we need the one with the unsigned char type for?

template<typename Type>
void ofxSlider<Type>::generateText()

template<>
void ofxSlider<unsigned char>::generateText()
@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 10, 2015

Adapted to everything we discussed.

I just had to comment out that if you add a control to a group it gets the groups layout. This is too inconsistent at the moment. When the group has a horizontal layout, the sliders would be vertical, but their layout attribute would be horizontal. When you then want to change the sliders to be horizontal, you would need to set the layout variable to vertical. The other inconsistent thing is that all the other controls like the toggles don't change in a horizontal group. That's why I set all controls to horizontal and the groups to vertical by default and you have to change the controls of a group too if you want a different layout for now.

Adapted to everything we discussed.

I just had to comment out that if you add a control to a group it gets the groups layout. This is too inconsistent at the moment. When the group has a horizontal layout, the sliders would be vertical, but their layout attribute would be horizontal. When you then want to change the sliders to be horizontal, you would need to set the layout variable to vertical. The other inconsistent thing is that all the other controls like the toggles don't change in a horizontal group. That's why I set all controls to horizontal and the groups to vertical by default and you have to change the controls of a group too if you want a different layout for now.

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 10, 2015

I also removed ofxGuiGraphics and ofxGuiZoomableGraphics to keep it to parameter controlled interfaces.

I also removed ofxGuiGraphics and ofxGuiZoomableGraphics to keep it to parameter controlled interfaces.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 10, 2015

Owner

this:

template<typename Type>
void ofxSlider<Type>::generateText()

template<>
void ofxSlider<unsigned char>::generateText()

specializes the templated function to work different for char to be cast to int when passed through the << operator, otherwise they are printed as characters instead of numbers. you can see the problem if you remove that function and add a color slider which would print as strange characters instead of numbers.

I just had to comment out that if you add a control to a group it gets the groups layout.

yes i thought about that but didn't really tested it, makes total sense, even the size that would be passed to the children won't make sense. just passing the correct layout and setting the inContainer flag in children should be enough.

I also removed ofxGuiGraphics and ofxGuiZoomableGraphics to keep it to parameter controlled interfaces.

ok perfect. i'm not sure that all the guis should have a parameter, something like a spacer won't have mouse interaction or a parameter but it's still a gui element, we might want to refactor the base class into 2 or 3 abstract classes at some point but lets leave it as it is by now. i'm not sure about the utility of ofxGuiGraphics any way so better to keep them out by now

thanks for all the work on this!!

Owner

arturoc commented Aug 10, 2015

this:

template<typename Type>
void ofxSlider<Type>::generateText()

template<>
void ofxSlider<unsigned char>::generateText()

specializes the templated function to work different for char to be cast to int when passed through the << operator, otherwise they are printed as characters instead of numbers. you can see the problem if you remove that function and add a color slider which would print as strange characters instead of numbers.

I just had to comment out that if you add a control to a group it gets the groups layout.

yes i thought about that but didn't really tested it, makes total sense, even the size that would be passed to the children won't make sense. just passing the correct layout and setting the inContainer flag in children should be enough.

I also removed ofxGuiGraphics and ofxGuiZoomableGraphics to keep it to parameter controlled interfaces.

ok perfect. i'm not sure that all the guis should have a parameter, something like a spacer won't have mouse interaction or a parameter but it's still a gui element, we might want to refactor the base class into 2 or 3 abstract classes at some point but lets leave it as it is by now. i'm not sure about the utility of ofxGuiGraphics any way so better to keep them out by now

thanks for all the work on this!!

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 10, 2015

What you described about the color slider labels and the ofxSlider<unsigned char>::generateText() function is happening right now (the strange chars) even though I have both methods in ofxSlider.cpp. Do you have an idea what else I could have done that leads to this error?

I use something like the ofxGuiGraphics class a lot. I have an ofFbo that is created in multiple steps using multiple other ofFbos that I can modify and I need ofxGuiGraphics to show the intermediate steps within the gui (like in this screenshot I posted in the forum). It could also be used for example to show the camera input as a (zoomable) preview object in the gui. But I am completely fine with keeping them in ofxGuiExtended.

What you described about the color slider labels and the ofxSlider<unsigned char>::generateText() function is happening right now (the strange chars) even though I have both methods in ofxSlider.cpp. Do you have an idea what else I could have done that leads to this error?

I use something like the ofxGuiGraphics class a lot. I have an ofFbo that is created in multiple steps using multiple other ofFbos that I can modify and I need ofxGuiGraphics to show the intermediate steps within the gui (like in this screenshot I posted in the forum). It could also be used for example to show the camera input as a (zoomable) preview object in the gui. But I am completely fine with keeping them in ofxGuiExtended.

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 10, 2015

I got a problem: I want to update my ofxSortableList (https://github.com/frauzufall/ofxSortableList) to the new style. I can't, because I can't swap elements within collection of ofxGuiGroup. Can we add this? It's not completely trivial because one also has to swap the parameter in the parameter group and this is also not implemented.

I got a problem: I want to update my ofxSortableList (https://github.com/frauzufall/ofxSortableList) to the new style. I can't, because I can't swap elements within collection of ofxGuiGroup. Can we add this? It's not completely trivial because one also has to swap the parameter in the parameter group and this is also not implemented.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 10, 2015

Owner

didn't saw that before, it's really nice! :)

i guess we can add methods to ofParameterGroup that allow to do that, another option is to just recreate the full parameter group with the new order which shouldn't be a problem in terms of performace since it's something that won't happen that often.

Owner

arturoc commented Aug 10, 2015

didn't saw that before, it's really nice! :)

i guess we can add methods to ofParameterGroup that allow to do that, another option is to just recreate the full parameter group with the new order which shouldn't be a problem in terms of performace since it's something that won't happen that often.

frauzufall added a commit to frauzufall/ofxSortableList that referenced this pull request Aug 11, 2015

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 11, 2015

That worked well, thank you! I was able to update ofxSortableList without changing ofxGui.

The bug with the strange characters when using ofxColorSlider remains..

Another thing that seems unreasonable is that a button with a listener calls the listener function when it is added to a group.

That worked well, thank you! I was able to update ofxSortableList without changing ofxGui.

The bug with the strange characters when using ofxColorSlider remains..

Another thing that seems unreasonable is that a button with a listener calls the listener function when it is added to a group.

frauzufall added a commit to frauzufall/ofx2DMapping that referenced this pull request Aug 12, 2015

@frauzufall

This comment has been minimized.

Show comment
Hide comment
@frauzufall

frauzufall Aug 19, 2015

I fixed the color slider char bug (it was actually already fixed in your refactor-gui branch) and the parameters that got triggered when added to the gui were my fault (I added the listener before adding them to the gui).

Some small changes:

  • ofxLabel is now a derivative from ofxValueLabel that is able to display other ofParameter values besides string. ofxLabel can be used the same way as before. To display other data types, use ofxValueLabel<Type> or ofxIntLabel, ofxFloatLabel or ofxBoolLabel.
  • ofxSlider has a precision option (not applied to the value, only to the displayed value)
  • I wanted to update to the current master and now I have all these unrelated commits in this PR -.-

You are probably busy with 0.9 so I will just post this branch to the forum to get some testing done. I am also using this branch to refactor my apps so I already use it a lot.

I also want to add the feature to disable controls, apply its own font size to a control (right now font changes affect all controls?) and think about the feature to control sliders with arrow keys or direct input as suggested in the forum.

I fixed the color slider char bug (it was actually already fixed in your refactor-gui branch) and the parameters that got triggered when added to the gui were my fault (I added the listener before adding them to the gui).

Some small changes:

  • ofxLabel is now a derivative from ofxValueLabel that is able to display other ofParameter values besides string. ofxLabel can be used the same way as before. To display other data types, use ofxValueLabel<Type> or ofxIntLabel, ofxFloatLabel or ofxBoolLabel.
  • ofxSlider has a precision option (not applied to the value, only to the displayed value)
  • I wanted to update to the current master and now I have all these unrelated commits in this PR -.-

You are probably busy with 0.9 so I will just post this branch to the forum to get some testing done. I am also using this branch to refactor my apps so I already use it a lot.

I also want to add the feature to disable controls, apply its own font size to a control (right now font changes affect all controls?) and think about the feature to control sliders with arrow keys or direct input as suggested in the forum.

@arturoc

This comment has been minimized.

Show comment
Hide comment
@arturoc

arturoc Aug 19, 2015

Owner

that spunds great, yes i've been crazy busy with a project and 0.9 but will take a look as soon as i have a moment

Owner

arturoc commented Aug 19, 2015

that spunds great, yes i've been crazy busy with a project and 0.9 but will take a look as soon as i have a moment

arturoc and others added some commits Feb 3, 2016

ofEvent now supports adding std::function as a listener, that allows
among other things:

- pass a lambda function as a listener
- pass a function with a different signature as a listener.

For example to pass a lambda as a listener now you can do:

```cpp
ofEvents().mouseMoved.newListener([](ofMouseEventArgs & mouse){
	cout << mouse << endl;
});
```

Since std::function doesn't have an equality operator, there's no way to
unregister an event the old way calling `ofRemoveListener(function)` since
that required to compare the passed function with every other registered in
the event and remove it if it was the same.

`ofRemoveListener`also has some other problems, for example, the typical pattern:

```cpp
class MyClass{
public:
    MyClass(){
         ofAddListener(ofEvents().mouseMoved,this,&MyClass::mouseMoved);
    }

    ~MyClass(){
         ofRemoveListener(ofEvents().mouseMoved,this,&MyClass::mouseMoved);
    }

    void mouseMoved(ofMouseMoved & mouse){
    ....
    }
}
```

Has a problem with copy construction:

```
MyClass obj;
vector<MyClass> objs;
objs.push_back(obj);
```

Won't be registered as listener and there won't be any compiler error.
Because of the [rule of three](https://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29)
Any class that adds a listener in it's constructor and unregisters
in it's destructor. Needs also a copy constructor, operator=, and in
c++11 to be completely correct also a move constructor and an operator=
with move parameter.

With the new way of registering listeners one does:

```cpp
class MyClass{
    ofEventListener mouseMovedListener;
public:
    MyClass(){
         mouseMovedListener = ofEvents().mouseMoved.newListener(this,&MyClass::mouseMoved);
    }

    void mouseMoved(ofMouseMoved & mouse){
    ....
    }
}
```

The ofEventListener class unregisters the event automatically when it goes out
of scope avoiding the need for a destructor and because of that avoiding the
need for copy constructor...

Also since the class is not copyable if someone tries to copy an instance
of a class that contains an ofEventListener the compiler will give an error.

In any case the old method still works.
Merge pull request #4775 from arturoc/feature-ofto
templated ofTo that converts string to anything that implements >>
fix warning in ofTrueTypeFont
since glyphPositions are `emplaced` back, visual studio (and possibly
other compilers) warn bitterly about implicit type conversion.

this pr makes the conversion explicit to end the whining.

Since we're storing the glyph position in an ofVec2f and we don't have
an integer vector type there's no way not to have a type conversion at
some point.
Merge pull request #4777 from arturoc/feature-testsgdb
tests: run under gdb in osx and linux to catch possible segfaults
Merge pull request #4774 from arturoc/feature-lambdaevents
std::function listeners for ofEvent + unregister token. Replaces #4392
add newListener method to ofParameter
if you want to use an ofEventListener to respond to an ofEvent, you have
to create one using a templated factory method which is part of
ofEvent<T>.

Since ofParameter shields users from accessing its data directly by
holding it inside a private data `obj`, there is no way to call the
`newListener` factory method on a parameter changed event which you want
to observe.

This PR proposes to add a `newListener` method to `ofParameter`, which
will, based on dark templating magick, forward any of its parameters to
the `ofEvent` object held by the private `ofParameter::obj`.

I wish there was a simpler way, but this seems to me the best way to
observe an ofParameter and responding to any changes using a lambda.

Minimal testcase:
<https://gist.github.com/tgfrerer/f9fc6e3b2ebe88633ab5>
Merge pull request #4784 from tgfrerer/feature-ofParam-newListener
add newListener() method to ofParameter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment