On windows/linux convert known native scancodes to default keys

* This lets us have more helpful behaviour for default keys rather than being
  all-or-nothing, and display which keys are which.
This commit is contained in:
baldurk
2025-12-05 15:34:11 +00:00
parent c554f726dd
commit f86aa4a2b7
4 changed files with 264 additions and 193 deletions
+17 -117
View File
@@ -70,69 +70,6 @@ Q_DECLARE_METATYPE(FixedVarTag);
static const uint32_t MaxVisibleRows = 10000;
namespace NativeScanCode
{
enum
{
#if defined(Q_OS_WIN32)
Key_A = 30,
Key_S = 31,
Key_D = 32,
Key_F = 33,
Key_W = 17,
Key_R = 19,
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
Key_A = 30 + 8,
Key_S = 31 + 8,
Key_D = 32 + 8,
Key_F = 33 + 8,
Key_W = 17 + 8,
Key_R = 19 + 8,
#elif defined(Q_OS_MACOS)
// scan codes not supported on OS X
Key_A = 0xDEADBEF1,
Key_S = 0xDEADBEF2,
Key_D = 0xDEADBEF3,
Key_F = 0xDEADBEF4,
Key_W = 0xDEADBEF5,
Key_R = 0xDEADBEF6,
#else
#error "Unknown platform! Define NativeScanCode"
#endif
};
}; // namespace NativeScanCode
namespace NativeVirtualKey
{
enum
{
#if defined(Q_OS_WIN32)
Key_A = quint32('A'),
Key_S = quint32('S'),
Key_D = quint32('D'),
Key_F = quint32('F'),
Key_W = quint32('W'),
Key_R = quint32('R'),
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
Key_A = quint32('a'),
Key_S = quint32('s'),
Key_D = quint32('d'),
Key_F = quint32('f'),
Key_W = quint32('w'),
Key_R = quint32('r'),
#elif defined(Q_OS_MACOS)
Key_A = 0x00,
Key_S = 0x01,
Key_D = 0x02,
Key_F = 0x03,
Key_W = 0x0D,
Key_R = 0x0F,
#else
#error "Unknown platform! Define NativeVirtualKey"
#endif
};
}; // namespace NativeVirtualKey
class CameraWrapper
{
public:
@@ -155,64 +92,27 @@ public:
KeyPressDirection GetDirection(QKeyEvent *e)
{
// if no settings are bound, use default bindings. This should be empty, but we also do this
// path if it's invalid and not the size we expect
if(m_Ctx.Config().MeshViewer_KeySettings.size() < (size_t)KeyPressDirection::NumSettings)
const rdcarray<uint32_t> &keys = m_Ctx.Config().MeshViewer_KeySettings;
for(int i = 0; i < (int)KeyPressDirection::Count; i++)
{
// if we have a native scancode, we expect to be able to match it. If we don't then don't get
// any false positives by checking the virtual key
if(e->nativeScanCode() > 1)
{
switch(e->nativeScanCode())
{
case NativeScanCode::Key_A: return KeyPressDirection::Left;
case NativeScanCode::Key_D: return KeyPressDirection::Right;
case NativeScanCode::Key_W: return KeyPressDirection::Forward;
case NativeScanCode::Key_S: return KeyPressDirection::Back;
case NativeScanCode::Key_R: return KeyPressDirection::Up;
case NativeScanCode::Key_F: return KeyPressDirection::Down;
default: break;
}
}
KeyPressDirection dir = KeyPressDirection(i);
Qt::Key primary, secondary;
int p = keySettingIdx(dir, true);
int s = keySettingIdx(dir, false);
if(p < keys.count() && keys[p] != 0)
primary = getKeySetting(keys[p]);
else
{
switch(e->nativeVirtualKey())
{
case NativeVirtualKey::Key_A: return KeyPressDirection::Left;
case NativeVirtualKey::Key_D: return KeyPressDirection::Right;
case NativeVirtualKey::Key_W: return KeyPressDirection::Forward;
case NativeVirtualKey::Key_S: return KeyPressDirection::Back;
case NativeVirtualKey::Key_R: return KeyPressDirection::Up;
case NativeVirtualKey::Key_F: return KeyPressDirection::Down;
default: break;
}
}
primary = getDefaultKey(dir, true);
// handle arrow keys, we can do this safely with Qt::Key
switch(e->key())
{
case Qt::Key_Left: return KeyPressDirection::Left;
case Qt::Key_Right: return KeyPressDirection::Right;
case Qt::Key_Up: return KeyPressDirection::Forward;
case Qt::Key_Down: return KeyPressDirection::Back;
case Qt::Key_PageUp: return KeyPressDirection::Up;
case Qt::Key_PageDown: return KeyPressDirection::Down;
default: break;
}
}
else
{
for(int i = 0; i < (int)KeyPressDirection::Count; i++)
{
KeyPressDirection dir = KeyPressDirection(i);
Qt::Key primary =
getKeySetting(m_Ctx.Config().MeshViewer_KeySettings[keySettingIdx(dir, true)]);
Qt::Key secondary =
getKeySetting(m_Ctx.Config().MeshViewer_KeySettings[keySettingIdx(dir, false)]);
if(s < keys.count() && keys[s] != 0)
secondary = getKeySetting(keys[s]);
else
secondary = getDefaultKey(dir, false);
if(e->key() == primary || e->key() == secondary)
return dir;
}
if(e->key() == primary || e->key() == secondary)
return dir;
}
return KeyPressDirection::None;