|
@@ -115,7 +115,7 @@ QPixmap * PianoRoll::s_toolErase = NULL;
|
|
|
QPixmap * PianoRoll::s_toolSelect = NULL;
|
|
|
QPixmap * PianoRoll::s_toolMove = NULL;
|
|
|
QPixmap * PianoRoll::s_toolOpen = NULL;
|
|
|
-QPixmap * PianoRoll::s_toolRazor = NULL;
|
|
|
+QPixmap* PianoRoll::s_toolRazor = nullptr;
|
|
|
|
|
|
TextFloat * PianoRoll::s_textFloat = NULL;
|
|
|
|
|
@@ -185,6 +185,7 @@ PianoRoll::PianoRoll() :
|
|
|
m_editMode( ModeDraw ),
|
|
|
m_ctrlMode( ModeDraw ),
|
|
|
m_mouseDownRight( false ),
|
|
|
+ m_firstRazorSplit(false),
|
|
|
m_scrollBack( false ),
|
|
|
m_stepRecorderWidget(this, DEFAULT_PR_PPB, PR_TOP_MARGIN, PR_BOTTOM_MARGIN + m_notesEditHeight, WHITE_KEY_WIDTH, 0),
|
|
|
m_stepRecorder(*this, m_stepRecorderWidget),
|
|
@@ -201,6 +202,7 @@ PianoRoll::PianoRoll() :
|
|
|
m_textColorLight( 0, 0, 0 ),
|
|
|
m_textShadow( 0, 0, 0 ),
|
|
|
m_markedSemitoneColor( 0, 0, 0 ),
|
|
|
+ m_razorCutLineColor(0, 0, 0),
|
|
|
m_noteOpacity( 255 ),
|
|
|
m_ghostNoteOpacity( 255 ),
|
|
|
m_noteBorders( true ),
|
|
@@ -272,9 +274,9 @@ PianoRoll::PianoRoll() :
|
|
|
{
|
|
|
s_toolOpen = new QPixmap( embed::getIconPixmap( "automation" ) );
|
|
|
}
|
|
|
- if( s_toolRazor == NULL )
|
|
|
+ if (s_toolRazor == nullptr)
|
|
|
{
|
|
|
- s_toolRazor = new QPixmap( embed::getIconPixmap( "razor" ) );
|
|
|
+ s_toolRazor = new QPixmap(embed::getIconPixmap("razor"));
|
|
|
}
|
|
|
|
|
|
// init text-float
|
|
@@ -1273,6 +1275,7 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
|
|
|
break;
|
|
|
|
|
|
case Qt::Key_Escape:
|
|
|
+ // On the Razor mode, ESC cancels it
|
|
|
if (m_editMode == ModeEditRazor)
|
|
|
{
|
|
|
cancelRazorAction();
|
|
@@ -1326,6 +1329,8 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
|
|
|
}
|
|
|
|
|
|
case Qt::Key_Control:
|
|
|
+ // Ctrl will not enter selection mode if we are
|
|
|
+ // in Razor mode, but unquantize it
|
|
|
if (m_editMode == ModeEditRazor)
|
|
|
{
|
|
|
break;
|
|
@@ -1378,6 +1383,12 @@ void PianoRoll::keyReleaseEvent(QKeyEvent* ke )
|
|
|
update();
|
|
|
break;
|
|
|
|
|
|
+ case Qt::Key_Shift:
|
|
|
+ if (m_editMode == ModeEditRazor && !m_firstRazorSplit)
|
|
|
+ {
|
|
|
+ cancelRazorAction();
|
|
|
+ }
|
|
|
+
|
|
|
// update after undo/redo
|
|
|
case Qt::Key_Z:
|
|
|
case Qt::Key_R:
|
|
@@ -1462,40 +1473,27 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
|
|
|
}
|
|
|
|
|
|
// -- Razor
|
|
|
- if (m_editMode == ModeEditRazor && me->button() == Qt::LeftButton
|
|
|
- && noteUnderMouse())
|
|
|
+ if (m_editMode == ModeEditRazor && me->button() == Qt::LeftButton)
|
|
|
{
|
|
|
- Note * n = noteUnderMouse();
|
|
|
+ NoteVector n;
|
|
|
+ Note* note = noteUnderMouse();
|
|
|
|
|
|
- float zoomFactor = ((float)m_ppb / TimePos::ticksPerBar());
|
|
|
- int x = getMouseTickPos() - m_whiteKeyWidth;
|
|
|
- int newLength = ((x/zoomFactor) + (m_currentPosition) - (n->pos()));
|
|
|
- int leftOverLength = n->length() - newLength;
|
|
|
-
|
|
|
- if (!newLength || !leftOverLength)
|
|
|
+ if (note)
|
|
|
{
|
|
|
- return;
|
|
|
- }
|
|
|
+ n.append(note);
|
|
|
|
|
|
- m_pattern->addJournalCheckPoint();
|
|
|
+ updateRazorPos(me);
|
|
|
|
|
|
- // Reduce note length
|
|
|
- n->setLength(newLength);
|
|
|
-
|
|
|
- // Add note with leftover length
|
|
|
- Note noteCopy(
|
|
|
- leftOverLength,
|
|
|
- n->pos() + newLength,
|
|
|
- n->key(),
|
|
|
- n->getVolume(),
|
|
|
- n->getPanning(),
|
|
|
- n->detuning()
|
|
|
- );
|
|
|
- if (n->selected()) { noteCopy.setSelected(true); }
|
|
|
- m_pattern->addNote(noteCopy, false);
|
|
|
+ // Call splitNotes for the note
|
|
|
+ m_pattern->splitNotes(n, TimePos(m_razorTickPos));
|
|
|
+
|
|
|
+ // Allow cancel razor mode when shift is released (if hold down).
|
|
|
+ m_firstRazorSplit = false;
|
|
|
+ }
|
|
|
|
|
|
// Keep in razor mode while SHIFT is hold during cut
|
|
|
- if (!(me->modifiers() & Qt::ShiftModifier)) {
|
|
|
+ if (!(me->modifiers() & Qt::ShiftModifier))
|
|
|
+ {
|
|
|
cancelRazorAction();
|
|
|
}
|
|
|
|
|
@@ -2012,6 +2010,7 @@ void PianoRoll::setRazorAction()
|
|
|
{
|
|
|
if (m_editMode != ModeEditRazor)
|
|
|
{
|
|
|
+ m_firstRazorSplit = true;
|
|
|
m_razorMode = m_editMode;
|
|
|
m_editMode = ModeEditRazor;
|
|
|
m_action = ActionRazor;
|
|
@@ -2027,15 +2026,6 @@ void PianoRoll::cancelRazorAction()
|
|
|
update();
|
|
|
}
|
|
|
|
|
|
-int PianoRoll::getMouseTickPos() {
|
|
|
- QPoint pos = mapFromGlobal(QCursor::pos());
|
|
|
- int pixelsPer = m_ppb / (TimePos::ticksPerBar() / quantization());
|
|
|
- float zoomFactor = ((float)m_ppb / TimePos::ticksPerBar());
|
|
|
- int scrollOffset = (int)(m_currentPosition * zoomFactor) % pixelsPer;
|
|
|
- return (pixelsPer * (((pos.x() - m_whiteKeyWidth)) / pixelsPer) + (m_whiteKeyWidth - scrollOffset));
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
|
|
|
|
|
|
void PianoRoll::testPlayKey( int key, int velocity, int pan )
|
|
@@ -2136,6 +2126,7 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me )
|
|
|
|
|
|
s_textFloat->hide();
|
|
|
|
|
|
+ // Quit razor mode if we pressed and released the right mouse button
|
|
|
if (m_editMode == ModeEditRazor && me->button() == Qt::RightButton)
|
|
|
{
|
|
|
cancelRazorAction();
|
|
@@ -2260,6 +2251,12 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ // Update Razor position if we are on Razor mode
|
|
|
+ if (m_editMode == ModeEditRazor)
|
|
|
+ {
|
|
|
+ updateRazorPos(me);
|
|
|
+ }
|
|
|
+
|
|
|
if( me->y() > PR_TOP_MARGIN || m_action != ActionNone )
|
|
|
{
|
|
|
bool edit_note = ( me->y() > noteEditTop() )
|
|
@@ -2635,6 +2632,24 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
|
|
|
|
|
|
|
|
|
|
|
+void PianoRoll::updateRazorPos(QMouseEvent* me)
|
|
|
+{
|
|
|
+ // Calculate the TimePos from the mouse
|
|
|
+ int mouseViewportPos = me->x() - m_whiteKeyWidth;
|
|
|
+ int mouseTickPos = mouseViewportPos / (m_ppb / TimePos::ticksPerBar()) + m_currentPosition;
|
|
|
+
|
|
|
+ // If ctrl is not pressed, quantize the position
|
|
|
+ if (!(me->modifiers() & Qt::ControlModifier))
|
|
|
+ {
|
|
|
+ mouseTickPos = floor(mouseTickPos / quantization()) * quantization();
|
|
|
+ }
|
|
|
+
|
|
|
+ m_razorTickPos = mouseTickPos;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
void PianoRoll::dragNotes( int x, int y, bool alt, bool shift, bool ctrl )
|
|
|
{
|
|
|
// dragging one or more notes around
|
|
@@ -3335,27 +3350,23 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
|
|
|
// -- Razor tool (draw cut line)
|
|
|
if (m_action == ActionRazor)
|
|
|
{
|
|
|
- auto xCoordOfTick = [=](int tick) {
|
|
|
+ auto xCoordOfTick = [this](int tick) {
|
|
|
return m_whiteKeyWidth + (
|
|
|
- (tick - m_currentPosition) * m_ppb / TimePos::ticksPerBar()
|
|
|
- );
|
|
|
+ (tick - m_currentPosition) * m_ppb / TimePos::ticksPerBar());
|
|
|
};
|
|
|
- Note * n = noteUnderMouse();
|
|
|
+ Note* n = noteUnderMouse();
|
|
|
if (n)
|
|
|
{
|
|
|
const int key = n->key() - m_startKey + 1;
|
|
|
int y = y_base - key * m_keyLineHeight;
|
|
|
- int x = getMouseTickPos();
|
|
|
+
|
|
|
+ int x = xCoordOfTick(m_razorTickPos);
|
|
|
|
|
|
if (x > xCoordOfTick(n->pos()) &&
|
|
|
x < xCoordOfTick(n->pos() + n->length()))
|
|
|
{
|
|
|
- p.setPen(QPen(QColor("#FF0000"), 1));
|
|
|
- p.drawLine(
|
|
|
- x, y,
|
|
|
- x,
|
|
|
- y + m_keyLineHeight
|
|
|
- );
|
|
|
+ p.setPen(QPen(m_razorCutLineColor, 1));
|
|
|
+ p.drawLine(x, y, x, y + m_keyLineHeight);
|
|
|
|
|
|
setCursor(Qt::BlankCursor);
|
|
|
}
|