From c8c710b07f34fa7634d8983a64611630dc070b15 Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 29 May 2019 10:29:01 +0200 Subject: [PATCH 01/30] Rebase BaraMGB's Knife --- include/SongEditor.h | 4 ++++ include/TrackContainerView.h | 1 + src/core/Track.cpp | 24 +++++++++++++++++++++++- src/gui/TrackContainerView.cpp | 10 +++++++++- src/gui/editors/SongEditor.cpp | 16 ++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/SongEditor.h b/include/SongEditor.h index 8a02d56919a..b9355cc25ca 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -63,6 +63,7 @@ class SongEditor : public TrackContainerView enum EditMode { DrawMode, + KnifeMode, SelectMode }; @@ -82,6 +83,7 @@ public slots: void setEditMode( EditMode mode ); void setEditModeDraw(); + void setEditModeKnife(); void setEditModeSelect(); void toggleProportionalSnap(); @@ -114,6 +116,7 @@ private slots: virtual void wheelEvent( QWheelEvent * we ); virtual bool allowRubberband() const; + virtual bool knifeMode() const; Song * m_song; @@ -192,6 +195,7 @@ protected slots: ActionGroup * m_editModeGroup; QAction* m_drawModeAction; + QAction* m_knifeModeAction; QAction* m_selectModeAction; QAction* m_crtlAction; diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index 67575583b51..f1d68719fed 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -77,6 +77,7 @@ class TrackContainerView : public QWidget, public ModelView, const TrackView * trackViewAt( const int _y ) const; virtual bool allowRubberband() const; + virtual bool knifeMode() const; inline bool rubberBandActive() const { diff --git a/src/core/Track.cpp b/src/core/Track.cpp index fe66ab4a5e5..a9d229062b6 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -716,7 +716,29 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { setInitialPos( me->pos() ); setInitialOffsets(); - if( !fixedTCOs() && me->button() == Qt::LeftButton ) + if ( m_trackView->trackContainerView()->knifeMode() + && me->button() == Qt::LeftButton ) + { + SampleTCO * leftTCO = dynamic_cast( m_tco ); + if ( leftTCO ) + { + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const int x = mapToParent( me->pos() ).x(); + MidiTime t = qMax( 0, m_trackView->trackContainerView()->currentPosition() + x * MidiTime::ticksPerTact()/ppt); + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ) {} + else { t = t.quantize( gui->songEditor()->m_editor->getSnapSize() ); } + leftTCO->copy(); + SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); + rightTCO->paste(); + + leftTCO->changeLength( t - leftTCO->startPosition() ); + rightTCO->movePosition(t); + rightTCO->changeLength( rightTCO->length() - leftTCO->length() ); + rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + } + } + else if( !fixedTCOs() && me->button() == Qt::LeftButton ) { if( me->modifiers() & Qt::ControlModifier ) { diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 7c69d5eb824..f37c4dc3880 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -307,6 +307,14 @@ bool TrackContainerView::allowRubberband() const +bool TrackContainerView::knifeMode() const +{ + return false; +} + + + + void TrackContainerView::setPixelsPerTact( int _ppt ) { m_ppt = _ppt; @@ -377,7 +385,7 @@ void TrackContainerView::dropEvent( QDropEvent * _de ) //it->toggledInstrumentTrackButton( true ); _de->accept(); } - else if( type == "samplefile" || type == "pluginpresetfile" + else if( type == "samplefile" || type == "pluginpresetfile" || type == "soundfontfile" || type == "vstpluginfile" || type == "patchfile" ) { diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 6e23fcdbef7..dea0b7f712c 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -356,6 +356,11 @@ void SongEditor::setEditModeDraw() setEditMode(DrawMode); } +void SongEditor::setEditModeKnife() +{ + setEditMode(KnifeMode); +} + void SongEditor::setEditModeSelect() { setEditMode(SelectMode); @@ -713,6 +718,14 @@ bool SongEditor::allowRubberband() const +bool SongEditor::knifeMode() const +{ + return m_mode == KnifeMode; +} + + + + ComboBoxModel *SongEditor::zoomingModel() const { return m_zoomingModel; @@ -777,13 +790,16 @@ SongEditorWindow::SongEditorWindow(Song* song) : m_editModeGroup = new ActionGroup(this); m_drawModeAction = m_editModeGroup->addAction(embed::getIconPixmap("edit_draw"), tr("Draw mode")); + m_knifeModeAction = m_editModeGroup->addAction(embed::getIconPixmap("edit_knife"), tr("Knife mode (split sample clips)")); m_selectModeAction = m_editModeGroup->addAction(embed::getIconPixmap("edit_select"), tr("Edit mode (select and move)")); m_drawModeAction->setChecked(true); connect(m_drawModeAction, SIGNAL(triggered()), m_editor, SLOT(setEditModeDraw())); + connect(m_knifeModeAction, SIGNAL(triggered()), m_editor, SLOT(setEditModeKnife())); connect(m_selectModeAction, SIGNAL(triggered()), m_editor, SLOT(setEditModeSelect())); editActionsToolBar->addAction( m_drawModeAction ); + editActionsToolBar->addAction( m_knifeModeAction ); editActionsToolBar->addAction( m_selectModeAction ); DropToolBar *timeLineToolBar = addDropToolBarToTop(tr("Timeline controls")); From c14efd457eca0d39dd388ec358113d5c14bef675 Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 29 May 2019 14:38:45 +0200 Subject: [PATCH 02/30] Draw marker --- include/SampleTrack.h | 11 ++++ include/Track.h | 1 + src/core/Track.cpp | 102 ++++++++++++++++++++++++++++--------- src/tracks/SampleTrack.cpp | 4 ++ 4 files changed, 95 insertions(+), 23 deletions(-) diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 9469669a17b..73239f63bab 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -73,6 +73,15 @@ class SampleTCO : public TrackContentObject bool isPlaying() const; void setIsPlaying(bool isPlaying); + void inline setMarkerPos( int x ) + { + m_markerPos = x; + } + void inline setMarkerEnabled( bool e ) + { + m_marker = e; + } + public slots: void setSampleBuffer( SampleBuffer* sb ); void setSampleFile( const QString & _sf ); @@ -87,6 +96,8 @@ public slots: BoolModel m_recordModel; bool m_isPlaying; + bool m_marker = false; + int m_markerPos = 0; friend class SampleTCOView; diff --git a/include/Track.h b/include/Track.h index b00c5024896..80812182905 100644 --- a/include/Track.h +++ b/include/Track.h @@ -286,6 +286,7 @@ protected slots: MoveSelection, Resize, ResizeLeft, + Split, CopySelection, ToggleSelected } ; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index a9d229062b6..cf52f7b2d4a 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -716,31 +716,40 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { setInitialPos( me->pos() ); setInitialOffsets(); - if ( m_trackView->trackContainerView()->knifeMode() - && me->button() == Qt::LeftButton ) + + if( !fixedTCOs() && me->button() == Qt::LeftButton ) { - SampleTCO * leftTCO = dynamic_cast( m_tco ); - if ( leftTCO ) + if( m_trackView->trackContainerView()->knifeMode() ) { - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); - const int x = mapToParent( me->pos() ).x(); - MidiTime t = qMax( 0, m_trackView->trackContainerView()->currentPosition() + x * MidiTime::ticksPerTact()/ppt); - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ) {} - else { t = t.quantize( gui->songEditor()->m_editor->getSnapSize() ); } - leftTCO->copy(); - SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->paste(); + m_action = Split; + SampleTCO * sTco = dynamic_cast( m_tco ); + if (sTco) + { + int markerPos = me->pos().x(); + + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ) + {} + else { + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + MidiTime incs = MidiTime( MidiTime::ticksPerTact() * gui->songEditor()->m_editor->getSnapSize() ); + MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; + midiPos = midiPos.quantize(gui->songEditor()->m_editor->getSnapSize()); + midiPos -= m_initialTCOPos % incs; + markerPos = midiPos * ppt / MidiTime::ticksPerTact(); + } - leftTCO->changeLength( t - leftTCO->startPosition() ); - rightTCO->movePosition(t); - rightTCO->changeLength( rightTCO->length() - leftTCO->length() ); - rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + SampleTCO * sTco = dynamic_cast( m_tco ); + sTco->setMarkerPos( markerPos ); + sTco->setMarkerEnabled( true ); + update(); + } + // We can't split anything except samples right now, so disable the + // action to avoid entering if statements we don't need to. This + // also saves us a few 'if(sTco)' checks + else { m_action = NoAction; } } - } - else if( !fixedTCOs() && me->button() == Qt::LeftButton ) - { - if( me->modifiers() & Qt::ControlModifier ) + else if ( me->modifiers() & Qt::ControlModifier ) { if( isSelected() ) { @@ -1056,6 +1065,25 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) MidiTime::ticksPerTact() ) ); s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) ); } + else if( m_action == Split ) + { + int markerPos = me->pos().x(); + + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ) + {} + else { + MidiTime incs = MidiTime( MidiTime::ticksPerTact() * gui->songEditor()->m_editor->getSnapSize() ); + MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; + midiPos = midiPos.quantize(gui->songEditor()->m_editor->getSnapSize()); + midiPos -= m_initialTCOPos % incs; + markerPos = midiPos * ppt / MidiTime::ticksPerTact(); + } + + SampleTCO * sTco = dynamic_cast( m_tco ); + sTco->setMarkerPos( markerPos ); + update(); + } else { SampleTCO * sTco = dynamic_cast( m_tco ); @@ -1092,12 +1120,40 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) { setSelected( !isSelected() ); } - - if( m_action == Move || m_action == Resize || m_action == ResizeLeft ) + else if( m_action == Move || m_action == Resize || m_action == ResizeLeft ) { // TODO: Fix m_tco->setJournalling() consistency m_tco->setJournalling( true ); } + else if( m_action == Split ) + { + SampleTCO * leftTCO = dynamic_cast( m_tco ); + + leftTCO->setMarkerEnabled( false ); + + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const int x = mapToParent( me->pos() ).x(); + MidiTime t = qMax( 0, m_trackView->trackContainerView()->currentPosition() + x * MidiTime::ticksPerTact()/ppt); + + //Don't do anything if we slid off the TCO + if ( t <= m_initialTCOPos || t >= m_initialTCOEnd ){} + else { + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ) {} + else { t = t.quantize( gui->songEditor()->m_editor->getSnapSize() ); } + + leftTCO->copy(); + SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); + rightTCO->paste(); + + leftTCO->changeLength( t - m_initialTCOPos ); + + rightTCO->movePosition(t); + rightTCO->changeLength( m_initialTCOEnd - t ); + rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + } + } + m_action = NoAction; delete m_hint; m_hint = NULL; diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 4b51ef6ec65..d439f850d8d 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -560,6 +560,10 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) embed::getIconPixmap( "muted", size, size ) ); } + if ( m_tco->m_marker ) + { + p.drawLine(m_tco->m_markerPos, rect().bottom(), m_tco->m_markerPos, rect().top()); + } // recording sample tracks is not possible at the moment /* if( m_tco->isRecord() ) From 6672bfc5d2b636d1d1df98f49eee45c1b08af736 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 27 Jul 2019 21:09:08 +0200 Subject: [PATCH 03/30] Refactoring and shift mode --- include/Track.h | 1 + src/core/Track.cpp | 107 ++++++++++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 39 deletions(-) diff --git a/include/Track.h b/include/Track.h index 80812182905..ea4912331f9 100644 --- a/include/Track.h +++ b/include/Track.h @@ -326,6 +326,7 @@ protected slots: bool mouseMovedDistance( QMouseEvent * me, int distance ); MidiTime draggedTCOPos( QMouseEvent * me ); + int knifeMarkerPos( QMouseEvent * me ); } ; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index cf52f7b2d4a..2bac6d36226 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -725,22 +725,8 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) SampleTCO * sTco = dynamic_cast( m_tco ); if (sTco) { - int markerPos = me->pos().x(); - - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ) - {} - else { - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); - MidiTime incs = MidiTime( MidiTime::ticksPerTact() * gui->songEditor()->m_editor->getSnapSize() ); - MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; - midiPos = midiPos.quantize(gui->songEditor()->m_editor->getSnapSize()); - midiPos -= m_initialTCOPos % incs; - markerPos = midiPos * ppt / MidiTime::ticksPerTact(); - } - SampleTCO * sTco = dynamic_cast( m_tco ); - sTco->setMarkerPos( markerPos ); + sTco->setMarkerPos( knifeMarkerPos( me ) ); sTco->setMarkerEnabled( true ); update(); } @@ -1067,21 +1053,8 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } else if( m_action == Split ) { - int markerPos = me->pos().x(); - - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ) - {} - else { - MidiTime incs = MidiTime( MidiTime::ticksPerTact() * gui->songEditor()->m_editor->getSnapSize() ); - MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; - midiPos = midiPos.quantize(gui->songEditor()->m_editor->getSnapSize()); - midiPos -= m_initialTCOPos % incs; - markerPos = midiPos * ppt / MidiTime::ticksPerTact(); - } - SampleTCO * sTco = dynamic_cast( m_tco ); - sTco->setMarkerPos( markerPos ); + sTco->setMarkerPos( knifeMarkerPos( me ) ); update(); } else @@ -1131,25 +1104,41 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) leftTCO->setMarkerEnabled( false ); + int relativePixelPos = me->pos().x(); const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); - const int x = mapToParent( me->pos() ).x(); - MidiTime t = qMax( 0, m_trackView->trackContainerView()->currentPosition() + x * MidiTime::ticksPerTact()/ppt); + MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; + const float snapSize = gui->songEditor()->m_editor->getSnapSize(); + + //Essentially duplicate logic from knifeMarkerPos, but shift needs to be inverted for some reason + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ){} + else if ( me->modifiers() & Qt::ShiftModifier ) + { //If shift is held we quantize the length of the new left clip... + MidiTime leftPos = splitPos.quantize( snapSize ); + //...or right clip... + MidiTime rightOff = m_tco->length() - splitPos; + MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + //...whichever gives a position closer to the cursor + if ( abs(leftPos - splitPos) < abs(rightPos - splitPos) ) splitPos = leftPos; + else splitPos = rightPos; + } + else + { + splitPos = MidiTime(splitPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; + } + splitPos += m_initialTCOPos; //Don't do anything if we slid off the TCO - if ( t <= m_initialTCOPos || t >= m_initialTCOEnd ){} + if ( splitPos <= m_initialTCOPos || splitPos >= m_initialTCOEnd ){} else { - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ) {} - else { t = t.quantize( gui->songEditor()->m_editor->getSnapSize() ); } - leftTCO->copy(); SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); rightTCO->paste(); - leftTCO->changeLength( t - m_initialTCOPos ); + leftTCO->changeLength( splitPos - m_initialTCOPos ); - rightTCO->movePosition(t); - rightTCO->changeLength( m_initialTCOEnd - t ); + rightTCO->movePosition( splitPos ); + rightTCO->changeLength( m_initialTCOEnd - splitPos ); rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); } } @@ -1296,6 +1285,46 @@ MidiTime TrackContentObjectView::draggedTCOPos( QMouseEvent * me ) +int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) +{ + //Position relative to start of clip + int markerPos = me->pos().x(); + + //In unquantized mode, we don't have to mess with the position at all + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ) + { return markerPos; } + //Otherwise we... + else { + //1: Convert the position to a MidiTime + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + const float snapSize = gui->songEditor()->m_editor->getSnapSize(); + MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; + //2: Snap to the correct position, based on modifier keys + if ( me->modifiers() & Qt::ShiftModifier ) + { //If shift is held we quantize the length of the new left clip... + MidiTime leftPos = midiPos.quantize( snapSize ); + //...or right clip... + MidiTime rightOff = m_tco->length() - midiPos; + MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + //...whichever gives a position closer to the cursor + if ( abs(leftPos - midiPos) < abs(rightPos - midiPos) ) midiPos = leftPos; + else midiPos = rightPos; + + markerPos = midiPos * ppt / MidiTime::ticksPerTact(); + } + else { + midiPos = MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; + } + //3: Convert back to a pixel position + markerPos = midiPos * ppt / MidiTime::ticksPerTact(); + return markerPos; + } +} + + + + // =========================================================================== // trackContentWidget // =========================================================================== From b52fbdbb4caf6f85b11c8565475fbd4c4dd2f6cd Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 27 Jul 2019 21:55:18 +0200 Subject: [PATCH 04/30] Allow resizing --- src/core/Track.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 2bac6d36226..bfa1464fd49 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -721,10 +721,22 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { if( m_trackView->trackContainerView()->knifeMode() ) { - m_action = Split; SampleTCO * sTco = dynamic_cast( m_tco ); - if (sTco) + + if( me->x() < RESIZE_GRIP_WIDTH && sTco + && !m_tco->getAutoResize() ) + { + m_action = ResizeLeft; + setCursor( Qt::SizeHorCursor ); + } + else if( me->x() >= width() - RESIZE_GRIP_WIDTH ) + { + m_action = Resize; + setCursor( Qt::SizeHorCursor ); + } + else if (sTco) { + m_action = Split; SampleTCO * sTco = dynamic_cast( m_tco ); sTco->setMarkerPos( knifeMarkerPos( me ) ); sTco->setMarkerEnabled( true ); From 79fda6f882e06794fdde72590b3af5d3f02ea464 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sun, 28 Jul 2019 12:27:01 +0200 Subject: [PATCH 05/30] Add Icon --- data/themes/classic/edit_knife.png | Bin 0 -> 262 bytes data/themes/default/edit_knife.png | Bin 0 -> 262 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/themes/classic/edit_knife.png create mode 100644 data/themes/default/edit_knife.png diff --git a/data/themes/classic/edit_knife.png b/data/themes/classic/edit_knife.png new file mode 100644 index 0000000000000000000000000000000000000000..e6d5bb1c8ed33f0b7f6f830bf3efc763a3e20a4b GIT binary patch literal 262 zcmV+h0r~!kP);pch8{AN(zg8k=;VF$!NTFJmX2JbMHOB zdbZQQw@xTgjPaCMXhq_wWbl!+ z_ne`Iw2ply+@bivTJA+@e=j^@b;pch8{AN(zg8k=;VF$!NTFJmX2JbMHOB zdbZQQw@xTgjPaCMXhq_wWbl!+ z_ne`Iw2ply+@bivTJA+@e=j^@b Date: Mon, 29 Jul 2019 11:40:11 +0200 Subject: [PATCH 06/30] Fix stuck marker on RMB, remove unnecessary cast --- src/core/Track.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index bfa1464fd49..bf9ac3971b4 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -737,7 +737,6 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) else if (sTco) { m_action = Split; - SampleTCO * sTco = dynamic_cast( m_tco ); sTco->setMarkerPos( knifeMarkerPos( me ) ); sTco->setMarkerEnabled( true ); update(); @@ -841,6 +840,14 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { remove(); } + if (m_action == Split){ + m_action = NoAction; + SampleTCO * sTco = dynamic_cast( m_tco ); + if (sTco) { + sTco->setMarkerEnabled( false ); + update(); + } + } } else if( me->button() == Qt::MidButton ) { From 06bccf6a1da4365774078ea8709a0bea681434f4 Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 29 Jul 2019 11:44:38 +0200 Subject: [PATCH 07/30] Remove redundant line, more const --- src/core/Track.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index bf9ac3971b4..9d78681a4b1 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1123,7 +1123,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) leftTCO->setMarkerEnabled( false ); - int relativePixelPos = me->pos().x(); + const int relativePixelPos = me->pos().x(); const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; const float snapSize = gui->songEditor()->m_editor->getSnapSize(); @@ -1133,10 +1133,10 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) || me->modifiers() & Qt::AltModifier ){} else if ( me->modifiers() & Qt::ShiftModifier ) { //If shift is held we quantize the length of the new left clip... - MidiTime leftPos = splitPos.quantize( snapSize ); + const MidiTime leftPos = splitPos.quantize( snapSize ); //...or right clip... - MidiTime rightOff = m_tco->length() - splitPos; - MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + const MidiTime rightOff = m_tco->length() - splitPos; + const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); //...whichever gives a position closer to the cursor if ( abs(leftPos - splitPos) < abs(rightPos - splitPos) ) splitPos = leftPos; else splitPos = rightPos; @@ -1307,7 +1307,7 @@ MidiTime TrackContentObjectView::draggedTCOPos( QMouseEvent * me ) int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) { //Position relative to start of clip - int markerPos = me->pos().x(); + const int markerPos = me->pos().x(); //In unquantized mode, we don't have to mess with the position at all if ( me->modifiers() & Qt::ControlModifier @@ -1322,15 +1322,13 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) //2: Snap to the correct position, based on modifier keys if ( me->modifiers() & Qt::ShiftModifier ) { //If shift is held we quantize the length of the new left clip... - MidiTime leftPos = midiPos.quantize( snapSize ); + const MidiTime leftPos = midiPos.quantize( snapSize ); //...or right clip... - MidiTime rightOff = m_tco->length() - midiPos; - MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + const MidiTime rightOff = m_tco->length() - midiPos; + const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); //...whichever gives a position closer to the cursor if ( abs(leftPos - midiPos) < abs(rightPos - midiPos) ) midiPos = leftPos; else midiPos = rightPos; - - markerPos = midiPos * ppt / MidiTime::ticksPerTact(); } else { midiPos = MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; From d1e5de44bde06c37574de12dd3646b11a28caefb Mon Sep 17 00:00:00 2001 From: Spekular Date: Mon, 29 Jul 2019 11:58:48 +0200 Subject: [PATCH 08/30] Fix --- src/core/Track.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 9d78681a4b1..f10555dfe2f 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1334,8 +1334,7 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) midiPos = MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; } //3: Convert back to a pixel position - markerPos = midiPos * ppt / MidiTime::ticksPerTact(); - return markerPos; + return midiPos * ppt / MidiTime::ticksPerTact(); } } From 18bd074e92e229d9d633d9c62990805c771a8fd9 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 7 Sep 2019 17:16:21 +0200 Subject: [PATCH 09/30] Review fixes --- include/Track.h | 1 + src/core/Track.cpp | 76 +++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/include/Track.h b/include/Track.h index ea4912331f9..d4bc2b8d20e 100644 --- a/include/Track.h +++ b/include/Track.h @@ -327,6 +327,7 @@ protected slots: bool mouseMovedDistance( QMouseEvent * me, int distance ); MidiTime draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); + MidiTime quantizeMarkerPos( MidiTime, bool shiftMode ); } ; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index f10555dfe2f..faec766a986 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -840,10 +840,12 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { remove(); } - if (m_action == Split){ + if (m_action == Split) + { m_action = NoAction; SampleTCO * sTco = dynamic_cast( m_tco ); - if (sTco) { + if (sTco) + { sTco->setMarkerEnabled( false ); update(); } @@ -1073,7 +1075,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) else if( m_action == Split ) { SampleTCO * sTco = dynamic_cast( m_tco ); - sTco->setMarkerPos( knifeMarkerPos( me ) ); + if (sTco) { sTco->setMarkerPos( knifeMarkerPos( me ) ); } update(); } else @@ -1121,35 +1123,23 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) { SampleTCO * leftTCO = dynamic_cast( m_tco ); - leftTCO->setMarkerEnabled( false ); + if (leftTCO) { leftTCO->setMarkerEnabled( false ); } const int relativePixelPos = me->pos().x(); const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; - const float snapSize = gui->songEditor()->m_editor->getSnapSize(); - //Essentially duplicate logic from knifeMarkerPos, but shift needs to be inverted for some reason if ( me->modifiers() & Qt::ControlModifier || me->modifiers() & Qt::AltModifier ){} - else if ( me->modifiers() & Qt::ShiftModifier ) - { //If shift is held we quantize the length of the new left clip... - const MidiTime leftPos = splitPos.quantize( snapSize ); - //...or right clip... - const MidiTime rightOff = m_tco->length() - splitPos; - const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); - //...whichever gives a position closer to the cursor - if ( abs(leftPos - splitPos) < abs(rightPos - splitPos) ) splitPos = leftPos; - else splitPos = rightPos; - } - else - { - splitPos = MidiTime(splitPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; - } + else { splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); } + splitPos += m_initialTCOPos; - //Don't do anything if we slid off the TCO - if ( splitPos <= m_initialTCOPos || splitPos >= m_initialTCOEnd ){} - else { + //Don't split if we slid off the TCO or if we're on the clip's start/end + //Cutting at exactly the start/end position would create a zero length + //clip (bad), and a clip the same length as the original one (pointless). + if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) + { leftTCO->copy(); SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); rightTCO->paste(); @@ -1314,25 +1304,13 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) || me->modifiers() & Qt::AltModifier ) { return markerPos; } //Otherwise we... - else { + else + { //1: Convert the position to a MidiTime const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); - const float snapSize = gui->songEditor()->m_editor->getSnapSize(); MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; //2: Snap to the correct position, based on modifier keys - if ( me->modifiers() & Qt::ShiftModifier ) - { //If shift is held we quantize the length of the new left clip... - const MidiTime leftPos = midiPos.quantize( snapSize ); - //...or right clip... - const MidiTime rightOff = m_tco->length() - midiPos; - const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); - //...whichever gives a position closer to the cursor - if ( abs(leftPos - midiPos) < abs(rightPos - midiPos) ) midiPos = leftPos; - else midiPos = rightPos; - } - else { - midiPos = MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; - } + midiPos = quantizeMarkerPos( midiPos, me->modifiers() & Qt::ShiftModifier ); //3: Convert back to a pixel position return midiPos * ppt / MidiTime::ticksPerTact(); } @@ -1341,6 +1319,28 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) +MidiTime TrackContentObjectView::quantizeMarkerPos( MidiTime midiPos, bool shiftMode ) +{ + const float snapSize = gui->songEditor()->m_editor->getSnapSize(); + if ( shiftMode ) + { //If shift is held we quantize the length of the new left clip... + const MidiTime leftPos = midiPos.quantize( snapSize ); + //...or right clip... + const MidiTime rightOff = m_tco->length() - midiPos; + const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + //...whichever gives a position closer to the cursor + if ( abs(leftPos - midiPos) < abs(rightPos - midiPos) ) { return leftPos; } + else { return rightPos; } + } + else + { + return (MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos); + } +} + + + + // =========================================================================== // trackContentWidget // =========================================================================== From c2c0c3cabf5339e3da357ea6c1ab0ea07b8058aa Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 7 Sep 2019 23:23:41 +0200 Subject: [PATCH 10/30] Only perform split logic for SampleTCO --- src/core/Track.cpp | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index faec766a986..6db96f5bdfa 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1123,32 +1123,35 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) { SampleTCO * leftTCO = dynamic_cast( m_tco ); - if (leftTCO) { leftTCO->setMarkerEnabled( false ); } + if (leftTCO) + { + leftTCO->setMarkerEnabled( false ); - const int relativePixelPos = me->pos().x(); - const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); - MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; + const int relativePixelPos = me->pos().x(); + const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); + MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ){} - else { splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); } + if ( me->modifiers() & Qt::ControlModifier + || me->modifiers() & Qt::AltModifier ){} + else { splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); } - splitPos += m_initialTCOPos; + splitPos += m_initialTCOPos; - //Don't split if we slid off the TCO or if we're on the clip's start/end - //Cutting at exactly the start/end position would create a zero length - //clip (bad), and a clip the same length as the original one (pointless). - if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) - { - leftTCO->copy(); - SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->paste(); + //Don't split if we slid off the TCO or if we're on the clip's start/end + //Cutting at exactly the start/end position would create a zero length + //clip (bad), and a clip the same length as the original one (pointless). + if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) + { + leftTCO->copy(); + SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); + rightTCO->paste(); - leftTCO->changeLength( splitPos - m_initialTCOPos ); + leftTCO->changeLength( splitPos - m_initialTCOPos ); - rightTCO->movePosition( splitPos ); - rightTCO->changeLength( m_initialTCOEnd - splitPos ); - rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + rightTCO->movePosition( splitPos ); + rightTCO->changeLength( m_initialTCOEnd - splitPos ); + rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + } } } From a519f7caf8f0914e6e45e955c3ebdb12cc3744ed Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 25 Sep 2019 10:55:12 +0200 Subject: [PATCH 11/30] Add unquantizedModHeld function --- include/Track.h | 1 + src/core/Track.cpp | 35 ++++++++++++++++++----------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/Track.h b/include/Track.h index d4bc2b8d20e..af5f4c79773 100644 --- a/include/Track.h +++ b/include/Track.h @@ -325,6 +325,7 @@ protected slots: void setInitialOffsets(); bool mouseMovedDistance( QMouseEvent * me, int distance ); + bool unquantizedModHeld( QMouseEvent * me ); MidiTime draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); MidiTime quantizeMarkerPos( MidiTime, bool shiftMode ); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 6db96f5bdfa..c171e8256fb 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -979,8 +979,6 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } else if( m_action == Resize || m_action == ResizeLeft ) { - // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize - const bool unquantized = (me->modifiers() & Qt::ControlModifier) || (me->modifiers() & Qt::AltModifier); const float snapSize = gui->songEditor()->m_editor->getSnapSize(); // Length in ticks of one snap increment const MidiTime snapLength = MidiTime( (int)(snapSize * MidiTime::ticksPerTact()) ); @@ -990,7 +988,8 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) // The clip's new length MidiTime l = static_cast( me->x() * MidiTime::ticksPerTact() / ppt ); - if ( unquantized ) + // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize + if ( unquantizedModHeld(me) ) { // We want to preserve this adjusted offset, // even if the user switches to snapping later setInitialPos( m_initialMousePos ); @@ -1131,9 +1130,10 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); MidiTime splitPos = relativePixelPos * MidiTime::ticksPerTact() / ppt; - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ){} - else { splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); } + if ( !unquantizedModHeld(me) ) + { + splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); + } splitPos += m_initialTCOPos; @@ -1253,6 +1253,14 @@ bool TrackContentObjectView::mouseMovedDistance( QMouseEvent * me, int distance + +bool TrackContentObjectView::unquantizedModHeld( QMouseEvent * me ) +{ + return me->modifiers() & Qt::ControlModifier || me->modifiers() & Qt::AltModifier; +} + + + /*! \brief Calculate the new position of a dragged TCO from a mouse event * * @@ -1267,12 +1275,8 @@ MidiTime TrackContentObjectView::draggedTCOPos( QMouseEvent * me ) MidiTime newPos = m_initialTCOPos + mouseOff * MidiTime::ticksPerTact() / ppt; MidiTime offset = newPos - m_initialTCOPos; // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize - if ( me->button() != Qt::NoButton - || (me->modifiers() & Qt::ControlModifier) - || (me->modifiers() & Qt::AltModifier) ) - { - // We want to preserve this adjusted offset, - // even if the user switches to snapping + if ( me->button() != Qt::NoButton || unquantizedModHeld(me) ) + { // We want to preserve this adjusted offset, even if the user switches to snapping setInitialPos( m_initialMousePos ); } else if ( me->modifiers() & Qt::ShiftModifier ) @@ -1303,12 +1307,9 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) const int markerPos = me->pos().x(); //In unquantized mode, we don't have to mess with the position at all - if ( me->modifiers() & Qt::ControlModifier - || me->modifiers() & Qt::AltModifier ) - { return markerPos; } - //Otherwise we... + if ( unquantizedModHeld(me) ) { return markerPos; } else - { + { //Otherwise we... //1: Convert the position to a MidiTime const float ppt = m_trackView->trackContainerView()->pixelsPerTact(); MidiTime midiPos = markerPos * MidiTime::ticksPerTact() / ppt; From cfa5389e8880beb99b098cbead5b34f55e500c73 Mon Sep 17 00:00:00 2001 From: Spekular Date: Wed, 25 Sep 2019 10:57:59 +0200 Subject: [PATCH 12/30] missed one --- src/core/Track.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index c171e8256fb..4cab65b556d 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1025,7 +1025,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) m_trackView->trackContainerView()->currentPosition()+ static_cast( x * MidiTime::ticksPerTact() / ppt ) ); - if( unquantized ) + if( unquantizedModHeld(me) ) { // We want to preserve this adjusted offset, // even if the user switches to snapping later setInitialPos( m_initialMousePos ); From aac9c07c0000b4ae28f4fd24bedf3efa66670e7a Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 May 2020 20:06:21 +0200 Subject: [PATCH 13/30] Don't use copy/paste --- src/core/Track.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index e462f910d90..50c8d0545c7 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1148,9 +1148,12 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) //clip (bad), and a clip the same length as the original one (pointless). if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) { - leftTCO->copy(); + //leftTCO->copy(); SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->paste(); + rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); + rightTCO->setIsPlaying(leftTCO->isPlaying()); + leftTCO->getTrack()->addTCO( rightTCO ); + //rightTCO->paste(); leftTCO->changeLength( splitPos - m_initialTCOPos ); From bdde4265d5bdf5d5355197dafe94f1b9b701d39d Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 May 2020 20:06:21 +0200 Subject: [PATCH 14/30] Don't use copy/paste --- src/core/Track.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index e462f910d90..21cd82fa2c9 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1148,9 +1148,9 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) //clip (bad), and a clip the same length as the original one (pointless). if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) { - leftTCO->copy(); SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->paste(); + rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); + rightTCO->setIsPlaying(leftTCO->isPlaying()); leftTCO->changeLength( splitPos - m_initialTCOPos ); From 8e8cf2ce84df318fde62fba3b21be26c3c958699 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 May 2020 20:19:07 +0200 Subject: [PATCH 15/30] More git troubles --- src/core/Track.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index f6407217687..21cd82fa2c9 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1148,18 +1148,9 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) //clip (bad), and a clip the same length as the original one (pointless). if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) { -<<<<<<< HEAD SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); rightTCO->setIsPlaying(leftTCO->isPlaying()); -======= - //leftTCO->copy(); - SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); - rightTCO->setIsPlaying(leftTCO->isPlaying()); - leftTCO->getTrack()->addTCO( rightTCO ); - //rightTCO->paste(); ->>>>>>> aac9c07c0000b4ae28f4fd24bedf3efa66670e7a leftTCO->changeLength( splitPos - m_initialTCOPos ); From 3f39abf578a1782ea210b64ee43a6ea820591a45 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 May 2020 20:19:07 +0200 Subject: [PATCH 16/30] Fix undo --- src/core/Track.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index f6407217687..771f59e95f0 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1148,24 +1148,20 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) //clip (bad), and a clip the same length as the original one (pointless). if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) { -<<<<<<< HEAD - SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); - rightTCO->setIsPlaying(leftTCO->isPlaying()); -======= - //leftTCO->copy(); + leftTCO->getTrack()->addJournalCheckPoint(); + leftTCO->getTrack()->saveJournallingState( false ); + SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); rightTCO->setIsPlaying(leftTCO->isPlaying()); - leftTCO->getTrack()->addTCO( rightTCO ); - //rightTCO->paste(); ->>>>>>> aac9c07c0000b4ae28f4fd24bedf3efa66670e7a leftTCO->changeLength( splitPos - m_initialTCOPos ); rightTCO->movePosition( splitPos ); rightTCO->changeLength( m_initialTCOEnd - splitPos ); rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + + leftTCO->getTrack()->restoreJournallingState(); } } } From 31b938d901d519fb14719bc5392b04e4007175e5 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sun, 10 May 2020 19:45:57 +0200 Subject: [PATCH 17/30] git dammit --- src/core/Track.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/Track.cpp b/src/core/Track.cpp index caf15c604fc..771f59e95f0 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1148,12 +1148,9 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) //clip (bad), and a clip the same length as the original one (pointless). if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) { -<<<<<<< HEAD leftTCO->getTrack()->addJournalCheckPoint(); leftTCO->getTrack()->saveJournallingState( false ); -======= ->>>>>>> 8e8cf2ce84df318fde62fba3b21be26c3c958699 SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); rightTCO->setIsPlaying(leftTCO->isPlaying()); From 902f7755a9358d906f90552407b4323e2c131210 Mon Sep 17 00:00:00 2001 From: Spekular Date: Fri, 22 May 2020 18:36:50 +0200 Subject: [PATCH 18/30] Cleaner solution ? --- include/SampleBuffer.h | 3 ++- include/SampleTrack.h | 1 + src/core/SampleBuffer.cpp | 27 +++++++++++++++++++++++++-- src/core/Track.cpp | 4 +--- src/tracks/SampleTrack.cpp | 7 +++++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/SampleBuffer.h b/include/SampleBuffer.h index 26e85602508..0d0847d7d31 100644 --- a/include/SampleBuffer.h +++ b/include/SampleBuffer.h @@ -84,7 +84,7 @@ class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject { m_isBackwards = _backwards; } - + int interpolationMode() const { return m_interpolationMode; @@ -109,6 +109,7 @@ class LMMS_EXPORT SampleBuffer : public QObject, public sharedObject SampleBuffer( const QString & _audio_file, bool _is_base64_data = false ); SampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ); explicit SampleBuffer( const f_cnt_t _frames ); + SampleBuffer( const SampleBuffer& orig ); virtual ~SampleBuffer(); diff --git a/include/SampleTrack.h b/include/SampleTrack.h index d368771dbd0..c31d19cd881 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -47,6 +47,7 @@ class SampleTCO : public TrackContentObject mapPropertyFromModel(bool,isRecord,setRecord,m_recordModel); public: SampleTCO( Track * _track ); + SampleTCO( const SampleTCO& orig ); virtual ~SampleTCO(); void changeLength( const MidiTime & _length ) override; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index d0c39b13aa8..fb8aded8493 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -130,6 +130,29 @@ SampleBuffer::SampleBuffer( const f_cnt_t _frames ) +SampleBuffer::SampleBuffer( const SampleBuffer& orig ): + m_audioFile( orig.m_audioFile ), + m_origData( MM_ALLOC( sampleFrame, orig.m_origFrames ) ), + m_origFrames( orig.m_origFrames ), + m_data( MM_ALLOC( sampleFrame, orig.m_frames ) ), + m_frames( orig.m_frames ), + m_startFrame( orig.m_startFrame ), + m_endFrame( orig.m_endFrame ), + m_loopStartFrame( orig.m_loopStartFrame ), + m_loopEndFrame( orig.m_loopEndFrame ), + m_amplification( orig.m_amplification ), + m_reversed( orig.m_reversed ), + m_frequency( orig.m_frequency ), + m_sampleRate( orig.m_sampleRate ) +{ + //Deep copy m_origData and m_data from original + memcpy( m_origData, orig.m_origData, m_origFrames * BYTES_PER_FRAME ); + memcpy( m_data, orig.m_data, m_frames * BYTES_PER_FRAME ); +} + + + + SampleBuffer::~SampleBuffer() { MM_FREE( m_origData ); @@ -781,7 +804,7 @@ bool SampleBuffer::play( sampleFrame * _ab, handleState * _state, } } - if( tmp != NULL ) + if( tmp != NULL ) { MM_FREE( tmp ); } @@ -1488,7 +1511,7 @@ SampleBuffer::handleState::handleState( bool _varying_pitch, int interpolation_m { int error; m_interpolationMode = interpolation_mode; - + if( ( m_resamplingData = src_new( interpolation_mode, DEFAULT_CHANNELS, &error ) ) == NULL ) { qDebug( "Error: src_new() failed in sample_buffer.cpp!\n" ); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 771f59e95f0..3b6803b799f 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -1151,9 +1151,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) leftTCO->getTrack()->addJournalCheckPoint(); leftTCO->getTrack()->saveJournallingState( false ); - SampleTCO * rightTCO = new SampleTCO ( leftTCO->getTrack() ); - rightTCO->setSampleBuffer( leftTCO->sampleBuffer() ); - rightTCO->setIsPlaying(leftTCO->isPlaying()); + SampleTCO * rightTCO = new SampleTCO ( *leftTCO ); leftTCO->changeLength( splitPos - m_initialTCOPos ); diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 331ca86e598..c441b70ee4a 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -104,6 +104,13 @@ SampleTCO::SampleTCO( Track * _track ) : updateTrackTcos(); } +SampleTCO::SampleTCO( const SampleTCO& orig ) : + SampleTCO( orig.getTrack() ) +{ + m_sampleBuffer = new SampleBuffer(*orig.m_sampleBuffer); + m_isPlaying = orig.m_isPlaying; +} + From 12d818d5b3de12626ad8ba49b6d26a6cba4950ae Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 2 Jun 2020 19:34:04 +0200 Subject: [PATCH 19/30] Set cursor, add copy assignment to SampleBuffer --- data/themes/classic/cursor_knife.png | Bin 0 -> 414 bytes data/themes/classic/edit_knife.png | Bin 262 -> 287 bytes data/themes/classic/style.css | 11 ++++++----- data/themes/default/cursor_knife.png | Bin 0 -> 414 bytes data/themes/default/edit_knife.png | Bin 262 -> 287 bytes data/themes/default/style.css | 3 ++- include/SampleBuffer.h | 2 ++ include/SampleTrack.h | 3 +++ include/Track.h | 7 ++++++- src/core/SampleBuffer.cpp | 25 +++++++++++++++++++++++++ src/core/Track.cpp | 26 ++++++++++++++++++++++---- src/tracks/SampleTrack.cpp | 2 +- 12 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 data/themes/classic/cursor_knife.png create mode 100644 data/themes/default/cursor_knife.png diff --git a/data/themes/classic/cursor_knife.png b/data/themes/classic/cursor_knife.png new file mode 100644 index 0000000000000000000000000000000000000000..23dd3331be5cc99d437605f003e7ea49a7acaf56 GIT binary patch literal 414 zcmV;P0b%}$P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10V_#F zK~z}7#nrKGgfJ8a;NPU8x($rY92AU@o+?w&x@3nekpU2!V8bMTnsB;Ha(A{d_(^Uo z(ErKrNe=)9WG?1LP$`ua!F63(*L5}oNzysTTPI_IJQBsopfwnaYy^Z-;S zpjS#=*KtT$YgttlwbtzWo?X`wzzU#_LWBTr!mxCvz zq_y_pcf&BGNBD*xf(Q*yhOpK~hbKX3t)C8@Z|xdPA;hlmy$Deh1yj}UcD(rjNPY+* zE^XWH-h55dpe)PFIF9cCzI^}F02X6R>X%qT@DjlMvv`u7Z_0`>c(KD_0RR9107*qo IM6N<$f-~=_u>b%7 literal 0 HcmV?d00001 diff --git a/data/themes/classic/edit_knife.png b/data/themes/classic/edit_knife.png index e6d5bb1c8ed33f0b7f6f830bf3efc763a3e20a4b..70b15113d1ab47359d90e3381cb87d2d25224532 100644 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@Uw&H|6fVg?4j!ywFfJby(BP*AeO zHKHUqKdq!Zu_%?Hyu4g5GcUV1Ik6yBFTW^#_B$IXprSRNE{-7@=X=j?;pch8{AN(zg8k=;VF$!NTFJmX2JbMHOB zdbZQQw@xTgjPaCMXhq_wWbl!+ z_ne`Iw2ply+@bivTJA+@e=j^@bpF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10V_#F zK~z}7#nrKGgfJ8a;NPU8x($rY92AU@o+?w&x@3nekpU2!V8bMTnsB;Ha(A{d_(^Uo z(ErKrNe=)9WG?1LP$`ua!F63(*L5}oNzysTTPI_IJQBsopfwnaYy^Z-;S zpjS#=*KtT$YgttlwbtzWo?X`wzzU#_LWBTr!mxCvz zq_y_pcf&BGNBD*xf(Q*yhOpK~hbKX3t)C8@Z|xdPA;hlmy$Deh1yj}UcD(rjNPY+* zE^XWH-h55dpe)PFIF9cCzI^}F02X6R>X%qT@DjlMvv`u7Z_0`>c(KD_0RR9107*qo IM6N<$f-~=_u>b%7 literal 0 HcmV?d00001 diff --git a/data/themes/default/edit_knife.png b/data/themes/default/edit_knife.png index e6d5bb1c8ed33f0b7f6f830bf3efc763a3e20a4b..70b15113d1ab47359d90e3381cb87d2d25224532 100644 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc0wmQNuC@Uw&H|6fVg?4j!ywFfJby(BP*AeO zHKHUqKdq!Zu_%?Hyu4g5GcUV1Ik6yBFTW^#_B$IXprSRNE{-7@=X=j?;pch8{AN(zg8k=;VF$!NTFJmX2JbMHOB zdbZQQw@xTgjPaCMXhq_wWbl!+ z_ne`Iw2ply+@bivTJA+@e=j^@b x, height -> y Q_PROPERTY( QSize mouseHotspotHand WRITE setMouseHotspotHand ) + Q_PROPERTY( QSize mouseHotspotKnife WRITE setMouseHotspotKnife ) public: TrackContentObjectView( TrackContentObject * tco, TrackView * tv ); @@ -245,6 +246,7 @@ class TrackContentObjectView : public selectableObject, public ModelView void setBBPatternBackground( const QColor & c ); void setGradient( const bool & b ); void setMouseHotspotHand(const QSize & s); + void setMouseHotspotKnife(const QSize & s); // access needsUpdate member variable bool needsUpdate(); @@ -322,7 +324,10 @@ protected slots: QColor m_textShadowColor; QColor m_BBPatternBackground; bool m_gradient; - QSize m_mouseHotspotHand; // QSize must be used because QPoint isn't supported by property system + QSize m_mouseHotspotHand; // QSize must be used because QPoint + QSize m_mouseHotspotKnife; // isn't supported by property system + QCursor m_cursorHand; + QCursor m_cursorKnife; bool m_cursorSetYet; bool m_needsUpdate; diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp index fb8aded8493..4d417bdfe0f 100644 --- a/src/core/SampleBuffer.cpp +++ b/src/core/SampleBuffer.cpp @@ -153,6 +153,31 @@ SampleBuffer::SampleBuffer( const SampleBuffer& orig ): +SampleBuffer& SampleBuffer::operator=( const SampleBuffer& that ) +{ + m_audioFile = that.m_audioFile; + m_origData = MM_ALLOC( sampleFrame, that.m_origFrames ); + m_origFrames = that.m_origFrames; + m_data = MM_ALLOC( sampleFrame, that.m_frames ); + m_frames = that.m_frames; + m_startFrame = that.m_startFrame; + m_endFrame = that.m_endFrame; + m_loopStartFrame = that.m_loopStartFrame; + m_loopEndFrame = that.m_loopEndFrame; + m_amplification = that.m_amplification; + m_reversed = that.m_reversed; + m_frequency = that.m_frequency; + m_sampleRate = that.m_sampleRate; + memcpy( m_origData, that.m_origData, m_origFrames * BYTES_PER_FRAME ); + memcpy( m_data, that.m_data, m_frames * BYTES_PER_FRAME ); + update(); + + return *this; +} + + + + SampleBuffer::~SampleBuffer() { MM_FREE( m_origData ); diff --git a/src/core/Track.cpp b/src/core/Track.cpp index fc2ff52d094..ceddbca8332 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -283,6 +283,9 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, m_BBPatternBackground( 0, 0, 0 ), m_gradient( true ), m_mouseHotspotHand( 0, 0 ), + m_mouseHotspotKnife( 0, 0 ), + m_cursorHand( QCursor( embed::getIconPixmap( "hand" ) ) ), + m_cursorKnife( QCursor( embed::getIconPixmap( "cursor_knife" ) ) ), m_cursorSetYet( false ), m_needsUpdate( true ) { @@ -295,7 +298,7 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, setAttribute( Qt::WA_OpaquePaintEvent, true ); setAttribute( Qt::WA_DeleteOnClose, true ); setFocusPolicy( Qt::StrongFocus ); - setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); + setCursor( m_cursorHand ); move( 0, 0 ); show(); @@ -346,7 +349,9 @@ void TrackContentObjectView::update() { if( !m_cursorSetYet ) { - setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); + m_cursorHand = QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ); + m_cursorKnife = QCursor( embed::getIconPixmap( "cursor_knife" ), m_mouseHotspotKnife.width(), m_mouseHotspotKnife.height() ); + setCursor( m_cursorHand ); m_cursorSetYet = true; } @@ -435,6 +440,11 @@ void TrackContentObjectView::setMouseHotspotHand(const QSize & s) m_mouseHotspotHand = s; } +void TrackContentObjectView::setMouseHotspotKnife(const QSize & s) +{ + m_mouseHotspotKnife = s; +} + // access needsUpdate member variable bool TrackContentObjectView::needsUpdate() { return m_needsUpdate; } @@ -622,7 +632,7 @@ void TrackContentObjectView::leaveEvent( QEvent * e ) { if( cursor().shape() != Qt::BitmapCursor ) { - setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); + setCursor( m_cursorHand ); } if( e != NULL ) { @@ -756,6 +766,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) else if (sTco) { m_action = Split; + setCursor( m_cursorKnife ); sTco->setMarkerPos( knifeMarkerPos( me ) ); sTco->setMarkerEnabled( true ); update(); @@ -1093,12 +1104,19 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) else if( m_action == Split ) { SampleTCO * sTco = dynamic_cast( m_tco ); - if (sTco) { sTco->setMarkerPos( knifeMarkerPos( me ) ); } + if (sTco) { + setCursor( m_cursorKnife ); + sTco->setMarkerPos( knifeMarkerPos( me ) ); + } update(); } else { SampleTCO * sTco = dynamic_cast( m_tco ); + + if (sTco && m_trackView->trackContainerView()->knifeMode()) + { setCursor( m_cursorKnife ); } + if( ( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() ) || ( me->x() < RESIZE_GRIP_WIDTH && !me->buttons() && sTco && !m_tco->getAutoResize() ) ) { diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index f0ae66def03..1e7e7de778c 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -107,7 +107,7 @@ SampleTCO::SampleTCO( Track * _track ) : SampleTCO::SampleTCO( const SampleTCO& orig ) : SampleTCO( orig.getTrack() ) { - m_sampleBuffer = new SampleBuffer(*orig.m_sampleBuffer); + m_sampleBuffer = orig.m_sampleBuffer; m_isPlaying = orig.m_isPlaying; } From e9906bc321195caf32340c49620e887f0867d108 Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 3 Oct 2020 22:06:24 +0200 Subject: [PATCH 20/30] Add TODO comment --- src/tracks/SampleTrack.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 1e7e7de778c..26527bc8cdd 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -107,6 +107,9 @@ SampleTCO::SampleTCO( Track * _track ) : SampleTCO::SampleTCO( const SampleTCO& orig ) : SampleTCO( orig.getTrack() ) { + // TODO: This creates a new SampleBuffer for the new TCO, eating up memory + // & eventually causing performance issues. Letting tracks share buffers + // when they're identical would fix this, but isn't possible right now. m_sampleBuffer = orig.m_sampleBuffer; m_isPlaying = orig.m_isPlaying; } From 19c31f345a761cbcfdbdfb3fcc577e7749b52290 Mon Sep 17 00:00:00 2001 From: Spekular Date: Fri, 1 Jan 2021 02:04:22 +0100 Subject: [PATCH 21/30] Make it build --- include/TrackContentObjectView.h | 2 +- src/gui/TrackContentObjectView.cpp | 18 +++++++++--------- src/tracks/SampleTrack.cpp | 13 ------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/include/TrackContentObjectView.h b/include/TrackContentObjectView.h index 3a76bea2401..1b5517b3579 100644 --- a/include/TrackContentObjectView.h +++ b/include/TrackContentObjectView.h @@ -225,7 +225,7 @@ protected slots: bool unquantizedModHeld( QMouseEvent * me ); TimePos draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); - MidiTime quantizeMarkerPos( MidiTime, bool shiftMode ); + TimePos quantizeMarkerPos( TimePos, bool shiftMode ); } ; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index e11106d384b..55efce00437 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -995,7 +995,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) const int relativePixelPos = me->pos().x(); const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - MidiTime splitPos = relativePixelPos * MidiTime::ticksPerBar() / ppb; + TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; if ( !unquantizedModHeld(me) ) { @@ -1428,35 +1428,35 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) if ( unquantizedModHeld(me) ) { return markerPos; } else { //Otherwise we... - //1: Convert the position to a MidiTime + //1: Convert the position to a TimePos const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - MidiTime midiPos = markerPos * MidiTime::ticksPerBar() / ppb; + TimePos midiPos = markerPos * TimePos::ticksPerBar() / ppb; //2: Snap to the correct position, based on modifier keys midiPos = quantizeMarkerPos( midiPos, me->modifiers() & Qt::ShiftModifier ); //3: Convert back to a pixel position - return midiPos * ppb / MidiTime::ticksPerBar(); + return midiPos * ppb / TimePos::ticksPerBar(); } } -MidiTime TrackContentObjectView::quantizeMarkerPos( MidiTime midiPos, bool shiftMode ) +TimePos TrackContentObjectView::quantizeMarkerPos( TimePos midiPos, bool shiftMode ) { const float snapSize = gui->songEditor()->m_editor->getSnapSize(); if ( shiftMode ) { //If shift is held we quantize the length of the new left clip... - const MidiTime leftPos = midiPos.quantize( snapSize ); + const TimePos leftPos = midiPos.quantize( snapSize ); //...or right clip... - const MidiTime rightOff = m_tco->length() - midiPos; - const MidiTime rightPos = m_tco->length() - rightOff.quantize( snapSize ); + const TimePos rightOff = m_tco->length() - midiPos; + const TimePos rightPos = m_tco->length() - rightOff.quantize( snapSize ); //...whichever gives a position closer to the cursor if ( abs(leftPos - midiPos) < abs(rightPos - midiPos) ) { return leftPos; } else { return rightPos; } } else { - return (MidiTime(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos); + return (TimePos(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos); } } diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 9e086c29746..e360deb2f21 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -106,19 +106,6 @@ SampleTCO::SampleTCO( Track * _track ) : updateTrackTcos(); } -SampleTCO::SampleTCO( const SampleTCO& orig ) : - SampleTCO( orig.getTrack() ) -{ - // TODO: This creates a new SampleBuffer for the new TCO, eating up memory - // & eventually causing performance issues. Letting tracks share buffers - // when they're identical would fix this, but isn't possible right now. - m_sampleBuffer = orig.m_sampleBuffer; - m_isPlaying = orig.m_isPlaying; -} - - - - SampleTCO::SampleTCO(const SampleTCO& orig) : SampleTCO(orig.getTrack()) { From 3a532b353da1a2b805f8169c7177fb0ee4cafea4 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 Jan 2021 00:23:12 +0100 Subject: [PATCH 22/30] Fixes from review --- include/SampleTrack.h | 10 +--- include/TrackContentObjectView.h | 2 + src/gui/TrackContentObjectView.cpp | 89 ++++++++++++++++-------------- 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 10f6f87e5f9..081c5a44541 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -79,14 +79,8 @@ class SampleTCO : public TrackContentObject bool isPlaying() const; void setIsPlaying(bool isPlaying); - void inline setMarkerPos( int x ) - { - m_markerPos = x; - } - void inline setMarkerEnabled( bool e ) - { - m_marker = e; - } + void inline setMarkerPos(int x) { m_markerPos = x; } + void inline setMarkerEnabled(bool e) { m_marker = e; } public slots: void setSampleBuffer( SampleBuffer* sb ); diff --git a/include/TrackContentObjectView.h b/include/TrackContentObjectView.h index 1b5517b3579..6d0fc7f76e8 100644 --- a/include/TrackContentObjectView.h +++ b/include/TrackContentObjectView.h @@ -226,6 +226,8 @@ protected slots: TimePos draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); TimePos quantizeMarkerPos( TimePos, bool shiftMode ); + //! Return true iff TCO could be split + bool splitTCO( QMouseEvent * me ); } ; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index 55efce00437..dd9cea69365 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -110,7 +110,6 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, setAttribute( Qt::WA_DeleteOnClose, true ); setFocusPolicy( Qt::StrongFocus ); setCursor( m_cursorHand ); - setCursor( QCursor( embed::getIconPixmap( "hand" ), m_mouseHotspotHand.width(), m_mouseHotspotHand.height() ) ); move( 0, 0 ); show(); @@ -985,45 +984,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) // TODO: Fix m_tco->setJournalling() consistency m_tco->setJournalling( true ); } - else if( m_action == Split ) - { - SampleTCO * leftTCO = dynamic_cast( m_tco ); - - if (leftTCO) - { - leftTCO->setMarkerEnabled( false ); - - const int relativePixelPos = me->pos().x(); - const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; - - if ( !unquantizedModHeld(me) ) - { - splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); - } - - splitPos += m_initialTCOPos; - - //Don't split if we slid off the TCO or if we're on the clip's start/end - //Cutting at exactly the start/end position would create a zero length - //clip (bad), and a clip the same length as the original one (pointless). - if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) - { - leftTCO->getTrack()->addJournalCheckPoint(); - leftTCO->getTrack()->saveJournallingState( false ); - - SampleTCO * rightTCO = new SampleTCO ( *leftTCO ); - - leftTCO->changeLength( splitPos - m_initialTCOPos ); - - rightTCO->movePosition( splitPos ); - rightTCO->changeLength( m_initialTCOEnd - splitPos ); - rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); - - leftTCO->getTrack()->restoreJournallingState(); - } - } - } + else if( m_action == Split ) { splitTCO( me ); } m_action = NoAction; delete m_hint; @@ -1456,8 +1417,54 @@ TimePos TrackContentObjectView::quantizeMarkerPos( TimePos midiPos, bool shiftMo } else { - return (TimePos(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos); + return TimePos(midiPos + m_initialTCOPos).quantize( snapSize ) - m_initialTCOPos; + } +} + + + + +// This should eventually be available for all clip types, hence why it's not +// located inside SampleTCOView +bool TrackContentObjectView::splitTCO( QMouseEvent * me ) +{ + SampleTCO * leftTCO = dynamic_cast( m_tco ); + + if (!leftTCO) { return false; } + + leftTCO->setMarkerEnabled( false ); + + const int relativePixelPos = me->pos().x(); + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); + TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; + + if ( !unquantizedModHeld(me) ) + { + splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); + } + + splitPos += m_initialTCOPos; + + //Don't split if we slid off the TCO or if we're on the clip's start/end + //Cutting at exactly the start/end position would create a zero length + //clip (bad), and a clip the same length as the original one (pointless). + if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) + { + leftTCO->getTrack()->addJournalCheckPoint(); + leftTCO->getTrack()->saveJournallingState( false ); + + SampleTCO * rightTCO = new SampleTCO ( *leftTCO ); + + leftTCO->changeLength( splitPos - m_initialTCOPos ); + + rightTCO->movePosition( splitPos ); + rightTCO->changeLength( m_initialTCOEnd - splitPos ); + rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); + + leftTCO->getTrack()->restoreJournallingState(); + return true; } + else { return false; } } From 08aaea3b6891b14c8555b3bca02db1b6237c3ab6 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 5 Jan 2021 17:38:58 +0100 Subject: [PATCH 23/30] Make splitTCO virtual --- include/SampleTrack.h | 1 + include/TrackContentObjectView.h | 16 +++++---- src/gui/TrackContentObjectView.cpp | 52 ++---------------------------- src/tracks/SampleTrack.cpp | 41 +++++++++++++++++++++++ 4 files changed, 54 insertions(+), 56 deletions(-) diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 081c5a44541..13d1de2d645 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -137,6 +137,7 @@ public slots: private: SampleTCO * m_tco; QPixmap m_paintPixmap; + bool splitTCO( QMouseEvent * me ) override; } ; diff --git a/include/TrackContentObjectView.h b/include/TrackContentObjectView.h index 6d0fc7f76e8..be5968845da 100644 --- a/include/TrackContentObjectView.h +++ b/include/TrackContentObjectView.h @@ -139,6 +139,10 @@ public slots: Merge }; + TrackView * m_trackView; + TimePos m_initialTCOPos; + TimePos m_initialTCOEnd; + virtual void constructContextMenu( QMenu * ) { } @@ -157,6 +161,9 @@ public slots: selectableObject::resizeEvent( re ); } + bool unquantizedModHeld( QMouseEvent * me ); + TimePos quantizeMarkerPos( TimePos, bool shiftMode ); + float pixelsPerBar(); @@ -186,12 +193,9 @@ protected slots: static TextFloat * s_textFloat; TrackContentObject * m_tco; - TrackView * m_trackView; Actions m_action; QPoint m_initialMousePos; QPoint m_initialMouseGlobalPos; - TimePos m_initialTCOPos; - TimePos m_initialTCOEnd; QVector m_initialOffsets; TextFloat * m_hint; @@ -222,12 +226,10 @@ protected slots: void setInitialOffsets(); bool mouseMovedDistance( QMouseEvent * me, int distance ); - bool unquantizedModHeld( QMouseEvent * me ); TimePos draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); - TimePos quantizeMarkerPos( TimePos, bool shiftMode ); - //! Return true iff TCO could be split - bool splitTCO( QMouseEvent * me ); + //! Return true iff TCO could be split. Currently only implemented for samples + virtual bool splitTCO( QMouseEvent * me ){ return false; }; } ; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index dd9cea69365..da68db7055a 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -77,13 +77,13 @@ TrackContentObjectView::TrackContentObjectView( TrackContentObject * tco, TrackView * tv ) : selectableObject( tv->getTrackContentWidget() ), ModelView( NULL, this ), - m_tco( tco ), m_trackView( tv ), + m_initialTCOPos( TimePos(0) ), + m_initialTCOEnd( TimePos(0) ), + m_tco( tco ), m_action( NoAction ), m_initialMousePos( QPoint( 0, 0 ) ), m_initialMouseGlobalPos( QPoint( 0, 0 ) ), - m_initialTCOPos( TimePos(0) ), - m_initialTCOEnd( TimePos(0) ), m_initialOffsets( QVector() ), m_hint( NULL ), m_mutedColor( 0, 0, 0 ), @@ -1424,52 +1424,6 @@ TimePos TrackContentObjectView::quantizeMarkerPos( TimePos midiPos, bool shiftMo -// This should eventually be available for all clip types, hence why it's not -// located inside SampleTCOView -bool TrackContentObjectView::splitTCO( QMouseEvent * me ) -{ - SampleTCO * leftTCO = dynamic_cast( m_tco ); - - if (!leftTCO) { return false; } - - leftTCO->setMarkerEnabled( false ); - - const int relativePixelPos = me->pos().x(); - const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; - - if ( !unquantizedModHeld(me) ) - { - splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); - } - - splitPos += m_initialTCOPos; - - //Don't split if we slid off the TCO or if we're on the clip's start/end - //Cutting at exactly the start/end position would create a zero length - //clip (bad), and a clip the same length as the original one (pointless). - if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) - { - leftTCO->getTrack()->addJournalCheckPoint(); - leftTCO->getTrack()->saveJournallingState( false ); - - SampleTCO * rightTCO = new SampleTCO ( *leftTCO ); - - leftTCO->changeLength( splitPos - m_initialTCOPos ); - - rightTCO->movePosition( splitPos ); - rightTCO->changeLength( m_initialTCOEnd - splitPos ); - rightTCO->setStartTimeOffset( leftTCO->startTimeOffset() - leftTCO->length() ); - - leftTCO->getTrack()->restoreJournallingState(); - return true; - } - else { return false; } -} - - - - // Return the color that the TCO's background should be QColor TrackContentObjectView::getColorForDisplay( QColor defaultColor ) { diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index e360deb2f21..64bf025dfbe 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -668,6 +668,47 @@ void SampleTCOView::reverseSample() +//! Split this TCO +bool SampleTCOView::splitTCO( QMouseEvent * me ) +{ + m_tco->setMarkerEnabled( false ); + + const int relativePixelPos = me->pos().x(); + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); + TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; + + if ( !unquantizedModHeld(me) ) + { + splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); + } + + splitPos += m_initialTCOPos; + + //Don't split if we slid off the TCO or if we're on the clip's start/end + //Cutting at exactly the start/end position would create a zero length + //clip (bad), and a clip the same length as the original one (pointless). + if ( splitPos > m_initialTCOPos && splitPos < m_initialTCOEnd ) + { + m_tco->getTrack()->addJournalCheckPoint(); + m_tco->getTrack()->saveJournallingState( false ); + + SampleTCO * rightTCO = new SampleTCO ( *m_tco ); + + m_tco->changeLength( splitPos - m_initialTCOPos ); + + rightTCO->movePosition( splitPos ); + rightTCO->changeLength( m_initialTCOEnd - splitPos ); + rightTCO->setStartTimeOffset( m_tco->startTimeOffset() - m_tco->length() ); + + m_tco->getTrack()->restoreJournallingState(); + return true; + } + else { return false; } +} + + + + SampleTrack::SampleTrack(TrackContainer* tc) : From 22a8d475d2e596c581de5fdd30671f86a27b5771 Mon Sep 17 00:00:00 2001 From: Spekular Date: Thu, 14 Jan 2021 21:32:05 +0100 Subject: [PATCH 24/30] Make splitTCO more generic Co-authored-by: IanCaio --- include/SampleTrack.h | 8 +------- include/TrackContentObjectView.h | 10 ++++++++-- src/gui/TrackContentObjectView.cpp | 22 +++++++++++++++------- src/tracks/SampleTrack.cpp | 22 +++++++--------------- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 13d1de2d645..039aa59369a 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -79,9 +79,6 @@ class SampleTCO : public TrackContentObject bool isPlaying() const; void setIsPlaying(bool isPlaying); - void inline setMarkerPos(int x) { m_markerPos = x; } - void inline setMarkerEnabled(bool e) { m_marker = e; } - public slots: void setSampleBuffer( SampleBuffer* sb ); void setSampleFile( const QString & _sf ); @@ -96,9 +93,6 @@ public slots: BoolModel m_recordModel; bool m_isPlaying; - bool m_marker = false; - int m_markerPos = 0; - friend class SampleTCOView; @@ -137,7 +131,7 @@ public slots: private: SampleTCO * m_tco; QPixmap m_paintPixmap; - bool splitTCO( QMouseEvent * me ) override; + bool splitTCO( const TimePos pos ) override; } ; diff --git a/include/TrackContentObjectView.h b/include/TrackContentObjectView.h index be5968845da..411d62c922b 100644 --- a/include/TrackContentObjectView.h +++ b/include/TrackContentObjectView.h @@ -120,6 +120,9 @@ class TrackContentObjectView : public selectableObject, public ModelView QColor getColorForDisplay( QColor ); + void inline setMarkerPos(int x) { m_markerPos = x; } + void inline setMarkerEnabled(bool e) { m_marker = e; } + public slots: virtual bool close(); void remove(); @@ -143,6 +146,9 @@ public slots: TimePos m_initialTCOPos; TimePos m_initialTCOEnd; + bool m_marker = false; + int m_markerPos = 0; + virtual void constructContextMenu( QMenu * ) { } @@ -162,7 +168,7 @@ public slots: } bool unquantizedModHeld( QMouseEvent * me ); - TimePos quantizeMarkerPos( TimePos, bool shiftMode ); + TimePos quantizeSplitPos( TimePos, bool shiftMode ); float pixelsPerBar(); @@ -229,7 +235,7 @@ protected slots: TimePos draggedTCOPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); //! Return true iff TCO could be split. Currently only implemented for samples - virtual bool splitTCO( QMouseEvent * me ){ return false; }; + virtual bool splitTCO( const TimePos pos ){ return false; }; } ; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index da68db7055a..679c7996674 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -597,8 +597,8 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) { m_action = Split; setCursor( m_cursorKnife ); - sTco->setMarkerPos( knifeMarkerPos( me ) ); - sTco->setMarkerEnabled( true ); + setMarkerPos( knifeMarkerPos( me ) ); + setMarkerEnabled( true ); update(); } // We can't split anything except samples right now, so disable the @@ -706,7 +706,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) SampleTCO * sTco = dynamic_cast( m_tco ); if (sTco) { - sTco->setMarkerEnabled( false ); + setMarkerEnabled( false ); update(); } } @@ -934,7 +934,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) SampleTCO * sTco = dynamic_cast( m_tco ); if (sTco) { setCursor( m_cursorKnife ); - sTco->setMarkerPos( knifeMarkerPos( me ) ); + setMarkerPos( knifeMarkerPos( me ) ); } update(); } @@ -984,7 +984,15 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) // TODO: Fix m_tco->setJournalling() consistency m_tco->setJournalling( true ); } - else if( m_action == Split ) { splitTCO( me ); } + else if( m_action == Split ) + { + const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); + const TimePos relPos = me->pos().x() * TimePos::ticksPerBar() / ppb; + splitTCO(unquantizedModHeld(me) ? + relPos : + quantizeSplitPos(relPos, me->modifiers() & Qt::ShiftModifier) + ); + } m_action = NoAction; delete m_hint; @@ -1393,7 +1401,7 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); TimePos midiPos = markerPos * TimePos::ticksPerBar() / ppb; //2: Snap to the correct position, based on modifier keys - midiPos = quantizeMarkerPos( midiPos, me->modifiers() & Qt::ShiftModifier ); + midiPos = quantizeSplitPos( midiPos, me->modifiers() & Qt::ShiftModifier ); //3: Convert back to a pixel position return midiPos * ppb / TimePos::ticksPerBar(); } @@ -1402,7 +1410,7 @@ int TrackContentObjectView::knifeMarkerPos( QMouseEvent * me ) -TimePos TrackContentObjectView::quantizeMarkerPos( TimePos midiPos, bool shiftMode ) +TimePos TrackContentObjectView::quantizeSplitPos( TimePos midiPos, bool shiftMode ) { const float snapSize = gui->songEditor()->m_editor->getSnapSize(); if ( shiftMode ) diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 64bf025dfbe..8a5ecc66837 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -631,9 +631,9 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) embed::getIconPixmap( "muted", size, size ) ); } - if ( m_tco->m_marker ) + if ( m_marker ) { - p.drawLine(m_tco->m_markerPos, rect().bottom(), m_tco->m_markerPos, rect().top()); + p.drawLine(m_markerPos, rect().bottom(), m_markerPos, rect().top()); } // recording sample tracks is not possible at the moment @@ -668,21 +668,13 @@ void SampleTCOView::reverseSample() -//! Split this TCO -bool SampleTCOView::splitTCO( QMouseEvent * me ) +//! Split this TCO. +/*! \param pos the position of the split, relative to the start of the clip */ +bool SampleTCOView::splitTCO( const TimePos pos ) { - m_tco->setMarkerEnabled( false ); + setMarkerEnabled( false ); - const int relativePixelPos = me->pos().x(); - const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - TimePos splitPos = relativePixelPos * TimePos::ticksPerBar() / ppb; - - if ( !unquantizedModHeld(me) ) - { - splitPos = quantizeMarkerPos( splitPos, me->modifiers() & Qt::ShiftModifier ); - } - - splitPos += m_initialTCOPos; + const TimePos splitPos = m_initialTCOPos + pos; //Don't split if we slid off the TCO or if we're on the clip's start/end //Cutting at exactly the start/end position would create a zero length From 478299457f31d3cff9fdea132db7f976790c6578 Mon Sep 17 00:00:00 2001 From: Spekular Date: Thu, 14 Jan 2021 22:06:43 +0100 Subject: [PATCH 25/30] Prevent resizing of MIDI clips in knife mode --- src/gui/TrackContentObjectView.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index 679c7996674..5bbd339667b 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -578,12 +578,11 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) setInitialOffsets(); if( !fixedTCOs() && me->button() == Qt::LeftButton ) { - if( m_trackView->trackContainerView()->knifeMode() ) + if( m_trackView->trackContainerView()->knifeMode() && !m_tco->getAutoResize() ) { SampleTCO * sTco = dynamic_cast( m_tco ); - if( me->x() < RESIZE_GRIP_WIDTH && sTco - && !m_tco->getAutoResize() ) + if( me->x() < RESIZE_GRIP_WIDTH && sTco ) { m_action = ResizeLeft; setCursor( Qt::SizeHorCursor ); From 245160dd196dc51bfc01ffceac6d92953c582aeb Mon Sep 17 00:00:00 2001 From: Spekular Date: Sat, 16 Jan 2021 15:16:54 +0100 Subject: [PATCH 26/30] Fix move/resize and rework box select via ctrl --- include/SongEditor.h | 4 +- include/TrackContentWidget.h | 1 + src/gui/TrackContentObjectView.cpp | 61 ++++++++++---------------- src/gui/editors/SongEditor.cpp | 35 +++------------ src/gui/widgets/TrackContentWidget.cpp | 18 +++++++- 5 files changed, 49 insertions(+), 70 deletions(-) diff --git a/include/SongEditor.h b/include/SongEditor.h index 7eb30107632..9c59e3328c4 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -176,6 +176,7 @@ class SongEditorWindow : public Editor QSize sizeHint() const override; SongEditor* m_editor; + void syncEditMode(); protected: void resizeEvent( QResizeEvent * event ) override; @@ -197,9 +198,6 @@ protected slots: void resized(); private: - void keyPressEvent( QKeyEvent * ke ) override; - void keyReleaseEvent( QKeyEvent * ke ) override; - QAction* m_addBBTrackAction; QAction* m_addSampleTrackAction; QAction* m_addAutomationTrackAction; diff --git a/include/TrackContentWidget.h b/include/TrackContentWidget.h index c2764bfc6b4..37362319b76 100644 --- a/include/TrackContentWidget.h +++ b/include/TrackContentWidget.h @@ -99,6 +99,7 @@ public slots: void dragEnterEvent( QDragEnterEvent * dee ) override; void dropEvent( QDropEvent * de ) override; void mousePressEvent( QMouseEvent * me ) override; + void mouseReleaseEvent( QMouseEvent * me ) override; void paintEvent( QPaintEvent * pe ) override; void resizeEvent( QResizeEvent * re ) override; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index 5bbd339667b..65b4b5b4f8b 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -578,34 +578,10 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) setInitialOffsets(); if( !fixedTCOs() && me->button() == Qt::LeftButton ) { - if( m_trackView->trackContainerView()->knifeMode() && !m_tco->getAutoResize() ) - { - SampleTCO * sTco = dynamic_cast( m_tco ); + SampleTCO * sTco = dynamic_cast( m_tco ); + const bool knifeMode = m_trackView->trackContainerView()->knifeMode(); - if( me->x() < RESIZE_GRIP_WIDTH && sTco ) - { - m_action = ResizeLeft; - setCursor( Qt::SizeHorCursor ); - } - else if( me->x() >= width() - RESIZE_GRIP_WIDTH ) - { - m_action = Resize; - setCursor( Qt::SizeHorCursor ); - } - else if (sTco) - { - m_action = Split; - setCursor( m_cursorKnife ); - setMarkerPos( knifeMarkerPos( me ) ); - setMarkerEnabled( true ); - update(); - } - // We can't split anything except samples right now, so disable the - // action to avoid entering if statements we don't need to. This - // also saves us a few 'if(sTco)' checks - else { m_action = NoAction; } - } - else if ( me->modifiers() & Qt::ControlModifier ) + if ( me->modifiers() & Qt::ControlModifier && !(sTco && knifeMode) ) { if( isSelected() ) { @@ -616,9 +592,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) m_action = ToggleSelected; } } - else if( !me->modifiers() - || (me->modifiers() & Qt::AltModifier) - || (me->modifiers() & Qt::ShiftModifier) ) + else { if( isSelected() ) { @@ -635,22 +609,33 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) setInitialPos( me->pos() ); setInitialOffsets(); - SampleTCO * sTco = dynamic_cast( m_tco ); - if( me->x() < RESIZE_GRIP_WIDTH && sTco - && !m_tco->getAutoResize() ) + if( m_tco->getAutoResize() ) + { // Always move clips that can't be manually resized + m_action = Move; + setCursor( Qt::SizeAllCursor ); + } + else if( me->x() >= width() - RESIZE_GRIP_WIDTH ) + { + m_action = Resize; + setCursor( Qt::SizeHorCursor ); + } + else if( me->x() < RESIZE_GRIP_WIDTH && sTco ) { m_action = ResizeLeft; setCursor( Qt::SizeHorCursor ); } - else if( m_tco->getAutoResize() || me->x() < width() - RESIZE_GRIP_WIDTH ) + else if( sTco && knifeMode ) { - m_action = Move; - setCursor( Qt::SizeAllCursor ); + m_action = Split; + setCursor( m_cursorKnife ); + setMarkerPos( knifeMarkerPos( me ) ); + setMarkerEnabled( true ); + update(); } else { - m_action = Resize; - setCursor( Qt::SizeHorCursor ); + m_action = Move; + setCursor( Qt::SizeAllCursor ); } if( m_action == Move ) diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 0ac66c242b3..5a148ff8a37 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -1047,6 +1047,13 @@ void SongEditorWindow::updateSnapLabel(){ +void SongEditorWindow::syncEditMode(){ + m_editModeGroup->checkedAction()->trigger(); +} + + + + void SongEditorWindow::resizeEvent(QResizeEvent *event) { emit resized(); @@ -1124,31 +1131,3 @@ void SongEditorWindow::adjustUiAfterProjectLoad() connect( qobject_cast( parentWidget() ), SIGNAL( focusLost() ), this, SLOT( lostFocus() ) ); m_editor->scrolled(0); } - - - - -void SongEditorWindow::keyPressEvent( QKeyEvent *ke ) -{ - if( ke->key() == Qt::Key_Control ) - { - m_crtlAction = m_editModeGroup->checkedAction(); - m_selectModeAction->setChecked( true ); - m_selectModeAction->trigger(); - } -} - - - - -void SongEditorWindow::keyReleaseEvent( QKeyEvent *ke ) -{ - if( ke->key() == Qt::Key_Control ) - { - if( m_crtlAction ) - { - m_crtlAction->setChecked( true ); - m_crtlAction->trigger(); - } - } -} diff --git a/src/gui/widgets/TrackContentWidget.cpp b/src/gui/widgets/TrackContentWidget.cpp index 11ac3a60f0b..b959b05c831 100644 --- a/src/gui/widgets/TrackContentWidget.cpp +++ b/src/gui/widgets/TrackContentWidget.cpp @@ -547,14 +547,22 @@ void TrackContentWidget::dropEvent( QDropEvent * de ) */ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) { + // Enable box select if control is held when clicking an empty space + // (If we had clicked a TCO it would have intercepted the mouse event) + if( me->modifiers() & Qt::ControlModifier ){ + gui->songEditor()->m_editor->setEditMode(SongEditor::EditMode::SelectMode); + } + // Forward event to allow box select if the editor supports it and is in that mode if( m_trackView->trackContainerView()->allowRubberband() == true ) { QWidget::mousePressEvent( me ); } + // Forward shift clicks so tracks can be resized else if( me->modifiers() & Qt::ShiftModifier ) { QWidget::mousePressEvent( me ); } + // For an unmodified click, create a new TCO else if( me->button() == Qt::LeftButton && !m_trackView->trackContainerView()->fixedTCOs() ) { @@ -573,6 +581,15 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) +void TrackContentWidget::mouseReleaseEvent( QMouseEvent * me ) +{ + gui->songEditor()->syncEditMode(); + QWidget::mousePressEvent(me); +} + + + + /*! \brief Repaint the trackContentWidget on command * * \param pe the Paint Event to respond to @@ -707,4 +724,3 @@ void TrackContentWidget::setGridColor( const QBrush & c ) //! \brief CSS theming qproperty access method void TrackContentWidget::setEmbossColor( const QBrush & c ) { m_embossColor = c; } - From d498802e9ba3462a671056024ac60139fd9b9b40 Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 26 Jan 2021 16:54:13 +0100 Subject: [PATCH 27/30] Apply suggestions from code review. Co-authored-by: IanCaio --- include/TrackContentObjectView.h | 2 +- src/gui/TrackContentObjectView.cpp | 49 ++++++++++++++---------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/include/TrackContentObjectView.h b/include/TrackContentObjectView.h index 411d62c922b..5f54d39f333 100644 --- a/include/TrackContentObjectView.h +++ b/include/TrackContentObjectView.h @@ -157,7 +157,6 @@ public slots: void contextMenuAction( ContextMenuAction action ); void dragEnterEvent( QDragEnterEvent * dee ) override; void dropEvent( QDropEvent * de ) override; - void leaveEvent( QEvent * e ) override; void mousePressEvent( QMouseEvent * me ) override; void mouseMoveEvent( QMouseEvent * me ) override; void mouseReleaseEvent( QMouseEvent * me ) override; @@ -236,6 +235,7 @@ protected slots: int knifeMarkerPos( QMouseEvent * me ); //! Return true iff TCO could be split. Currently only implemented for samples virtual bool splitTCO( const TimePos pos ){ return false; }; + void updateCursor(QMouseEvent * me); } ; diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index 65b4b5b4f8b..cc1b97b83cc 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -449,22 +449,32 @@ void TrackContentObjectView::dropEvent( QDropEvent * de ) -/*! \brief Handle a dragged selection leaving our 'airspace'. +/* @brief Chooses the correct cursor to be displayed on the widget * - * \param e The QEvent to watch. + * @param me The QMouseEvent that is triggering the cursor change */ -void TrackContentObjectView::leaveEvent( QEvent * e ) +void TrackContentObjectView::updateCursor(QMouseEvent * me) { - if( cursor().shape() != Qt::BitmapCursor ) + SampleTCO * sTco = dynamic_cast(m_tco); + + // If we are at the edges, use the resize cursor + if ((me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize()) + || (me->x() < RESIZE_GRIP_WIDTH && !me->buttons() && sTco && !m_tco->getAutoResize())) { - setCursor( m_cursorHand ); + setCursor(Qt::SizeHorCursor); } - if( e != NULL ) + // If we are in the middle on knife mode, use the knife cursor + else if (sTco && m_trackView->trackContainerView()->knifeMode()) { - QWidget::leaveEvent( e ); + setCursor(m_cursorKnife); } + // If we are in the middle in any other mode, use the hand cursor + else { setCursor(m_cursorHand); } } + + + /*! \brief Create a DataFile suitable for copying multiple trackContentObjects. * * trackContentObjects in the vector are written to the "tcos" node in the @@ -603,7 +613,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) gui->songEditor()->m_editor->selectAllTcos( false ); m_tco->addJournalCheckPoint(); - // move or resize + // Move, Resize, ResizeLeft and Split m_tco->setJournalling( false ); setInitialPos( me->pos() ); @@ -922,24 +932,8 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me ) } update(); } - else - { - SampleTCO * sTco = dynamic_cast( m_tco ); - - if (sTco && m_trackView->trackContainerView()->knifeMode()) - { setCursor( m_cursorKnife ); } - - - if( ( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() ) - || ( me->x() < RESIZE_GRIP_WIDTH && !me->buttons() && sTco && !m_tco->getAutoResize() ) ) - { - setCursor( Qt::SizeHorCursor ); - } - else - { - leaveEvent( NULL ); - } - } + // None of the actions above, we will just handle the cursor + else { updateCursor(me); } } @@ -970,6 +964,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) } else if( m_action == Split ) { + m_tco->setJournalling( true ); const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); const TimePos relPos = me->pos().x() * TimePos::ticksPerBar() / ppb; splitTCO(unquantizedModHeld(me) ? @@ -982,7 +977,7 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) delete m_hint; m_hint = NULL; s_textFloat->hide(); - leaveEvent( NULL ); + updateCursor(me); selectableObject::mouseReleaseEvent( me ); } From 81fc12730f057f80051ffabc2dd495099584d8bd Mon Sep 17 00:00:00 2001 From: Spekular Date: Tue, 26 Jan 2021 17:00:07 +0100 Subject: [PATCH 28/30] Don't show inaccurate/useless/empty text float in knife mode --- src/gui/TrackContentObjectView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index cc1b97b83cc..8d97282c16d 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -673,7 +673,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) // s_textFloat->reparent( this ); // setup text-float as if TCO was already moved/resized s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) ); - s_textFloat->show(); + if ( m_action != Split) { s_textFloat->show(); } } delete m_hint; From 4c604d86dc8cb3b49bdb590639b4a1aca413f333 Mon Sep 17 00:00:00 2001 From: Ian Caio Date: Thu, 11 Feb 2021 21:36:51 -0300 Subject: [PATCH 29/30] Addresses Github review - Fixes a typo where QWidget::mousePressEvent was being called inside mouseReleaseEvent. - Avoids unnecessarily disabling journalling on the Split action, since it doesn't require it. --- src/gui/TrackContentObjectView.cpp | 9 ++++++--- src/gui/widgets/TrackContentWidget.cpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/TrackContentObjectView.cpp b/src/gui/TrackContentObjectView.cpp index 8d97282c16d..49f539b72e2 100644 --- a/src/gui/TrackContentObjectView.cpp +++ b/src/gui/TrackContentObjectView.cpp @@ -613,8 +613,12 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me ) gui->songEditor()->m_editor->selectAllTcos( false ); m_tco->addJournalCheckPoint(); - // Move, Resize, ResizeLeft and Split - m_tco->setJournalling( false ); + // Move, Resize and ResizeLeft + // Split action doesn't disable TCO journalling + if (m_action == Move || m_action == Resize || m_action == ResizeLeft) + { + m_tco->setJournalling(false); + } setInitialPos( me->pos() ); setInitialOffsets(); @@ -964,7 +968,6 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me ) } else if( m_action == Split ) { - m_tco->setJournalling( true ); const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); const TimePos relPos = me->pos().x() * TimePos::ticksPerBar() / ppb; splitTCO(unquantizedModHeld(me) ? diff --git a/src/gui/widgets/TrackContentWidget.cpp b/src/gui/widgets/TrackContentWidget.cpp index b959b05c831..d7dee1a1ba1 100644 --- a/src/gui/widgets/TrackContentWidget.cpp +++ b/src/gui/widgets/TrackContentWidget.cpp @@ -584,7 +584,7 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) void TrackContentWidget::mouseReleaseEvent( QMouseEvent * me ) { gui->songEditor()->syncEditMode(); - QWidget::mousePressEvent(me); + QWidget::mouseReleaseEvent(me); } From 6fb38c49a3eddcb5f14a746c0f1d975fd2aecf6f Mon Sep 17 00:00:00 2001 From: Spekular Date: Fri, 12 Mar 2021 22:44:35 +0100 Subject: [PATCH 30/30] Revert format changes in Track * Revert format changes in Track.h * Revert formatting changes in Track.cpp --- include/Track.h | 6 +++--- src/core/Track.cpp | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/Track.h b/include/Track.h index 797d62fbf97..9ddd34f4fc6 100644 --- a/include/Track.h +++ b/include/Track.h @@ -177,7 +177,7 @@ class LMMS_EXPORT Track : public Model, public JournallingObject { return m_processingLock.tryLock(); } - + QColor color() { return m_color; @@ -186,7 +186,7 @@ class LMMS_EXPORT Track : public Model, public JournallingObject { return m_hasColor; } - + BoolModel* getMutedModel(); public slots: @@ -218,7 +218,7 @@ public slots: tcoVector m_trackContentObjects; QMutex m_processingLock; - + QColor m_color; bool m_hasColor; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 01c94e774f5..a6111c06e82 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -210,12 +210,12 @@ void Track::saveSettings( QDomDocument & doc, QDomElement & element ) { element.setAttribute( "trackheight", m_height ); } - + if( m_hasColor ) { element.setAttribute( "color", m_color.name() ); } - + QDomElement tsDe = doc.createElement( nodeName() ); // let actual track (InstrumentTrack, bbTrack, sampleTrack etc.) save // its settings @@ -671,3 +671,4 @@ BoolModel *Track::getMutedModel() { return &m_mutedModel; } +