SDL2_pollevent() Controller dpad continuous hold? - c++

I'm trying to register controller button/dpad presses and continuous hold of said buttons that way it spits the output out continuously instead of one press at a time and then exiting the poll event loop. Right now I have a small piece of dummy code that I'm trying to print in a stream if I hold a button down. Any assistance into this issue?
while( !quit_program )
{
//Handle events on queue
while( SDL_PollEvent( &e ))
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit_program = true;
}
else if(e.type == SDL_CONTROLLERBUTTONDOWN)
{
count++;
cout<<"button pushed# "<<count<<endl;
}
}
}

Until you get a SDL_CONTROLLERBUTTONUP (for the same button of course) you can consider the button as being pressed. Then to count you could do something like this (for a single button):
bool that_button_pressed{false};
while(!quit_program) {
//Handle events on queue
while(SDL_PollEvent(&e)) {
// User requests quit
if(e.type == SDL_QUIT)
quit_program = true;
if (e.type == SDL_CONTROLLERBUTTONDOWN && e.button == a_button_of_your_choice) {
that_button_pressed = true;
}
if (e.type == SDL_CONTROLLERBUTTONUP && e.button == a_button_of_your_choice) {
that_button_pressed = false;
}
}
if (that_button_pressed) {
count++;
// Print or implement your logic
}
}
Of course this counter would also depend on your loop timings. Here that_button_pressed would represent one of the SDL_GameControllerButton's.

Related

Multiple key presses SFML

