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 <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 */ \
|
||||
{ #x, irr::x, L'\0', lang },
|
||||
#define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \
|
||||
|
@ -33,7 +26,7 @@ struct table_key {
|
|||
|
||||
#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
|
||||
DEFINEKEY3(0)
|
||||
DEFINEKEY3(1)
|
||||
|
@ -223,18 +216,17 @@ static std::vector<table_key> table = {
|
|||
DEFINEKEY5("^")
|
||||
DEFINEKEY5("_")
|
||||
};
|
||||
|
||||
static const table_key invalid_key = {"", irr::KEY_UNKNOWN, L'\0', ""};
|
||||
const KeyPress::table_key KeyPress::invalid_key = {"", irr::KEY_UNKNOWN, L'\0', ""};
|
||||
|
||||
#undef N_
|
||||
|
||||
|
||||
static const table_key &lookup_keychar(wchar_t Char)
|
||||
const KeyPress::table_key &KeyPress::lookupKeychar(wchar_t Char)
|
||||
{
|
||||
if (Char == L'\0')
|
||||
return invalid_key;
|
||||
|
||||
for (const auto &table_key : table) {
|
||||
for (const auto &table_key : keycode_table) {
|
||||
if (table_key.Char == Char)
|
||||
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.
|
||||
auto newsym = wide_to_utf8(std::wstring_view(&Char, 1));
|
||||
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))
|
||||
return invalid_key;
|
||||
|
||||
for (const auto &table_key : table) {
|
||||
for (const auto &table_key : keycode_table) {
|
||||
if (table_key.Key == key)
|
||||
return table_key;
|
||||
}
|
||||
|
@ -258,12 +250,12 @@ static const table_key &lookup_keykey(irr::EKEY_CODE 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())
|
||||
return invalid_key;
|
||||
|
||||
for (const auto &table_key : table) {
|
||||
for (const auto &table_key : keycode_table) {
|
||||
if (table_key.Name == name)
|
||||
return table_key;
|
||||
}
|
||||
|
@ -271,34 +263,43 @@ static const table_key &lookup_keyname(std::string_view name)
|
|||
auto wname = utf8_to_wide(name);
|
||||
if (wname.empty())
|
||||
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);
|
||||
return std::holds_alternative<EKEY_CODE>(key) ?
|
||||
lookup_keykey(std::get<irr::EKEY_CODE>(key)) :
|
||||
lookup_keychar(std::get<wchar_t>(key));
|
||||
lookupKeykey(std::get<irr::EKEY_CODE>(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) ?
|
||||
lookup_keykey(std::get<irr::EKEY_CODE>(scancode)) :
|
||||
lookup_scancode(std::get<u32>(scancode));
|
||||
switch (getType()) {
|
||||
case KeyPress::KEYCODE_INPUT:
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (loadFromScancode(name))
|
||||
return;
|
||||
const auto &key = lookup_keyname(name);
|
||||
const auto &key = lookupKeyname(name);
|
||||
loadFromKey(key.Key, key.Char);
|
||||
}
|
||||
|
||||
|
@ -325,7 +326,7 @@ std::string KeyPress::formatScancode() const
|
|||
|
||||
std::string KeyPress::sym() const
|
||||
{
|
||||
std::string name = lookup_scancode(scancode).Name;
|
||||
std::string name = lookupScancode().Name;
|
||||
if (USE_SDL2 || name.empty())
|
||||
if (auto newname = formatScancode(); !newname.empty())
|
||||
return newname;
|
||||
|
@ -334,7 +335,7 @@ std::string KeyPress::sym() const
|
|||
|
||||
std::string KeyPress::name() const
|
||||
{
|
||||
const auto &name = lookup_scancode(scancode).LangName;
|
||||
const auto &name = lookupScancode().LangName;
|
||||
if (!name.empty())
|
||||
return name;
|
||||
return formatScancode();
|
||||
|
@ -342,12 +343,12 @@ std::string KeyPress::name() const
|
|||
|
||||
irr::EKEY_CODE KeyPress::getKeycode() const
|
||||
{
|
||||
return lookup_scancode(scancode).Key;
|
||||
return lookupScancode().Key;
|
||||
}
|
||||
|
||||
wchar_t KeyPress::getKeychar() const
|
||||
{
|
||||
return lookup_scancode(scancode).Char;
|
||||
return lookupScancode().Char;
|
||||
}
|
||||
|
||||
bool KeyPress::loadFromScancode(const std::string &name)
|
||||
|
@ -375,6 +376,20 @@ KeyPress KeyPress::getSpecialKey(const std::string &name)
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "keys.h"
|
||||
#include <Keycodes.h>
|
||||
#include <IEventReceiver.h>
|
||||
#include <string>
|
||||
|
@ -17,6 +18,12 @@
|
|||
class KeyPress
|
||||
{
|
||||
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(const std::string &name);
|
||||
|
@ -55,18 +62,32 @@ public:
|
|||
return scancode < o.scancode;
|
||||
}
|
||||
|
||||
// Check whether the keypress is valid
|
||||
operator bool() const
|
||||
{
|
||||
return std::holds_alternative<irr::EKEY_CODE>(scancode) ?
|
||||
Keycode::isValid(std::get<irr::EKEY_CODE>(scancode)) :
|
||||
std::get<u32>(scancode) != 0;
|
||||
InputType getType() const {
|
||||
return static_cast<InputType>(scancode.index());
|
||||
}
|
||||
|
||||
// Check whether the keypress is valid
|
||||
operator bool() const;
|
||||
|
||||
static KeyPress getSpecialKey(const std::string &name);
|
||||
|
||||
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);
|
||||
void loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar);
|
||||
std::string formatScancode() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue