From 75ef99e2caf196bf43dc2f58faebf288e8db5f71 Mon Sep 17 00:00:00 2001 From: Marco Antognini Date: Mon, 27 Mar 2017 00:36:59 +0200 Subject: [PATCH] Add new API for scancodes --- include/SFML/Window/Event.hpp | 11 +- include/SFML/Window/Keyboard.hpp | 224 +++++++++++++++++++++++++- src/SFML/Window/Android/InputImpl.hpp | 32 +++- src/SFML/Window/Keyboard.cpp | 23 +++ src/SFML/Window/OSX/InputImpl.hpp | 32 +++- src/SFML/Window/Unix/InputImpl.hpp | 32 +++- src/SFML/Window/Win32/InputImpl.hpp | 32 +++- src/SFML/Window/iOS/InputImpl.hpp | 32 +++- 8 files changed, 375 insertions(+), 43 deletions(-) diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index aad2cc8f8..97507a5f7 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -61,11 +61,12 @@ public: //////////////////////////////////////////////////////////// struct KeyEvent { - Keyboard::Key code; //!< 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? + 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? }; //////////////////////////////////////////////////////////// diff --git a/include/SFML/Window/Keyboard.hpp b/include/SFML/Window/Keyboard.hpp index 8101e19db..7c0579253 100644 --- a/include/SFML/Window/Keyboard.hpp +++ b/include/SFML/Window/Keyboard.hpp @@ -29,6 +29,7 @@ // Headers //////////////////////////////////////////////////////////// #include +#include namespace sf @@ -44,6 +45,10 @@ public: //////////////////////////////////////////////////////////// /// \brief Key codes /// + /// The enumerators refer to the "localized" key; i.e. depending + /// on the layout set by the operating system, a key can be mapped + /// to `Y` or `Z`. + /// //////////////////////////////////////////////////////////// enum Key { @@ -161,6 +166,158 @@ public: Return = Enter //!< \deprecated Use Enter instead }; + //////////////////////////////////////////////////////////// + /// \brief Scancodes + /// + /// The enumerators are bound to a physical key and do *not* depend + /// on the keyboard layout used by the operating system. Usually, the AT-101 + /// keyboard can be used as reference for the physical position of the keys. + /// + /// The scancodes are based on a subset of Table 12: Keyboard/Keypad Page + /// of Universal Serial Bus (USB): HID Usage Tables, v1.12. + /// + /// \todo When porting this for SFML 3, remove the `s` prefix and use + /// enum class. + /// + //////////////////////////////////////////////////////////// + enum Scancode + { + sUnknown = -1, ///< Represents any scancode not present in this enum + sA = 0, ///< Keyboard a and A key + sB, ///< Keyboard b and B key + sC, ///< Keyboard c and C key + sD, ///< Keyboard d and D key + sE, ///< Keyboard e and E key + sF, ///< Keyboard f and F key + sG, ///< Keyboard g and G key + sH, ///< Keyboard h and H key + sI, ///< Keyboard i and I key + sJ, ///< Keyboard j and J key + sK, ///< Keyboard k and K key + sL, ///< Keyboard l and L key + sM, ///< Keyboard m and M key + sN, ///< Keyboard n and N key + sO, ///< Keyboard o and O key + sP, ///< Keyboard p and P key + sQ, ///< Keyboard q and Q key + sR, ///< Keyboard r and R key + sS, ///< Keyboard s and S key + sT, ///< Keyboard t and T key + sU, ///< Keyboard u and U key + sV, ///< Keyboard v and V key + sW, ///< Keyboard w and W key + sX, ///< Keyboard x and X key + sY, ///< Keyboard y and Y key + sZ, ///< Keyboard z and Z key + sNum1, ///< Keyboard 1 and ! key + sNum2, ///< Keyboard 2 and @ key + sNum3, ///< Keyboard 3 and # key + sNum4, ///< Keyboard 4 and $ key + sNum5, ///< Keyboard 5 and % key + sNum6, ///< Keyboard 6 and ^ key + sNum7, ///< Keyboard 7 and & key + sNum8, ///< Keyboard 8 and * key + sNum9, ///< Keyboard 9 and ) key + sNum0, ///< Keyboard 0 and ) key + sEnter, ///< Keyboard Return (ENTER) key + sEscape, ///< Keyboard Escape key + sBackspace, ///< Keyboard Backspace key + // TODO above it's BackSpace, but is it correct? What do we use here? + sTab, ///< Keyboard Tab key + sSpace, ///< Keyboard Space key + sHyphen, ///< Keyboard - and _ key + sEquals, ///< Keyboard = and + + sLBracket, ///< Keyboard [ and { key + sRBracket, ///< Keyboard ] and } key + sBackslash, ///< Keyboard \ and | key + // TODO capitalisation + sDash, ///< Keyboard Non-US # and ~ + sSemicolon, ///< Keyboard ; and : key + // TODO capitalisation + sQuote, ///< Keyboard ' and " key + sGraveAccent, ///< Keyboard ` and ~ key + sComma, ///< Keyboard , and < key + sPeriod, ///< Keyboard . and > key + sForwardSlash, ///< Keyboard / and ? key + sF1, ///< Keyboard F1 key + sF2, ///< Keyboard F2 key + sF3, ///< Keyboard F3 key + sF4, ///< Keyboard F4 key + sF5, ///< Keyboard F5 key + sF6, ///< Keyboard F6 key + sF7, ///< Keyboard F7 key + sF8, ///< Keyboard F8 key + sF9, ///< Keyboard F9 key + sF10, ///< Keyboard F10 key + sF11, ///< Keyboard F11 key + sF12, ///< Keyboard F12 key + sF13, ///< Keyboard F13 key + sF14, ///< Keyboard F14 key + sF15, ///< Keyboard F15 key + sCapsLock, ///< Keyboard Caps Lock key + sPrintScreen, ///< Keyboard Print Screen key + sScrollLock, ///< Keyboard Scroll Lock key + sPause, ///< Keyboard Pause key + sInsert, ///< Keyboard Insert key + sHome, ///< Keyboard Home key + sPageUp, ///< Keyboard Page Up key + sDelete, ///< Keyboard Delete Forward key + sEnd, ///< Keyboard End key + sPageDown, ///< Keyboard Page Down key + sRight, ///< Keyboard Right Arrow key + sLeft, ///< Keyboard Left Arrow key + sDown, ///< Keyboard Down Arrow key + sUp, ///< Keyboard Up Arrow key + sNumLock, ///< Keypad Num Lock and Clear key + sDivide, ///< Keypad / key + sMultiply, ///< Keypad * key + sMinus, ///< Keypad - key + sPlus, ///< Keypad + key + sPadEquals, ///< keypad = key, probably Mac only + sReturn, ///< Keypad Enter (return) key + sDecimal, ///< Keypad . and Delete key + sNumpad1, ///< Keypad 1 and End key + sNumpad2, ///< Keypad 2 and Down Arrow key + sNumpad3, ///< Keypad 3 and Page Down key + sNumpad4, ///< Keypad 4 and Left Arrow key + sNumpad5, ///< Keypad 5 key + sNumpad6, ///< Keypad 6 and Right Arrow key + sNumpad7, ///< Keypad 7 and Home key + sNumpad8, ///< Keypad 8 and Up Arrow key + sNumpad9, ///< Keypad 9 and Page Up key + sNumpad0, ///< Keypad 0 and Insert key + sReverseSolidus, ///< Keyboard Non-US \ and | key + // FIXME what is this one? Might need better name. The doc says: + // - Typically near the Left-Shift key in AT-102 implementations. + // - Typical language mappings: Belg:<\> FrCa:«°» Dan:<\> Dutch:]|[ Fren:<> Ger:<|> Ital:<> LatAm:<> Nor:<> Span:<> Swed:<|> Swiss:<\> UK:\| Brazil: \|. + // What is the difference with "regular" \ and | key? + sApplication, ///< Keyboard Application key + sExecute, ///< Keyboard Execute key + sHelp, ///< Keyboard Help key + sMenu, ///< Keyboard Menu key + sSelect, ///< Keyboard Select key + sStop, ///< Keyboard Stop key + sAgain, ///< Keyboard Again key + sUndo, ///< Keyboard Undo key + sCut, ///< Keyboard Cut key + sCopy, ///< Keyboard Copy key + sPaste, ///< Keyboard Paste key + sFind, ///< Keyboard Find key + sMute, ///< Keyboard Mute key + sVolumeUp, ///< Keyboard Volume Up key + sVolumeDown, ///< Keyboard Volume Down key + sLControl, ///< Keyboard Left Control key + sLShift, ///< Keyboard Left Shift key + sLAlt, ///< Keyboard Left Alt key + sLSystem, ///< Keyboard Left System key + sRControl, ///< Keyboard Right Control key + sRShift, ///< Keyboard Right Shift key + sRAlt, ///< Keyboard Right Alt key + sRSystem, ///< Keyboard Right System key + + sCodeCount ///< Keep last -- the total number of scancodes + }; + //////////////////////////////////////////////////////////// /// \brief Check if a key is pressed /// @@ -171,12 +328,73 @@ public: //////////////////////////////////////////////////////////// static bool isKeyPressed(Key key); + //////////////////////////////////////////////////////////// + /// \brief Check if a key is pressed + /// + /// \param code Scancode to check + /// + /// \return True if the physical key is pressed, false otherwise + /// + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Scancode code); + + //////////////////////////////////////////////////////////// + /// \brief Localize a physical key to a logical one + /// + /// \param code Scancode to localize + /// + /// \return The key corresponding to the scancode under the current + /// keyboard layout used by the operating system, or + /// sf::Keyboard::Unknown when the scancode cannot be mapped + /// to a Key. + /// + /// \see unlocalize + /// + //////////////////////////////////////////////////////////// + static Key localize(Scancode code); + + //////////////////////////////////////////////////////////// + /// \brief Identify the physical key corresponding to a logical one + /// + /// \param key Key to "unlocalize" + /// + /// \return The scancode corresponding to the key under the current + /// keyboard layout used by the operating system, or + /// sf::Keyboard::sUnknown when the key cannot be mapped + /// to a Keyboard::Scancode. + /// + /// \see localize + /// + //////////////////////////////////////////////////////////// + static Scancode unlocalize(Key key); + + //////////////////////////////////////////////////////////// + /// \brief Provide a string representation for a given scancode + /// + /// From a high level point of view, this conversion corresponds + /// somewhat to the string available through sf::Event::TextEvent + /// when the given physical key is pressed by the user, when no + /// modifiers are involved. + /// + /// \warning The result is OS-dependent: for example, sf::Keyboard::sLSystem + /// is "Left Meta" on Linux, "Left Windows" on Windows and + /// "Left Command" on macOS. + /// + /// The current keyboard layout set by the operating system is used to + /// interpret the scancode: for example, sf::Keyboard::SemiColon is + /// mapped to ";" for layout and to "é" for others. + /// + /// \return The localized description of the code + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Scancode code); + //////////////////////////////////////////////////////////// /// \brief Show or hide the virtual keyboard /// - /// Warning: the virtual keyboard is not supported on all - /// systems. It will typically be implemented on mobile OSes - /// (Android, iOS) but not on desktop OSes (Windows, Linux, ...). + /// \warning The virtual keyboard is not supported on all + /// systems. It will typically be implemented on mobile OSes + /// (Android, iOS) but not on desktop OSes (Windows, Linux, ...). /// /// If the virtual keyboard is not available, this function does /// nothing. diff --git a/src/SFML/Window/Android/InputImpl.hpp b/src/SFML/Window/Android/InputImpl.hpp index d2783e15a..ffbc63124 100644 --- a/src/SFML/Window/Android/InputImpl.hpp +++ b/src/SFML/Window/Android/InputImpl.hpp @@ -45,19 +45,37 @@ class InputImpl public: //////////////////////////////////////////////////////////// - /// \brief Check if a key is pressed - /// - /// \param key Key to check - /// - /// \return True if the key is pressed, false otherwise + /// \copydoc sf::Keyboard::isKeyPressed(Key) /// //////////////////////////////////////////////////////////// static bool isKeyPressed(Keyboard::Key key); //////////////////////////////////////////////////////////// - /// \brief Show or hide the virtual keyboard + /// \copydoc sf::Keyboard::isKeyPressed(Scancode) /// - /// \param visible True to show, false to hide + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Key localize(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::unlocalize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Scancode unlocalize(Keyboard::Key key); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localizedRepresentation + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::setVirtualKeyboardVisible /// //////////////////////////////////////////////////////////// static void setVirtualKeyboardVisible(bool visible); diff --git a/src/SFML/Window/Keyboard.cpp b/src/SFML/Window/Keyboard.cpp index 764d2d6f6..d8d25122f 100644 --- a/src/SFML/Window/Keyboard.cpp +++ b/src/SFML/Window/Keyboard.cpp @@ -37,6 +37,29 @@ bool Keyboard::isKeyPressed(Key key) return priv::InputImpl::isKeyPressed(key); } +//////////////////////////////////////////////////////////// +bool Keyboard::isKeyPressed(Scancode code) +{ + return priv::InputImpl::isKeyPressed(code); +} + +//////////////////////////////////////////////////////////// +Keyboard::Key Keyboard::localize(Scancode code) +{ + return priv::InputImpl::localize(code); +} + +//////////////////////////////////////////////////////////// +Keyboard::Scancode Keyboard::unlocalize(Key key) +{ + return priv::InputImpl::unlocalize(key); +} + +//////////////////////////////////////////////////////////// +String Keyboard::localizedRepresentation(Scancode code) +{ + return priv::InputImpl::localizedRepresentation(code); +} //////////////////////////////////////////////////////////// void Keyboard::setVirtualKeyboardVisible(bool visible) diff --git a/src/SFML/Window/OSX/InputImpl.hpp b/src/SFML/Window/OSX/InputImpl.hpp index ff2e696b6..1965a8cf9 100644 --- a/src/SFML/Window/OSX/InputImpl.hpp +++ b/src/SFML/Window/OSX/InputImpl.hpp @@ -46,19 +46,37 @@ class InputImpl public: //////////////////////////////////////////////////////////// - /// \brief Check if a key is pressed - /// - /// \param key Key to check - /// - /// \return True if the key is pressed, false otherwise + /// \copydoc sf::Keyboard::isKeyPressed(Key) /// //////////////////////////////////////////////////////////// static bool isKeyPressed(Keyboard::Key key); //////////////////////////////////////////////////////////// - /// \brief Show or hide the virtual keyboard + /// \copydoc sf::Keyboard::isKeyPressed(Scancode) /// - /// \param visible True to show, false to hide + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Key localize(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::unlocalize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Scancode unlocalize(Keyboard::Key key); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localizedRepresentation + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::setVirtualKeyboardVisible /// //////////////////////////////////////////////////////////// static void setVirtualKeyboardVisible(bool visible); diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp index 4d4f61efc..1f135eadb 100644 --- a/src/SFML/Window/Unix/InputImpl.hpp +++ b/src/SFML/Window/Unix/InputImpl.hpp @@ -45,19 +45,37 @@ class InputImpl public: //////////////////////////////////////////////////////////// - /// \brief Check if a key is pressed - /// - /// \param key Key to check - /// - /// \return True if the key is pressed, false otherwise + /// \copydoc sf::Keyboard::isKeyPressed(Key) /// //////////////////////////////////////////////////////////// static bool isKeyPressed(Keyboard::Key key); //////////////////////////////////////////////////////////// - /// \brief Show or hide the virtual keyboard + /// \copydoc sf::Keyboard::isKeyPressed(Scancode) /// - /// \param visible True to show, false to hide + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Key localize(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::unlocalize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Scancode unlocalize(Keyboard::Key key); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localizedRepresentation + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::setVirtualKeyboardVisible /// //////////////////////////////////////////////////////////// static void setVirtualKeyboardVisible(bool visible); diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp index 54f1f9d64..2b14e06cb 100644 --- a/src/SFML/Window/Win32/InputImpl.hpp +++ b/src/SFML/Window/Win32/InputImpl.hpp @@ -45,19 +45,37 @@ class InputImpl public: //////////////////////////////////////////////////////////// - /// \brief Check if a key is pressed - /// - /// \param key Key to check - /// - /// \return True if the key is pressed, false otherwise + /// \copydoc sf::Keyboard::isKeyPressed(Key) /// //////////////////////////////////////////////////////////// static bool isKeyPressed(Keyboard::Key key); //////////////////////////////////////////////////////////// - /// \brief Show or hide the virtual keyboard + /// \copydoc sf::Keyboard::isKeyPressed(Scancode) /// - /// \param visible True to show, false to hide + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Key localize(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::unlocalize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Scancode unlocalize(Keyboard::Key key); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localizedRepresentation + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::setVirtualKeyboardVisible /// //////////////////////////////////////////////////////////// static void setVirtualKeyboardVisible(bool visible); diff --git a/src/SFML/Window/iOS/InputImpl.hpp b/src/SFML/Window/iOS/InputImpl.hpp index c9c82f665..a37778ab0 100644 --- a/src/SFML/Window/iOS/InputImpl.hpp +++ b/src/SFML/Window/iOS/InputImpl.hpp @@ -45,19 +45,37 @@ class InputImpl public: //////////////////////////////////////////////////////////// - /// \brief Check if a key is pressed - /// - /// \param key Key to check - /// - /// \return True if the key is pressed, false otherwise + /// \copydoc sf::Keyboard::isKeyPressed(Key) /// //////////////////////////////////////////////////////////// static bool isKeyPressed(Keyboard::Key key); //////////////////////////////////////////////////////////// - /// \brief Show or hide the virtual keyboard + /// \copydoc sf::Keyboard::isKeyPressed(Scancode) /// - /// \param visible True to show, false to hide + //////////////////////////////////////////////////////////// + static bool isKeyPressed(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Key localize(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::unlocalize + /// + //////////////////////////////////////////////////////////// + static Keyboard::Scancode unlocalize(Keyboard::Key key); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::localizedRepresentation + /// + //////////////////////////////////////////////////////////// + static String localizedRepresentation(Keyboard::Scancode code); + + //////////////////////////////////////////////////////////// + /// \copydoc sf::Keyboard::setVirtualKeyboardVisible /// //////////////////////////////////////////////////////////// static void setVirtualKeyboardVisible(bool visible);