I'm trying to detect keyPress only once, but it goes for random amount of presses. I'm using keyrelease, and it work normally if I have breakpoint.
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
} else {
characterScreen.handleEvent(event, window);
}
}
bool keyReleased = event.type == sf::Event::KeyPressed;
bool rightArrowKey = event.key.code == sf::Keyboard::Right;
bool leftArrowKey = event.key.code == sf::Keyboard::Left;
if (keyReleased&&leftArrowKey)
{
if (selectedCharacter == 0)
{
selectedCharacter = characterList.size() - 1;
}
else
{
selectedCharacter--;
}
changeCharacters(characterList[selectedCharacter], font, characterScreen);
std::cout << "left pressed" << std::endl;
keyReleased = false;
std::cout << keyReleased << std::endl;
}
else if (keyReleased && rightArrowKey)
{
if (selectedCharacter == characterList.size()-1)
{
selectedCharacter = 0;
}
else
{
selectedCharacter++;
}
changeCharacters(characterList[selectedCharacter], font, characterScreen);
}
window.clear(sf::Color::White);
characterScreen.update();
characterScreen.render(window);
window.display();
}
I've tryed window.setKeyRepeatEnabled(false); and keypressed, still nothing. Tryed different keyboard aswell.
When using (C)SMFL, we generally have a main loop condition rendering the main frame (the windows) and checking events, it can be an infinite loop (such as while (1)) or a more recomanded one like your while (window.isOpen()).
It means that the windows and all events listener are refreshed / updated each loop's turn, so if you press a key on your keyboard, you will trigger your keyboard's event listener, fine, and you will continue your code until re-enter in your main loop, and re-refreshing the windows and re-updating your event listener.
What the point of explaining that ? it just means by only pressing once a key, your computer will process maybe 10, 100 or maybe 1000 iteration of your main loop (depending on it's performances and more). So it's "normal" to works fine when you use convenient features like breakpoints, but in reality you can't.
You have a lot of possibilities, bad ones (like "use delay / pause" who's not recommended since it will halt your window's refresh and can be interpreted by a crash by your OS) or good ones like tampon variables, who'll cancel the entrance of some conditions by their state:
Example:
bool tmp_var = false;
while (window.isOpen()) {
// Warn, you called your variable keyReleased but it check keyPressed
if (event.type == sf::Event::KeyPressed && tmp_var == false) {
// Check wich key is pressed and perform required actions
tmp_var = true;
} else if (event.type == sf::Event::KeyReleased) {
tmp_var = false;
}
}
Note that the code can be not correct, I wanted to point out the reasoning

SDL C++ Mouse Input Handling Toggle Effect

So I'm working on a tower defense game. And I need to select a tile where the user clicks the mouse (right now i'm just drawing a border around the tile). Now the code I have works sometimes and I'm not sure how to get it to work better. Right now with the code I have when I click on an area, the tile gets selected and sometimes it deselects right away and other times it doesn't. Almost like I'm holding the mouse down and it just keeps "clicking" the mouse. What I need is for it to select the tile without deselecting it no matter how long the mouse button is being pressed. My mouse input class is set up like this:
MouseInput.h
#pragma once
#include <SDL.h>
class MouseInput
{
public:
MouseInput();
~MouseInput();
void Update();
bool GetMouseButton(int index);
SDL_Event GetEvent();
bool GetPressed();
bool GetReleased();
private:
void GetButtonStates();
private:
bool mouseArray[3];
int x, y;
bool justReleased;
bool justPressed;
SDL_Event e;
};
MouseInput.cpp
#include "Input.h"
MouseInput::MouseInput()
:
x(0),
y(0),
justReleased(false),
justPressed(false)
{
SDL_PumpEvents();
for (int i = 0; i < 3; i++)
{
mouseArray[i] = false;
}
}
MouseInput::~MouseInput()
{
}
void MouseInput::Update()
{
SDL_PollEvent(&e);
justReleased = false;
justPressed = false;
if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
justPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_LEFT)
justReleased = true;
}
bool MouseInput::GetPressed()
{
return justPressed;
}
bool MouseInput::GetReleased()
{
return justReleased;
}
bool MouseInput::GetMouseButton(int index)
{
if (index <= 3 && index >= 1)
{
return mouseArray[index - 1];
}
return false;
}
SDL_Event MouseInput::GetEvent()
{
return e;
}
void MouseInput::GetButtonStates()
{
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
{
// 1 = Left; 2 = Center; 3 = Right
mouseArray[e.button.button - 1] = true;
}
if (e.type == SDL_MOUSEBUTTONUP)
{
mouseArray[e.button.button - 1] = false;
}
}
In my Game class I have setup the mouseinput as well as a variable to store the coordinates of the tile that was clicked. I also Have a variable pressed to check to see if the mouse was pressed. In my updating function I check if the mouse was not pressed. If the mouse was not pressed, then I check if the mouse is pressed that way the game can get the coordinates of the mouse position. I know that sounds crazy so here is some of my code:
std::pair<int, int> coords; // Will store the coordinates of the tile position that the mouse rests in
bool pressed; // If the mouse was pressed (i should call it toggle because it's true if the mouse was pressed once, then false if the mouse was pressed again, then true...ect.)
Updating function
Mouse Class
bool clicked; // In my custom Mouse.h file and set to false in constructor
MouseInput input; // In my custom Mouse.h file
Mouse class Update()
input.Update(); // Calls the MouseInput updating
if (input.GetPressed() && !clicked)
{
clicked = !clicked;
printf("OK");
}
//else if (clicked && input.GetReleased())
else if (clicked && input.GetPressed()) // Somewhat works. It works almost like before. If I click the mouse it shows up then sometimes when I click again it works, and other times I have to click a couple times
{
clicked = !clicked;
}
In my game class I just check if mouse clicked is true, then draw what i need
if (mouse.GetClicked())
{
// Draw what I need here.
// Currently is only drawn when I hold down the mouse
// And not drawn when I release the mouse.
}
Then when I'm drawing the square around the tile, I only draw it if pressed = true. Otherwise it is not drawn. This code works sometimes, and other times it doesn't. In order to get the effect I want, I have to real quickly click the mouse. If I don't, sometimes it appears as if I'm holding the mouse button down and the square just flashes.
The issue is that the "mouse-down" event is exactly that - an event. It should happen once, be handled, and then not occur until the button is physically pressed again. With your code, once pressed it'll set the internal state to "pressed" and then not change it until it's released. Which is okay, except your code polling this internal state treats it as if it's an event, not as state, so every time the update function runs while the mouse button is pressed, it'll see a "new button press".
This (simplified version of your code that uses one button and an idea of showing an image only when a button's pressed) might help you visualise it:
bool buttonPressed = false;
bool imageShown = false;
while (true)
{
SDL_Event e;
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
buttonPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP)
buttonPressed = false;
if (!imageShown && buttonPressed)
imageShown = true;
else if (buttonPressed)
imageShown = false;
}
Do you see how each time the loop runs, even if no events have been fired this iteration, the state remains? This would cause the imageShown variable to keep toggling on and off each iteration, until a "button up" event is fired to reset the state.
You should probably rework a bit of your input controller - you need to expose a way to differentiate from "button being pressed right now" and "button that's been pressed for a while".
An idea would be to provide eg. ButtonsPressed and ButtonsJustPressed members (although I'm sure you can think of more appropriate names). The ButtonsJustPressed members should be reset to false each time you call GetButtonStates, so they're only true if on that specific iteration of the loop, they've been pressed, while the ButtonsPressed members are exactly what you're doing right now.
A tweaked version of the above to take this into account:
bool buttonJustPressed = false;
bool buttonJustReleased = false;
bool imageShown = false;
while (true)
{
// As far as we know, this iteration no events have been fired
buttonJustPressed = false;
buttonJustReleased = false
SDL_Event e;
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
buttonJustPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP)
buttonJustReleased = true;
if (!imageShown && buttonJustPressed)
imageShown = true;
else if (imageShown && buttonJustReleased)
imageShown = false;
}
See how this version will only change the visibility of the image if a button has just been pressed/released - if the button's being held down, the events aren't fired, so the state remains false, and the image's state remains the same.

