Skip to content

Commit

Permalink
Sampletrack - resize from left (#3487)
Browse files Browse the repository at this point in the history
Sampletrack - resize from left
  • Loading branch information
BaraMGB authored and tresf committed Nov 1, 2017
1 parent 68c85c8 commit c765249
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 57 deletions.
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
139 changes: 87 additions & 52 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;
}
}
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,23 +752,26 @@ 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 )
{
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 @@ -608,10 +620,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() )
{
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

0 comments on commit c765249

Please sign in to comment.