Witam. Aktualnie w ramach ćwiczeń z obiektówki, staram się przy pomocy SFML stworzyć edytor GUI. Na razie idzie nieźle, chociaż ostatnio męczy mnie dość dziwny bug, którego - mimo wielu prób - nie mogę się pozbyć. Jestem w trakcie tworzenia klasy przycisku, jego główne metody mają zwracać, czy przycisk jest przyciśnięty ( .isPressed() ) oraz kliknięty ( .isClicked() ). Na początek zamieszczę kod danej klasy(inne klasy tymczasowo z nich wyciąłem).
gui.h :
https://pastebin.com/XuvJ9Ctzgui.cpp :
https://pastebin.com/wsSZamYFmain.cpp :
https://pastebin.com/FXz3p30XDobra, teraz gdzie pojawia się problem? W tym momencie:
void RectangularButton::update( sf::Event action ) {
checkIfPressed( action );
checkIfClicked( action );
}
void RectangularButton::checkIfPressed( sf::Event action ) {
if( isMouseOver() && action.type == sf::Event::MouseButtonPressed && action.mouseButton.button == sf::Mouse::Left )
pressed = true;
}
void RectangularButton::checkIfClicked( sf::Event action ) {
if( pressed ) {
if( isMouseOver() && action.type == sf::Event::MouseButtonReleased && action.mouseButton.button == sf::Mouse::Left ) {
clicked = true;
pressed = false;
}
else if( action.type == sf::Event::MouseButtonReleased && action.mouseButton.button == sf::Mouse::Left )
pressed = false;
}
else clicked = false;
}
Metoda checkIfPressed działa bez zarzutu, gdy ktoś wciśnie lewy przycisk myszy i jednocześnie zrobi to będąc wewnątrz przycisku ( isMouseOver() ) to "pressed" przyjmie wartość true. Będzie ją posiadać póki użytkownik nie zwolni klawisza myszy (to już wewnątrz funkcji checkIfClicked). Teraz w tej drugiej metodzie mogą być 3 scenariusze.
1. Przycisk został wciśnięty, a następnie poprawnie zwolniony wewnątrz jego pola. (Wtedy kliknięcie = true, a przyciśnięcie = false)
2. Przycisk został wciśnięty, a następnie zwolniony poza polem. (Wtedy kliknięcie i przyciśnięcie = false).
3. Każda inna opcja - tak naprawdę scenariusz resetujący kliknięcie z powrotem na false (true ma być pojedynczym impulsem, znikającym przy kolejnym okrążeniu programu).
Jaki jest więc problem? Scenariusze działają jak powinny, jest jednak jeden błąd, którego nie jestem w stanie wytłumaczyć. Gdy clicked przyjmie wartość true (pierwszy scenariusz z metody chechIsClicked) to będzie ją posiadać tak długo, aż nie zostanie wykonana JAKAKOLWIEK inna akcja (przesunięcie myszki o 1px, wciśnięcie dowolnego przycisku na klawiaturze/myszce). Jeżeli po zwolnieniu klawisza, mysz oraz klawiatura pozostaną nieruszone, clicked będzie ciągle posiadało wartość true.
Czy ktoś ma pomysł czemu tak jest? Jeżeli nie zrozumieliście o co mi chodzi (jestem słabym tłumaczem), to skompilujcie kod i sami zobaczcie. Kliknijcie przycisk i postarajcie się nie ruszyć niczym nawet o milimetr.