Browse Source

Add love.keyboard.isModifierActive.

Miku AuahDark 3 years ago
parent
commit
321397d1dd

+ 1 - 0
changes.txt

@@ -42,6 +42,7 @@ Released: N/A
 * Added a variant of love.graphics.setColorMask which accepts a single boolean.
 * Added a variant of love.graphics.setColorMask which accepts a single boolean.
 * Added new 'clampone' wrap mode.
 * Added new 'clampone' wrap mode.
 * Added a variant of Font:getWidth which takes a codepoint number argument.
 * Added a variant of Font:getWidth which takes a codepoint number argument.
+* Added love.keyboard.isModifierActive.
 * Added love.system.getPreferredLocales.
 * Added love.system.getPreferredLocales.
 * Added love.localechanged callback.
 * Added love.localechanged callback.
 
 

+ 20 - 0
src/modules/keyboard/Keyboard.cpp

@@ -47,6 +47,16 @@ bool Keyboard::getConstant(Scancode in, const char *&out)
 	return scancodes.find(in, out);
 	return scancodes.find(in, out);
 }
 }
 
 
+bool Keyboard::getConstant(const char *in, ModifierKey &out)
+{
+	return modifiers.find(in, out);
+}
+
+bool Keyboard::getConstant(ModifierKey in, const char *&out)
+{
+	return modifiers.find(in, out);
+}
+
 StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
 StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
 {
 {
 	{"unknown", Keyboard::KEY_UNKNOWN},
 	{"unknown", Keyboard::KEY_UNKNOWN},
@@ -521,5 +531,15 @@ StringMap<Keyboard::Scancode, Keyboard::SCANCODE_MAX_ENUM>::Entry Keyboard::scan
 
 
 StringMap<Keyboard::Scancode, Keyboard::SCANCODE_MAX_ENUM> Keyboard::scancodes(Keyboard::scancodeEntries, sizeof(Keyboard::scancodeEntries));
 StringMap<Keyboard::Scancode, Keyboard::SCANCODE_MAX_ENUM> Keyboard::scancodes(Keyboard::scancodeEntries, sizeof(Keyboard::scancodeEntries));
 
 
+StringMap<Keyboard::ModifierKey, Keyboard::MODKEY_MAX_ENUM>::Entry Keyboard::modifierEntries[] =
+{
+	{"numlock", MODKEY_NUMLOCK},
+	{"capslock", MODKEY_CAPSLOCK},
+	{"scrolllock", MODKEY_SCROLLLOCK},
+	{"mode", MODKEY_MODE},
+};
+
+StringMap<Keyboard::ModifierKey, Keyboard::MODKEY_MAX_ENUM> Keyboard::modifiers(Keyboard::modifierEntries, sizeof(Keyboard::modifierEntries));
+
 } // keyboard
 } // keyboard
 } // love
 } // love

+ 25 - 0
src/modules/keyboard/Keyboard.h

@@ -519,6 +519,18 @@ public:
 		SCANCODE_MAX_ENUM
 		SCANCODE_MAX_ENUM
 	};
 	};
 
 
+	/**
+	 * Modifier keys. These are special keys that temporarily modifies the normal function of a button when active.
+	 **/
+	enum ModifierKey {
+		MODKEY_NUMLOCK,
+		MODKEY_CAPSLOCK,
+		MODKEY_SCROLLLOCK,
+		MODKEY_MODE,
+
+		MODKEY_MAX_ENUM
+	};
+
 	virtual ~Keyboard() {}
 	virtual ~Keyboard() {}
 
 
 	// Implements Module.
 	// Implements Module.
@@ -550,6 +562,13 @@ public:
 	 **/
 	 **/
 	virtual bool isScancodeDown(const std::vector<Scancode> &scancodelist) const = 0;
 	virtual bool isScancodeDown(const std::vector<Scancode> &scancodelist) const = 0;
 
 
