mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Introduce KeyPress variant for GameKeyType
This commit is contained in:
parent
88d887cf8d
commit
c58814e703
2 changed files with 74 additions and 38 deletions
|
@ -13,13 +13,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct table_key {
|
|
||||||
std::string Name; // An EKEY_CODE 'symbol' name as a string
|
|
||||||
irr::EKEY_CODE Key;
|
|
||||||
wchar_t Char; // L'\0' means no character assigned
|
|
||||||
std::string LangName; // empty string means it doesn't have a human description
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \
|
#define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \
|
||||||
{ #x, irr::x, L'\0', lang },
|
{ #x, irr::x, L'\0', lang },
|
||||||
#define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \
|
#define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \
|
||||||
|
@ -33,7 +26,7 @@ struct table_key {
|
||||||
|
|
||||||
#define N_(text) text
|
#define N_(text) text
|
||||||
|
|
||||||
static std::vector<table_key> table = {
|
std::vector<KeyPress::table_key> KeyPress::keycode_table = {
|
||||||
// Keys that can be reliably mapped between Char and Key
|
// Keys that can be reliably mapped between Char and Key
|
||||||
DEFINEKEY3(0)
|
DEFINEKEY3(0)
|
||||||
DEFINEKEY3(1)
|
DEFINEKEY3(1)
|
||||||
|
@ -223,18 +216,17 @@ static std::vector<table_key> table = {
|
||||||
DEFINEKEY5("^")
|
DEFINEKEY5("^")
|
||||||
DEFINEKEY5("_")
|
DEFINEKEY5("_")
|
||||||
};
|
};
|
||||||
|
const KeyPress::table_key KeyPress::invalid_key = {"", irr::KEY_UNKNOWN, L'\0', ""};
|
||||||
static const table_key invalid_key = {"", irr::KEY_UNKNOWN, L'\0', ""};
|
|
||||||
|
|
||||||
#undef N_
|
#undef N_
|
||||||
|
|
||||||
|
|
||||||
static const table_key &lookup_keychar(wchar_t Char)
|
const KeyPress::table_key &KeyPress::lookupKeychar(wchar_t Char)
|
||||||
{
|
{
|
||||||
if (Char == L'\0')
|
if (Char == L'\0')
|
||||||
return invalid_key;
|
return invalid_key;
|
||||||
|
|
||||||
for (const auto &table_key : table) {
|
for (const auto &table_key : keycode_table) {
|
||||||
if (table_key.Char == Char)
|
if (table_key.Char == Char)
|
||||||
return table_key;
|
return table_key;
|
||||||
}
|
}
|
||||||
|
@ -242,15 +234,15 @@ static const table_key &lookup_keychar(wchar_t Char)
|
||||||
// Create a new entry in the lookup table if one is not available.
|
// Create a new entry in the lookup table if one is not available.
|
||||||
auto newsym = wide_to_utf8(std::wstring_view(&Char, 1));
|
auto newsym = wide_to_utf8(std::wstring_view(&Char, 1));
|
||||||
table_key new_key {newsym, irr::KEY_KEY_CODES_COUNT, Char, newsym};
|
table_key new_key {newsym, irr::KEY_KEY_CODES_COUNT, Char, newsym};
|
||||||
return table.emplace_back(std::move(new_key));
|
return keycode_table.emplace_back(std::move(new_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const table_key &lookup_keykey(irr::EKEY_CODE key)
|
const KeyPress::table_key &KeyPress::lookupKeykey(irr::EKEY_CODE key)
|
||||||
{
|
{
|
||||||
if (!Keycode::isValid(key))
|
if (!Keycode::isValid(key))
|
||||||
return invalid_key;
|
return invalid_key;
|
||||||
|
|
||||||
for (const auto &table_key : table) {
|
for (const auto &table_key : keycode_table) {
|
||||||
if (table_key.Key == key)
|
if (table_key.Key == key)
|
||||||
return table_key;
|
return table_key;
|
||||||
}
|
}
|
||||||
|
@ -258,12 +250,12 @@ static const table_key &lookup_keykey(irr::EKEY_CODE key)
|
||||||
return invalid_key;
|
return invalid_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const table_key &lookup_keyname(std::string_view name)
|
const KeyPress::table_key &KeyPress::lookupKeyname(std::string_view name)
|
||||||
{
|
{
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
return invalid_key;
|
return invalid_key;
|
||||||
|
|
||||||
for (const auto &table_key : table) {
|
for (const auto &table_key : keycode_table) {
|
||||||
if (table_key.Name == name)
|
if (table_key.Name == name)
|
||||||
return table_key;
|
return table_key;
|
||||||
}
|
}
|
||||||
|
@ -271,34 +263,43 @@ static const table_key &lookup_keyname(std::string_view name)
|
||||||
auto wname = utf8_to_wide(name);
|
auto wname = utf8_to_wide(name);
|
||||||
if (wname.empty())
|
if (wname.empty())
|
||||||
return invalid_key;
|
return invalid_key;
|
||||||
return lookup_keychar(wname[0]);
|
return lookupKeychar(wname[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const table_key &lookup_scancode(const u32 scancode)
|
const KeyPress::table_key &KeyPress::lookupScancode(const u32 scancode)
|
||||||
{
|
{
|
||||||
auto key = RenderingEngine::get_raw_device()->getKeyFromScancode(scancode);
|
auto key = RenderingEngine::get_raw_device()->getKeyFromScancode(scancode);
|
||||||
return std::holds_alternative<EKEY_CODE>(key) ?
|
return std::holds_alternative<EKEY_CODE>(key) ?
|
||||||
lookup_keykey(std::get<irr::EKEY_CODE>(key)) :
|
lookupKeykey(std::get<irr::EKEY_CODE>(key)) :
|
||||||
lookup_keychar(std::get<wchar_t>(key));
|
lookupKeychar(std::get<wchar_t>(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const table_key &lookup_scancode(const std::variant<u32, irr::EKEY_CODE> &scancode)
|
const KeyPress::table_key &KeyPress::lookupScancode() const
|
||||||
{
|
{
|
||||||
return std::holds_alternative<irr::EKEY_CODE>(scancode) ?
|
switch (getType()) {
|
||||||
lookup_keykey(std::get<irr::EKEY_CODE>(scancode)) :
|
case KeyPress::KEYCODE_INPUT:
|
||||||
lookup_scancode(std::get<u32>(scancode));
|
return lookupKeykey(std::get<irr::EKEY_CODE>(scancode));
|
||||||
|
case KeyPress::SCANCODE_INPUT:
|
||||||
|
return lookupScancode(std::get<u32>(scancode));
|
||||||
|
default:
|
||||||
|
return invalid_key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyPress::loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar)
|
void KeyPress::loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar)
|
||||||
{
|
{
|
||||||
scancode = RenderingEngine::get_raw_device()->getScancodeFromKey(Keycode(keycode, keychar));
|
auto irr_scancode = RenderingEngine::get_raw_device()->getScancodeFromKey(Keycode(keycode, keychar));
|
||||||
|
if (std::holds_alternative<irr::EKEY_CODE>(irr_scancode))
|
||||||
|
scancode.emplace<irr::EKEY_CODE>(std::get<irr::EKEY_CODE>(irr_scancode));
|
||||||
|
else
|
||||||
|
scancode.emplace<u32>(std::get<u32>(irr_scancode));
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyPress::KeyPress(const std::string &name)
|
KeyPress::KeyPress(const std::string &name)
|
||||||
{
|
{
|
||||||
if (loadFromScancode(name))
|
if (loadFromScancode(name))
|
||||||
return;
|
return;
|
||||||
const auto &key = lookup_keyname(name);
|
const auto &key = lookupKeyname(name);
|
||||||
loadFromKey(key.Key, key.Char);
|
loadFromKey(key.Key, key.Char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +326,7 @@ std::string KeyPress::formatScancode() const
|
||||||
|
|
||||||
std::string KeyPress::sym() const
|
std::string KeyPress::sym() const
|
||||||
{
|
{
|
||||||
std::string name = lookup_scancode(scancode).Name;
|
std::string name = lookupScancode().Name;
|
||||||
if (USE_SDL2 || name.empty())
|
if (USE_SDL2 || name.empty())
|
||||||
if (auto newname = formatScancode(); !newname.empty())
|
if (auto newname = formatScancode(); !newname.empty())
|
||||||
return newname;
|
return newname;
|
||||||
|
@ -334,7 +335,7 @@ std::string KeyPress::sym() const
|
||||||
|
|
||||||
std::string KeyPress::name() const
|
std::string KeyPress::name() const
|
||||||
{
|
{
|
||||||
const auto &name = lookup_scancode(scancode).LangName;
|
const auto &name = lookupScancode().LangName;
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
return name;
|
return name;
|
||||||
return formatScancode();
|
return formatScancode();
|
||||||
|
@ -342,12 +343,12 @@ std::string KeyPress::name() const
|
||||||
|
|
||||||
irr::EKEY_CODE KeyPress::getKeycode() const
|
irr::EKEY_CODE KeyPress::getKeycode() const
|
||||||
{
|
{
|
||||||
return lookup_scancode(scancode).Key;
|
return lookupScancode().Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t KeyPress::getKeychar() const
|
wchar_t KeyPress::getKeychar() const
|
||||||
{
|
{
|
||||||
return lookup_scancode(scancode).Char;
|
return lookupScancode().Char;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyPress::loadFromScancode(const std::string &name)
|
bool KeyPress::loadFromScancode(const std::string &name)
|
||||||
|
@ -375,6 +376,20 @@ KeyPress KeyPress::getSpecialKey(const std::string &name)
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyPress::operator bool() const
|
||||||
|
{
|
||||||
|
switch (getType()) {
|
||||||
|
case KeyPress::SCANCODE_INPUT:
|
||||||
|
return std::get<u32>(scancode) != 0;
|
||||||
|
case KeyPress::KEYCODE_INPUT:
|
||||||
|
return Keycode::isValid(std::get<irr::EKEY_CODE>(scancode));
|
||||||
|
case KeyPress::GAME_ACTION_INPUT:
|
||||||
|
return std::get<GameKeyType>(scancode) < KeyType::INTERNAL_ENUM_COUNT;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Key config
|
Key config
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "irrlichttypes.h"
|
#include "irrlichttypes.h"
|
||||||
|
#include "keys.h"
|
||||||
#include <Keycodes.h>
|
#include <Keycodes.h>
|
||||||
#include <IEventReceiver.h>
|
#include <IEventReceiver.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -17,6 +18,12 @@
|
||||||
class KeyPress
|
class KeyPress
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum InputType {
|
||||||
|
SCANCODE_INPUT, // Keyboard input (scancodes)
|
||||||
|
KEYCODE_INPUT, // (Deprecated) irr::EKEY_CODE-based keyboard and mouse input
|
||||||
|
GAME_ACTION_INPUT, // GameKeyType input passed by touchscreen buttons
|
||||||
|
};
|
||||||
|
|
||||||
KeyPress() = default;
|
KeyPress() = default;
|
||||||
|
|
||||||
KeyPress(const std::string &name);
|
KeyPress(const std::string &name);
|
||||||
|
@ -55,18 +62,32 @@ public:
|
||||||
return scancode < o.scancode;
|
return scancode < o.scancode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the keypress is valid
|
InputType getType() const {
|
||||||
operator bool() const
|
return static_cast<InputType>(scancode.index());
|
||||||
{
|
|
||||||
return std::holds_alternative<irr::EKEY_CODE>(scancode) ?
|
|
||||||
Keycode::isValid(std::get<irr::EKEY_CODE>(scancode)) :
|
|
||||||
std::get<u32>(scancode) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether the keypress is valid
|
||||||
|
operator bool() const;
|
||||||
|
|
||||||
static KeyPress getSpecialKey(const std::string &name);
|
static KeyPress getSpecialKey(const std::string &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using value_type = std::variant<u32, irr::EKEY_CODE>;
|
struct table_key { // internal keycode lookup table
|
||||||
|
std::string Name; // An EKEY_CODE 'symbol' name as a string
|
||||||
|
irr::EKEY_CODE Key;
|
||||||
|
wchar_t Char; // L'\0' means no character assigned
|
||||||
|
std::string LangName; // empty string means it doesn't have a human description
|
||||||
|
};
|
||||||
|
static const table_key invalid_key;
|
||||||
|
static std::vector<table_key> keycode_table;
|
||||||
|
static const table_key &lookupKeychar(wchar_t Char);
|
||||||
|
static const table_key &lookupKeykey(irr::EKEY_CODE key);
|
||||||
|
static const table_key &lookupKeyname(std::string_view name);
|
||||||
|
static const table_key &lookupScancode(const u32 scancode);
|
||||||
|
const table_key &lookupScancode() const;
|
||||||
|
|
||||||
|
using value_type = std::variant<u32, irr::EKEY_CODE, GameKeyType>;
|
||||||
|
|
||||||
bool loadFromScancode(const std::string &name);
|
bool loadFromScancode(const std::string &name);
|
||||||
void loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar);
|
void loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar);
|
||||||
std::string formatScancode() const;
|
std::string formatScancode() const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue