Rewrite sf::Event API to improve type safety

This new API is built on top of std::variant. This allows us to
store many different event types in a space-efficient way and access
the active event type in a type-safe manner that eliminates the
categories of UB that are possible with unions.

Co-authored-by: kimci86 <kimci86@hotmail.fr>
This commit is contained in:
Chris Thrasher 2023-11-03 21:47:14 -06:00
parent b447d41c6e
commit 59447dd8e5
43 changed files with 895 additions and 750 deletions

View File

@ -59,7 +59,7 @@ body:
{
for (sf::Event event; window.pollEvent(event);)
{
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
}

View File

@ -56,7 +56,7 @@ body:
{
for (sf::Event event; window.pollEvent(event);)
{
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
}

View File

@ -41,7 +41,7 @@ int main()
{
for (sf::Event event; window.pollEvent(event);)
{
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
}

View File

@ -47,7 +47,7 @@
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// // Close window: exit
/// if (event.type == sf::Event::Closed)
/// if (event.is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -115,46 +115,49 @@ int main(int argc, char* argv[])
{
for (sf::Event event; active ? window.pollEvent(event) : window.waitEvent(event);)
{
switch (event.type)
if (event.is<sf::Event::Closed>())
{
case sf::Event::Closed:
window.close();
}
else if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
{
if (keyPressed->code == sf::Keyboard::Key::Escape)
window.close();
break;
case sf::Event::KeyPressed:
if (event.key.code == sf::Keyboard::Key::Escape)
window.close();
break;
case sf::Event::Resized:
view.setSize(sf::Vector2f(event.size.width, event.size.height));
view.setCenter(sf::Vector2f(event.size.width, event.size.height) / 2.f);
window.setView(view);
break;
case sf::Event::LostFocus:
background = sf::Color::Black;
break;
case sf::Event::GainedFocus:
background = sf::Color::White;
break;
// On Android MouseLeft/MouseEntered are (for now) triggered,
// whenever the app loses or gains focus.
case sf::Event::MouseLeft:
active = false;
break;
case sf::Event::MouseEntered:
active = true;
break;
case sf::Event::TouchBegan:
if (event.touch.finger == 0)
{
image.setPosition({static_cast<float>(event.touch.x), static_cast<float>(event.touch.y)});
}
else if (const auto* resized = event.getIf<sf::Event::Resized>())
{
const auto size = sf::Vector2f(resized->size);
view.setSize(size);
view.setCenter(size / 2.f);
window.setView(view);
}
else if (event.is<sf::Event::FocusLost>())
{
background = sf::Color::Black;
}
else if (event.is<sf::Event::FocusGained>())
{
background = sf::Color::White;
}
// On Android MouseLeft/MouseEntered are (for now) triggered,
// whenever the app loses or gains focus.
else if (event.is<sf::Event::MouseLeft>())
{
active = false;
}
else if (event.is<sf::Event::MouseEntered>())
{
active = true;
}
else if (const auto* touchBegan = event.getIf<sf::Event::TouchBegan>())
{
if (touchBegan->finger == 0)
{
image.setPosition(sf::Vector2f(touchBegan->position));
#if defined(USE_JNI)
vibrate(sf::milliseconds(10));
vibrate(sf::milliseconds(10));
#endif
}
break;
default:
break;
}
}
}

View File

@ -182,17 +182,17 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Window closed or escape key pressed: exit
if ((event.type == sf::Event::Closed) ||
((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape)))
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// Arrow key pressed:
if (prerequisitesSupported && (event.type == sf::Event::KeyPressed))
if (prerequisitesSupported && event.is<sf::Event::KeyPressed>())
{
switch (event.key.code)
switch (event.getIf<sf::Event::KeyPressed>()->code)
{
case sf::Keyboard::Key::Enter:
generateTerrain(terrainStagingBuffer.data());

View File

@ -161,19 +161,33 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Window closed or escape key pressed: exit
if ((event.type == sf::Event::Closed) ||
((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape)))
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
else if ((event.type == sf::Event::JoystickButtonPressed) || (event.type == sf::Event::JoystickButtonReleased) ||
(event.type == sf::Event::JoystickMoved) || (event.type == sf::Event::JoystickConnected))
else if (const auto* joystickButtonPressed = event.getIf<sf::Event::JoystickButtonPressed>())
{
// Update displayed joystick values
updateValues(event.joystickConnect.joystickId);
updateValues(joystickButtonPressed->joystickId);
}
else if (event.type == sf::Event::JoystickDisconnected)
else if (const auto* joystickButtonReleased = event.getIf<sf::Event::JoystickButtonReleased>())
{
// Update displayed joystick values
updateValues(joystickButtonReleased->joystickId);
}
else if (const auto* joystickMoved = event.getIf<sf::Event::JoystickMoved>())
{
// Update displayed joystick values
updateValues(joystickMoved->joystickId);
}
else if (const auto* joystickConnected = event.getIf<sf::Event::JoystickConnected>())
{
// Update displayed joystick values
updateValues(joystickConnected->joystickId);
}
else if (event.is<sf::Event::JoystickDisconnected>())
{
// Reset displayed joystick values to empty
for (auto& [label, joystickObject] : texts)

View File

@ -211,21 +211,23 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
{
exit = true;
window.close();
}
// Escape key: exit
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape))
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Escape)
{
exit = true;
window.close();
}
// Return key: toggle mipmapping
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Enter))
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Enter)
{
if (mipmapEnabled)
{
@ -242,14 +244,15 @@ int main()
}
// Space key: toggle sRGB conversion
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Space))
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Space)
{
sRgb = !sRgb;
window.close();
}
// Adjust the viewport when the window is resized
if (event.type == sf::Event::Resized)
if (const auto* resized = event.getIf<sf::Event::Resized>())
{
const sf::Vector2u textureSize = backgroundTexture.getSize();
@ -260,10 +263,11 @@ int main()
return EXIT_FAILURE;
}
glViewport(0, 0, static_cast<GLsizei>(event.size.width), static_cast<GLsizei>(event.size.height));
const auto [width, height] = resized->size;
glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const GLfloat newRatio = static_cast<float>(event.size.width) / static_cast<float>(event.size.height);
const GLfloat newRatio = static_cast<float>(width) / static_cast<float>(height);
#ifdef SFML_OPENGL_ES
glFrustumf(-newRatio, newRatio, -1.f, 1.f, 1.f, 500.f);
#else

View File

