SFML Mouse click detection

I'm coding a game with SFML library. I have some buttons and when I click on, I want to do something.

But I have a probleme, I don't know how to detect a simple click, not key released or key pressed, just a click.

I write this code :

Game loop :

void                            GameEngine::gameLoop()
{
  Menu                                  menu(_win);

  while (_win.isOpen() && gl_quit == false)
    {
      sf::Event         event;
      while (_win.pollEvent(event))
        {
          if (event.type == sf::Event::Closed)
            _win.close();
        }
      menu.mouseEvent(event);
      menu.keyboardEvent();

      menu.calcul();
      menu.reDraw();

      _win.display();
      _win.clear();
    }
}

Menu.cpp

bool                            Menu::mouseEvent(sf::Event &event)
{
  if (event.type == sf::Event::MouseButtonReleased)
    {
      if (event.mouseButton.button == sf::Mouse::Left)
        {
          for (std::map<std::string, Button *>::iterator it = _buttons.begin();
               it != _buttons.end(); ++it)
            {
              if (it->second->collide(sf::Mouse::getPosition(_win)))
                (this->*(it->second->getAction()))();
            }
        }
    }
}

And for example when I click on the "Play" button, this method is called :

void                            Menu::on_Jouer_clicked()
{
  std::cout << "fct jouer" << std::endl;
}

And the this is the result in consol :

~/Projet/gametest :./game 
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer
fct jouer

The function is called too many times.


Solution 1:

Not sure if I remember correctly but can't you use something like this to check for a mouse click (Also specify left or right click)

if (event.type == sf::Event::MouseButtonPressed)

If you want your check to specify where a click is then you can use this below and check if it is within the bounds of the buttons mentioned:

sf::Vector2i position = sf::Mouse::getPosition();

Then you can use the position variable (position.x and position.y for the specific coordinates) to check.

Solution 2:

This question is not very recent, but i struggle for some time to get the answer when i started sfml a few months ago. Even when i read the documentation of the mouse and events "lol". But i studied more c++, and i came with this:

bool lock_click; // Create a bool variable for locking the click.
if (evnt.type == sf::Event::MouseButtonPressed) //Mouse button Pressed
{
    if (evnt.mouseButton.button == sf::Mouse::Left && lock_click != true) //specifies
    {
        /* your code here*/
        std::cout << "lmb-pressed" << std::endl; // usually this will show in a loop because is being pressed;
        lock_click = true; //And now, after all your code, this will lock the loop and not print "lmb" in a x held time. 
        /* or here idk */
    }   
}
if (evnt.type == sf::Event::MouseButtonReleased) //Mouse button Released now.
{
    if (evnt.mouseButton.button == sf::Mouse::Left) //specifies the held button that we specified before.
    {
        lock_click = false; //unlock when the button has been released.
    }
}

There is a "option" if you are using keyboard in your app that is: window.setKeyRepeatEnabled(false), but it only works for keyboards. (Maybe other methods like joystick works too but i'm not sure)

The only problem is that you have to make this for each mouse button but i think it's not big deal. (unless you have that type of calculator mouse and you want it to work fine for everyone that have calculator mouses too idk)