Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/themes/default/razor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion include/PianoRoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ class PianoRoll : public QWidget
ModeErase,
ModeSelect,
ModeEditDetuning,
ModeEditRazor
};

/*! \brief Resets settings to default when e.g. creating a new project */
Expand Down Expand Up @@ -226,7 +227,8 @@ protected slots:
ActionResizeNote,
ActionSelectNotes,
ActionChangeNoteProperty,
ActionResizeNoteEditArea
ActionResizeNoteEditArea,
ActionRazor
};

enum NoteEditMode
Expand Down Expand Up @@ -282,6 +284,10 @@ protected slots:
void playChordNotes(int key, int velocity=-1);
void pauseChordNotes(int key);

void setRazorAction();
void cancelRazorAction();
int getMouseTickPos();

void updateScrollbars();
void updatePositionLineHeight();

Expand All @@ -304,6 +310,7 @@ protected slots:
static QPixmap * s_toolSelect;
static QPixmap * s_toolMove;
static QPixmap * s_toolOpen;
static QPixmap * s_toolRazor;

static PianoRollKeyTypes prKeyOrder[];

Expand Down Expand Up @@ -389,6 +396,7 @@ protected slots:

EditModes m_editMode;
EditModes m_ctrlMode; // mode they were in before they hit ctrl
EditModes m_razorMode; // mode they where in before entering razor

bool m_mouseDownRight; //true if right click is being held down

Expand Down
162 changes: 157 additions & 5 deletions src/gui/editors/PianoRoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +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;

TextFloat * PianoRoll::s_textFloat = NULL;

Expand Down Expand Up @@ -271,6 +272,10 @@ PianoRoll::PianoRoll() :
{
s_toolOpen = new QPixmap( embed::getIconPixmap( "automation" ) );
}
if( s_toolRazor == NULL )
{
s_toolRazor = new QPixmap( embed::getIconPixmap( "razor" ) );
}

// init text-float
if( s_textFloat == NULL )
Expand Down Expand Up @@ -1268,8 +1273,15 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
break;

case Qt::Key_Escape:
// Same as Ctrl + Shift + A
clearSelectedNotes();
if (m_editMode == ModeEditRazor)
{
cancelRazorAction();
}
else
{
// Same as Ctrl + Shift + A
clearSelectedNotes();
}
break;

case Qt::Key_Backspace:
Expand Down Expand Up @@ -1314,6 +1326,10 @@ void PianoRoll::keyPressEvent(QKeyEvent* ke)
}

case Qt::Key_Control:
if (m_editMode == ModeEditRazor)
{
break;
}
// Enter selection mode if:
// -> this window is active
// -> shift is not pressed
Expand Down Expand Up @@ -1353,6 +1369,10 @@ void PianoRoll::keyReleaseEvent(QKeyEvent* ke )
switch( ke->key() )
{
case Qt::Key_Control:
if (m_editMode == ModeEditRazor)
{
break;
}
computeSelectedNotes( ke->modifiers() & Qt::ShiftModifier);
m_editMode = m_ctrlMode;
update();
Expand Down Expand Up @@ -1441,6 +1461,48 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
return;
}

// -- Razor
if (m_editMode == ModeEditRazor && me->button() == Qt::LeftButton
&& noteUnderMouse())
{
Note * n = 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)
{
return;
}

m_pattern->addJournalCheckPoint();

// 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);

// Keep in razor mode while SHIFT is hold during cut
if (!(me->modifiers() & Qt::ShiftModifier)) {
cancelRazorAction();
}

update();
return;
}

if( m_editMode == ModeEditDetuning && noteUnderMouse() )
{
static QPointer<AutomationPattern> detuningPattern = nullptr;
Expand Down Expand Up @@ -1946,6 +2008,33 @@ void PianoRoll::pauseChordNotes(int key)
}
}

void PianoRoll::setRazorAction()
{
if (m_editMode != ModeEditRazor)
{
m_razorMode = m_editMode;
m_editMode = ModeEditRazor;
m_action = ActionRazor;
setCursor(Qt::ArrowCursor);
update();
}
}