@ -392,12 +392,12 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
if (event.type == sf::Event::KeyPressed)
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
{
switch (event.key.code)
switch (keyPressed->code)
{
// Escape key: exit
case sf::Keyboard::Key::Escape:

View File

@ -680,12 +680,12 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
if (event.type == sf::Event::KeyPressed)
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
{
switch (event.key.code)
switch (keyPressed->code)
{
// Escape key: exit
case sf::Keyboard::Key::Escape:
@ -715,7 +715,7 @@ int main()
break;
default:
effects[current]->handleKey(event.key.code);
effects[current]->handleKey(keyPressed->code);
break;
}
}

View File

@ -43,7 +43,7 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Window closed: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
{
window.close();
break;

View File

@ -118,16 +118,16 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Window closed or escape key pressed: exit
if ((event.type == sf::Event::Closed) ||
((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape)))
if (event.is<sf::Event::Closed>() || (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// Space key pressed: play
if (((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Space)) ||
(event.type == sf::Event::TouchBegan))
if ((event.is<sf::Event::KeyPressed>() && event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Space) ||
event.is<sf::Event::TouchBegan>())
{
if (!isPlaying)
{
@ -150,7 +150,7 @@ int main()
}
// Window size changed, adjust view appropriately
if (event.type == sf::Event::Resized)
if (event.is<sf::Event::Resized>())
{
sf::View view;
view.setSize({gameWidth, gameHeight});

View File

@ -2545,15 +2545,16 @@ public:
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
// Escape key: exit
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape))
if (event.is<sf::Event::KeyPressed>() &&
event.getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape)
window.close();
// Re-create the swapchain when the window is resized
if (event.type == sf::Event::Resized)
if (event.is<sf::Event::Resized>())
swapchainOutOfDate = true;
}

View File

@ -144,20 +144,22 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
window.close();
// Escape key: exit
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape))
window.close();
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
if (keyPressed->code == sf::Keyboard::Key::Escape)
window.close();
// Resize event: adjust the viewport
if (event.type == sf::Event::Resized)
if (const auto* resized = event.getIf<sf::Event::Resized>())
{
glViewport(0, 0, static_cast<GLsizei>(event.size.width), static_cast<GLsizei>(event.size.height));
const auto [width, height] = resized->size;
glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
const GLfloat newRatio = static_cast<float>(event.size.width) / static_cast<float>(event.size.height);
const GLfloat newRatio = static_cast<float>(width) / static_cast<float>(height);
#ifdef SFML_OPENGL_ES
glFrustumf(-newRatio, newRatio, -1.f, 1.f, 1.f, 500.f);
#else

View File

@ -240,7 +240,7 @@ private:
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// // Request for closing the window
/// if (event.type == sf::Event::Closed)
/// if (event.is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -93,16 +93,16 @@ SFML_WINDOW_API void setString(const String& text);
/// // or use it in the event loop
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// if(event.type == sf::Event::Closed)
/// if(event.is<sf::Event::Closed>())
/// window.close();
/// if(event.type == sf::Event::KeyPressed)
/// if(const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
/// {
/// // Using Ctrl + V to paste a string into SFML
/// if(event.key.control && event.key.code == sf::Keyboard::Key::V)
/// if(keyPressed->control && keyPressed->code == sf::Keyboard::Key::V)
/// string = sf::Clipboard::getString();
///
/// // Using Ctrl + C to copy a string out of SFML
/// if(event.key.control && event.key.code == sf::Keyboard::Key::C)
/// if(keyPressed->control && keyPressed->code == sf::Keyboard::Key::C)
/// sf::Clipboard::setString("Hello World!");
/// }
/// }

View File

@ -34,8 +34,10 @@
#include <SFML/Window/Mouse.hpp>
#include <SFML/Window/Sensor.hpp>
#include <SFML/System/Vector2.hpp>
#include <variant>
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
namespace sf
{
@ -43,186 +45,282 @@ namespace sf
/// \brief Defines a system event and its parameters
///
////////////////////////////////////////////////////////////
struct Event
class SFML_WINDOW_API Event
{
public:
////////////////////////////////////////////////////////////
/// \brief Size events parameters (Resized)
/// \brief Empty event
///
////////////////////////////////////////////////////////////
struct SizeEvent
struct Empty
{
unsigned int width; //!< New width, in pixels
unsigned int height; //!< New height, in pixels
};
////////////////////////////////////////////////////////////
/// \brief Keyboard event parameters (KeyPressed, KeyReleased)
/// \brief Closed event
///
////////////////////////////////////////////////////////////
struct KeyEvent
struct Closed
{
Keyboard::Key code; //!< Code of the key that has been pressed
Keyboard::Scancode scancode; //!< Physical code of the key that has been pressed
bool alt; //!< Is the Alt key pressed?
bool control; //!< Is the Control key pressed?
bool shift; //!< Is the Shift key pressed?
bool system; //!< Is the System key pressed?
};
////////////////////////////////////////////////////////////
/// \brief Text event parameters (TextEntered)
/// \brief Resized event
///
////////////////////////////////////////////////////////////
struct TextEvent
struct Resized
{
std::uint32_t unicode; //!< UTF-32 Unicode value of the character
Vector2u size; //!< New size, in pixels
};
////////////////////////////////////////////////////////////
/// \brief Mouse move event parameters (MouseMoved)
/// \brief Lost focus event
///
////////////////////////////////////////////////////////////
struct MouseMoveEvent
struct FocusLost
{
int x; //!< X position of the mouse pointer, relative to the left of the owner window
int y; //!< Y position of the mouse pointer, relative to the top of the owner window
};
////////////////////////////////////////////////////////////
/// \brief Mouse buttons events parameters
/// (MouseButtonPressed, MouseButtonReleased)
/// \brief Gained focus event
///
////////////////////////////////////////////////////////////
struct MouseButtonEvent
struct FocusGained
{
Mouse::Button button; //!< Code of the button that has been pressed
int x; //!< X position of the mouse pointer, relative to the left of the owner window
int y; //!< Y position of the mouse pointer, relative to the top of the owner window
};
////////////////////////////////////////////////////////////
/// \brief Mouse wheel events parameters (MouseWheelScrolled)
/// \brief Text event
///
////////////////////////////////////////////////////////////
struct MouseWheelScrollEvent
struct TextEntered
{
Mouse::Wheel wheel; //!< Which wheel (for mice with multiple ones)
float delta; //!< Wheel offset (positive is up/left, negative is down/right). High-precision mice may use non-integral offsets.
int x; //!< X position of the mouse pointer, relative to the left of the owner window
int y; //!< Y position of the mouse pointer, relative to the top of the owner window
std::uint32_t unicode{}; //!< UTF-32 Unicode value of the character
};
////////////////////////////////////////////////////////////
/// \brief Joystick connection events parameters
/// (JoystickConnected, JoystickDisconnected)
/// \brief KeyChanged events
///
////////////////////////////////////////////////////////////
struct JoystickConnectEvent
struct KeyChanged
{
Keyboard::Key code{}; //!< Code of the key
Keyboard::Scancode scancode{}; //!< Physical code of the key
bool alt{}; //!< Is the Alt key pressed?
bool control{}; //!< Is the Control key pressed?
bool shift{}; //!< Is the Shift key pressed?
bool system{}; //!< Is the System key pressed?
};
struct KeyPressed : KeyChanged
{
};
struct KeyReleased : KeyChanged
{
unsigned int joystickId; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
};
////////////////////////////////////////////////////////////
/// \brief Joystick axis move event parameters (JoystickMoved)
/// \brief Mouse wheel scrolled event
///
////////////////////////////////////////////////////////////
struct JoystickMoveEvent
struct MouseWheelScrolled
{
unsigned int joystickId; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
Joystick::Axis axis; //!< Axis on which the joystick moved
float position; //!< New position on the axis (in range [-100 .. 100])
Mouse::Wheel wheel{}; //!< Which wheel (for mice with multiple ones)
float delta{}; //!< Wheel offset (positive is up/left, negative is down/right). High-precision mice may use non-integral offsets.
Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
};
////////////////////////////////////////////////////////////
/// \brief Joystick buttons events parameters
/// (JoystickButtonPressed, JoystickButtonReleased)
/// \brief Mouse button changed events
///
////////////////////////////////////////////////////////////
struct JoystickButtonEvent
struct MouseButtonChanged
{
Mouse::Button button{}; //!< Code of the button that has been pressed
Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
};
struct MouseButtonPressed : MouseButtonChanged
{
};
struct MouseButtonReleased : MouseButtonChanged
{
unsigned int joystickId; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
unsigned int button; //!< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
};
////////////////////////////////////////////////////////////
/// \brief Touch events parameters (TouchBegan, TouchMoved, TouchEnded)
/// \brief Mouse move event
///
////////////////////////////////////////////////////////////
struct TouchEvent
struct MouseMoved
{
unsigned int finger; //!< Index of the finger in case of multi-touch events
int x; //!< X position of the touch, relative to the left of the owner window
int y; //!< Y position of the touch, relative to the top of the owner window
Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
};
////////////////////////////////////////////////////////////
/// \brief Sensor event parameters (SensorChanged)
/// \brief Mouse entered event
///
////////////////////////////////////////////////////////////
struct SensorEvent
struct MouseEntered
{
Sensor::Type type; //!< Type of the sensor
float x; //!< Current value of the sensor on X axis
float y; //!< Current value of the sensor on Y axis
float z; //!< Current value of the sensor on Z axis
};
////////////////////////////////////////////////////////////
/// \brief Enumeration of the different types of events
/// \brief Mouse left event
///
////////////////////////////////////////////////////////////
enum EventType
struct MouseLeft
{
Closed, //!< The window requested to be closed (no data)
Resized, //!< The window was resized (data in event.size)
LostFocus, //!< The window lost the focus (no data)
GainedFocus, //!< The window gained the focus (no data)
TextEntered, //!< A character was entered (data in event.text)
KeyPressed, //!< A key was pressed (data in event.key)
KeyReleased, //!< A key was released (data in event.key)
MouseWheelScrolled, //!< The mouse wheel was scrolled (data in event.mouseWheelScroll)
MouseButtonPressed, //!< A mouse button was pressed (data in event.mouseButton)
MouseButtonReleased, //!< A mouse button was released (data in event.mouseButton)
MouseMoved, //!< The mouse cursor moved (data in event.mouseMove)
MouseEntered, //!< The mouse cursor entered the area of the window (no data)
MouseLeft, //!< The mouse cursor left the area of the window (no data)
JoystickButtonPressed, //!< A joystick button was pressed (data in event.joystickButton)
JoystickButtonReleased, //!< A joystick button was released (data in event.joystickButton)
JoystickMoved, //!< The joystick moved along an axis (data in event.joystickMove)
JoystickConnected, //!< A joystick was connected (data in event.joystickConnect)
JoystickDisconnected, //!< A joystick was disconnected (data in event.joystickConnect)
TouchBegan, //!< A touch event began (data in event.touch)
TouchMoved, //!< A touch moved (data in event.touch)
TouchEnded, //!< A touch event ended (data in event.touch)
SensorChanged, //!< A sensor value changed (data in event.sensor)
Count //!< Keep last -- the total number of event types
};
////////////////////////////////////////////////////////////
/// \brief Joystick button events
///
////////////////////////////////////////////////////////////
struct JoystickButtonChanged
{
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
unsigned int button{}; //!< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
};
struct JoystickButtonPressed : JoystickButtonChanged
{
};
struct JoystickButtonReleased : JoystickButtonChanged
{
};
////////////////////////////////////////////////////////////
/// \brief Joystick axis move event
///
////////////////////////////////////////////////////////////
struct JoystickMoved
{
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
Joystick::Axis axis{}; //!< Axis on which the joystick moved
float position{}; //!< New position on the axis (in range [-100 .. 100])
};
////////////////////////////////////////////////////////////
/// \brief Joystick connection events
///
////////////////////////////////////////////////////////////
struct JoystickChanged
{
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
};
struct JoystickConnected : JoystickChanged
{
};
struct JoystickDisconnected : JoystickChanged
{
};
////////////////////////////////////////////////////////////
/// \brief Touch events
///
////////////////////////////////////////////////////////////
struct TouchChanged
{
unsigned int finger{}; //!< Index of the finger in case of multi-touch events
Vector2i position; //!< Position of the touch, relative to the top left of the owner window
};
struct TouchBegan : TouchChanged
{
};
struct TouchMoved : TouchChanged
{
};
struct TouchEnded : TouchChanged
{
};
////////////////////////////////////////////////////////////
/// \brief Sensor event
///
////////////////////////////////////////////////////////////
struct SensorChanged
{
Sensor::Type type{}; //!< Type of the sensor
Vector3f value; //!< Current value of the sensor on the X, Y, and Z axes
};
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
/// Sets the event to sf::Event::Empty
///
////////////////////////////////////////////////////////////
Event() = default;
////////////////////////////////////////////////////////////
/// \brief Construct from a given sf::Event subtype
///
/// \param t Event subtype
///
////////////////////////////////////////////////////////////
template <typename T>
Event(const T& t);
////////////////////////////////////////////////////////////
/// \brief Check current event type
///
/// \return True if template parameter is current event type
///
////////////////////////////////////////////////////////////
template <typename T>
[[nodiscard]] bool is() const;
////////////////////////////////////////////////////////////
/// \brief Get particular event type
///
/// \return Address of current event type, otherwise nullptr
///
////////////////////////////////////////////////////////////
template <typename T>
[[nodiscard]] const T* getIf() const;
private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
EventType type{}; //!< Type of the event
std::variant<Empty,
Closed,
Resized,
FocusLost,
FocusGained,
TextEntered,
KeyPressed,
KeyReleased,
MouseWheelScrolled,
MouseButtonPressed,
MouseButtonReleased,
MouseMoved,
MouseEntered,
MouseLeft,
JoystickButtonPressed,
JoystickButtonReleased,
JoystickMoved,
JoystickConnected,
JoystickDisconnected,
TouchBegan,
TouchMoved,
TouchEnded,
SensorChanged>
m_data; //!< Event data
union
////////////////////////////////////////////////////////////
// Helper functions
////////////////////////////////////////////////////////////
template <typename T, typename... Ts>
static constexpr bool isInParameterPack(const std::variant<Ts...>&)
{
SizeEvent size; //!< Size event parameters (Event::Resized)
KeyEvent key; //!< Key event parameters (Event::KeyPressed, Event::KeyReleased)
TextEvent text; //!< Text event parameters (Event::TextEntered)
MouseMoveEvent mouseMove; //!< Mouse move event parameters (Event::MouseMoved)
MouseButtonEvent mouseButton; //!< Mouse button event parameters (Event::MouseButtonPressed, Event::MouseButtonReleased)
MouseWheelScrollEvent mouseWheelScroll; //!< Mouse wheel event parameters (Event::MouseWheelScrolled)
JoystickMoveEvent joystickMove; //!< Joystick move event parameters (Event::JoystickMoved)
JoystickButtonEvent joystickButton; //!< Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased)
JoystickConnectEvent joystickConnect; //!< Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected)
TouchEvent touch; //!< Touch events parameters (Event::TouchBegan, Event::TouchMoved, Event::TouchEnded)
SensorEvent sensor; //!< Sensor event parameters (Event::SensorChanged)
};
return (std::is_same_v<T, Ts> || ...);
}
template <typename T>
static constexpr bool isEventType = isInParameterPack<T>(decltype(m_data)());
};
} // namespace sf
#include <SFML/Window/Event.inl>
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
} // namespace sf
////////////////////////////////////////////////////////////
@ -235,30 +333,32 @@ struct Event
///
/// A sf::Event instance contains the type of the event
/// (mouse moved, key pressed, window closed, ...) as well
/// as the details about this particular event. Please note that
/// the event parameters are defined in a union, which means that
/// only the member matching the type of the event will be properly
/// filled; all other members will have undefined values and must not
/// be read if the type of the event doesn't match. For example,
/// if you received a KeyPressed event, then you must read the
/// event.key member, all other members such as event.mouseMove
/// or event.text will have undefined values.
/// as the details about this particular event. Each event
/// corresponds to a different struct which contains the data
/// required to process that event.
///
/// The way to access the current active event is via
/// sf::Event::getIf. This member function returns the address
/// of the event struct if the event type matches the active
/// event, otherise it returns nullptr. sf::Event::is is used
/// to check the active event type without actually reading
/// any of the corresponding event data.
///
/// Usage example:
/// \code
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// // Request for closing the window
/// if (event.type == sf::Event::Closed)
/// if (event.is<sf::Event::Closed>())
/// window.close();
///
/// // The escape key was pressed
/// if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Key::Escape))
/// window.close();
/// if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>())
/// if (keyPressed->code == sf::Keyboard::Key::Escape)
/// window.close();
///
/// // The window was resized
/// if (event.type == sf::Event::Resized)
/// doSomethingWithTheNewSize(event.size.width, event.size.height);
/// if (const auto* resized = event.getIf<sf::Event::Resized>())
/// doSomethingWithTheNewSize(resized->size);
///
/// // etc ...
/// }

View File

@ -0,0 +1,60 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2024 Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
// Repeating isEventType<T> allows for cleaner compiler errors.
// It is not strictly necessary but it's useful nonetheless.
// It works by ensuring that the code within the conditional is
// only compiled when the condition is met. Otherwise you get
// a static_assert failure in addition to the compiler failing
// to compile the code within the compiletime conditional when
// an incorrect template parameter is provided.
////////////////////////////////////////////////////////////
template <typename T>
Event::Event(const T& t)
{
static_assert(isEventType<T>, "T must be a subtype of sf::Event");
if constexpr (isEventType<T>)
m_data = t;
}
////////////////////////////////////////////////////////////
template <typename T>
bool Event::is() const
{
static_assert(isEventType<T>, "T must be a subtype of sf::Event");
if constexpr (isEventType<T>)
return std::holds_alternative<T>(m_data);
}
////////////////////////////////////////////////////////////
template <typename T>
const T* Event::getIf() const
{
static_assert(isEventType<T>, "T must be a subtype of sf::Event");
if constexpr (isEventType<T>)
return std::get_if<T>(&m_data);
}

View File

@ -350,7 +350,7 @@ private:
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// // Request for closing the window
/// if (event.type == sf::Event::Closed)
/// if (event.is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -52,7 +52,7 @@ namespace priv
class WindowImpl;
}
struct Event;
class Event;
////////////////////////////////////////////////////////////
/// \brief Window that serves as a base for other windows
@ -566,7 +566,7 @@ private:
/// for (sf::Event event; window.pollEvent(event);)
/// {
/// // Request for closing the window
/// if (event.type == sf::Event::Closed)
/// if (event.is<sf::Event::Closed>())
/// window.close();
/// }
///

