From 4d8490e21bba7285e1004bf5852d0e72b146e701 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 13 Dec 2008 09:02:11 +0000 Subject: [PATCH] Fixed bug I introduced last checkin, and now if you click towards the end of the key in the piano roll, it plays the note louder than if you play it towards the base git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1910 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 3 ++ TODO | 1 + include/piano_roll.h | 7 +++ src/gui/piano_roll.cpp | 117 +++++++++++++++++++++++++++++++---------- 4 files changed, 100 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 304940c05..95965fd61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -11,6 +11,9 @@ none selected) - when "scribbling" note volumes, if there is a chord, it will play all 3 notes, rather than just the first one + - if you click towards the end of the key in the piano roll, it plays + the note louder than if you play it towards the base + 2008-12-11 Tobias Doerffel diff --git a/TODO b/TODO index c4d28e262..ab6f9ee8c 100644 --- a/TODO +++ b/TODO @@ -63,6 +63,7 @@ Andrew Kelley's todo: * humanizing tool * quick slice * look through FL Studio's tools and implement some of them +- if you press both controls at the same time, the piano roll gets stuck in selection mode - recording automation - make knobs easier to tune (less sensitive) diff --git a/include/piano_roll.h b/include/piano_roll.h index 3bd540923..45c628ffb 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -171,6 +171,13 @@ private: bool isSelection() const; void testPlayNote( note * n ); + inline int noteEditTop() const; + inline int keyAreaBottom() const; + inline int noteEditBottom() const; + inline int keyAreaTop() const; + inline int noteEditRight() const; + inline int noteEditLeft() const; + void dragNotes( int x, int y, bool alt ); static const int cm_scrollAmtHoriz = 10; diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 4ad4dd4c6..cf78efe0b 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -91,8 +91,11 @@ const int C_KEY_LABEL_X = WHITE_KEY_WIDTH - 19; const int KEY_LINE_HEIGHT = 12; const int OCTAVE_HEIGHT = KEY_LINE_HEIGHT * KeysPerOctave; // = 12 * 12; +const int NOTE_EDIT_RESIZE_BAR = 6; const int PR_BOTTOM_MARGIN = SCROLLBAR_SIZE; const int PR_TOP_MARGIN = 48; +const int PR_RIGHT_MARGIN = SCROLLBAR_SIZE; + // width of area used for resizing (the grip at the end of a note) const int RESIZE_AREA_WIDTH = 4; @@ -1065,6 +1068,48 @@ void pianoRoll::leaveEvent( QEvent * _e ) +inline int pianoRoll::noteEditTop() const +{ + return height() - PR_BOTTOM_MARGIN - + m_notesEditHeight + NOTE_EDIT_RESIZE_BAR; +} + + + +inline int pianoRoll::noteEditBottom() const +{ + return height() - PR_BOTTOM_MARGIN; +} + + + +inline int pianoRoll::noteEditRight() const +{ + return width() - PR_RIGHT_MARGIN; +} + + + +inline int pianoRoll::noteEditLeft() const +{ + return WHITE_KEY_WIDTH; +} + + + +inline int pianoRoll::keyAreaTop() const +{ + return PR_TOP_MARGIN; +} + + + +inline int pianoRoll::keyAreaBottom() const +{ + return height() - PR_BOTTOM_MARGIN - m_notesEditHeight; +} + + void pianoRoll::mousePressEvent( QMouseEvent * _me ) { @@ -1083,8 +1128,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) { volume vol = DefaultVolume; - bool edit_note = ( _me->y() > height() - - PR_BOTTOM_MARGIN - m_notesEditHeight ); + bool edit_note = ( _me->y() > noteEditTop() ); int key_num = getKey( _me->y() ); @@ -1375,6 +1419,18 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me ) update(); } + else + { + // clicked on keyboard on the left - play note + m_lastKey = key_num; + if( ! m_recording && ! engine::getSong()->isPlaying() ) + { + int v = ( (float) x ) / ( (float) WHITE_KEY_WIDTH ) * 127; + m_pattern->getInstrumentTrack()->processInEvent( + midiEvent( MidiNoteOn, 0, key_num, v ), + midiTime() ); + } + } } } @@ -1422,7 +1478,7 @@ void pianoRoll::computeSelectedNotes(bool shift) qSwap( sel_key_start, sel_key_end ); } - //int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1; + //int y_base = noteEditTop() - 1; if( validPattern() == true ) { const noteVector & notes = m_pattern->notes(); @@ -1522,6 +1578,11 @@ void pianoRoll::mouseReleaseEvent( QMouseEvent * _me ) ++it; } + + // stop playing keys that we let go of + m_pattern->getInstrumentTrack()->processInEvent( + midiEvent( MidiNoteOff, 0, m_lastKey, 0 ), midiTime() ); + } m_currentNote = NULL; @@ -1552,8 +1613,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) if( _me->y() > PR_TOP_MARGIN || m_action != ActionNone ) { - bool edit_note = ( _me->y() > - height() - PR_BOTTOM_MARGIN - m_notesEditHeight ) + bool edit_note = ( _me->y() > noteEditTop() ) && m_action != ActionSelectNotes; @@ -1564,24 +1624,26 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) // (could be the user just moved the cursor one pixel up/down // but is still on the same key) if( key_num != m_lastKey && - ( m_action == ActionMoveNote || m_action == ActionMoveSelection ) && + ( (m_action == ActionMoveNote || m_action == ActionMoveSelection ) + || ( x < WHITE_KEY_WIDTH && m_action == ActionNone ) ) && edit_note == false && _me->buttons() & Qt::LeftButton ) { m_pattern->getInstrumentTrack()->processInEvent( midiEvent( MidiNoteOff, 0, m_lastKey, 0 ), midiTime() ); - if( _me->buttons() & Qt::LeftButton && - m_action != ActionResizeNote && - m_action != ActionSelectNotes && - m_action != ActionMoveSelection && - m_recording == false ) + if( _me->buttons() & Qt::LeftButton ) { m_lastKey = key_num; + + int v = DefaultVolume * 127 / 100; + if( x < WHITE_KEY_WIDTH ) + { + v = ( (float) x ) / ( (float) WHITE_KEY_WIDTH ) * 127; + } + m_pattern->getInstrumentTrack()->processInEvent( - midiEvent( MidiNoteOn, 0, key_num, - DefaultVolume * 127 / 100 ), - midiTime() ); + midiEvent( MidiNoteOn, 0, key_num, v ), midiTime() ); } } if( x < WHITE_KEY_WIDTH && m_action == ActionNone ) @@ -1914,9 +1976,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me ) if( key_num <= s_key ) { QCursor::setPos( mapToGlobal( QPoint( _me->x(), - height() - - PR_BOTTOM_MARGIN - - m_notesEditHeight ) ) ); + keyAreaBottom() ) ) ); m_topBottomScroll->setValue( m_topBottomScroll->value() + 1 ); key_num = s_key; @@ -2071,7 +2131,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) } // start drawing at the bottom - int key_line_y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1; + int key_line_y = keyAreaBottom() - 1; // used for aligning black-keys later int first_white_key_height = WHITE_KEY_SMALL_HEIGHT; // key-counter - only needed for finding out whether the processed @@ -2155,7 +2215,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) int white_cnt = 0; // and go! - for( int y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight + y_offset; + for( int y = keyAreaBottom() + y_offset; y > PR_TOP_MARGIN; ++keys_processed ) { // check for black key that is only half visible on the bottom @@ -2211,8 +2271,8 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) // erase the area below the piano, because there might be keys that // should be only half-visible - p.fillRect( QRect( 0, height() - PR_BOTTOM_MARGIN - m_notesEditHeight, - WHITE_KEY_WIDTH, m_notesEditHeight ), + p.fillRect( QRect( 0, keyAreaBottom(), + WHITE_KEY_WIDTH, noteEditBottom()-keyAreaBottom() ), QColor( 0, 0, 0 ) ); @@ -2299,7 +2359,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) qSwap( sel_key_start, sel_key_end ); } - int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1; + int y_base = keyAreaBottom() - 1; if( validPattern() == true ) { p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, @@ -2308,8 +2368,7 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) const noteVector & notes = m_pattern->notes(); - const int visible_keys = ( height() - PR_TOP_MARGIN - - PR_BOTTOM_MARGIN - m_notesEditHeight ) / + const int visible_keys = ( keyAreaBottom()-keyAreaTop() ) / KEY_LINE_HEIGHT + 2; QPolygon volumeHandles; @@ -2423,12 +2482,14 @@ void pianoRoll::paintEvent( QPaintEvent * _pe ) if( validPattern() == true ) { int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() ); - p.fillRect( 10, height() + 3 - PR_BOTTOM_MARGIN - - m_notesEditHeight - KEY_LINE_HEIGHT * + p.fillRect( 10, keyAreaBottom() + 3 - KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 ), width() - 10, KEY_LINE_HEIGHT - 7, QColor( 64, 64, 64 ) ); } + + // bar to resize note edit area + p.fillRect( 0, keyAreaBottom(), noteEditRight()-noteEditLeft(), NOTE_EDIT_RESIZE_BAR, QColor( 255, 255, 255 ) ); const QPixmap * cursor = NULL; // draw current edit-mode-icon below the cursor @@ -2535,7 +2596,7 @@ void pianoRoll::wheelEvent( QWheelEvent * _we ) int pianoRoll::getKey( int _y ) const { - int key_line_y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1; + int key_line_y = keyAreaBottom() - 1; // pressed key on piano int key_num = ( key_line_y - _y ) / KEY_LINE_HEIGHT; key_num += m_startKey; @@ -3071,7 +3132,7 @@ noteVector::const_iterator pianoRoll::noteIteratorUnderMouse( void ) if( pos.x() <= WHITE_KEY_WIDTH || pos.x() > width() - SCROLLBAR_SIZE || pos.y() < PR_TOP_MARGIN - || pos.y() > height() - PR_BOTTOM_MARGIN - m_notesEditHeight ) + || pos.y() > keyAreaBottom() ) { return( notes.end() ); }