Handling callbacks

In part 2 of this tutorial, you have seen how to create a login screen. It all looks fine but there is one important thing missing: the callbacks.

You will need to find out when the user clicked on the login button. This is what you will learn in this part of the tutorial. Note that this page only gives a short intro on how to handle callbacks, polling is not the only way.

At the bottom of the page you will find the full code for the working login screen.

The easiest way to handle callback is to poll them from the window. This is very similar to the pollEvent function from sfml.
The other ways to handle callbacks are discussed in the callback tutorial.

tgui::Callback callback;
while (gui.pollCallback(callback))
{
}

By default, widgets will not send any callback. You will have to explicitly ask the widget to send you callback. You do this with the bindCallback function. Because we get all callback in one place when polling it from the window, you will also have to set an id. This id is part of the callback so that you can distinguish the widgets from each other when receiving callbacks.

button->bindCallback(tgui::Button::LeftMouseClicked);
button->setCallbackId(1);

Now that the button is sending callbacks, it is time to receive them.
First we will check if the id is 1 to make sure that the event comes from the button.
Then we get the username and password that were filled in inside the edit boxes. As the pointers are not accessible in this scope, we will use the get function to get the pointers back.

tgui::Callback callback;
while (gui.pollCallback(callback))
{
    if (callback.id == 1)
    {
        tgui::EditBox::Ptr editBoxUsername = gui.get("Username");
        tgui::EditBox::Ptr editBoxPassword = gui.get("Password");

        sf::String username = editBoxUsername->getText();
        sf::String password = editBoxPassword->getText();
    }
}

Here is the full code of the introduction tutorial.

#include <TGUI/TGUI.hpp>

void loadWidgets( tgui::Gui& gui )
{
    // Create the background image
    tgui::Picture::Ptr picture(gui);
    picture->load("myBackgroundImage.png");
    picture->setSize(800, 600);

    // Create the username label
    tgui::Label::Ptr labelUsername(gui);
    labelUsername->setText("Username:");
    labelUsername->setPosition(200, 100);

    // Create the password label
    tgui::Label::Ptr labelPassword(gui);
    labelPassword->setText("Password:");
    labelPassword->setPosition(200, 250);

    // Create the username edit box
    tgui::EditBox::Ptr editBoxUsername(gui, "Username");
    editBoxUsername->load("TGUI/widgets/Black.conf");
    editBoxUsername->setSize(400, 40);
    editBoxUsername->setPosition(200, 140);

    // Create the password edit box (we will copy the previously created edit box)
    tgui::EditBox::Ptr editBoxPassword = gui.copy(editBoxUsername, "Password");
    editBoxPassword->setPosition(200, 290);
    editBoxPassword->setPasswordCharacter('*');

    // Create the login button
    tgui::Button::Ptr button(gui);
    button->load("TGUI/widgets/Black.conf");
    button->setSize(260, 60);
    button->setPosition(270, 440);
    button->setText("Login");
    button->bindCallback(tgui::Button::LeftMouseClicked);
    button->setCallbackId(1);
}

int main()
{
    // Create the window
    sf::RenderWindow window(sf::VideoMode(800, 600), "Window");
    tgui::Gui gui(window);

    // Load the font (you should check the return value to make sure that it is loaded)
    gui.setGlobalFont("TGUI/fonts/DejaVuSans.ttf");

    // Load the widgets
    loadWidgets(gui);

    // Main loop
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            // Pass the event to all the widgets
            gui.handleEvent(event);
        }

        // The callback loop
        tgui::Callback callback;
        while (gui.pollCallback(callback))
        {
            // Make sure tha callback comes from the button
            if (callback.id == 1)
            {
                // Get the username and password
                tgui::EditBox::Ptr editBoxUsername = gui.get("Username");
                tgui::EditBox::Ptr editBoxPassword = gui.get("Password");

                sf::String username = editBoxUsername->getText();
                sf::String password = editBoxPassword->getText();

                // Continue here by checking if the username and password are correct ...
            }
        }

        window.clear();

        // Draw all created widgets
        gui.draw();

        window.display();
    }

    return EXIT_SUCCESS;
}

There is still one very important thing that you should take into account: errors.
In the above code, there is no error checking. If you write a program then you will probably want to add error checking to the following places:

Previous: Working with widgets