Remove inheritance in sf::Event subtypes

This avoids confusing auto-completion hints when looking for an event
subtype to use as `sf::Event::is` or `sf::Event::getIf` type parameter.

This also avoids the inconsistency between what is possible with
`sf::Event::is` and `sf::Event::getIf` functions (they do not accept
event subtypes parents) and what would be possible with
`sf::Event::visit` (it could take a handler for a parent type).
This commit is contained in:
kimci86 2024-07-09 20:26:43 +02:00 committed by Chris Thrasher
parent 01f26346cb
commit 72eb115551
7 changed files with 147 additions and 66 deletions

View File

@ -91,23 +91,31 @@ public:
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief KeyChanged event subtypes /// \brief Key pressed event subtype
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct KeyChanged struct KeyPressed
{ {
Keyboard::Key code{}; //!< Code of the key Keyboard::Key code{}; //!< Code of the key that has been pressed
Keyboard::Scancode scancode{}; //!< Physical code of the key Keyboard::Scancode scancode{}; //!< Physical code of the key that has been pressed
bool alt{}; //!< Is the Alt key pressed? bool alt{}; //!< Is the Alt key pressed?
bool control{}; //!< Is the Control key pressed? bool control{}; //!< Is the Control key pressed?
bool shift{}; //!< Is the Shift key pressed? bool shift{}; //!< Is the Shift key pressed?
bool system{}; //!< Is the System key pressed? bool system{}; //!< Is the System key pressed?
}; };
struct KeyPressed : KeyChanged
{ ////////////////////////////////////////////////////////////
}; /// \brief Key released event subtype
struct KeyReleased : KeyChanged ///
////////////////////////////////////////////////////////////
struct KeyReleased
{ {
Keyboard::Key code{}; //!< Code of the key that has been released
Keyboard::Scancode scancode{}; //!< Physical code of the key that has been released
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?
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -122,19 +130,23 @@ public:
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Mouse button changed event subtypes /// \brief Mouse button pressed event subtype
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct MouseButtonChanged struct MouseButtonPressed
{ {
Mouse::Button button{}; //!< Code of the button that has been pressed 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 Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
}; };
struct MouseButtonPressed : MouseButtonChanged
{ ////////////////////////////////////////////////////////////
}; /// \brief Mouse button released event subtype
struct MouseButtonReleased : MouseButtonChanged ///
////////////////////////////////////////////////////////////
struct MouseButtonReleased
{ {
Mouse::Button button{}; //!< Code of the button that has been released
Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -196,19 +208,23 @@ public:
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Joystick button event subtypes /// \brief Joystick button pressed event subtype
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct JoystickButtonChanged struct JoystickButtonPressed
{ {
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1]) 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]) unsigned int button{}; //!< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
}; };
struct JoystickButtonPressed : JoystickButtonChanged
{ ////////////////////////////////////////////////////////////
}; /// \brief Joystick button released event subtype
struct JoystickButtonReleased : JoystickButtonChanged ///
////////////////////////////////////////////////////////////
struct JoystickButtonReleased
{ {
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
unsigned int button{}; //!< Index of the button that has been released (in range [0 .. Joystick::ButtonCount - 1])
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -223,37 +239,51 @@ public:
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Joystick connection event subtypes /// \brief Joystick connected event subtype
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct JoystickChanged struct JoystickConnected
{ {
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1]) unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
}; };
struct JoystickConnected : JoystickChanged
{ ////////////////////////////////////////////////////////////
}; /// \brief Joystick disconnected event subtype
struct JoystickDisconnected : JoystickChanged ///
////////////////////////////////////////////////////////////
struct JoystickDisconnected
{ {
unsigned int joystickId{}; //!< Index of the joystick (in range [0 .. Joystick::Count - 1])
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Touch event subtypes /// \brief Touch began event subtype
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
struct TouchChanged struct TouchBegan
{ {
unsigned int finger{}; //!< Index of the finger in case of multi-touch events 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 Vector2i position; //!< Start position of the touch, relative to the top left of the owner window
}; };
struct TouchBegan : TouchChanged
////////////////////////////////////////////////////////////
/// \brief Touch moved event subtype
///
////////////////////////////////////////////////////////////
struct TouchMoved
{ {
unsigned int finger{}; //!< Index of the finger in case of multi-touch events
Vector2i position; //!< Current position of the touch, relative to the top left of the owner window
}; };
struct TouchMoved : TouchChanged
{ ////////////////////////////////////////////////////////////
}; /// \brief Touch ended event subtype
struct TouchEnded : TouchChanged ///
////////////////////////////////////////////////////////////
struct TouchEnded
{ {
unsigned int finger{}; //!< Index of the finger in case of multi-touch events
Vector2i position; //!< Final position of the touch, relative to the top left of the owner window
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -413,19 +413,21 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
const std::int32_t key = AKeyEvent_getKeyCode(inputEvent); const std::int32_t key = AKeyEvent_getKeyCode(inputEvent);
const std::int32_t metakey = AKeyEvent_getMetaState(inputEvent); const std::int32_t metakey = AKeyEvent_getMetaState(inputEvent);
Event::KeyChanged keyChanged; const auto forwardKeyEvent = [&](auto keyEvent)
keyChanged.code = androidKeyToSF(key); {
keyChanged.alt = metakey & AMETA_ALT_ON; keyEvent.code = androidKeyToSF(key);
keyChanged.control = false; keyEvent.alt = metakey & AMETA_ALT_ON;
keyChanged.shift = metakey & AMETA_SHIFT_ON; keyEvent.shift = metakey & AMETA_SHIFT_ON;
forwardEvent(keyEvent);
};
switch (action) switch (action)
{ {
case AKEY_EVENT_ACTION_DOWN: case AKEY_EVENT_ACTION_DOWN:
forwardEvent(Event::KeyPressed{keyChanged}); forwardKeyEvent(Event::KeyPressed{});
return 1; return 1;
case AKEY_EVENT_ACTION_UP: case AKEY_EVENT_ACTION_UP:
forwardEvent(Event::KeyReleased{keyChanged}); forwardKeyEvent(Event::KeyReleased{});
if (auto unicode = static_cast<std::uint32_t>(getUnicode(inputEvent))) if (auto unicode = static_cast<std::uint32_t>(getUnicode(inputEvent)))
forwardEvent(Event::TextEntered{static_cast<std::uint32_t>(unicode)}); forwardEvent(Event::TextEntered{static_cast<std::uint32_t>(unicode)});
@ -433,8 +435,8 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
case AKEY_EVENT_ACTION_MULTIPLE: case AKEY_EVENT_ACTION_MULTIPLE:
// Since complex inputs don't get separate key down/up events // Since complex inputs don't get separate key down/up events
// both have to be faked at once // both have to be faked at once
forwardEvent(Event::KeyPressed{keyChanged}); forwardKeyEvent(Event::KeyPressed{});
forwardEvent(Event::KeyReleased{keyChanged}); forwardKeyEvent(Event::KeyReleased{});
// This requires some special treatment, since this might represent // This requires some special treatment, since this might represent
// a repetition of key presses or a complete sequence // a repetition of key presses or a complete sequence

View File

@ -400,23 +400,26 @@ std::optional<sf::Event> eventProcess()
{ {
// key down and key up events // key down and key up events
// //
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();
keyMap[kb] = inputEvent.value; keyMap[kb] = inputEvent.value;
if (special && inputEvent.value) if (special && inputEvent.value)
doDeferredText = special; doDeferredText = special;
if (inputEvent.value) const auto makeKeyEvent = [&](auto keyEvent)
return sf::Event::KeyPressed{keyChanged}; {
keyEvent.code = kb;
keyEvent.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented
keyEvent.alt = altDown();
keyEvent.control = controlDown();
keyEvent.shift = shiftDown();
keyEvent.system = systemDown();
return keyEvent;
};
return sf::Event::KeyReleased{keyChanged}; if (inputEvent.value)
return makeKeyEvent(sf::Event::KeyPressed{});
return makeKeyEvent(sf::Event::KeyReleased{});
} }
} }
else if (inputEvent.type == EV_REL) else if (inputEvent.type == EV_REL)

View File

@ -54,10 +54,17 @@ void initialiseKeyboardHelper();
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Set up a SFML key event based on the given modifiers flags and key code /// \brief Set up a SFML key pressed event based on the given modifiers flags and key code
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
sf::Event::KeyChanged keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code); sf::Event::KeyPressed keyPressedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code);
////////////////////////////////////////////////////////////
/// \brief Set up a SFML key released event based on the given modifiers flags and key code
///
////////////////////////////////////////////////////////////
sf::Event::KeyReleased keyReleasedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -151,9 +151,23 @@ void initialiseKeyboardHelper()
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
sf::Event::KeyChanged keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code) sf::Event::KeyPressed keyPressedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code)
{ {
sf::Event::KeyChanged event; sf::Event::KeyPressed 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;
}
////////////////////////////////////////////////////////
sf::Event::KeyReleased keyReleasedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code)
{
sf::Event::KeyReleased event;
event.code = key; event.code = key;
event.scancode = code; event.scancode = code;
event.alt = modifiers & NSAlternateKeyMask; event.alt = modifiers & NSAlternateKeyMask;
@ -248,11 +262,11 @@ void processOneModifier(NSUInteger modifiers,
// Check for key pressed event // Check for key pressed event
if (isDown && !wasDown) if (isDown && !wasDown)
requester.keyDown(sf::Event::KeyPressed{keyEventWithModifiers(modifiers, key, code)}); requester.keyDown(keyPressedEventWithModifiers(modifiers, key, code));
// And check for key released event // And check for key released event
else if (!isDown && wasDown) else if (!isDown && wasDown)
requester.keyUp(sf::Event::KeyReleased{keyEventWithModifiers(modifiers, key, code)}); requester.keyUp(keyReleasedEventWithModifiers(modifiers, key, code));
// else isDown == wasDown, so no change // else isDown == wasDown, so no change

View File

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

View File

@ -42,7 +42,7 @@
@interface SFOpenGLView (keyboard_priv) @interface SFOpenGLView (keyboard_priv)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a key down/up NSEvent into an SFML key event /// \brief Convert a key down NSEvent into an SFML key pressed event
/// ///
/// The conversion is based on localizedKeys and nonLocalizedKeys functions. /// The conversion is based on localizedKeys and nonLocalizedKeys functions.
/// ///
@ -51,7 +51,19 @@
/// \return sf::Keyboard::Key::Unknown as Code if the key is unknown /// \return sf::Keyboard::Key::Unknown as Code if the key is unknown
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
+ (sf::Event::KeyChanged)convertNSKeyEventToSFMLEvent:(NSEvent*)event; + (sf::Event::KeyPressed)convertNSKeyDownEventToSFMLEvent:(NSEvent*)event;
////////////////////////////////////////////////////////////
/// \brief Convert a key up NSEvent into an SFML key released event
///
/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
///
/// \param event a key event
///
/// \return sf::Keyboard::Key::Unknown as Code if the key is unknown
///
////////////////////////////////////////////////////////////
+ (sf::Event::KeyReleased)convertNSKeyUpEventToSFMLEvent:(NSEvent*)event;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Check if the event represent some Unicode text /// \brief Check if the event represent some Unicode text