Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sampletrack - resize from left #3487

Merged
merged 13 commits into from
Nov 1, 2017
5 changes: 5 additions & 0 deletions include/Track.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ class TrackContentObject : public Model, public JournallingObject
/// Returns true if and only if a->startPosition() < b->startPosition()
static bool comparePosition(const TrackContentObject* a, const TrackContentObject* b);

MidiTime startTimeOffset() const;
void setStartTimeOffset( const MidiTime &startTimeOffset );

public slots:
void copy();
void paste();
Expand All @@ -174,6 +177,7 @@ public slots:

MidiTime m_startPosition;
MidiTime m_length;
MidiTime m_startTimeOffset;

BoolModel m_mutedModel;
BoolModel m_soloModel;
Expand Down Expand Up @@ -281,6 +285,7 @@ protected slots:
Move,
MoveSelection,
Resize,
ResizeLeft,
CopySelection,
ToggleSelected
} ;
Expand Down
143 changes: 89 additions & 54 deletions src/core/Track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ void TrackContentObject::changeLength( const MidiTime & length )
emit lengthChanged();
}




bool TrackContentObject::comparePosition(const TrackContentObject *a, const TrackContentObject *b)
{
return a->startPosition() < b->startPosition();
Expand Down Expand Up @@ -224,6 +227,22 @@ void TrackContentObject::toggleMute()



MidiTime TrackContentObject::startTimeOffset() const
{
return m_startTimeOffset;
}




void TrackContentObject::setStartTimeOffset( const MidiTime &startTimeOffset )
{
m_startTimeOffset = startTimeOffset;
}







Expand Down Expand Up @@ -698,52 +717,33 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
}
else
{
gui->songEditor()->m_editor->selectAllTcos( false );
QVector<TrackContentObjectView *> tcoViews;
tcoViews.push_back( this );
DataFile dataFile = createTCODataFiles( tcoViews );
QPixmap thumbnail = QPixmap::grabWidget( this ).scaled(
128, 128,
Qt::KeepAspectRatio,
Qt::SmoothTransformation );
new StringPairDrag( QString( "tco_%1" ).arg(
m_tco->getTrack()->type() ),
dataFile.toString(), thumbnail, this );
m_action = ToggleSelected;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BaraMGB I guess something went wrong when you sync with master branch.
See https://github.com/LMMS/lmms/pull/3649/files#diff-cb2a453c979a4777b9330e2b96644f0eR701.

}
}
else
else if( !me->modifiers() )
{
if( isSelected() )
{
m_action = MoveSelection;
}
else
{
gui->songEditor()->m_editor->selectAllTcos( false );
m_tco->addJournalCheckPoint();

// move or resize
m_tco->setJournalling( false );

setInitialMousePos( me->pos() );

if( me->x() < width() - RESIZE_GRIP_WIDTH )
SampleTCO * sTco = dynamic_cast<SampleTCO*>( m_tco );
if( me->x() < RESIZE_GRIP_WIDTH && sTco )
{
m_action = ResizeLeft;
m_oldTime = m_tco->startPosition();
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
s_textFloat->setTitle( tr( "Current length" ) );
}
else if( me->x() < width() - RESIZE_GRIP_WIDTH )
{
m_action = Move;
m_oldTime = m_tco->startPosition();
QCursor c( Qt::SizeAllCursor );
QApplication::setOverrideCursor( c );
s_textFloat->setTitle( tr( "Current position" ) );
delete m_hint;
m_hint = TextFloat::displayMessage( tr( "Hint" ),
tr( "Press <%1> and drag to make "
"a copy." ).arg(
#ifdef LMMS_BUILD_APPLE
"⌘"),
#else
"Ctrl"),
#endif
embed::getIconPixmap( "hint" ), 0 );
}
else if( !m_tco->getAutoResize() )
{
Expand All @@ -752,31 +752,34 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
QCursor c( Qt::SizeHorCursor );
QApplication::setOverrideCursor( c );
s_textFloat->setTitle( tr( "Current length" ) );
delete m_hint;
m_hint = TextFloat::displayMessage( tr( "Hint" ),
tr( "Press <%1> for free "
"resizing." ).arg(
#ifdef LMMS_BUILD_APPLE
"⌘"),
#else
"Ctrl"),
#endif
embed::getIconPixmap( "hint" ), 0 );
}
// s_textFloat->reparent( this );
// setup text-float as if TCO was already moved/resized
mouseMoveEvent( me );
s_textFloat->show();
}
}
delete m_hint;
QString hint = m_action == Move ? tr( "Press <%1> and drag to make "
"a copy." )
: tr( "Press <%1> for free "
"resizing." );
m_hint = TextFloat::displayMessage( tr( "Hint" ),
hint.arg(
#ifdef LMMS_BUILD_APPLE
"⌘"),
#else
"Ctrl"),
#endif
embed::getIconPixmap( "hint" ), 0 );
// s_textFloat->reparent( this );
// setup text-float as if TCO was already moved/resized
mouseMoveEvent( me );
s_textFloat->show();
}
else if( me->button() == Qt::RightButton )
{
if( me->modifiers() & Qt::ControlModifier )
{
m_tco->toggleMute();
}
else if( me->modifiers() & Qt::ShiftModifier && fixedTCOs() == false )
else if( me->modifiers() & Qt::ShiftModifier && !fixedTCOs() )
{
remove();
}
Expand All @@ -787,7 +790,7 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
{
m_tco->toggleMute();
}
else if( fixedTCOs() == false )
else if( !fixedTCOs() )
{
remove();
}
Expand Down Expand Up @@ -916,14 +919,43 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me )
( *it )->movePosition( t );
}
}
else if( m_action == Resize )
else if( m_action == Resize || m_action == ResizeLeft )
{
MidiTime t = qMax( MidiTime::ticksPerTact() / 16, static_cast<int>( me->x() * MidiTime::ticksPerTact() / ppt ) );
if( ! ( me->modifiers() & Qt::ControlModifier ) && me->button() == Qt::NoButton )
if( m_action == Resize )
{
MidiTime t = qMax( MidiTime::ticksPerTact() / 16, static_cast<int>( me->x() * MidiTime::ticksPerTact() / ppt ) );
if( ! ( me->modifiers() & Qt::ControlModifier ) && me->button() == Qt::NoButton )
{
t = qMax<int>( MidiTime::ticksPerTact(), t.toNearestTact() );
}
m_tco->changeLength( t );
}
else
{
t = qMax<int>( MidiTime::ticksPerTact(), t.toNearestTact() );
SampleTCO * sTco = dynamic_cast<SampleTCO*>( m_tco );
if( sTco )
{
const int x = mapToParent( me->pos() ).x() - m_initialMousePos.x();

MidiTime t = qMax( 0, (int)
m_trackView->trackContainerView()->currentPosition()+
static_cast<int>( x * MidiTime::ticksPerTact() /
ppt ) );
if( ! ( me->modifiers() & Qt::ControlModifier )
&& me->button() == Qt::NoButton )
{
t = t.toNearestTact();
}
MidiTime oldPos = m_tco->startPosition();
if( m_tco->length() + ( oldPos - t ) >= MidiTime::ticksPerTact() )
{
m_tco->movePosition( t );
m_trackView->getTrackContentWidget()->changePosition();
m_tco->changeLength( m_tco->length() + ( oldPos - t ) );
sTco->setStartTimeOffset( sTco->startTimeOffset() + ( oldPos - t ) );
}
}
}
m_tco->changeLength( t );
s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ).
arg( m_tco->length().getTact() ).
arg( m_tco->length().getTicks() %
Expand All @@ -939,7 +971,9 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me )
}
else
{
if( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() )
SampleTCO * sTco = dynamic_cast<SampleTCO*>( m_tco );
if( ( me->x() > width() - RESIZE_GRIP_WIDTH && !me->buttons() && !m_tco->getAutoResize() )
|| ( me->x() < RESIZE_GRIP_WIDTH && !me->buttons() && sTco ) )
{
if( QApplication::overrideCursor() != NULL &&
QApplication::overrideCursor()->shape() !=
Expand Down Expand Up @@ -982,8 +1016,9 @@ void TrackContentObjectView::mouseReleaseEvent( QMouseEvent * me )
setSelected( !isSelected() );
}

if( m_action == Move || m_action == Resize )
if( m_action == Move || m_action == Resize || m_action == ResizeLeft )
{
// TODO: Fix m_tco->setJournalling() consistency
m_tco->setJournalling( true );
}
m_action = NoAction;
Expand Down
22 changes: 17 additions & 5 deletions src/tracks/SampleTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ void SampleTCO::setSampleBuffer( SampleBuffer* sb )
void SampleTCO::setSampleFile( const QString & _sf )
{
m_sampleBuffer->setAudioFile( _sf );
setStartTimeOffset( 0 );
changeLength( (int) ( m_sampleBuffer->frames() / Engine::framesPerTick() ) );

emit sampleChanged();
Expand Down Expand Up @@ -183,11 +184,17 @@ void SampleTCO::updateTrackTcos()
}
}




bool SampleTCO::isPlaying() const
{
return m_isPlaying;
}




void SampleTCO::setIsPlaying(bool isPlaying)
{
m_isPlaying = isPlaying;
Expand Down Expand Up @@ -241,6 +248,7 @@ void SampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _this )
_this.setAttribute( "len", length() );
_this.setAttribute( "muted", isMuted() );
_this.setAttribute( "src", sampleFile() );
_this.setAttribute( "off", startTimeOffset() );
if( sampleFile() == "" )
{
QString s;
Expand All @@ -265,6 +273,7 @@ void SampleTCO::loadSettings( const QDomElement & _this )
}
changeLength( _this.attribute( "len" ).toInt() );
setMuted( _this.attribute( "muted" ).toInt() );
setStartTimeOffset( _this.attribute( "off" ).toInt() );
}


