Simple button listener handler


#1

A simple handler for buttons. Similar constructs can be done for all other Listeners, and it can be wrapped together with templates. That is left as an exercise for the reader :)  (code below needs C++11 compliant compiler):

#include <map>
#include <functional>
class ButtonListenerHandler : public Button::Listener
{
public:
    typedef std::function< void(void) > TButtonClickedHandler;
  
    void setHandler(Button* button, TButtonClickedHandler handler)
    {
        button->addListener(this);
        m_map[button] = handler;
    }
    
    void buttonClicked(Button* buttonThatWasClicked)
    {
        auto it = m_map.find(buttonThatWasClicked);
        if (it != m_map.end())
        {
            (it->second)();
        }
    }
    
private:
    typedef std::map<Button*, TButtonClickedHandler> TButtonClickedMap;
    TButtonClickedMap m_map;
};
// Usage
class MyComponentWithButtonsOnIt : public Component, public ButtonListenerHandler
{
public:
   MyComponentWithButtonsOnIt();    
private:
   void firstButtonClicked() { ... }
   void secondButtonClicked() { ... }
   void togglingButtonClicked1();
   void togglingButtonClicked2();
   
   ScopedPointer<Button> m_firstButton;
   ScopedPointer<Button> m_secondButton;
   ScopedPointer<Button> m_togglingButton;
};
// Setup the handler functions in the constructor
MyComponentWithButtonsOnIt::MyComponentWithButtonsOnIt()
{
...
   setHandler(m_firstButton, std::bind(&MyComponentWithButtonsOnIt::firstButtonClicked,this));
   setHandler(m_secondButton, std::bind(&MyComponentWithButtonsOnIt::secondButtonClicked,this));
   
   // This button will alternate between two handlers, not so easy to do with if/else if/else if construct
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked1,this));
}
void MyComponentWithButtonsOnIt::togglingButtonClicked1()
{
   // Set new handler for the toggling button
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked2,this));
}
void MyComponentWithButtonsOnIt::togglingButtonClicked2()
{
   // Set new handler for the toggling button
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked1,this));
}


#2

That's a useful little class. Thanks!

But I think you need to add the line:

     button->addListener(this);

to the setHandler() function. Also, you need to put a return type on setHandler(), such as void.

 


#3

Can we do something about these old threads and how the & signs and <> signs show up in the code statements as &amp; and &lt; &gt; ? I’ve cleaned up the OP here, which helps everyone:

#include <map>
#include <functional>
class ButtonListenerHandler : public Button::Listener
{
public:
    typedef std::function< void(void) > TButtonClickedHandler;
  
    void setHandler(Button* button, TButtonClickedHandler handler)
    {
        button->addListener(this);
        m_map[button] = handler;
    }
    
    void buttonClicked(Button* buttonThatWasClicked)
    {
        auto it = m_map.find(buttonThatWasClicked);
        if (it != m_map.end())
        {
            (it->second)();
        }
    }
    
private:
    typedef std::map<Button*, TButtonClickedHandler> TButtonClickedMap;
    TButtonClickedMap m_map;
};
// Usage
class MyComponentWithButtonsOnIt : public Component, public ButtonListenerHandler
{
public:
   MyComponentWithButtonsOnIt();    
private:
   void firstButtonClicked() { ... }
   void secondButtonClicked() { ... }
   void togglingButtonClicked1();
   void togglingButtonClicked2();
   
   ScopedPointer<Button> m_firstButton;
   ScopedPointer<Button> m_secondButton;
   ScopedPointer<Button> m_togglingButton;
};
// Setup the handler functions in the constructor
MyComponentWithButtonsOnIt::MyComponentWithButtonsOnIt()
{
...
   setHandler(m_firstButton, std::bind(&MyComponentWithButtonsOnIt::firstButtonClicked,this));
   setHandler(m_secondButton, std::bind(&MyComponentWithButtonsOnIt::secondButtonClicked,this));
   
   // This button will alternate between two handlers, not so easy to do with if/else if/else if construct
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked1,this));
}
void MyComponentWithButtonsOnIt::togglingButtonClicked1()
{
   // Set new handler for the toggling button
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked2,this));
}
void MyComponentWithButtonsOnIt::togglingButtonClicked2()
{
   // Set new handler for the toggling button
   setHandler(m_togglingButton, std::bind(&MyComponentWithButtonsOnIt::togglingButtonClicked1,this));
}