How do I get a "list" of ALL the events in real time in SDL 2.0?

I come from Pygame, and there I had pygame.event.get(), which returned a list of all events (So, once I had that list of events inside the mainloop, I could check for multiple keypresses or whatever in real-time, since ALL possible events were available).
Now here's my code:
#include "init.h"
#include "texture.h"
int main(int argc, char** argv) {
Init();
while (running) {
while (SDL_PollEvent(&e) != 0) { // PROBLEM <<< I don't want "POLL".
auto key = e.key.keysym.sym;
if (e.type == SDL_QUIT) {
running = false;
} else if (e.type == SDL_KEYDOWN) {
if (key == SDLK_ESCAPE) {
running = false;
}
if (key == SDLK_UP) {
square_rect.y -= PLAYER_SPEED;
} else if (key == SDLK_DOWN) {
square_rect.y += PLAYER_SPEED;
} else if (key == SDLK_LEFT) {
square_rect.x -= PLAYER_SPEED;
} else if (key == SDLK_RIGHT) {
square_rect.x += PLAYER_SPEED;
}
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &square_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
In the tutorials I've seen so far, they've used SDL_PollEvent(), and I did not notice the difference until now, when I tried to move my square with the keyboard arrows. Obviously, I can't press two arrow keys at once, since the loop is capturing one event at a time.
And the problem is, there's no such thing as "SDL_Event_Get()" in the API. Only these:
SDL_PeepEvents()
SDL_PollEvent()
SDL_PumpEvents()
SDL_PushEvent()
Well, I don't know how Pete Shinners ported SDL 1.2 to Python and handled the events in such a marvelous way, so I'm having a hard time understanding SDL 2.0 (I'm probably not the only one). Is there such a thing as "get all the events ()" in SDL 2.0? What if I wanted to check if ALL possible keys were pressed AT THE SAME TIME?
You can use SDL_GetKeyboardState as described in the documentation:
const Uint8 *state = SDL_GetKeyboardState(NULL);
if (state[SDL_SCANCODE_RETURN]) {
printf("<RETURN> is pressed.\n");
}
if (state[SDL_SCANCODE_RIGHT] && state[SDL_SCANCODE_UP]) {
printf("Right and Up Keys Pressed.\n");
}
Generally speaking you can fetch the events into any container, and then check if any number of events are in such a container. A good container for this would be std::set or std::unordered_set, but in both cases you would have to define either operator< or std::hash for the type SDL_Event.
An alternative is to make your own generic algorithm that works with any container:
template<typename OutIt>
void push_events(OutIt out) {
SDL_Event e;
while (SDL_PollEvent(&e) != 0)
*out++ = e;
}
and then apply it to some container of choice, like std::vector:
std::vector<SDL_Event> vector;
push_events(std::back_inserter(vector));
Another option is to keep your own std::set of key pressed, in which to "remember" what keys are pressed at any given moment.
For example, given:
std::set<SDL_Keycode> keys;
then:
SDL_Event e;
while (SDL_PollEvent(&e) != 0) {
switch (e.type) {
case SDL_KEYDOWN:
auto key = e.key.keysym.sym;
keys.insert(key);
break;
case SDL_KEYUP:
auto key = e.key.keysym.sym;
keys.erase(key);
break;
}
}
and then check via something along the lines of:
if (keys.count(SDLK_SPACE) && keys.count(SDLK_UP))
// ...
but I'm not sure what that buys you.

SFML - pollEvent double run mouseclick

I have main like this :
#include <SFML/Graphics.hpp>
#include <iostream>
#include "okno.h"
using namespace sf;
int main()
{
// Create the main window
RenderWindow app(VideoMode::getDesktopMode(), "Okno" ,Style::Fullscreen);
app.setKeyRepeatEnabled(false);
okno aplikacja(app);
// Start the game loop
while (app.isOpen())
{
// Process events
Event event;
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
while (app.pollEvent(event))
{
// Close window : exit
if (event.type == Event::Closed)
app.close();
if( event.type == Event::KeyPressed && event.key.code == Keyboard::Escape )
app.close();
}
aplikacja.click_przyciski(event);
aplikacja.obsluga_przyciskow();
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
aplikacja.rysuj();
aplikacja.menu=true;
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
//sleep(seconds(5));
// Update the window
//app.display();
}
return EXIT_SUCCESS;
}
And class okno.cpp like this :
#include "okno.h"
#include <iostream>
using namespace std;
int wyswietlanie =0;
okno::okno(RenderWindow &app): window(app)
{
textures[0].loadFromFile("grafika/tlo.png");
textures[1].loadFromFile("grafika/logo.png");
textures[2].loadFromFile("grafika/siatka.png");
textures[3].loadFromFile("grafika/button_start.png");
textures[4].loadFromFile("grafika/button_informacje.png");
textures[5].loadFromFile("grafika/button_wyjscie.png");
textures[6].loadFromFile("grafika/button_cofnij.png");
czcionka.loadFromFile("czcionki/czcionka_1.ttf");
for (int j=0;j<i;j++)
sprites[j].setTexture(textures[j]);
float x,y;
x=window.getView().getSize().x;
y=window.getView().getSize().y;
tekst.setString("Projekt wykonal : \n Wojciech Sorota.");
tekst.setCharacterSize(30);
tekst.setPosition(x/10,y/10);
tekst.setColor(sf::Color::Red);
tekst.setFont(czcionka);
sprites[0].setScale(x/sprites[0].getTextureRect().width,y/sprites[0].getTextureRect().height);
sprites[1].setPosition(x/2 - sprites[1].getTextureRect().width/2,y/2 - sprites[1].getTextureRect().height/2);
sprites[3].setPosition(x/10,y/10);
sprites[2].setScale(x/2/sprites[2].getTextureRect().width,y/2/sprites[2].getTextureRect().height);
sprites[2].setPosition(x/8,y/4);
sprites[4].setPosition( x/10+ sprites[3].getPosition().x + x/ 15,y/10 );
sprites[5].setPosition( x/10 +sprites[4].getPosition().x +x/15,y/10);
sprites[6].setPosition(x/10 + tekst.getPosition().x + tekst.getGlobalBounds().width,y/10);
menu=true;
}
okno::~okno()
{}
void okno::rysuj()
{
this->rysuj_intro();
this->rysuj_menu();
}
void okno::start_gra()
{
}
void okno::click_przyciski(Event &event)
{
if(event.type == Event::MouseButtonReleased && event.mouseButton.button == Mouse::Left)
{
if(click_sprite(sprites[3]))
start_gra();
else if(click_sprite(sprites[5]))
window.close();
else if( click_sprite(sprites[4]))
wyswietl_info(event);
}
}
void okno::wyswietl_info(Event &event)
{
{
while(1)
{
if(sf::Mouse::isButtonPressed(sf::Mouse::Left) && click_sprite(sprites[6]))
{
event.type=Event::JoystickButtonPressed;
event.mouseButton.button = Mouse::Right;
return;
}
window.clear();
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[6]);
window.draw(tekst);
obsluga_przyciskow();
window.display();
}
}}
bool okno::click_sprite(Sprite a)
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// retrieve the bounding box of the sprite
sf::FloatRect bounds = a.getGlobalBounds();
// hit test
if (bounds.contains(mouse))
{
return true;
}
return false;
}
void okno::obluga_cofnij()
{
}
void okno::obsluga_przyciskow()
{
if(mysz_nad_sprite(sprites[3]))
sprites[3].setColor(sf::Color(100,100,100));
else
sprites[3].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[4]))
sprites[4].setColor(sf::Color(100,100,100));
else
sprites[4].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[5]))
sprites[5].setColor(sf::Color(100,100,100));
else
sprites[5].setColor(sf::Color(255,255,255));
if(mysz_nad_sprite(sprites[6]))
sprites[6].setColor(sf::Color(100,100,100));
else
sprites[6].setColor(sf::Color(255,255,255));
}
bool okno::mysz_nad_sprite(Sprite a)
{
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
if (a.getGlobalBounds().contains(mouse))
return true;
return false;
}
void okno::rysuj_intro()
{
if (wyswietlanie == 0)
{
for ( int n=0;n<=254;n++)
{
window.clear();
sprites[0].setColor(sf::Color(255, 255, 255, n));
sprites[1].setColor(sf::Color(255,255,255,n));
sleep(milliseconds(n/15));
window.draw(sprites[0]);
window.draw(sprites[1]);
window.display();
}
for (int n=254;n>=0;n--)
{
window.clear();
sprites[1].setColor(sf::Color(255, 255, 255, n));
sleep(milliseconds(n/15));
window.draw(sprites[0]);
window.draw(sprites[1]);
window.display();
}
wyswietlanie++;
}
}
void okno::rysuj_menu()
{
window.clear();
if (wyswietlanie==1)
for ( int n=0;n<=254;n++)
{
window.clear();
sprites[2].setColor(sf::Color(255,255,255,n));
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[3]);
window.draw(sprites[4]);
window.draw(sprites[5]);
window.display();
if (n==254)
wyswietlanie++;
window.clear();
}
window.draw(sprites[0]);
window.draw(sprites[2]);
window.draw(sprites[3]);
window.draw(sprites[4]);
window.draw(sprites[5]);
window.display();
}
My question is why after i click on sprites[6] then i go back to loop [ pollEvent ] and then pollEvent return last event , but last event is mouseclick soo then it run script on mouseclick how to protect my function for this ?
SFML Event handling
Events should be handled something like this:
sf::Event event;
while (app.pollEvent(event))
{
// handle each event you want
switch (event.type)
{
case sf::Event::Closed:
closed(event);
Exit();
break;
case sf::Event::KeyPressed:
keyPressed(event);
break;
case sf::Event::KeyReleased:
keyReleased(event);
break;
case sf::Event::MouseButtonPressed:
mouseButtonPressed(event);
break;
case sf::Event::MouseButtonReleased:
mouseButtonReleased(event);
break;
case sf::Event::MouseMoved:
mouseMoved(event);
break;
/* ...many more events exist */
default:
cerr << "unhandle event of type: " << event.type << endl;
break;
}
}
And then, have a function for each event you want to handle.
void mouseMoved(const sf::Event& event)
{
// do something with the mouse event
mRelMousePos.x = event.mouseMove.x - mMousePos.x;
mRelMousePos.y = event.mouseMove.y - mMousePos.y;
mMousePos.x = event.mouseMove.x;
mMousePos.y = event.mouseMove.y;
}
As mentionned by #Hiura, you can't assign an event type to an sf::event and then reuse it in the pollEvent method, to be more precise, it's more the event.mouseButton.button = Mouse::Right; part that is problematic here. This is partly because the sf::Event class stores its event parameters (mouseButton, key, etc.) inside a union and partly because that's not the use intended for the sf::Event class.
Your code
Please code in english, always, you never know when you'll need to share a piece of code. And I'm not saying this because I'm a self-centered english speaking individual, in fact, I'm a french canadian.
Now, let's take a look specifically at the code you provided.
// Process events
Event event;
// these are problematic, you shouldn't do that.
//event.type=Event::JoystickButtonPressed;
//event.mouseButton.button = Mouse::Right;
while (app.pollEvent(event))
{
// using a switch or else if here would lower code repetition
// and useless check.
// Since both cases do the same thing, you could have just merge them.
// Close window : exit
if ((event.type == Event::Closed)
|| (event.type == Event::KeyPressed
&& event.key.code == Keyboard::Escape ))
{
app.close();
}
else if (event.type == Event::MouseButtonReleased
&& event.mouseButton.button == Mouse::Left)
{
// this should really go here
aplikacja.click_button(event); // thanks Google Translation
}
}
// Why? Why do you send the last event from your event loop to that?
//aplikacja.click_przyciski(event);
Some unnecessary tweaks here just for fun:
bool okno::click_sprite(Sprite sprite) // remember, meaningful names
{
// transform the mouse position from window coordinates to world coordinates
sf::Vector2f mouse = window.mapPixelToCoords(sf::Mouse::getPosition(window));
// see how it's clearer and I just removed 7-8 LOC and the comments
// are now unnecessary here. The if clause was redundant since the contains
// method already returns a bool value.
return sprite.getGlobalBounds().contains(mouse);
}
I'm not going to go through the entire code, but you are close to a working app with SFML. There is some nice tutorials and the SFML source code is quite clear, see the SFML Github repo and the SFML game dev book for more info on how to use each part of SFML.