void PianoRoll::cancelRazorAction()
{
m_editMode = m_razorMode;
m_action = ActionNone;
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));
}




Expand Down Expand Up @@ -2047,6 +2136,11 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me )

s_textFloat->hide();

if (m_editMode == ModeEditRazor && me->button() == Qt::RightButton)
{
cancelRazorAction();
}

if( me->button() & Qt::LeftButton )
{
mustRepaint = true;
Expand Down Expand Up @@ -2105,7 +2199,11 @@ void PianoRoll::mouseReleaseEvent( QMouseEvent * me )
}

m_currentNote = NULL;
m_action = ActionNone;

if (m_action != ActionRazor)
{
m_action = ActionNone;
}

if( m_editMode == ModeDraw )
{
Expand All @@ -2131,6 +2229,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )

if( m_action == ActionNone && me->buttons() == 0 )
{
// When cursor is between note editing area and volume/panning
// area show vertical size cursor.
if( me->y() > keyAreaBottom() && me->y() < noteEditTop() )
{
setCursor( Qt::SizeVerCursor );
Expand Down Expand Up @@ -2439,7 +2539,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
}
}
}
else if (me->buttons() == Qt::NoButton && m_editMode != ModeDraw)
else if (me->buttons() == Qt::NoButton && m_editMode != ModeDraw && m_editMode != ModeEditRazor)
{
// Is needed to restore cursor when it previously was set to
// Qt::SizeVerCursor (between keyAreaBottom and noteEditTop)
Expand Down Expand Up @@ -3232,6 +3332,45 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
}
}

// -- Razor tool (draw cut line)
if (m_action == ActionRazor)
{
auto xCoordOfTick = [=](int tick) {
return m_whiteKeyWidth + (
(tick - m_currentPosition) * m_ppb / TimePos::ticksPerBar()
);
};
Note * n = noteUnderMouse();
if (n)
{
const int key = n->key() - m_startKey + 1;
int y = y_base - key * m_keyLineHeight;
int x = getMouseTickPos();

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
);

setCursor(Qt::BlankCursor);
}
else
{
setCursor(Qt::ArrowCursor);
}
}
else
{
setCursor(Qt::ArrowCursor);
}
}
// -- End razor tool

//draw current step recording notes
for( const Note *note : m_stepRecorder.getCurStepNotes() )
{
Expand Down Expand Up @@ -3353,6 +3492,7 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
case ModeErase: cursor = s_toolErase; break;
case ModeSelect: cursor = s_toolSelect; break;
case ModeEditDetuning: cursor = s_toolOpen; break;
case ModeEditRazor: cursor = s_toolRazor; break;
}
QPoint mousePosition = mapFromGlobal( QCursor::pos() );
if( cursor != NULL && mousePosition.y() > keyAreaTop() && mousePosition.x() > noteEditLeft())
Expand Down Expand Up @@ -3560,7 +3700,12 @@ void PianoRoll::focusOutEvent( QFocusEvent * )
m_pattern->instrumentTrack()->pianoModel()->setKeyState( i, false );
}
}
m_editMode = m_ctrlMode;
if (m_editMode == ModeEditRazor) {
m_editMode = m_razorMode;
m_action = ActionNone;
} else {
m_editMode = m_ctrlMode;
}
update();
}

Expand Down Expand Up @@ -4443,7 +4588,14 @@ PianoRollWindow::PianoRollWindow() :
connect(glueAction, SIGNAL(triggered()), m_editor, SLOT(glueNotes()));
glueAction->setShortcut( Qt::SHIFT | Qt::Key_G );

// Razor
QAction * razorAction = new QAction(embed::getIconPixmap("razor"),
tr("Razor"), noteToolsButton);
connect(razorAction, &QAction::triggered, m_editor, &PianoRoll::setRazorAction);
razorAction->setShortcut( Qt::SHIFT | Qt::Key_R );

noteToolsButton->addAction(glueAction);
noteToolsButton->addAction(razorAction);

notesActionsToolBar->addWidget(noteToolsButton);

Expand Down