# How to implement SDL Button/Menu GUI with callbacks?

I have been reading Bjarne Stroustrup's Programming Principles and Practice Using C++ for a while now and am nearing the end of the book. I have to tried to make a very simple game using the SDL libraries as a little exercise to practice programming and utilize techniques from the book.

I've attempted to implement a rather crude GUI system that sort of resembles the one described in the book. The problem that I am having is implementing a callback system so that when a button is constructed it takes a member function as an argument so that it can be called when the button pressed. The reason why it needs to be a member function is that the game has a state system very similar to this http://gamedevgeek.com/tutorials/managing-game-states-in-c/ since I followed the tutorial when crafting my own game state system.

The existing code looks like this:

class Button : public Widget {
private:
SDL_Surface* m_image;
SDL_Rect* m_clip;
bool m_pressed;
bool m_released;
int frame;
public:
Button(int x, int y, int w, int h, SDL_Surface* img, SDL_Rect* clip);
void handle_events(SDL_Event& event);
void show(SDL_Surface* screen, GameState* state);
bool released();
};

Button::Button(int x, int y, int w, int h, SDL_Surface* img, SDL_Rect* clip)
:Widget(x,y,w,h),
m_image(img),
m_pressed(0),
m_released(0),
m_clip(clip),
frame(0)
{
}


So my question is: How do you pass a function in the constructor and call it when the button is pressed? (Like a callback). Currently each state, for example a Menu state, will just look if a button is pressed and perform a corresponding task which is pretty bad and hardly readable.

Stroustrup's code for the GUI system in the PPP book can be found here: http://www.stroustrup.com/Programming/Graphics/ in the two GUI files.

If you want simple callbacks, you can just use normal C function pointers. You can see here a small tutorial on them: http://www.learncpp.com/cpp-tutorial/78-function-pointers/

So, in your case you'd add a parameter like void (*clickedCallback)() in the ctor of the Button. Then, when it is clicked you'd call the function your saved before: m_clickedCallback();

Optionally, you might want to send the button which called the callback as argument. The definition/calling will become:

void (*m_clickedCallback)(const Button&);
// ...
m_clickedCallback(*this);


LE: On a second read, it seems you might want a member function (not a simple one). That is slightly more complicated, because you'd have to pass the object instance around when you want to call its method. More info on this topic you can find on Parashift's superb website: http://www.parashift.com/c++-faq/pointers-to-members.html.

Basically you'd need some sort of wrapper/struct that holds both the function to a member (similarly to the C one, but with the class specified) and the member instance where to call the callback function on.

• ahh yes, I finally got it to work the problem was that I naively forgot that the member function to be called, needed to be static. I was sure I had tried that, but anyway it works now, thank you. – BeanBag May 29 '13 at 5:42

The more modern way of doing it is by using delegates or functors.

C++11 has them built in: http://en.cppreference.com/w/cpp/utility/functional/function They're also a part of Boost if you're using an older compiler: http://www.boost.org/doc/libs/1_53_0/doc/html/function.html

Or if you want something a little more streamlined you can use something like FastDelegate: http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible