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

Author Topic: [Solved] sf::Event in Button class  (Read 3477 times)

0 Members and 1 Guest are viewing this topic.

Kanoha

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
[Solved] sf::Event in Button class
« on: August 03, 2016, 08:42:33 pm »
Hi,
I have made a class Button and inside I've placed a bool Button::isClicked(). With this code it worked fine:

bool Button::isClicked()
{
    sf::Event event;

    sf::Vector2f mousePosition = static_cast<sf::Vector2f>(sf::Mouse::getPosition());

    if(this->getGlobalBounds().contains(mousePosition)
    && sf::Mouse::isButtonPressed(sf::Mouse::Left)) //if clicked
    {
        return true;
    }
    else
    {
        return false;
    }
}

But I couldn't place other buttons on the same place on an "other window" (I did a thing like this:)

if(status == "MENU")
                  {
                        ...

                        window.clear();
                        window.draw(...);
                   }
                   if(status == "GAME")
                  {
                          ...

                        window.clear();
                        window.draw(...);
                   }
                   

So I tried to do something like that:

bool Button::isClicked()
{
    sf::Event event;

    sf::Vector2f mousePosition = static_cast<sf::Vector2f>(sf::Mouse::getPosition());

    if(this->getGlobalBounds().contains(mousePosition)
    && event.type == sf::Event::MouseButtonReleased
    && event.mouseButton.button == sf::Mouse::Left) //if clicked
    {
        return true;
    }
    else
    {
        return false;
    }
}

but it doesn't work. The program runs fine (I have no errors) but I can't press the buttons. So I tried to put that code in the main.cpp for see if it is the fault of the event that could be written with a wrong syntax:

while(window.isOpen())
                 {

                  ...

                sf::Vector2f mousePosition = static_cast<sf::Vector2f>(sf::Mouse::getPosition());

                 if(button.getGlobalBounds().contains(mousePosition)
                 && event.type == sf::Event::MouseButtonReleased
                 && event.mouseButton.button == sf::Mouse::Left) //if clicked
                 {
                       //Do something
                 }

                   }

   Instread of:

while(window.isOpen())
                 {

                  ...

                 if(button.isClicked()) //if clicked
                 {
                       //Do something
                 }

                   }

And that works. Any ideas?
« Last Edit: August 04, 2016, 12:30:52 pm by Kanoha »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::Event in Button class
« Reply #1 on: August 03, 2016, 09:02:27 pm »
You might get more expected results using sf::Mouse::getPosition(window) as the version without specifying a window is the global position (on the desktop).

However, you're using events.

If an event is a mouse event, it has the mouse position stored in the event e.g. if the event is a mouse button press, the position would be available via event.mouseButton.x and event.mouseButton.y.

The one thing you're missing here, though, is actually filling that event with any information. You will need window.pollEvent(event) to see if there are any events. If there aren't, don't use that event. i.e. only use it if window.pollEvent returns true.

You may find this SFML tutorial on events helpful.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Kanoha

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
Re: sf::Event in Button class
« Reply #2 on: August 03, 2016, 09:25:07 pm »
You might get more expected results using sf::Mouse::getPosition(window) as the version without specifying a window is the global position (on the desktop).
My RenderWindow is in fullscreen.
The one thing you're missing here, though, is actually filling that event with any information. You will need window.pollEvent(event) to see if there are any events. If there aren't, don't use that event. i.e. only use it if window.pollEvent returns true.
But if I can't use events in a class, how do I do to make something like I wanted to do (a click that isn't repetitive) ?

Thanks for your replies.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::Event in Button class
« Reply #3 on: August 03, 2016, 09:37:59 pm »
Even if your window is fullscreen, it isn't guaranteed to be at (0, 0). The user may have a second display on the left or above the first display, which is the display that would be used for the full-screen, whereas the second display would be the far left/top of the desktop so would have the zero co-ordinate. Passing the window to getPosition solves all of this  ;)

If you can't use events and you want something to only happen when things change, you'll need to track their states. e.g. store if the left mouse button is pressed and if sf::Mouse::isButtonPressed(sf::Mouse::Left) doesn't match your stored state, consider it an event. Which one would depend on which states they are.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Kanoha

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
Re: sf::Event in Button class
« Reply #4 on: August 03, 2016, 11:36:59 pm »
But it doesn't exist an "isButtonReleased()" boolean in sf::Mouse... How could I try to make something like that?

Kanoha

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
Re: sf::Event in Button class
« Reply #5 on: August 04, 2016, 12:16:47 pm »
I finally have resolved my problem. Instead of:

bool Button::isClicked(sf::RenderWindow& window)
{
    sf::Vector2f mousePosition = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));

sf::Event event;

    if(this->getGlobalBounds().contains(mousePosition)
    && event.type == sf::Event::MouseButtonReleased
    && event.mouseButton.button == sf::Mouse::Left) //if clicked
    {
        return true;
    }
    else
    {
        return false;
    }
}

I did add an argument after "sf::RenderWindow& window" that askes the copy of the "main event". So the class finally looks like this:

bool Button::isClicked(sf::RenderWindow& window, sf::Event& event)
{
    sf::Vector2f mousePosition = static_cast<sf::Vector2f>(sf::Mouse::getPosition(window));

    if(this->getGlobalBounds().contains(mousePosition)
    && event.type == sf::Event::MouseButtonReleased
    && event.mouseButton.button == sf::Mouse::Left) //if clicked
    {
        return true;
    }
    else
    {
        return false;
    }
}
 

Thanks for all your replies!

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: [Solved] sf::Event in Button class
« Reply #6 on: August 04, 2016, 12:34:31 pm »
That is what I would've suggested if you hadn't've said that you "can't use events in a class"  :P

Just be aware that the event is not a copy; it's a reference. Any changes you might make to that event (although you probably won't) will also change the original event that was passed so be aware if you still intend to use the event afterwards.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Kanoha

  • Newbie
  • *
  • Posts: 19
    • View Profile
    • Email
Re: [Solved] sf::Event in Button class
« Reply #7 on: August 04, 2016, 12:53:10 pm »
Ok, Hapax, thanks!