+	/**
+	 * Checks whether specific modifier key is active or not.
+	 * @param key Modifier key to check.
+	 * @return Whether the specified modifier key is active.
+	 **/
+	virtual bool isModifierActive(ModifierKey key) const = 0;
+
 	/**
 	/**
 	 * Gets the key corresponding to the specified scancode according to the
 	 * Gets the key corresponding to the specified scancode according to the
 	 * current keyboard layout.
 	 * current keyboard layout.
@@ -592,6 +611,9 @@ public:
 	static bool getConstant(const char *in, Scancode &out);
 	static bool getConstant(const char *in, Scancode &out);
 	static bool getConstant(Scancode in, const char *&out);
 	static bool getConstant(Scancode in, const char *&out);
 
 
+	static bool getConstant(const char *in, ModifierKey &out);
+	static bool getConstant(ModifierKey in, const char *&out);
+
 private:
 private:
 
 
 	static StringMap<Key, KEY_MAX_ENUM>::Entry keyEntries[];
 	static StringMap<Key, KEY_MAX_ENUM>::Entry keyEntries[];
@@ -600,6 +622,9 @@ private:
 	static StringMap<Scancode, SCANCODE_MAX_ENUM>::Entry scancodeEntries[];
 	static StringMap<Scancode, SCANCODE_MAX_ENUM>::Entry scancodeEntries[];
 	static StringMap<Scancode, SCANCODE_MAX_ENUM> scancodes;
 	static StringMap<Scancode, SCANCODE_MAX_ENUM> scancodes;
 
 
+	static StringMap<ModifierKey, MODKEY_MAX_ENUM>::Entry modifierEntries[];
+	static StringMap<ModifierKey, MODKEY_MAX_ENUM> modifiers;
+
 }; // Keyboard
 }; // Keyboard
 
 
 } // keyboard
 } // keyboard

+ 26 - 0
src/modules/keyboard/sdl/Keyboard.cpp

@@ -18,9 +18,16 @@
  * 3. This notice may not be removed or altered from any source distribution.
  * 3. This notice may not be removed or altered from any source distribution.
  **/
  **/
 
 
+#include <SDL_version.h>
+
 #include "Keyboard.h"
 #include "Keyboard.h"
 #include "window/Window.h"
 #include "window/Window.h"
 
 
+// SDL before 2.0.18 lack KMOD_SCROLL. Use KMOD_RESERVED instead.
+#if !SDL_VERSION_ATLEAST(2, 0, 18)
+#define KMOD_SCROLL KMOD_RESERVED
+#endif // !SDL_VERSION_ATLEAST(2, 0, 18)
+
 namespace love
 namespace love
 {
 {
 namespace keyboard
 namespace keyboard
@@ -78,6 +85,25 @@ bool Keyboard::isScancodeDown(const std::vector<Scancode> &scancodelist) const
 	return false;
 	return false;
 }
 }
 
 
+bool Keyboard::isModifierActive(ModifierKey key) const
+{
+	int modstate = SDL_GetModState();
+
+	switch (key)
+	{
+	case MODKEY_NUMLOCK:
+		return (modstate & KMOD_NUM) != 0;
+	case MODKEY_CAPSLOCK:
+		return (modstate & KMOD_CAPS) != 0;
+	case MODKEY_SCROLLLOCK:
+		return (modstate & KMOD_SCROLL) != 0;
+	case MODKEY_MODE:
+		return (modstate & KMOD_MODE) != 0;
+	}
+
+	return false;
+}
+
 Keyboard::Key Keyboard::getKeyFromScancode(Scancode scancode) const
 Keyboard::Key Keyboard::getKeyFromScancode(Scancode scancode) const
 {
 {
 	SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN;
 	SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN;

+ 1 - 0
src/modules/keyboard/sdl/Keyboard.h

@@ -48,6 +48,7 @@ public:
 	bool hasKeyRepeat() const;
 	bool hasKeyRepeat() const;
 	bool isDown(const std::vector<Key> &keylist) const;
 	bool isDown(const std::vector<Key> &keylist) const;
 	bool isScancodeDown(const std::vector<Scancode> &scancodelist) const;
 	bool isScancodeDown(const std::vector<Scancode> &scancodelist) const;
+	bool isModifierActive(ModifierKey key) const;
 
 
 	Key getKeyFromScancode(Scancode scancode) const;
 	Key getKeyFromScancode(Scancode scancode) const;
 	Scancode getScancodeFromKey(Key key) const;
 	Scancode getScancodeFromKey(Key key) const;

+ 12 - 0
src/modules/keyboard/wrap_Keyboard.cpp

@@ -187,6 +187,17 @@ int w_hasScreenKeyboard(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
+int w_isModifierActive(lua_State* L)
+{
+	const char *keystr = luaL_checkstring(L, 1);
+	Keyboard::ModifierKey key;
+	if (!Keyboard::getConstant(keystr, key))
+		return luax_enumerror(L, "modifier keys", keystr);
+
+	luax_pushboolean(L, instance()->isModifierActive(key));
+	return 1;
+}
+
 // List of functions to wrap.
 // List of functions to wrap.
 static const luaL_Reg functions[] =
 static const luaL_Reg functions[] =
 {
 {
@@ -199,6 +210,7 @@ static const luaL_Reg functions[] =
 	{ "isScancodeDown", w_isScancodeDown },
 	{ "isScancodeDown", w_isScancodeDown },
 	{ "getScancodeFromKey", w_getScancodeFromKey },
 	{ "getScancodeFromKey", w_getScancodeFromKey },
 	{ "getKeyFromScancode", w_getKeyFromScancode },
 	{ "getKeyFromScancode", w_getKeyFromScancode },
+	{ "isModifierActive", w_isModifierActive },
 	{ 0, 0 }
 	{ 0, 0 }
 };
 };