committed by
Tres Finocchiaro
parent
68c85c8e05
commit
c765249723
@@ -149,6 +149,9 @@ public:
|
||||
/// 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();
|
||||
@@ -174,6 +177,7 @@ private:
|
||||
|
||||
MidiTime m_startPosition;
|
||||
MidiTime m_length;
|
||||
MidiTime m_startTimeOffset;
|
||||
|
||||
BoolModel m_mutedModel;
|
||||
BoolModel m_soloModel;
|
||||
@@ -281,6 +285,7 @@ private:
|
||||
Move,
|
||||
MoveSelection,
|
||||
Resize,
|
||||
ResizeLeft,
|
||||
CopySelection,
|
||||
ToggleSelected
|
||||
} ;
|
||||
|
||||
@@ -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();
|
||||
@@ -224,6 +227,22 @@ void TrackContentObject::toggleMute()
|
||||
|
||||
|
||||
|
||||
MidiTime TrackContentObject::startTimeOffset() const
|
||||
{
|
||||
return m_startTimeOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TrackContentObject::setStartTimeOffset( const MidiTime &startTimeOffset )
|
||||
{
|
||||
m_startTimeOffset = startTimeOffset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -698,20 +717,10 @@ 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() )
|
||||
{
|
||||
@@ -719,31 +728,22 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
|
||||
}
|
||||
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() )
|
||||
{
|
||||
@@ -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 )
|
||||
{
|
||||
@@ -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 )
|
||||
{
|
||||
t = qMax<int>( MidiTime::ticksPerTact(), t.toNearestTact() );
|
||||
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
|
||||
{
|
||||
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() %
|
||||
@@ -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() !=
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
@@ -183,11 +184,17 @@ void SampleTCO::updateTrackTcos()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool SampleTCO::isPlaying() const
|
||||
{
|
||||
return m_isPlaying;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCO::setIsPlaying(bool isPlaying)
|
||||
{
|
||||
m_isPlaying = isPlaying;
|
||||
@@ -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;
|
||||
@@ -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() );
|
||||
}
|
||||
|
||||
|
||||
@@ -369,6 +378,8 @@ void SampleTCOView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTCOView::dropEvent( QDropEvent * _de )
|
||||
{
|
||||
if( StringPairDrag::decodeKey( _de ) == "samplefile" )
|
||||
@@ -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() );
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user