diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 9bc4c7569b3..f804fb7dd82 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -371,6 +371,13 @@ protected slots: static const std::vector m_zoomLevels; static const std::vector m_zoomYLevels; + /** + * @returns the width of a note's resize area in pixels. + * @note When zoomed in, this is a constant pixel value, but when zoomed far out, + * it is a fraction of the note width, to make it easier to move short notes. + */ + int resizeGripWidth(const Note& note) const; + MidiClip* m_midiClip; NoteVector m_ghostNotes; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 32b26fc5113..106ba80f0e0 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -106,8 +106,10 @@ const int PR_TOP_MARGIN = 18; 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 = 9; +//! Width of area used for resizing (the grip at the end of a note) +constexpr int RESIZE_GRIP_WIDTH = 9; +//! The maximum fraction of the note width that the resize grip is allowed to take up +constexpr float RESIZE_GRIP_MAX_WIDTH_FRACTION = 0.25f; // width of line for setting volume/panning of note const int NOTE_EDIT_LINE_WIDTH = 3; @@ -1922,8 +1924,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) } // clicked at the "tail" of the note? - if( pos_ticks * m_ppb / TimePos::ticksPerBar() > - m_currentNote->endPos() * m_ppb / TimePos::ticksPerBar() - RESIZE_AREA_WIDTH + if (x + m_currentPosition * m_ppb / TimePos::ticksPerBar() > + m_currentNote->endPos() * m_ppb / TimePos::ticksPerBar() - resizeGripWidth(*m_currentNote) && m_currentNote->length() > 0 ) { m_midiClip->addJournalCheckPoint(); @@ -2719,8 +2721,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) int noteRightX = ( note->pos() + note->length() - m_currentPosition) * m_ppb/TimePos::ticksPerBar(); // cursor at the "tail" of the note? - bool atTail = note->length() > 0 && x > noteRightX - - RESIZE_AREA_WIDTH; + bool atTail = note->length() > 0 && x > noteRightX - resizeGripWidth(*note); Qt::CursorShape cursorShape = atTail ? Qt::SizeHorCursor : Qt::SizeAllCursor; setCursor( cursorShape ); @@ -3290,6 +3291,11 @@ void PianoRoll::dragNotes(int x, int y, bool alt, bool shift, bool ctrl) } +int PianoRoll::resizeGripWidth(const Note& note) const +{ + const int noteWidth = note.length() * m_ppb / TimePos::ticksPerBar(); + return std::min(RESIZE_GRIP_WIDTH, static_cast(std::round(RESIZE_GRIP_MAX_WIDTH_FRACTION * noteWidth))); +} void PianoRoll::paintEvent(QPaintEvent * pe )