From 0edc0db7bdc018d68a9645838e942bc8d344a5dd Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Thu, 16 Apr 2009 10:40:00 +0200 Subject: [PATCH] PianoView/PianoRoll: fixed keycodes for OS X This patch enables the usage of PC keyboard for playing instrument piano or piano roll on OS X by evaluating nativeVirtualKey rather than nativeScanCode. (cherry picked from commit 6f0388be7ceaa45a60f0adaa7af1e00f7767f574) --- include/piano.h | 4 +- src/core/piano.cpp | 210 +++++++++++++++++++++++++---------------- src/gui/piano_roll.cpp | 10 +- 3 files changed, 134 insertions(+), 90 deletions(-) diff --git a/include/piano.h b/include/piano.h index 85e853a5e..082adee8a 100644 --- a/include/piano.h +++ b/include/piano.h @@ -1,7 +1,7 @@ /* * piano.h - piano and pianoView, an interactive piano/keyboard-widget * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2009 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -77,7 +77,7 @@ public: pianoView( QWidget * _parent ); virtual ~pianoView(); - static int getKeyFromScancode( int _sc ); + static int getKeyFromKeyEvent( QKeyEvent * _ke ); protected: diff --git a/src/core/piano.cpp b/src/core/piano.cpp index 503d99627..48817bea6 100644 --- a/src/core/piano.cpp +++ b/src/core/piano.cpp @@ -244,87 +244,133 @@ pianoView::~pianoView() * \todo check the scan codes for ',' = c, 'L' = c#, '.' = d, ':' = d#, * '/' = d, '[' = f', '=' = f'#, ']' = g' - Paul's additions */ -int pianoView::getKeyFromScancode( int _k ) +int pianoView::getKeyFromKeyEvent( QKeyEvent * _ke ) { -#ifdef LMMS_BUILD_WIN32 - switch( _k ) - { - case 44: return( 0 ); // Y = C - case 31: return( 1 ); // S = C# - case 45: return( 2 ); // X = D - case 32: return( 3 ); // D = D# - case 46: return( 4 ); // C = E - case 47: return( 5 ); // V = F - case 34: return( 6 ); // G = F# - case 48: return( 7 ); // B = G - case 35: return( 8 ); // H = G# - case 49: return( 9 ); // N = A - case 36: return( 10 ); // J = A# - case 50: return( 11 ); // M = B - case 51: return( 12 ); // , = c - case 38: return( 13 ); // L = c# - case 52: return( 14 ); // . = d - case 39: return( 15 ); // ; = d# - case 86: return( 16 ); // / = e - case 16: return( 12 ); // Q = c - case 3: return( 13 ); // 2 = c# - case 17: return( 14 ); // W = d - case 4: return( 15 ); // 3 = d# - case 18: return( 16 ); // E = e - case 19: return( 17 ); // R = f - case 6: return( 18 ); // 5 = f# - case 20: return( 19 ); // T = g - case 7: return( 20 ); // 6 = g# - case 21: return( 21 ); // Z = a - case 8: return( 22 ); // 7 = a# - case 22: return( 23 ); // U = b - case 23: return( 24 ); // I = c' - case 10: return( 25 ); // 9 = c'# - case 24: return( 26 ); // O = d' - case 11: return( 27 ); // 0 = d'# - case 25: return( 28 ); // P = e' - } +#ifdef LMMS_BUILD_APPLE + const int k = _ke->nativeVirtualKey(); #else - switch( _k ) + const int k = _ke->nativeScanCode(); +#endif + +#ifdef LMMS_BUILD_WIN32 + switch( k ) { - case 52: return( 0 ); // Y = C - case 39: return( 1 ); // S = C# - case 53: return( 2 ); // X = D - case 40: return( 3 ); // D = D# - case 54: return( 4 ); // C = E - case 55: return( 5 ); // V = F - case 42: return( 6 ); // G = F# - case 56: return( 7 ); // B = G - case 43: return( 8 ); // H = G# - case 57: return( 9 ); // N = A - case 44: return( 10 ); // J = A# - case 58: return( 11 ); // M = B - case 59: return( 12 ); // , = c - case 46: return( 13 ); // L = c# - case 60: return( 14 ); // . = d - case 47: return( 15 ); // ; = d# - case 61: return( 16 ); // / = e - case 24: return( 12 ); // Q = c - case 11: return( 13 ); // 2 = c# - case 25: return( 14 ); // W = d - case 12: return( 15 ); // 3 = d# - case 26: return( 16 ); // E = e - case 27: return( 17 ); // R = f - case 14: return( 18 ); // 5 = f# - case 28: return( 19 ); // T = g - case 15: return( 20 ); // 6 = g# - case 29: return( 21 ); // Z = a - case 16: return( 22 ); // 7 = a# - case 30: return( 23 ); // U = b - case 31: return( 24 ); // I = c' - case 18: return( 25 ); // 9 = c'# - case 32: return( 26 ); // O = d' - case 19: return( 27 ); // 0 = d'# - case 33: return( 28 ); // P = e' + case 44: return 0; // Z = C + case 31: return 1; // S = C# + case 45: return 2; // X = D + case 32: return 3; // D = D# + case 46: return 4; // C = E + case 47: return 5; // V = F + case 34: return 6; // G = F# + case 48: return 7; // B = G + case 35: return 8; // H = G# + case 49: return 9; // N = A + case 36: return 10; // J = A# + case 50: return 11; // M = B + case 51: return 12; // , = c + case 38: return 13; // L = c# + case 52: return 14; // . = d + case 39: return 15; // ; = d# + case 86: return 16; // / = e + case 16: return 12; // Q = c + case 3: return 13; // 2 = c# + case 17: return 14; // W = d + case 4: return 15; // 3 = d# + case 18: return 16; // E = e + case 19: return 17; // R = f + case 6: return 18; // 5 = f# + case 20: return 19; // T = g + case 7: return 20; // 6 = g# + case 21: return 21; // Y = a + case 8: return 22; // 7 = a# + case 22: return 23; // U = b + case 23: return 24; // I = c' + case 10: return 25; // 9 = c'# + case 24: return 26; // O = d' + case 11: return 27; // 0 = d'# + case 25: return 28; // P = e' + } +#endif +#ifdef LMMS_BUILD_LINUX + switch( k ) + { + case 52: return 0; // Z = C + case 39: return 1; // S = C# + case 53: return 2; // X = D + case 40: return 3; // D = D# + case 54: return 4; // C = E + case 55: return 5; // V = F + case 42: return 6; // G = F# + case 56: return 7; // B = G + case 43: return 8; // H = G# + case 57: return 9; // N = A + case 44: return 10; // J = A# + case 58: return 11; // M = B + case 59: return 12; // , = c + case 46: return 13; // L = c# + case 60: return 14; // . = d + case 47: return 15; // ; = d# + case 61: return 16; // / = e + case 24: return 12; // Q = c + case 11: return 13; // 2 = c# + case 25: return 14; // W = d + case 12: return 15; // 3 = d# + case 26: return 16; // E = e + case 27: return 17; // R = f + case 14: return 18; // 5 = f# + case 28: return 19; // T = g + case 15: return 20; // 6 = g# + case 29: return 21; // Y = a + case 16: return 22; // 7 = a# + case 30: return 23; // U = b + case 31: return 24; // I = c' + case 18: return 25; // 9 = c'# + case 32: return 26; // O = d' + case 19: return 27; // 0 = d'# + case 33: return 28; // P = e' + } +#endif +#ifdef LMMS_BUILD_APPLE + switch( k ) + { + case 6: return 0; // Z = C + case 1: return 1; // S = C# + case 7: return 2; // X = D + case 2: return 3; // D = D# + case 8: return 4; // C = E + case 9: return 5; // V = F + case 5: return 6; // G = F# + case 11: return 7; // B = G + case 4: return 8; // H = G# + case 45: return 9; // N = A + case 38: return 10; // J = A# + case 46: return 11; // M = B + case 43: return 12; // , = c + case 37: return 13; // L = c# + case 47: return 14; // . = d + case 41: return 15; // ; = d# + case 44: return 16; // / = e + case 12: return 12; // Q = c + case 19: return 13; // 2 = c# + case 13: return 14; // W = d + case 20: return 15; // 3 = d# + case 14: return 16; // E = e + case 15: return 17; // R = f + case 23: return 18; // 5 = f# + case 17: return 19; // T = g + case 22: return 20; // 6 = g# + case 16: return 21; // Y = a + case 26: return 22; // 7 = a# + case 32: return 23; // U = b + case 34: return 24; // I = c' + case 25: return 25; // 9 = c'# + case 31: return 26; // O = d' + case 29: return 27; // 0 = d'# + case 35: return 28; // P = e' } #endif - return( -100 ); + return -100; } @@ -406,7 +452,7 @@ int pianoView::getKeyFromMouse( const QPoint & _p ) const } // some range-checking-stuff - return( tLimit( key_num, 0, KeysPerOctave * NumOctaves - 1 ) ); + return tLimit( key_num, 0, KeysPerOctave * NumOctaves - 1 ); } @@ -650,7 +696,7 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me ) /*! \brief Handle a key press event on the piano display view * - * We determine our key number from the getKeyFromScanCode() method, + * We determine our key number from the getKeyFromKeyEvent() method, * and pass the event on to the piano's handleKeyPress() method if * auto-repeat is off. * @@ -658,8 +704,8 @@ void pianoView::mouseMoveEvent( QMouseEvent * _me ) */ void pianoView::keyPressEvent( QKeyEvent * _ke ) { - int key_num = getKeyFromScancode( _ke->nativeScanCode() ) + - ( DefaultOctave - 1 ) * KeysPerOctave; + const int key_num = getKeyFromKeyEvent( _ke ) + + ( DefaultOctave - 1 ) * KeysPerOctave; if( _ke->isAutoRepeat() == FALSE && key_num > -1 ) { @@ -686,7 +732,7 @@ void pianoView::keyPressEvent( QKeyEvent * _ke ) */ void pianoView::keyReleaseEvent( QKeyEvent * _ke ) { - int key_num = getKeyFromScancode( _ke->nativeScanCode() ) + + const int key_num = getKeyFromKeyEvent( _ke ) + ( DefaultOctave - 1 ) * KeysPerOctave; if( _ke->isAutoRepeat() == FALSE && key_num > -1 ) { @@ -768,7 +814,7 @@ int pianoView::getKeyX( int _key_num ) const int k = m_startKey; if( _key_num < m_startKey ) { - return( ( _key_num - k ) * PW_WHITE_KEY_WIDTH / 2 ); + return ( _key_num - k ) * PW_WHITE_KEY_WIDTH / 2; } int x = 0; @@ -798,7 +844,7 @@ int pianoView::getKeyX( int _key_num ) const x -= PW_WHITE_KEY_WIDTH / 2; - return( x ); + return x; } diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index af4f881a9..a1ed8b5fb 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -890,9 +890,8 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) { if( validPattern() && _ke->modifiers() == Qt::NoModifier ) { - int key_num = pianoView::getKeyFromScancode( - _ke->nativeScanCode() ) + - ( DefaultOctave - 1 ) * KeysPerOctave; + const int key_num = pianoView::getKeyFromKeyEvent( _ke ) + + ( DefaultOctave - 1 ) * KeysPerOctave; if( _ke->isAutoRepeat() == false && key_num > -1 ) { @@ -1197,9 +1196,8 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * _ke ) { if( validPattern() && _ke->modifiers() == Qt::NoModifier ) { - int key_num = pianoView::getKeyFromScancode( - _ke->nativeScanCode() ) + - ( DefaultOctave - 1 ) * KeysPerOctave; + const int key_num = pianoView::getKeyFromKeyEvent( _ke ) + + ( DefaultOctave - 1 ) * KeysPerOctave; if( _ke->isAutoRepeat() == false && key_num > -1 ) {