Expand Down Expand Up @@ -369,6 +378,8 @@ void SampleTCOView::dragEnterEvent( QDragEnterEvent * _dee )





void SampleTCOView::dropEvent( QDropEvent * _de )
{
if( StringPairDrag::decodeKey( _de ) == "samplefile" )
Expand Down Expand Up @@ -501,8 +512,9 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
float nom = Engine::getSong()->getTimeSigModel().getNumerator();
float den = Engine::getSong()->getTimeSigModel().getDenominator();
float ticksPerTact = DefaultTicksPerTact * nom / den;

QRect r = QRect( TCO_BORDER_WIDTH, spacing,

float offset = m_tco->startTimeOffset() / ticksPerTact * pixelsPerTact();
QRect r = QRect( TCO_BORDER_WIDTH + offset, spacing,
qMax( static_cast<int>( m_tco->sampleLength() * ppt / ticksPerTact ), 1 ), rect().bottom() - 2 * spacing );
m_tco->m_sampleBuffer->visualize( p, r, pe->rect() );

Expand Down Expand Up @@ -605,10 +617,10 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames,
float framesPerTick = Engine::framesPerTick();
if( _start >= sTco->startPosition() && _start < sTco->endPosition() )
{
if( sTco->isPlaying() == false )
if( sTco->isPlaying() == false && _start > sTco->startPosition() + sTco->startTimeOffset() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should refactor the offset information because playing is more important than GUI events.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain, what is in your mind? @jasp00

{
f_cnt_t sampleStart = framesPerTick * ( _start - sTco->startPosition() );
f_cnt_t tcoFrameLength = framesPerTick * ( sTco->endPosition() - sTco->startPosition() );
f_cnt_t sampleStart = framesPerTick * ( _start - sTco->startPosition() - sTco->startTimeOffset() );
f_cnt_t tcoFrameLength = framesPerTick * ( sTco->endPosition() - sTco->startPosition() - sTco->startTimeOffset() );
f_cnt_t sampleBufferLength = sTco->sampleBuffer()->frames();
//if the Tco smaller than the sample length we play only until Tco end
//else we play the sample to the end but nothing more
Expand Down