View File

@ -266,10 +266,7 @@ static void onResume(ANativeActivity* activity)
goToFullscreenMode(activity);
// Send an event to warn people the activity has been resumed
sf::Event event;
event.type = sf::Event::MouseEntered;
states->forwardEvent(event);
states->forwardEvent(sf::Event::MouseEntered{});
}
@ -281,10 +278,7 @@ static void onPause(ANativeActivity* activity)
const std::lock_guard lock(states->mutex);
// Send an event to warn people the activity has been paused
sf::Event event;
event.type = sf::Event::MouseLeft;
states->forwardEvent(event);
states->forwardEvent(sf::Event::MouseLeft{});
}
@ -307,12 +301,7 @@ static void onDestroy(ANativeActivity* activity)
// If the main thread hasn't yet finished, send the event and wait for
// it to finish.
if (!states->mainOver)
{
sf::Event event;
event.type = sf::Event::Closed;
states->forwardEvent(event);
}
states->forwardEvent(sf::Event::Closed{});
}
// Wait for the main thread to be terminated
@ -350,9 +339,7 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind
states->window = window;
// Notify SFML mechanism
sf::Event event;
event.type = sf::Event::GainedFocus;
states->forwardEvent(event);
states->forwardEvent(sf::Event::FocusGained{});
// Wait for the event to be taken into account by SFML
states->updated = false;
@ -375,9 +362,7 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* /*
states->window = nullptr;
// Notify SFML mechanism
sf::Event event;
event.type = sf::Event::LostFocus;
states->forwardEvent(event);
states->forwardEvent(sf::Event::FocusLost{});
// Wait for the event to be taken into account by SFML
states->updated = false;
@ -453,11 +438,8 @@ static void onContentRectChanged(ANativeActivity* activity, const ARect* /* rect
if (states->window != nullptr)
{
// Send an event to warn people about the window move/resize
sf::Event event;
event.type = sf::Event::Resized;
event.size.width = static_cast<unsigned int>(ANativeWindow_getWidth(states->window));
event.size.height = static_cast<unsigned int>(ANativeWindow_getHeight(states->window));
const sf::Event::Resized event{
sf::Vector2u(sf::Vector2(ANativeWindow_getWidth(states->window), ANativeWindow_getHeight(states->window)))};
states->forwardEvent(event);
}
}

View File

@ -234,14 +234,14 @@ void WindowImplAndroid::forwardEvent(const Event& event)
{
ActivityStates& states = getActivity();
if (event.type == Event::GainedFocus)
if (event.is<Event::FocusGained>())
{
WindowImplAndroid::singleInstance->m_size = Vector2u(
Vector2i(ANativeWindow_getWidth(states.window), ANativeWindow_getHeight(states.window)));
WindowImplAndroid::singleInstance->m_windowBeingCreated = true;
WindowImplAndroid::singleInstance->m_hasFocus = true;
}
else if (event.type == Event::LostFocus)
else if (event.is<Event::FocusLost>())
{
WindowImplAndroid::singleInstance->m_windowBeingDestroyed = true;
WindowImplAndroid::singleInstance->m_hasFocus = false;
@ -392,13 +392,10 @@ int WindowImplAndroid::processScrollEvent(AInputEvent* inputEvent, ActivityState
lJNIEnv->DeleteLocalRef(objectMotionEvent);
// Create and send our mouse wheel event
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Vertical;
event.mouseWheelScroll.delta = static_cast<float>(delta);
event.mouseWheelScroll.x = static_cast<int>(AMotionEvent_getX(inputEvent, 0));
event.mouseWheelScroll.y = static_cast<int>(AMotionEvent_getY(inputEvent, 0));
Event::MouseWheelScrolled event;
event.wheel = Mouse::Wheel::Vertical;
event.delta = static_cast<float>(delta);
event.position = Vector2i(Vector2(AMotionEvent_getX(inputEvent, 0), AMotionEvent_getY(inputEvent, 0)));
forwardEvent(event);
// Detach this thread from the JVM
@ -416,36 +413,28 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
std::int32_t key = AKeyEvent_getKeyCode(inputEvent);
std::int32_t metakey = AKeyEvent_getMetaState(inputEvent);
Event event;
event.key.code = androidKeyToSF(key);
event.key.alt = metakey & AMETA_ALT_ON;
event.key.control = false;
event.key.shift = metakey & AMETA_SHIFT_ON;
Event::KeyChanged keyChanged;
keyChanged.code = androidKeyToSF(key);
keyChanged.alt = metakey & AMETA_ALT_ON;
keyChanged.control = false;
keyChanged.shift = metakey & AMETA_SHIFT_ON;
switch (action)
{
case AKEY_EVENT_ACTION_DOWN:
event.type = Event::KeyPressed;
forwardEvent(event);
forwardEvent(Event::KeyPressed{keyChanged});
return 1;
case AKEY_EVENT_ACTION_UP:
event.type = Event::KeyReleased;
forwardEvent(event);
forwardEvent(Event::KeyReleased{keyChanged});
if (auto unicode = static_cast<std::uint32_t>(getUnicode(inputEvent)))
{
event.type = Event::TextEntered;
event.text.unicode = static_cast<std::uint32_t>(unicode);
forwardEvent(event);
}
forwardEvent(Event::TextEntered{static_cast<std::uint32_t>(unicode)});
return 1;
case AKEY_EVENT_ACTION_MULTIPLE:
// Since complex inputs don't get separate key down/up events
// both have to be faked at once
event.type = Event::KeyPressed;
forwardEvent(event);
event.type = Event::KeyReleased;
forwardEvent(event);
forwardEvent(Event::KeyPressed{keyChanged});
forwardEvent(Event::KeyReleased{keyChanged});
// This requires some special treatment, since this might represent
// a repetition of key presses or a complete sequence
@ -457,8 +446,7 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
}
else if (auto unicode = static_cast<std::uint32_t>(getUnicode(inputEvent))) // This is a repeated sequence
{
event.type = Event::TextEntered;
event.text.unicode = static_cast<std::uint32_t>(unicode);
const Event event(Event::TextEntered{static_cast<std::uint32_t>(unicode)});
std::int32_t repeats = AKeyEvent_getRepeatCount(inputEvent);
for (std::int32_t i = 0; i < repeats; ++i)
@ -479,9 +467,9 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityState
Event event;
if (device == AINPUT_SOURCE_MOUSE)
event.type = Event::MouseMoved;
event = Event::MouseMoved{};
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
event.type = Event::TouchMoved;
event = Event::TouchMoved{};
std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent);
@ -494,21 +482,20 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityState
if (device == AINPUT_SOURCE_MOUSE)
{
event.mouseMove.x = x;
event.mouseMove.y = y;
const Event::MouseMoved mouseMoved{{x, y}};
event = mouseMoved;
states.mousePosition = Vector2i(event.mouseMove.x, event.mouseMove.y);
states.mousePosition = mouseMoved.position;
}
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{
if (states.touchEvents[id].x == x && states.touchEvents[id].y == y)
continue;
event.touch.finger = static_cast<unsigned int>(id);
event.touch.x = x;
event.touch.y = y;
const Event::TouchMoved touchMoved{static_cast<unsigned int>(id), {x, y}};
event = touchMoved;
states.touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
states.touchEvents[id] = touchMoved.position;
}
forwardEvent(event);
@ -536,42 +523,33 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* inputEvent,
{
if (device == AINPUT_SOURCE_MOUSE)
{
event.type = Event::MouseButtonPressed;
event.mouseButton.button = button;
event.mouseButton.x = x;
event.mouseButton.y = y;
event = Event::MouseButtonPressed{button, {x, y}};
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = true;
}
else if (static_cast<unsigned int>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{
event.type = Event::TouchBegan;
event.touch.finger = static_cast<unsigned int>(id);
event.touch.x = x;
event.touch.y = y;
Event::TouchBegan touchBegan;
touchBegan.finger = static_cast<unsigned int>(id);
touchBegan.position = {x, y};
event = touchBegan;
states.touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
states.touchEvents[id] = touchBegan.position;
}
}
else
{
if (device == AINPUT_SOURCE_MOUSE)
{
event.type = Event::MouseButtonReleased;
event.mouseButton.button = button;
event.mouseButton.x = x;
event.mouseButton.y = y;
event = Event::MouseButtonReleased{button, {x, y}};
if (id >= 0 && id < static_cast<int>(Mouse::ButtonCount))
states.isButtonPressed[button] = false;
}
else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN)
{
event.type = Event::TouchEnded;
event.touch.finger = static_cast<unsigned int>(id);
event.touch.x = x;
event.touch.y = y;
event = Event::TouchEnded{static_cast<unsigned int>(id), {x, y}};
states.touchEvents.erase(id);
}

View File

@ -18,6 +18,7 @@ set(SRC
${INCROOT}/GlResource.hpp
${INCROOT}/ContextSettings.hpp
${INCROOT}/Event.hpp
${INCROOT}/Event.inl
${SRCROOT}/InputImpl.hpp
${INCROOT}/Joystick.hpp
${SRCROOT}/Joystick.cpp

View File

@ -306,7 +306,7 @@ sf::Keyboard::Key toKey(int code)
}
}
void pushEvent(sf::Event& event)
void pushEvent(const sf::Event& event)
{
if (eventQueue.size() >= maxQueue)
eventQueue.pop();
@ -325,31 +325,16 @@ void processSlots()
{
for (auto& slot : touchSlots)
{
sf::Event event;
event.touch.x = slot.pos.x;
event.touch.y = slot.pos.y;
if (slot.oldId == slot.id)
{
event.type = sf::Event::TouchMoved;
event.touch.finger = static_cast<unsigned int>(slot.id);
pushEvent(event);
pushEvent(sf::Event::TouchMoved{static_cast<unsigned int>(slot.id), slot.pos});
}
else
{
if (slot.oldId != -1)
{
event.type = sf::Event::TouchEnded;
event.touch.finger = static_cast<unsigned int>(slot.oldId);
pushEvent(event);
}
pushEvent(sf::Event::TouchEnded{static_cast<unsigned int>(slot.oldId), slot.pos});
if (slot.id != -1)
{
event.type = sf::Event::TouchBegan;
event.touch.finger = static_cast<unsigned int>(slot.id);
pushEvent(event);
}
pushEvent(sf::Event::TouchBegan{static_cast<unsigned int>(slot.id), slot.pos});
slot.oldId = slot.id;
}
@ -368,9 +353,8 @@ bool eventProcess(sf::Event& event)
static unsigned int doDeferredText = 0;
if (doDeferredText)
{
event.type = sf::Event::TextEntered;
event.text.unicode = doDeferredText;
doDeferredText = 0;
event = sf::Event::TextEntered{doDeferredText};
doDeferredText = 0;
return true;
}
@ -388,10 +372,10 @@ bool eventProcess(sf::Event& event)
{
if (const std::optional<sf::Mouse::Button> mb = toMouseButton(inputEvent.code))
{
event.type = inputEvent.value ? sf::Event::MouseButtonPressed : sf::Event::MouseButtonReleased;
event.mouseButton.button = *mb;
event.mouseButton.x = mousePos.x;
event.mouseButton.y = mousePos.y;
if (inputEvent.value)
event = sf::Event::MouseButtonPressed{*mb, mousePos};
else
event = sf::Event::MouseButtonReleased{*mb, mousePos};
mouseMap[*mb] = inputEvent.value;
return true;
@ -410,8 +394,7 @@ bool eventProcess(sf::Event& event)
//
if (special)
{
event.type = sf::Event::TextEntered;
event.text.unicode = special;
event = sf::Event::TextEntered{special};
return true;
}
}
@ -419,13 +402,18 @@ bool eventProcess(sf::Event& event)
{
// key down and key up events
//
event.type = inputEvent.value ? sf::Event::KeyPressed : sf::Event::KeyReleased;
event.key.code = kb;
event.key.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented
event.key.alt = altDown();
event.key.control = controlDown();
event.key.shift = shiftDown();
event.key.system = systemDown();
sf::Event::KeyChanged keyChanged;
keyChanged.code = kb;
keyChanged.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented
keyChanged.alt = altDown();
keyChanged.control = controlDown();
keyChanged.shift = shiftDown();
keyChanged.system = systemDown();
if (inputEvent.value)
event = sf::Event::KeyPressed{keyChanged};
else
event = sf::Event::KeyReleased{keyChanged};
keyMap[kb] = inputEvent.value;
@ -452,18 +440,16 @@ bool eventProcess(sf::Event& event)
break;
case REL_WHEEL:
event.type = sf::Event::MouseWheelScrolled;
event.mouseWheelScroll.delta = static_cast<float>(inputEvent.value);
event.mouseWheelScroll.x = mousePos.x;
event.mouseWheelScroll.y = mousePos.y;
sf::Event::MouseWheelScrolled mouseWheelScrolled;
mouseWheelScrolled.delta = static_cast<float>(inputEvent.value);
mouseWheelScrolled.position = mousePos;
event = mouseWheelScrolled;
return true;
}
if (posChange)
{
event.type = sf::Event::MouseMoved;
event.mouseMove.x = mousePos.x;
event.mouseMove.y = mousePos.y;
event = sf::Event::MouseMoved{mousePos};
return true;
}
}
@ -548,8 +534,7 @@ bool eventProcess(sf::Event& event)
if (code > 0)
{
// TODO: Proper unicode handling
event.type = sf::Event::TextEntered;
event.text.unicode = code;
event = sf::Event::TextEntered{code};
return true;
}

View File

@ -1712,9 +1712,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
err() << "Failed to grab mouse cursor" << std::endl;
}
Event event;
event.type = Event::GainedFocus;
pushEvent(event);
pushEvent(Event::FocusGained{});
// If the window has been previously marked urgent (notification) as a result of a focus request, undo that
const auto hints = X11Ptr<XWMHints>(XGetWMHints(m_display.get(), m_window));
@ -1739,9 +1737,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
if (m_cursorGrabbed)
XUngrabPointer(m_display.get(), CurrentTime);
Event event;
event.type = Event::LostFocus;
pushEvent(event);
pushEvent(Event::FocusLost{});
break;
}
@ -1751,11 +1747,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
// ConfigureNotify can be triggered for other reasons, check if the size has actually changed
if ((windowEvent.xconfigure.width != m_previousSize.x) || (windowEvent.xconfigure.height != m_previousSize.y))
{
Event event;
event.type = Event::Resized;
event.size.width = static_cast<unsigned int>(windowEvent.xconfigure.width);
event.size.height = static_cast<unsigned int>(windowEvent.xconfigure.height);
pushEvent(event);
pushEvent(Event::Resized{Vector2u(Vector2(windowEvent.xconfigure.width, windowEvent.xconfigure.height))});
m_previousSize.x = windowEvent.xconfigure.width;
m_previousSize.y = windowEvent.xconfigure.height;
@ -1781,9 +1773,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
(windowEvent.xclient.data.l[0]) == static_cast<long>(wmDeleteWindow))
{
// Handle the WM_DELETE_WINDOW message
Event event;
event.type = Event::Closed;
pushEvent(event);
pushEvent(Event::Closed{});
}
else if (netWmPing && (windowEvent.xclient.format == 32) &&
(windowEvent.xclient.data.l[0]) == static_cast<long>(netWmPing))
@ -1807,14 +1797,13 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
{
// Fill the event parameters
// TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping
Event event;
event.type = Event::KeyPressed;
event.key.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
event.key.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
event.key.alt = windowEvent.xkey.state & Mod1Mask;
event.key.control = windowEvent.xkey.state & ControlMask;
event.key.shift = windowEvent.xkey.state & ShiftMask;
event.key.system = windowEvent.xkey.state & Mod4Mask;
Event::KeyPressed event;
event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
event.alt = windowEvent.xkey.state & Mod1Mask;
event.control = windowEvent.xkey.state & ControlMask;
event.shift = windowEvent.xkey.state & ShiftMask;
event.system = windowEvent.xkey.state & Mod4Mask;
const bool filtered = XFilterEvent(&windowEvent, None);
@ -1868,12 +1857,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
{
iter = Utf8::decode(iter, keyBuffer + length, unicode, 0);
if (unicode != 0)
{
Event textEvent;
textEvent.type = Event::TextEntered;
textEvent.text.unicode = unicode;
pushEvent(textEvent);
}
pushEvent(Event::TextEntered{unicode});
}
}
}
@ -1883,12 +1867,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
static XComposeStatus status;
char keyBuffer[16];
if (XLookupString(&windowEvent.xkey, keyBuffer, sizeof(keyBuffer), nullptr, &status))
{
Event textEvent;
textEvent.type = Event::TextEntered;
textEvent.text.unicode = static_cast<std::uint32_t>(keyBuffer[0]);
pushEvent(textEvent);
}
pushEvent(Event::TextEntered{static_cast<std::uint32_t>(keyBuffer[0])});
}
}
@ -1901,14 +1880,13 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
case KeyRelease:
{
// Fill the event parameters
Event event;
event.type = Event::KeyReleased;
event.key.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
event.key.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
event.key.alt = windowEvent.xkey.state & Mod1Mask;
event.key.control = windowEvent.xkey.state & ControlMask;
event.key.shift = windowEvent.xkey.state & ShiftMask;
event.key.system = windowEvent.xkey.state & Mod4Mask;
Event::KeyReleased event;
event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey);
event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey);
event.alt = windowEvent.xkey.state & Mod1Mask;
event.control = windowEvent.xkey.state & ControlMask;
event.shift = windowEvent.xkey.state & ShiftMask;
event.system = windowEvent.xkey.state & Mod4Mask;
pushEvent(event);
break;
@ -1921,19 +1899,17 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
const unsigned int button = windowEvent.xbutton.button;
if ((button == Button1) || (button == Button2) || (button == Button3) || (button == 8) || (button == 9))
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.x = windowEvent.xbutton.x;
event.mouseButton.y = windowEvent.xbutton.y;
Event::MouseButtonPressed event;
event.position = {windowEvent.xbutton.x, windowEvent.xbutton.y};
// clang-format off
switch(button)
{
case Button1: event.mouseButton.button = Mouse::Button::Left; break;
case Button2: event.mouseButton.button = Mouse::Button::Middle; break;
case Button3: event.mouseButton.button = Mouse::Button::Right; break;
case 8: event.mouseButton.button = Mouse::Button::Extra1; break;
case 9: event.mouseButton.button = Mouse::Button::Extra2; break;
case Button1: event.button = Mouse::Button::Left; break;
case Button2: event.button = Mouse::Button::Middle; break;
case Button3: event.button = Mouse::Button::Right; break;
case 8: event.button = Mouse::Button::Extra1; break;
case 9: event.button = Mouse::Button::Extra2; break;
}
// clang-format on
@ -1951,49 +1927,42 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
const unsigned int button = windowEvent.xbutton.button;
if ((button == Button1) || (button == Button2) || (button == Button3) || (button == 8) || (button == 9))
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.x = windowEvent.xbutton.x;
event.mouseButton.y = windowEvent.xbutton.y;
Event::MouseButtonReleased event;
event.position = {windowEvent.xbutton.x, windowEvent.xbutton.y};
switch (button)
{
case Button1:
event.mouseButton.button = Mouse::Button::Left;
event.button = Mouse::Button::Left;
break;
case Button2:
event.mouseButton.button = Mouse::Button::Middle;
event.button = Mouse::Button::Middle;
break;
case Button3:
event.mouseButton.button = Mouse::Button::Right;
event.button = Mouse::Button::Right;
break;
case 8:
event.mouseButton.button = Mouse::Button::Extra1;
event.button = Mouse::Button::Extra1;
break;
case 9:
event.mouseButton.button = Mouse::Button::Extra2;
event.button = Mouse::Button::Extra2;
break;
}
pushEvent(event);
}
else if ((button == Button4) || (button == Button5))
{
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Vertical;
event.mouseWheelScroll.delta = (button == Button4) ? 1 : -1;
event.mouseWheelScroll.x = windowEvent.xbutton.x;
event.mouseWheelScroll.y = windowEvent.xbutton.y;
Event::MouseWheelScrolled event;
event.wheel = Mouse::Wheel::Vertical;
event.delta = (button == Button4) ? 1 : -1;
event.position = {windowEvent.xbutton.x, windowEvent.xbutton.y};
pushEvent(event);
}
else if ((button == 6) || (button == 7))
{
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Horizontal;
event.mouseWheelScroll.delta = (button == 6) ? 1 : -1;
event.mouseWheelScroll.x = windowEvent.xbutton.x;
event.mouseWheelScroll.y = windowEvent.xbutton.y;
Event::MouseWheelScrolled event;
event.wheel = Mouse::Wheel::Horizontal;
event.delta = (button == 6) ? 1 : -1;
event.position = {windowEvent.xbutton.x, windowEvent.xbutton.y};
pushEvent(event);
}
break;
@ -2002,11 +1971,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
// Mouse moved
case MotionNotify:
{
Event event;
event.type = Event::MouseMoved;
event.mouseMove.x = windowEvent.xmotion.x;
event.mouseMove.y = windowEvent.xmotion.y;
pushEvent(event);
pushEvent(Event::MouseMoved{{windowEvent.xmotion.x, windowEvent.xmotion.y}});
break;
}
@ -2014,11 +1979,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
case EnterNotify:
{
if (windowEvent.xcrossing.mode == NotifyNormal)
{
Event event;
event.type = Event::MouseEntered;
pushEvent(event);
}
pushEvent(Event::MouseEntered{});
break;
}
@ -2026,11 +1987,7 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
case LeaveNotify:
{
if (windowEvent.xcrossing.mode == NotifyNormal)
{
Event event;
event.type = Event::MouseLeft;
pushEvent(event);
}
pushEvent(Event::MouseLeft{});
break;
}

View File

@ -734,9 +734,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Close event
case WM_CLOSE:
{
Event event;
event.type = Event::Closed;
pushEvent(event);
pushEvent(Event::Closed{});
break;
}
@ -750,11 +748,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
m_lastSize = getSize();
// Push a resize event
Event event;
event.type = Event::Resized;
event.size.width = m_lastSize.x;
event.size.height = m_lastSize.y;
pushEvent(event);
pushEvent(Event::Resized{m_lastSize});
// Restore/update cursor grabbing
grabCursor(m_cursorGrabbed);
@ -782,11 +776,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
m_lastSize = getSize();
// Push a resize event
Event event;
event.type = Event::Resized;
event.size.width = m_lastSize.x;
event.size.height = m_lastSize.y;
pushEvent(event);
pushEvent(Event::Resized{m_lastSize});
}
// Restore/update cursor grabbing
@ -825,9 +815,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Restore cursor grabbing
grabCursor(m_cursorGrabbed);
Event event;
event.type = Event::GainedFocus;
pushEvent(event);
pushEvent(Event::FocusGained{});
break;
}
@ -837,9 +825,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Ungrab the cursor
grabCursor(false);
Event event;
event.type = Event::LostFocus;
pushEvent(event);
pushEvent(Event::FocusLost{});
break;
}
@ -869,10 +855,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
}
// Send a TextEntered event
Event event;
event.type = Event::TextEntered;
event.text.unicode = character;
pushEvent(event);
pushEvent(Event::TextEntered{character});
}
}
break;
@ -884,14 +867,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
if (m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0))
{
Event event;
event.type = Event::KeyPressed;
event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0;
event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0;
event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
event.key.code = virtualKeyCodeToSF(wParam, lParam);
event.key.scancode = toScancode(wParam, lParam);
Event::KeyPressed event;
event.alt = HIWORD(GetKeyState(VK_MENU)) != 0;
event.control = HIWORD(GetKeyState(VK_CONTROL)) != 0;
event.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
event.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
event.code = virtualKeyCodeToSF(wParam, lParam);
event.scancode = toScancode(wParam, lParam);
pushEvent(event);
}
break;
@ -901,14 +883,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
case WM_KEYUP:
case WM_SYSKEYUP:
{
Event event;
event.type = Event::KeyReleased;
event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0;
event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0;
event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
event.key.code = virtualKeyCodeToSF(wParam, lParam);
event.key.scancode = toScancode(wParam, lParam);
Event::KeyReleased event;
event.alt = HIWORD(GetKeyState(VK_MENU)) != 0;
event.control = HIWORD(GetKeyState(VK_CONTROL)) != 0;
event.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0;
event.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN));
event.code = virtualKeyCodeToSF(wParam, lParam);
event.scancode = toScancode(wParam, lParam);
pushEvent(event);
break;
}
@ -924,13 +905,10 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
auto delta = static_cast<std::int16_t>(HIWORD(wParam));
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Vertical;
event.mouseWheelScroll.delta = static_cast<float>(delta) / 120.f;
event.mouseWheelScroll.x = position.x;
event.mouseWheelScroll.y = position.y;
Event::MouseWheelScrolled event;
event.wheel = Mouse::Wheel::Vertical;
event.delta = static_cast<float>(delta) / 120.f;
event.position = {position.x, position.y};
pushEvent(event);
break;
}
@ -946,12 +924,10 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
auto delta = static_cast<std::int16_t>(HIWORD(wParam));
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Horizontal;
event.mouseWheelScroll.delta = -static_cast<float>(delta) / 120.f;
event.mouseWheelScroll.x = position.x;
event.mouseWheelScroll.y = position.y;
Event::MouseWheelScrolled event;
event.wheel = Mouse::Wheel::Horizontal;
event.delta = -static_cast<float>(delta) / 120.f;
event.position = {position.x, position.y};
pushEvent(event);
break;
}
@ -959,11 +935,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse left button down event
case WM_LBUTTONDOWN:
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.button = Mouse::Button::Left;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonPressed event;
event.button = Mouse::Button::Left;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -971,11 +945,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse left button up event
case WM_LBUTTONUP:
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.button = Mouse::Button::Left;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonReleased event;
event.button = Mouse::Button::Left;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -983,11 +955,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse right button down event
case WM_RBUTTONDOWN:
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.button = Mouse::Button::Right;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonPressed event;
event.button = Mouse::Button::Right;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -995,11 +965,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse right button up event
case WM_RBUTTONUP:
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.button = Mouse::Button::Right;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonReleased event;
event.button = Mouse::Button::Right;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -1007,11 +975,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse wheel button down event
case WM_MBUTTONDOWN:
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.button = Mouse::Button::Middle;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonPressed event;
event.button = Mouse::Button::Middle;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -1019,11 +985,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse wheel button up event
case WM_MBUTTONUP:
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.button = Mouse::Button::Middle;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonReleased event;
event.button = Mouse::Button::Middle;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -1031,11 +995,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse X button down event
case WM_XBUTTONDOWN:
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::Button::Extra1 : Mouse::Button::Extra2;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonPressed event;
event.button = HIWORD(wParam) == XBUTTON1 ? Mouse::Button::Extra1 : Mouse::Button::Extra2;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -1043,11 +1005,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Mouse X button up event
case WM_XBUTTONUP:
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::Button::Extra1 : Mouse::Button::Extra2;
event.mouseButton.x = static_cast<std::int16_t>(LOWORD(lParam));
event.mouseButton.y = static_cast<std::int16_t>(HIWORD(lParam));
Event::MouseButtonReleased event;
event.button = HIWORD(wParam) == XBUTTON1 ? Mouse::Button::Extra1 : Mouse::Button::Extra2;
event.position = {static_cast<std::int16_t>(LOWORD(lParam)), static_cast<std::int16_t>(HIWORD(lParam))};
pushEvent(event);
break;
}
@ -1061,9 +1021,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
m_mouseInside = false;
// Generate a MouseLeft event
Event event;
event.type = Event::MouseLeft;
pushEvent(event);
pushEvent(Event::MouseLeft{});
}
break;
}
@ -1104,9 +1062,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
setTracking(false);
// Generate a MouseLeft event
Event event;
event.type = Event::MouseLeft;
pushEvent(event);
pushEvent(Event::MouseLeft{});
}
}
else
@ -1120,18 +1076,12 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
setTracking(true);
// Generate a MouseEntered event
Event event;
event.type = Event::MouseEntered;
pushEvent(event);
pushEvent(Event::MouseEntered{});
}
}
// Generate a MouseMove event
Event event;
event.type = Event::MouseMoved;
event.mouseMove.x = x;
event.mouseMove.y = y;
pushEvent(event);
pushEvent(Event::MouseMoved{{x, y}});
break;
}

View File

@ -409,10 +409,10 @@ void WindowBase::create(VideoMode mode, std::uint32_t& style, State& state)
void WindowBase::filterEvent(const Event& event)
{
// Notify resize events to the derived class
if (event.type == Event::Resized)
if (const auto* resized = event.getIf<Event::Resized>())
{
// Cache the new size
m_size = {event.size.width, event.size.height};
m_size = resized->size;
// Notify the derived class
onResize();

View File

@ -238,10 +238,10 @@ void WindowImpl::processJoystickEvents()
const bool connected = m_joystickStatesImpl->states[i].connected;
if (previousState.connected ^ connected)
{
Event event;
event.type = connected ? Event::JoystickConnected : Event::JoystickDisconnected;
event.joystickButton.joystickId = i;
pushEvent(event);
if (connected)
pushEvent(Event::JoystickConnected{i});
else
pushEvent(Event::JoystickDisconnected{i});
// Clear previous axes positions
if (connected)
@ -262,13 +262,7 @@ void WindowImpl::processJoystickEvents()
const float currPos = m_joystickStatesImpl->states[i].axes[axis];
if (std::abs(currPos - prevPos) >= m_joystickThreshold)
{
Event event;
event.type = Event::JoystickMoved;
event.joystickMove.joystickId = i;
event.joystickMove.axis = axis;
event.joystickMove.position = currPos;
pushEvent(event);
pushEvent(Event::JoystickMoved{i, axis, currPos});
m_previousAxes[i][axis] = currPos;
}
}
@ -282,11 +276,10 @@ void WindowImpl::processJoystickEvents()
if (prevPressed ^ currPressed)
{
Event event;
event.type = currPressed ? Event::JoystickButtonPressed : Event::JoystickButtonReleased;
event.joystickButton.joystickId = i;
event.joystickButton.button = j;
pushEvent(event);
if (currPressed)
pushEvent(Event::JoystickButtonPressed{i, j});
else
pushEvent(Event::JoystickButtonReleased{i, j});
}
}
}
@ -313,15 +306,7 @@ void WindowImpl::processSensorEvents()
// If the value has changed, trigger an event
if (m_sensorValue[sensor] != previousValue) // TODO use a threshold?
{
Event event;
event.type = Event::SensorChanged;
event.sensor.type = sensor;
event.sensor.x = m_sensorValue[sensor].x;
event.sensor.y = m_sensorValue[sensor].y;
event.sensor.z = m_sensorValue[sensor].z;
pushEvent(event);
}
pushEvent(Event::SensorChanged{sensor, m_sensorValue[sensor]});
}
}
}

View File

@ -119,13 +119,9 @@ std::vector<sf::Vector2i> touchPositions;
// - the application is sent to background
// - the application is interrupted by a call or message
// Generate a LostFocus event
// Generate a FocusLost event
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::LostFocus;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::FocusLost{});
}
@ -143,13 +139,9 @@ std::vector<sf::Vector2i> touchPositions;
// - the application is sent to foreground
// - the application was interrupted by a call or message
// Generate a GainedFocus event
// Generate a FocusGained event
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::GainedFocus;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::FocusGained{});
}
@ -165,11 +157,7 @@ std::vector<sf::Vector2i> touchPositions;
{
// Generate a Closed event
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::Closed;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::Closed{});
}
- (bool)supportsOrientation:(UIDeviceOrientation)orientation
@ -229,11 +217,7 @@ std::vector<sf::Vector2i> touchPositions;
std::swap(size.x, size.y);
// Send a Resized event to the current window
sf::Event event;
event.type = sf::Event::Resized;
event.size.width = size.x;
event.size.height = size.y;
sfWindow->forwardEvent(event);
sfWindow->forwardEvent(sf::Event::Resized{size});
}
}
}
@ -269,14 +253,7 @@ std::vector<sf::Vector2i> touchPositions;
// notify the event to the application window
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::TouchBegan;
event.touch.finger = index;
event.touch.x = position.x;
event.touch.y = position.y;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::TouchBegan{index, position});
}
@ -293,14 +270,7 @@ std::vector<sf::Vector2i> touchPositions;
// notify the event to the application window
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::TouchMoved;
event.touch.finger = index;
event.touch.x = position.x;
event.touch.y = position.y;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::TouchMoved{index, position});
}
@ -313,14 +283,7 @@ std::vector<sf::Vector2i> touchPositions;
// notify the event to the application window
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::TouchEnded;
event.touch.finger = index;
event.touch.x = position.x * static_cast<int>(backingScaleFactor);
event.touch.y = position.y * static_cast<int>(backingScaleFactor);
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::TouchEnded{index, position * static_cast<int>(backingScaleFactor)});
}
@ -328,12 +291,7 @@ std::vector<sf::Vector2i> touchPositions;
- (void)notifyCharacter:(std::uint32_t)character
{
if (self.sfWindow)
{
sf::Event event;
event.type = sf::Event::TextEntered;
event.text.unicode = character;
sfWindow->forwardEvent(event);
}
sfWindow->forwardEvent(sf::Event::TextEntered{character});
}

View File

@ -230,9 +230,9 @@ bool WindowImplUIKit::hasFocus() const
////////////////////////////////////////////////////////////
void WindowImplUIKit::forwardEvent(Event event)
{
if (event.type == Event::GainedFocus)
if (event.is<Event::FocusGained>())
m_hasFocus = true;
else if (event.type == Event::LostFocus)
else if (event.is<Event::FocusLost>())
m_hasFocus = false;
pushEvent(event);

View File

@ -57,7 +57,7 @@ void initialiseKeyboardHelper();
/// \brief Set up a SFML key event based on the given modifiers flags and key code
///
////////////////////////////////////////////////////////////
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code);
sf::Event::KeyChanged keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code);
////////////////////////////////////////////////////////////

View File

@ -151,16 +151,15 @@ void initialiseKeyboardHelper()
////////////////////////////////////////////////////////
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code)
sf::Event::KeyChanged keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code)
{
sf::Event::KeyEvent event{};
sf::Event::KeyChanged event;
event.code = key;
event.scancode = code;
event.alt = modifiers & NSAlternateKeyMask;
event.control = modifiers & NSControlKeyMask;
event.shift = modifiers & NSShiftKeyMask;
event.system = modifiers & NSCommandKeyMask;
return event;
}
@ -244,19 +243,16 @@ void processOneModifier(NSUInteger modifiers,
sf::Keyboard::Scancode code,
sf::priv::WindowImplCocoa& requester)
{
// Setup a potential event key.
const sf::Event::KeyEvent event = keyEventWithModifiers(modifiers, key, code);
// State
const BOOL isDown = isKeyMaskActive(modifiers, mask);
// Check for key pressed event
if (isDown && !wasDown)
requester.keyDown(event);
requester.keyDown(sf::Event::KeyPressed{keyEventWithModifiers(modifiers, key, code)});
// And check for key released event
else if (!isDown && wasDown)
requester.keyUp(event);
requester.keyUp(sf::Event::KeyReleased{keyEventWithModifiers(modifiers, key, code)});
// else isDown == wasDown, so no change

View File

@ -84,7 +84,7 @@
// Handle key down event
if (m_useKeyRepeat || ![theEvent isARepeat])
{
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
const auto key = sf::Event::KeyPressed{[SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent]};
if ((key.code != sf::Keyboard::Key::Unknown) || (key.scancode != sf::Keyboard::Scan::Unknown))
m_requester->keyDown(key);
@ -156,7 +156,7 @@
if (m_requester == nil)
return;
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
const auto key = sf::Event::KeyReleased{[SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent]};
if ((key.code != sf::Keyboard::Key::Unknown) || (key.scancode != sf::Keyboard::Scan::Unknown))
m_requester->keyUp(key);
@ -178,7 +178,7 @@
////////////////////////////////////////////////////////
+ (sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
+ (sf::Event::KeyChanged)convertNSKeyEventToSFMLEvent:(NSEvent*)event
{
// The scancode always depends on the hardware keyboard, not some OS setting.
sf::Keyboard::Scancode code = sf::priv::HIDInputManager::nonLocalizedKey([event keyCode]);

View File

@ -51,7 +51,7 @@
/// \return sf::Keyboard::Key::Unknown as Code if the key is unknown
///
////////////////////////////////////////////////////////////
+ (sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
+ (sf::Event::KeyChanged)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
////////////////////////////////////////////////////////////
/// \brief Check if the event represent some Unicode text

View File

@ -138,7 +138,7 @@
NSPoint loc = [self cursorPositionFromEvent:theEvent];
if (button)
m_requester->mouseDownAt(*button, static_cast<int>(loc.x), static_cast<int>(loc.y));
m_requester->mouseDownAt(*button, sf::Vector2i(sf::Vector2(loc.x, loc.y)));
}
}
@ -183,7 +183,7 @@
NSPoint loc = [self cursorPositionFromEvent:theEvent];
if (button)
m_requester->mouseUpAt(*button, static_cast<int>(loc.x), static_cast<int>(loc.y));
m_requester->mouseUpAt(*button, sf::Vector2i(sf::Vector2(loc.x, loc.y)));
}
}
@ -244,7 +244,7 @@
// when the mouse is dragged. That would be too easy!)
[self updateMouseState];
if ((m_requester != nil) && m_mouseIsIn)
m_requester->mouseMovedAt(static_cast<int>(loc.x), static_cast<int>(loc.y));
m_requester->mouseMovedAt(sf::Vector2i(sf::Vector2(loc.x, loc.y)));
}
@ -304,8 +304,7 @@
NSPoint loc = [self cursorPositionFromEvent:theEvent];
m_requester->mouseWheelScrolledAt(static_cast<float>([theEvent deltaX]),
static_cast<float>([theEvent deltaY]),
static_cast<int>(loc.x),
static_cast<int>(loc.y));
sf::Vector2i(sf::Vector2(loc.x, loc.y)));
}
// Transmit to non-SFML responder

View File

@ -289,7 +289,7 @@
[self updateCursorGrabbed];
if (m_requester)
m_requester->windowGainedFocus();
m_requester->windowFocusGained();
if (m_fullscreen)
[self enterFullscreen];
@ -304,7 +304,7 @@
[self updateCursorGrabbed];
if (m_requester)
m_requester->windowLostFocus();
m_requester->windowFocusLost();
if (m_fullscreen)
[self exitFullscreen];

View File

@ -75,13 +75,6 @@ void scaleOut(T& out, id<WindowImplDelegateProtocol> delegate)
out *= static_cast<T>(delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor());
}
template <class T>
void scaleOutWidthHeight(T& width, T& height, id<WindowImplDelegateProtocol> delegate)
{
scaleOut(width, delegate);
scaleOut(height, delegate);
}
template <class T>
void scaleOutXY(T& out, id<WindowImplDelegateProtocol> delegate)
{

View File

@ -110,7 +110,7 @@ public:
/// \param size new width and height
///
////////////////////////////////////////////////////////////
void windowResized(const Vector2u& size);
void windowResized(Vector2u size);
////////////////////////////////////////////////////////////
/// \brief Window Lost Focus Event - called by the cocoa window object
@ -118,7 +118,7 @@ public:
/// Send the event to SFML WindowImpl class.
///
////////////////////////////////////////////////////////////
void windowLostFocus();
void windowFocusLost();
////////////////////////////////////////////////////////////
/// \brief Window Get Focus Event - called by the cocoa window object
@ -126,55 +126,51 @@ public:
/// Send the event to SFML WindowImpl class.
///
////////////////////////////////////////////////////////////
void windowGainedFocus();
void windowFocusGained();
////////////////////////////////////////////////////////////
/// \brief Mouse Down Event - called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param button active button
/// \param x mouse x position
/// \param y mouse y position
/// \param button active button
/// \param position mouse x and y position
///
////////////////////////////////////////////////////////////
void mouseDownAt(Mouse::Button button, int x, int y);
void mouseDownAt(Mouse::Button button, Vector2i position);
////////////////////////////////////////////////////////////
/// \brief Mouse Up Event - called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param button active button
/// \param x mouse x position
/// \param y mouse y position
/// \param button active button
/// \param position mouse x and y position
///
////////////////////////////////////////////////////////////
void mouseUpAt(Mouse::Button button, int x, int y);
void mouseUpAt(Mouse::Button button, Vector2i position);
////////////////////////////////////////////////////////////
/// \brief Mouse Moved Event - called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param x mouse x position
/// \param y mouse y position
/// \param position mouse x and y position
///
////////////////////////////////////////////////////////////
void mouseMovedAt(int x, int y);
void mouseMovedAt(Vector2i position);
////////////////////////////////////////////////////////////
/// \brief Mouse Wheel Scrolled Event - called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param deltaX horizontal scrolling delta
/// \param deltaY vertical scrolling delta
/// \param x mouse x position
/// \param y mouse y position
/// \param deltaX horizontal scrolling delta
/// \param deltaY vertical scrolling delta
/// \param position mouse x and y position
///
////////////////////////////////////////////////////////////
void mouseWheelScrolledAt(float deltaX, float deltaY, int x, int y);
void mouseWheelScrolledAt(float deltaX, float deltaY, Vector2i position);
////////////////////////////////////////////////////////////
/// \brief Mouse In Event - called by the cocoa view object
@ -197,20 +193,20 @@ public:
///
/// Send the event to SFML WindowImpl class.
///
/// \param key active key
/// \param event active key
///
////////////////////////////////////////////////////////////
void keyDown(Event::KeyEvent key);
void keyDown(Event::KeyPressed event);
////////////////////////////////////////////////////////////
/// \brief Key Up Event - called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param key active key
/// \param event active key
///
////////////////////////////////////////////////////////////
void keyUp(Event::KeyEvent key);
void keyUp(Event::KeyReleased event);
////////////////////////////////////////////////////////////
/// \brief Text Entred Event - called by the cocoa view object

View File

@ -217,49 +217,33 @@ void WindowImplCocoa::setUpProcess()
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowClosed()
{
Event event;
event.type = Event::Closed;
pushEvent(event);
pushEvent(Event::Closed{});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowResized(const Vector2u& size)
void WindowImplCocoa::windowResized(Vector2u size)
{
Event event;
event.type = Event::Resized;
event.size.width = size.x;
event.size.height = size.y;
scaleOutWidthHeight(event.size.width, event.size.height, m_delegate);
pushEvent(event);
scaleOutXY(size, m_delegate);
pushEvent(Event::Resized{size});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowLostFocus()
void WindowImplCocoa::windowFocusLost()
{
if (!m_showCursor && [m_delegate isMouseInside])
showMouseCursor(); // Make sure the cursor is visible
Event event;
event.type = Event::LostFocus;
pushEvent(event);
pushEvent(Event::FocusLost{});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowGainedFocus()
void WindowImplCocoa::windowFocusGained()
{
if (!m_showCursor && [m_delegate isMouseInside])
hideMouseCursor(); // Restore user's setting
Event event;
event.type = Event::GainedFocus;
pushEvent(event);
pushEvent(Event::FocusGained{});
}
#pragma mark
@ -267,65 +251,34 @@ void WindowImplCocoa::windowGainedFocus()
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseDownAt(Mouse::Button button, int x, int y)
void WindowImplCocoa::mouseDownAt(Mouse::Button button, Vector2i position)
{
Event event;
event.type = Event::MouseButtonPressed;
event.mouseButton.button = button;
event.mouseButton.x = x;
event.mouseButton.y = y;
scaleOutXY(event.mouseButton, m_delegate);
pushEvent(event);
scaleOutXY(position, m_delegate);
pushEvent(Event::MouseButtonPressed{button, position});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseUpAt(Mouse::Button button, int x, int y)
void WindowImplCocoa::mouseUpAt(Mouse::Button button, Vector2i position)
{
Event event;
event.type = Event::MouseButtonReleased;
event.mouseButton.button = button;
event.mouseButton.x = x;
event.mouseButton.y = y;
scaleOutXY(event.mouseButton, m_delegate);
pushEvent(event);
scaleOutXY(position, m_delegate);
pushEvent(Event::MouseButtonReleased{button, position});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseMovedAt(int x, int y)
void WindowImplCocoa::mouseMovedAt(Vector2i position)
{
Event event;
event.type = Event::MouseMoved;
event.mouseMove.x = x;
event.mouseMove.y = y;
scaleOutXY(event.mouseMove, m_delegate);
pushEvent(event);
scaleOutXY(position, m_delegate);
pushEvent(Event::MouseMoved{position});
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseWheelScrolledAt(float deltaX, float deltaY, int x, int y)
void WindowImplCocoa::mouseWheelScrolledAt(float deltaX, float deltaY, Vector2i position)
{
Event event;
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Vertical;
event.mouseWheelScroll.delta = deltaY;
event.mouseWheelScroll.x = x;
event.mouseWheelScroll.y = y;
scaleOutXY(event.mouseWheelScroll, m_delegate);
pushEvent(event);
event.type = Event::MouseWheelScrolled;
event.mouseWheelScroll.wheel = Mouse::Wheel::Horizontal;
event.mouseWheelScroll.delta = deltaX;
event.mouseWheelScroll.x = x;
event.mouseWheelScroll.y = y;
scaleOutXY(event.mouseWheelScroll, m_delegate);
pushEvent(event);
scaleOutXY(position, m_delegate);
pushEvent(Event::MouseWheelScrolled{Mouse::Wheel::Vertical, deltaY, position});
pushEvent(Event::MouseWheelScrolled{Mouse::Wheel::Horizontal, deltaX, position});
}
////////////////////////////////////////////////////////////
@ -333,11 +286,7 @@ void WindowImplCocoa::mouseMovedIn()
{
if (!m_showCursor)
hideMouseCursor(); // Restore user's setting
Event event;
event.type = Event::MouseEntered;
pushEvent(event);
pushEvent(Event::MouseEntered{});
}
////////////////////////////////////////////////////////////
@ -345,11 +294,7 @@ void WindowImplCocoa::mouseMovedOut()
{
if (!m_showCursor)
showMouseCursor(); // Make sure the cursor is visible
Event event;
event.type = Event::MouseLeft;
pushEvent(event);
pushEvent(Event::MouseLeft{});
}
@ -358,23 +303,15 @@ void WindowImplCocoa::mouseMovedOut()
////////////////////////////////////////////////////////////
void WindowImplCocoa::keyDown(Event::KeyEvent key)
void WindowImplCocoa::keyDown(Event::KeyPressed event)
{
Event event;
event.type = Event::KeyPressed;
event.key = key;
pushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::keyUp(Event::KeyEvent key)
void WindowImplCocoa::keyUp(Event::KeyReleased event)
{
Event event;
event.type = Event::KeyReleased;
event.key = key;
pushEvent(event);
}
@ -382,11 +319,7 @@ void WindowImplCocoa::keyUp(Event::KeyEvent key)
////////////////////////////////////////////////////////////
void WindowImplCocoa::textEntered(unichar charcode)
{
Event event;
event.type = Event::TextEntered;
event.text.unicode = charcode;
pushEvent(event);
pushEvent(Event::TextEntered{charcode});
}

View File

@ -60,7 +60,7 @@ class WindowImplCocoa;
/// The requester is a WindowImplCocoa. It's used to send back
/// event via these functions:
///
/// windowClosed, windowResized, windowLostFocus, windowGainedFocus
/// windowClosed, windowResized, windowFocusLost, windowFocusGained
///
/// mouseDownAt, mouseUpAt, mouseMovedAt, mouseWheelScrolledAt,
/// mouseMovedIn, mouseMovedOut

View File

@ -16,7 +16,253 @@ TEST_CASE("[Window] sf::Event")
SECTION("Construction")
{
const sf::Event event{};
CHECK(event.type == sf::Event::Closed);
SECTION("Default constructor")
{
const sf::Event event;
CHECK(event.is<sf::Event::Empty>());
CHECK(event.getIf<sf::Event::Empty>());
}
SECTION("Template constructor")
{
const sf::Event event = sf::Event::Resized{{1, 2}};
CHECK(event.is<sf::Event::Resized>());
CHECK(event.getIf<sf::Event::Resized>());
const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2));
}
}
SECTION("Assign all possible values")
{
sf::Event event;
event = sf::Event::Closed{};
CHECK(event.is<sf::Event::Closed>());
CHECK(event.getIf<sf::Event::Closed>());
event = sf::Event::Resized{{1, 2}};
CHECK(event.is<sf::Event::Resized>());
CHECK(event.getIf<sf::Event::Resized>());
const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2));
event = sf::Event::FocusLost{};
CHECK(event.is<sf::Event::FocusLost>());
CHECK(event.getIf<sf::Event::FocusLost>());
event = sf::Event::FocusGained{};
CHECK(event.is<sf::Event::FocusGained>());
CHECK(event.getIf<sf::Event::FocusGained>());
event = sf::Event::TextEntered{123456};
CHECK(event.is<sf::Event::TextEntered>());
CHECK(event.getIf<sf::Event::TextEntered>());
const auto& textEntered = *event.getIf<sf::Event::TextEntered>();
CHECK(textEntered.unicode == 123456);
event = sf::Event::KeyPressed{sf::Keyboard::Key::C, sf::Keyboard::Scan::C, true, true, true, true};
CHECK(event.is<sf::Event::KeyPressed>());
CHECK(event.getIf<sf::Event::KeyPressed>());
const auto& keyPressed = *event.getIf<sf::Event::KeyPressed>();
CHECK(keyPressed.code == sf::Keyboard::Key::C);
CHECK(keyPressed.scancode == sf::Keyboard::Scan::C);
CHECK(keyPressed.alt);
CHECK(keyPressed.control);
CHECK(keyPressed.shift);
CHECK(keyPressed.system);
event = sf::Event::KeyReleased{sf::Keyboard::Key::D, sf::Keyboard::Scan::D, true, true, true, true};
CHECK(event.is<sf::Event::KeyReleased>());
CHECK(event.getIf<sf::Event::KeyReleased>());
const auto& keyReleased = *event.getIf<sf::Event::KeyReleased>();
CHECK(keyReleased.code == sf::Keyboard::Key::D);
CHECK(keyReleased.scancode == sf::Keyboard::Scan::D);
CHECK(keyReleased.alt);
CHECK(keyReleased.control);
CHECK(keyReleased.shift);
CHECK(keyReleased.system);
event = sf::Event::MouseWheelScrolled{sf::Mouse::Wheel::Horizontal, 3.14f, {4, 5}};
CHECK(event.is<sf::Event::MouseWheelScrolled>());
CHECK(event.getIf<sf::Event::MouseWheelScrolled>());
const auto& mouseWheelScrolled = *event.getIf<sf::Event::MouseWheelScrolled>();
CHECK(mouseWheelScrolled.wheel == sf::Mouse::Wheel::Horizontal);
CHECK(mouseWheelScrolled.delta == 3.14f);
CHECK(mouseWheelScrolled.position == sf::Vector2i(4, 5));
event = sf::Event::MouseButtonPressed{sf::Mouse::Button::Middle, {6, 7}};
CHECK(event.is<sf::Event::MouseButtonPressed>());
CHECK(event.getIf<sf::Event::MouseButtonPressed>());
const auto& mouseButtonPressed = *event.getIf<sf::Event::MouseButtonPressed>();
CHECK(mouseButtonPressed.button == sf::Mouse::Button::Middle);
CHECK(mouseButtonPressed.position == sf::Vector2i(6, 7));
event = sf::Event::MouseButtonReleased{sf::Mouse::Button::Extra1, {8, 9}};
CHECK(event.is<sf::Event::MouseButtonReleased>());
CHECK(event.getIf<sf::Event::MouseButtonReleased>());
const auto& mouseButtonReleased = *event.getIf<sf::Event::MouseButtonReleased>();
CHECK(mouseButtonReleased.button == sf::Mouse::Button::Extra1);
CHECK(mouseButtonReleased.position == sf::Vector2i(8, 9));
event = sf::Event::MouseMoved{{4, 2}};
CHECK(event.is<sf::Event::MouseMoved>());
CHECK(event.getIf<sf::Event::MouseMoved>());
const auto& mouseMoved = *event.getIf<sf::Event::MouseMoved>();
CHECK(mouseMoved.position == sf::Vector2i(4, 2));
event = sf::Event::MouseEntered{};
CHECK(event.is<sf::Event::MouseEntered>());
CHECK(event.getIf<sf::Event::MouseEntered>());
event = sf::Event::MouseLeft{};
CHECK(event.is<sf::Event::MouseLeft>());
CHECK(event.getIf<sf::Event::MouseLeft>());
event = sf::Event::JoystickButtonPressed{100, 200};
CHECK(event.is<sf::Event::JoystickButtonPressed>());
CHECK(event.getIf<sf::Event::JoystickButtonPressed>());
const auto& joystickButtonPressed = *event.getIf<sf::Event::JoystickButtonPressed>();
CHECK(joystickButtonPressed.joystickId == 100);
CHECK(joystickButtonPressed.button == 200);
event = sf::Event::JoystickButtonReleased{300, 400};
CHECK(event.is<sf::Event::JoystickButtonReleased>());
CHECK(event.getIf<sf::Event::JoystickButtonReleased>());
const auto& joystickButtonReleased = *event.getIf<sf::Event::JoystickButtonReleased>();
CHECK(joystickButtonReleased.joystickId == 300);
CHECK(joystickButtonReleased.button == 400);
event = sf::Event::JoystickMoved{300, sf::Joystick::Axis::Z, 1.23f};
CHECK(event.is<sf::Event::JoystickMoved>());
CHECK(event.getIf<sf::Event::JoystickMoved>());
const auto& joystickMoved = *event.getIf<sf::Event::JoystickMoved>();
CHECK(joystickMoved.joystickId == 300);
CHECK(joystickMoved.axis == sf::Joystick::Axis::Z);
CHECK(joystickMoved.position == 1.23f);
event = sf::Event::JoystickConnected{42};
CHECK(event.is<sf::Event::JoystickConnected>());
CHECK(event.getIf<sf::Event::JoystickConnected>());
const auto& joystickConnected = *event.getIf<sf::Event::JoystickConnected>();
CHECK(joystickConnected.joystickId == 42);
event = sf::Event::JoystickDisconnected{43};
CHECK(event.is<sf::Event::JoystickDisconnected>());
CHECK(event.getIf<sf::Event::JoystickDisconnected>());
const auto& joystickDisconnected = *event.getIf<sf::Event::JoystickDisconnected>();
CHECK(joystickDisconnected.joystickId == 43);
event = sf::Event::TouchBegan{99, {98, 97}};
CHECK(event.is<sf::Event::TouchBegan>());
CHECK(event.getIf<sf::Event::TouchBegan>());
const auto& touchBegan = *event.getIf<sf::Event::TouchBegan>();
CHECK(touchBegan.finger == 99);
CHECK(touchBegan.position == sf::Vector2i(98, 97));
event = sf::Event::TouchMoved{96, {95, 94}};
CHECK(event.is<sf::Event::TouchMoved>());
CHECK(event.getIf<sf::Event::TouchMoved>());
const auto& touchMoved = *event.getIf<sf::Event::TouchMoved>();
CHECK(touchMoved.finger == 96);
CHECK(touchMoved.position == sf::Vector2i(95, 94));
event = sf::Event::TouchEnded{93, {92, 91}};
CHECK(event.is<sf::Event::TouchEnded>());
CHECK(event.getIf<sf::Event::TouchEnded>());
const auto& touchEnded = *event.getIf<sf::Event::TouchEnded>();
CHECK(touchEnded.finger == 93);
CHECK(touchEnded.position == sf::Vector2i(92, 91));
event = sf::Event::SensorChanged{sf::Sensor::Type::Gravity, {1.2f, 3.4f, 5.6f}};
CHECK(event.is<sf::Event::SensorChanged>());
CHECK(event.getIf<sf::Event::SensorChanged>());
const auto& sensorChanged = *event.getIf<sf::Event::SensorChanged>();
CHECK(sensorChanged.type == sf::Sensor::Type::Gravity);
CHECK(sensorChanged.value == sf::Vector3f(1.2f, 3.4f, 5.6f));
}
SECTION("Subtypes")
{
// Empty structs
STATIC_CHECK(std::is_empty_v<sf::Event::Empty>);
STATIC_CHECK(std::is_empty_v<sf::Event::Closed>);
STATIC_CHECK(std::is_empty_v<sf::Event::FocusLost>);
STATIC_CHECK(std::is_empty_v<sf::Event::FocusGained>);
STATIC_CHECK(std::is_empty_v<sf::Event::MouseEntered>);
STATIC_CHECK(std::is_empty_v<sf::Event::MouseLeft>);
// Non-empty structs
const sf::Event::Resized resized;
CHECK(resized.size == sf::Vector2u());
const sf::Event::TextEntered textEntered;
CHECK(textEntered.unicode == 0);
const sf::Event::KeyPressed keyPressed;
CHECK(keyPressed.code == sf::Keyboard::Key{});
CHECK(keyPressed.scancode == sf::Keyboard::Scancode{});
CHECK(!keyPressed.alt);
CHECK(!keyPressed.control);
CHECK(!keyPressed.shift);
CHECK(!keyPressed.system);
const sf::Event::KeyReleased keyReleased;
CHECK(keyReleased.code == sf::Keyboard::Key{});
CHECK(keyReleased.scancode == sf::Keyboard::Scancode{});
CHECK(!keyReleased.alt);
CHECK(!keyReleased.control);
CHECK(!keyReleased.shift);
CHECK(!keyReleased.system);
const sf::Event::MouseWheelScrolled mouseWheelScrolled;
CHECK(mouseWheelScrolled.wheel == sf::Mouse::Wheel{});
CHECK(mouseWheelScrolled.delta == 0);
CHECK(mouseWheelScrolled.position == sf::Vector2i());
const sf::Event::MouseButtonPressed mouseButtonPressed;
CHECK(mouseButtonPressed.button == sf::Mouse::Button{});
CHECK(mouseButtonPressed.position == sf::Vector2i());
const sf::Event::MouseButtonReleased mouseButtonReleased;
CHECK(mouseButtonReleased.button == sf::Mouse::Button{});
CHECK(mouseButtonReleased.position == sf::Vector2i());
const sf::Event::MouseMoved mouseMoved;
CHECK(mouseMoved.position == sf::Vector2i());
const sf::Event::JoystickButtonPressed joystickButtonPressed;
CHECK(joystickButtonPressed.joystickId == 0);
CHECK(joystickButtonPressed.button == 0);
const sf::Event::JoystickButtonReleased joystickButtonReleased;
CHECK(joystickButtonReleased.joystickId == 0);
CHECK(joystickButtonReleased.button == 0);
const sf::Event::JoystickMoved joystickMoved;
CHECK(joystickMoved.joystickId == 0);
CHECK(joystickMoved.axis == sf::Joystick::Axis{});
CHECK(joystickMoved.position == 0);
const sf::Event::JoystickConnected joystickConnected;
CHECK(joystickConnected.joystickId == 0);
const sf::Event::JoystickDisconnected joystickDisconnected;
CHECK(joystickDisconnected.joystickId == 0);
const sf::Event::TouchBegan touchBegan;
CHECK(touchBegan.finger == 0);
CHECK(touchBegan.position == sf::Vector2i());
const sf::Event::TouchMoved touchMoved;
CHECK(touchMoved.finger == 0);
CHECK(touchMoved.position == sf::Vector2i());
const sf::Event::TouchEnded touchEnded;
CHECK(touchEnded.finger == 0);
CHECK(touchEnded.position == sf::Vector2i());
const sf::Event::SensorChanged sensorChanged;
CHECK(sensorChanged.type == sf::Sensor::Type{});
CHECK(sensorChanged.value == sf::Vector3f());
}
}

View File

@ -67,13 +67,14 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
{
window.close();
}
// Escape pressed: exit
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Escape)
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Escape)
{
window.close();
}

View File

@ -65,13 +65,14 @@ int main()
for (sf::Event event; window.pollEvent(event);)
{
// Close window: exit
if (event.type == sf::Event::Closed)
if (event.is<sf::Event::Closed>())
{
window.close();
}
// Escape pressed: exit
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Key::Escape)
if (const auto* keyPressed = event.getIf<sf::Event::KeyPressed>();
keyPressed && keyPressed->code == sf::Keyboard::Key::Escape)
{
window.close();
}