SFML2 Mouse::isButtonPressed filling up event queue

First of all I'd like to say that I'm not sure if the title is appropriate but it's the only logical explanation I could find.
What I'm trying to do is move my window by clicking a sprite (sort of like simulating a titlebar).
All working fine until I let go of the mouse button the rate new mouse events are emitted is way lower and with huge 1.5~2s pauses between them.
Is it possible that sf::Mouse::isBUttonPressed is filling the queue or is it another issue?
Edit: The window class has a sf::Event object and passes it to each object's event handler.
The sprite class has an event handler of this form:
bool object::handleEvents(sf::Event& event)
{
switch(event.type)
{
case sf::Event::MouseMoved:
case sf::Event::MouseButtonPressed:
case sf::Event::MouseButtonReleased:
{
auto mouse_pos = sf::Mouse::getPosition(*this->parent);
if(this->isPointInside(mouse_pos))
{
if(event.type == sf::Event::MouseMoved)
{
this->hovering = true;
if(this->callback["onHover"])
this->callback["onHover"](this, nullptr);
return true;
}
else if(event.type == sf::Event::MouseButtonPressed)
{
this->clicked = true;
this->focused = true;
if(event.mouseButton.button == sf::Mouse::Left)
if(this->callback["onLClick"])
this->callback["onLClick"](this, ref(mouse_pos));
if(event.mouseButton.button == sf::Mouse::Right)
if(this->callback["onRClick"])
this->callback["onRClick"](this, ref(mouse_pos));
return true;
}
else if(event.type == sf::Event::MouseButtonReleased && this->clicked)
{
this->clicked = false;
if(event.mouseButton.button == sf::Mouse::Left)
if(this->callback["onLClickReleased"])
this->callback["onLClickReleased"](this, ref(mouse_pos));
if(event.mouseButton.button == sf::Mouse::Right)
if(this->callback["onRClickReleased"])
this->callback["onRClickReleased"](this, ref(mouse_pos));
return true;
}
}
else
{
if(this->hovering)
{
if(this->callback["onHoverLost"])
this->callback["onHoverLost"](this, nullptr);
this->hovering = false;
}
}
}break;
default: ;
}
return false;
}
and the code responsible for moving the window:
titlebar->callback["onLClick"] = [&](object* obj, void* data)
{
sf::Vector2i* relpos = (sf::Vector2i*)(data);
while(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
sf::Vector2i abspos = sf::Mouse::getPosition();
window.setPosition(sf::Vector2i((abspos.x - relpos->x),(abspos.y - relpos->y)));
}
titlebar->clicked = false;
};
The sf::Mouse class as well as sf::Keyboard and sf::Joystick aren't connected to the event system, but are completely independent, thus it's impossible that isButtonPressed would've any influence on the events.
The real problem in your code is the 'infinite' loop when the left mouse button is pressed. If the left mouse button is pressed, everything that happens in your application is, that the window gets moved around. There won't be any event dispatches (= processing) and every event that happens within that time, will get pilled in the event queue. Thus when you return to process the events, you'll have a longer queue than usual and will start dispatching with the oldest event.
So if you now move your window around for 2 seconds, you'll get a filled queue worth 2 seconds which can delay the further processing.
To solve this problem, you'll most probably have to dispatch all the events while you're moving the window.