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::Scancode scancode{}; //!< Physical code of the key
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?
};
struct KeyPressed : KeyChanged
{
};
struct KeyReleased : KeyChanged
////////////////////////////////////////////////////////////
/// \brief Key released event subtype
///
////////////////////////////////////////////////////////////
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
Vector2i position; //!< Position of the mouse pointer, relative to the top left of the owner window
};
struct MouseButtonPressed : MouseButtonChanged
{
};
struct MouseButtonReleased : MouseButtonChanged
////////////////////////////////////////////////////////////
/// \brief Mouse button released event subtype
///
////////////////////////////////////////////////////////////
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 button{}; //!< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
};
struct JoystickButtonPressed : JoystickButtonChanged
{
};
struct JoystickButtonReleased : JoystickButtonChanged
////////////////////////////////////////////////////////////
/// \brief Joystick button released event subtype
///
////////////////////////////////////////////////////////////
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])
};
struct JoystickConnected : JoystickChanged
{
};
struct JoystickDisconnected : JoystickChanged
////////////////////////////////////////////////////////////
/// \brief Joystick disconnected event subtype
///
////////////////////////////////////////////////////////////
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
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
{
};
struct TouchEnded : TouchChanged
////////////////////////////////////////////////////////////
/// \brief Touch ended event subtype
///
////////////////////////////////////////////////////////////
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 metakey = AKeyEvent_getMetaState(inputEvent);
Event::KeyChanged keyChanged;
keyChanged.code = androidKeyToSF(key);
keyChanged.alt = metakey & AMETA_ALT_ON;
keyChanged.control = false;
keyChanged.shift = metakey & AMETA_SHIFT_ON;
const auto forwardKeyEvent = [&](auto keyEvent)
{
keyEvent.code = androidKeyToSF(key);
keyEvent.alt = metakey & AMETA_ALT_ON;
keyEvent.shift = metakey & AMETA_SHIFT_ON;
forwardEvent(keyEvent);
};
switch (action)
{
case AKEY_EVENT_ACTION_DOWN:
forwardEvent(Event::KeyPressed{keyChanged});
forwardKeyEvent(Event::KeyPressed{});
return 1;
case AKEY_EVENT_ACTION_UP:
forwardEvent(Event::KeyReleased{keyChanged});
forwardKeyEvent(Event::KeyReleased{});
if (auto unicode = static_cast<std::uint32_t>(getUnicode(inputEvent)))
forwardEvent(Event::TextEntered{static_cast<std::uint32_t>(unicode)});
@ -433,8 +435,8 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates&
case AKEY_EVENT_ACTION_MULTIPLE:
// Since complex inputs don't get separate key down/up events
// both have to be faked at once
forwardEvent(Event::KeyPressed{keyChanged});
forwardEvent(Event::KeyReleased{keyChanged});
forwardKeyEvent(Event::KeyPressed{});
forwardKeyEvent(Event::KeyReleased{});
// This requires some special treatment, since this might represent
// 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
//
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;
if (special && inputEvent.value)
doDeferredText = special;
if (inputEvent.value)
return sf::Event::KeyPressed{keyChanged};
const auto makeKeyEvent = [&](auto keyEvent)
{
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)

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.scancode = code;
event.alt = modifiers & NSAlternateKeyMask;
@ -248,11 +262,11 @@ void processOneModifier(NSUInteger modifiers,
// Check for key pressed event
if (isDown && !wasDown)
requester.keyDown(sf::Event::KeyPressed{keyEventWithModifiers(modifiers, key, code)});
requester.keyDown(keyPressedEventWithModifiers(modifiers, key, code));
// And check for key released event
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

View File

@ -84,7 +84,7 @@
// Handle key down event
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))
m_requester->keyDown(key);
@ -156,7 +156,7 @@
if (m_requester == nil)
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))
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.
sf::Keyboard::Scancode code = sf::priv::HIDInputManager::nonLocalizedKey([event keyCode]);
@ -186,7 +186,20 @@
// Get the corresponding key under the current keyboard layout.
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)
////////////////////////////////////////////////////////////
/// \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.
///
@ -51,7 +51,19 @@
/// \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