Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: wxWidgets-SFML-integration with lambda expressions  (Read 5394 times)

0 Members and 1 Guest are viewing this topic.

Omega

  • Newbie
  • *
  • Posts: 29
    • View Profile
wxWidgets-SFML-integration with lambda expressions
« on: December 21, 2013, 09:18:21 pm »
I recently discovered the power of lambda expressions and how they can be utilized with wxWidgets (http://wxwidgets.blogspot.com/2013/08/wxwidgets-and-c-11.html). I can't begin to explain the versatility of lambda expressions as well as some people have (http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11), but using them can greatly simplify the coding process as I hope to demonstrate with my take on the wxWidgets/SFML tutorial (http://sfml-dev.org/tutorials/1.6/graphics-wxwidgets.php).

In this sample, I have demonstrated using the Bind() method to handle events that use lambda functions as callbacks. I have also demonstrated that a parent's Bind() method handling one event may be "overriden" in a child's Bind() method; finally, I have demonstrated that a child's "overriden" Bind() may Skip() back to the parent's Bind() handling to take advantage of its implementation.

Comments, critique, and discussion is welcome.

wxIMPLEMENT_APP_CONSOLE(MyApp);

class wxsfControl
        : public wxControl
        , public sf::RenderWindow
{
public:
        wxsfControl(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0L)
                : wxControl (parent, id, pos, size, style) // initialize wxControl first...
                , sf::RenderWindow (this->GetHandle()) // ...before initializing sf::RenderWindow with wxControl::GetHandle()
                , _color (sf::Color::Black)
        {
                // handle idle event, aka OnIdle()
                Bind(wxEVT_IDLE, [=](wxIdleEvent&) {
                        Refresh(); // wxWindow::Refresh()
                } );

                // handle paint event, aka OnPaint()
                Bind(wxEVT_PAINT, [=](wxPaintEvent&) {
                        wxPaintDC dc(this);
                        update(); // wxsfControl::update()
                        display(); // sf::RenderWindow::display()
                } );

                // handle erase background event, aka OnEraseBackground()
                Bind(wxEVT_ERASE_BACKGROUND, [=](wxEraseEvent&) {
                        // catch erase event to prevent flickering but do nothing or do something particular that needs to be done at this event
                } );

                // handle enter window event, aka OnEnterWindow()
                Bind(wxEVT_ENTER_WINDOW, [=](wxMouseEvent&) {
                        std::cout << "wxsfControl handled mouse event: enter window." << std::endl;
                } );

                // handle leave window event, aka OnLeaveWindow()
                Bind(wxEVT_LEAVE_WINDOW, [=](wxMouseEvent&) {
                        std::cout << "wxsfControl handled mouse event: leave window." << std::endl;
                } );

                // handle mouse motion event, aka OnMouseMotion()
                Bind(wxEVT_MOTION, [=](wxMouseEvent& e) {
                        wxPoint mouse = e.GetPosition();
                        std::cout << "wxsfControl handled mouse event: motion (x: " << mouse.x << " , y: " << mouse.y << ")." << std::endl;
                } );

                // handle mouse left down, aka OnLeftDown()
                Bind(wxEVT_LEFT_DOWN, [=](wxMouseEvent&) {
                        _color = sf::Color::Red;
                        std::cout << "wxsfControl handled mouse event: left down." << std::endl;
                } );

                // handle mouse right down, aka OnRightDown()
                Bind(wxEVT_RIGHT_DOWN, [=](wxMouseEvent&) {
                        _color = sf::Color::Blue;
                        std::cout << "wxsfControl handled mouse event: right down." << std::endl;
                } );
               
                std::cout << "wxsfControl constructed..." << std::endl;
        }
        ~wxsfControl() { std::cout << "...wxsfControl destructed." << std::endl; }
protected:
private:
        virtual void update() { clear(_color); }
        sf::Color _color;
};

class MyControl
        : public wxsfControl
{
public:
        MyControl(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0L)
                : wxsfControl(parent, id, pos, size, style)
        {
                // handle mouse left down, similar to overriding a virtual method, such as OnLeftDown()
                Bind(wxEVT_LEFT_DOWN, [=](wxMouseEvent& e) {
                        std::cout << "MyControl handled mouse event: left down." << std::endl;
                        e.Skip(); // give parent class, wxsfControl, a chance to handle this overriden event
                } );
        }
protected:
private:
        // override virtual wxsfControl::update() with special implementation here
};
 

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #1 on: December 22, 2013, 12:32:15 pm »
It's interesting that a rather ancient API like wxWidgets is compatible with lambda expressions... :)
But it seems like they've modernized it quite a bit meanwhile.

You could consider adding the code to the SFML Wiki.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #2 on: December 22, 2013, 04:43:39 pm »
Well, it's all ok for Windows. But can you try it with wxWidgets3.0, GTK3+ and modern kernel? I was not able get it to work properly. But i also used XInitThreads...  :-\ May be that was my problem...

Omega

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #3 on: December 23, 2013, 02:00:55 am »
Well, it's all ok for Windows. But can you try it with wxWidgets3.0, GTK3+ and modern kernel? I was not able get it to work properly. But i also used XInitThreads...  :-\ May be that was my problem...

Does your compiler support C++11? For instance, I use Visual Studio Express 2010 and it only supports some of the C++11 features which supports lambda expressions but not for-range expressions.

This example is used with wxWidgets3.0 and SFML2.0.
« Last Edit: December 23, 2013, 02:24:27 am by Omega »

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #4 on: December 23, 2013, 04:56:50 pm »
Yes, i use C++11 in my programs.  But i'm talking not about your code, but about my little problem. =) Mixing wxWidgets with SFML is working fine in Windows. It does not work properly in Linux. It runs, but SFML window does not generates events. I'm looking for someone who also works with this under Linux. =) My game editor is based on wxWidgets, and now i use it only in Windows. Solution of this problem will save my time a little.

Omega

  • Newbie
  • *
  • Posts: 29
    • View Profile
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #5 on: December 24, 2013, 03:46:08 am »
From what I've read, if you're integrating wxWidgets with SFML, you need to let wxWidgets handle the events because of this specific conflict with event handling. From my understanding, wxWidgets is a framework and SFML is simply a library, so it's best to let the framework do the event handling to avoid this particular conflict. For all intents and purposes, both the events are the same, so you might as well handle them with the framework (wxWidgets) and just notify the integrated libraries (SFML) of the event.

If there is a solution to have both wxWidgets AND SFML handle their own events independently and at the same time, I'd like to know about it myself, but it seems unnecessary.

ChronicRat

  • Sr. Member
  • ****
  • Posts: 327
  • C++ programmer
    • View Profile
    • My blog
Re: wxWidgets-SFML-integration with lambda expressions
« Reply #6 on: December 26, 2013, 11:18:57 am »
Yes, i'd made wrapper for Linux version already. But i don't like such solution of the problem. Because of my engine's internal event routines based on SFML event system. Well, this task is not a blocker, so i will solve it later.