0
votes

I seem to be having a bit of trouble when managing multiple windows in SFML C++. When I try to manage multiple windows, they both open correctly and I can interact in the larger one, however, the smaller one, which upon creation is overlapping the larger window, I can not interact with until I move the large window away. An image is below to help with the visual. Also below is the main loop for my code.

To help the visual, "SFML - F1 Menu" is the window not responding to interaction.

The main loop of the code is as follows:

while (MainWin.isOpen() || F1Menu.isOpen())
{
    sf::Event Event;
    if (MainWin.pollEvent(Event))
    {
        switch (Event.type)
        {
            case sf::Event::Closed:
                MainWin.close();
                if (F1Menu.isOpen())
                    F1Menu.close();
            break;

            case sf::Event::Resized:
                MainView.reset(sf::FloatRect(0.f, 0.f, (MainWin.getSize().x*0.9f), (MainWin.getSize().y*0.9)));
                MainWin.setView(MainView);
            break;

            case sf::Event::KeyPressed:
                if (Event.key.code == sf::Keyboard::F1)
                    F1Menu.create(sf::VideoMode(200, 500), "SFML 2D - F1 Menu");
                else if (Event.key.code == sf::Keyboard::Escape)
                {
                    MainWin.close();
                    if (F1Menu.isOpen())
                        F1Menu.close();
                }
            break;
        }
    }

    if (F1Menu.pollEvent(Event))
    {
        switch (Event.type)
        {
            case sf::Event::Closed:
                F1Menu.close();
            break;

            case sf::Event::MouseButtonReleased:
                if (Event.mouseButton.button == sf::Mouse::Left)
                    if (LMButton.mouseIn(F1Menu))
                        LoadMap("MapA.dat");
            break;

            case sf::Event::MouseMoved:
                if (LMButton.mouseIn(F1Menu))
                    LMButton.setColor(sf::Color::Yellow);
                else
                    LMButton.setColor(sf::Color::White);
            break;
        }
    }

    moveClock.restart();
    if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        player.move(0, -4 * time);
        player.setDirection(sfm::Direction::Up);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        player.move(0, 4 * time);
        player.setDirection(sfm::Direction::Down);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        player.move(-4 * time, 0);
        player.setDirection(sfm::Direction::Left);
    }

    else if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        player.move(4 * time, 0);
        player.setDirection(sfm::Direction::Right);
    }

    if (F1Menu.isOpen())
    {
        F1Menu.clear();
        F1Menu.draw(LMButton);
        F1Menu.display();
    }

    if (MainWin.isOpen())
    {
        MainWin.clear();
        if (SplashScreen.didAnimate)
            SplashScreen.Animate(MainWin, sfg::Animation::FadeIn);
        if (inMenu)
        {

        }
        if (isPlaying)
        {
            DrawMap(MainWin);
            MainWin.draw(player);
        }
        MainWin.display();
    }
}
1
are you creating your second window inside an event? that's usually a pretty bad idea, as you don't want to be calling tons of create calls for F1 EDIT: I see you're using if as opposed to the common practice of using a while to poll events. Is there a reason for this? This could be giving you some trouble later on - Syntactic Fructose
I will be adding a check for the F1 Menu, if it is already open, do not open it again, or instead close it. There is no specific reason for the if, I can change it to while. Do you have any ideas on the presented problem though? - Reborn
Your event checking is fundamentally flawed to begin with. There can be multiple events per polling, using a while would allow you to pop off the top of the stack and continue to handle all events. You should fix your code and see if your problem is solved. Note that you should not be creating a window inside an event loop because you cannot guarante it will be called only once(unless you just nest it inside an if to check if window has not already been created) - Syntactic Fructose
Problem still exists. And nesting the window creation in an if was the idea all along - Reborn

1 Answers

1
votes

In my knowledge, you aren't able to poll two separate windows with one sf::Event object. this is because when polling events, you are essentially popping off of the event stack and handling each one. The signature of pollEvent is

bool pollEvent(sf::Event &event);

note that there is no const qualifier here, because each processed event gets popped off the event stack. By the time you finish polling your main window there are no events left for your other window. This could be the cause of your window being unable to focus. Your second window should use it's own separate sf::Event

On a side note I would highly recommend encapsulating your data inside classes. You can find a great reference here on how to go about doing so. It's great coding practice and helps minimize confusion when bug hunting