- splitted track_container.h into track_container.h and track_container_view.h

- splitted bb_editor.h into bb_track_container.h and bb_editor.h
- moved view-component-implementations of trackContainer and bbTrackContainer to src/gui/
- added dummyInstrumentTrack-implementation



git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@829 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2008-04-01 20:27:39 +00:00
parent c36e408f2b
commit 9ba283ee94
20 changed files with 1070 additions and 937 deletions

View File

@@ -61,7 +61,7 @@
#include "tool_button.h"
#include "text_float.h"
#include "combobox.h"
#include "bb_editor.h"
#include "bb_track_container.h"
#include "piano_roll.h"
#include "debug.h"

View File

@@ -0,0 +1,268 @@
/*
* bb_track_container.cpp - model-component of BB-Editor
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "bb_track_container.h"
#include "bb_track.h"
#include "combobox.h"
#include "engine.h"
#include "song.h"
bbTrackContainer::bbTrackContainer( void ) :
trackContainer(),
m_bbComboBoxModel( this )
{
connect( &m_bbComboBoxModel, SIGNAL( dataChanged() ),
this, SLOT( currentBBChanged() ),
Qt::QueuedConnection );
// we *always* want to receive updates even in case BB actually did
// not change upon setCurrentBB()-call
connect( &m_bbComboBoxModel, SIGNAL( dataUnchanged() ),
this, SLOT( currentBBChanged() ),
Qt::QueuedConnection );
}
bbTrackContainer::~bbTrackContainer()
{
}
bool bbTrackContainer::play( midiTime _start, fpp_t _frames,
f_cnt_t _offset,
Sint16 _tco_num )
{
bool played_a_note = FALSE;
if( lengthOfBB( _tco_num ) <= 0 )
{
return( played_a_note );
}
_start = ( _start.getTact() % lengthOfBB( _tco_num ) ) * 64 +
_start.getTact64th();
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
if( tl[i]->play( _start, _frames, _offset, _tco_num ) == TRUE )
{
played_a_note = TRUE;
}
}
return( played_a_note );
}
void bbTrackContainer::updateAfterTrackAdd( void )
{
// make sure, new track(s) have TCOs for every beat/bassline
for( int i = 0; i < tMax<int>( 1, numOfBBs() ); ++i )
{
createTCOsForBB( i );
}
}
tact bbTrackContainer::lengthOfBB( int _bb )
{
midiTime max_length;
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
trackContentObject * tco = tl[i]->getTCO( _bb );
max_length = tMax( max_length, tco->length() );
}
if( max_length.getTact64th() == 0 )
{
return( max_length.getTact() );
}
return( max_length.getTact() + 1 );
}
int bbTrackContainer::numOfBBs( void ) const
{
return( engine::getSong()->countTracks( track::BBTrack ) );
}
void bbTrackContainer::removeBB( int _bb )
{
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
delete tl[i]->getTCO( _bb );
tl[i]->removeTact( _bb * 64 );
}
if( _bb <= currentBB() )
{
setCurrentBB( tMax( currentBB() - 1, 0 ) );
}
}
void bbTrackContainer::swapBB( int _bb1, int _bb2 )
{
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
tl[i]->swapPositionOfTCOs( _bb1, _bb2 );
}
updateComboBox();
}
void bbTrackContainer::updateBBTrack( trackContentObject * _tco )
{
bbTrack * t = bbTrack::findBBTrack( _tco->startPosition() / 64 );
if( t != NULL )
{
t->dataChanged();
//t->getTrackContentWidget()->update();
}
}
void bbTrackContainer::play( void )
{
if( engine::getSong()->playing() )
{
if( engine::getSong()->playMode() != song::Mode_PlayBB )
{
engine::getSong()->stop();
engine::getSong()->playBB();
}
else
{
engine::getSong()->pause();
}
}
else if( engine::getSong()->paused() )
{
engine::getSong()->resumeFromPause();
}
else
{
engine::getSong()->playBB();
}
}
void bbTrackContainer::stop( void )
{
engine::getSong()->stop();
}
void bbTrackContainer::updateComboBox( void )
{
const int cur_bb = currentBB();
m_bbComboBoxModel.clear();
for( int i = 0; i < numOfBBs(); ++i )
{
bbTrack * bbt = bbTrack::findBBTrack( i );
m_bbComboBoxModel.addItem( bbt->name(),
bbt->pixmap() ? new QPixmap( *bbt->pixmap() )
: NULL );
}
setCurrentBB( cur_bb );
}
void bbTrackContainer::currentBBChanged( void )
{
// first make sure, all channels have a TCO at current BB
createTCOsForBB( currentBB() );
// now update all track-labels (the current one has to become white,
// the others green)
for( int i = 0; i < numOfBBs(); ++i )
{
bbTrack::findBBTrack( i )->dataChanged();
//trackLabel()->update();
}
//emit dataChanged();
//emit positionChanged( NULL );
}
void bbTrackContainer::createTCOsForBB( int _bb )
{
if( numOfBBs() == 0 || engine::getSong()->isLoadingProject() )
{
return;
}
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
while( tl[i]->numOfTCOs() < _bb + 1 )
{
midiTime position = midiTime( tl[i]->numOfTCOs(), 0 );
trackContentObject * tco = tl[i]->addTCO(
tl[i]->createTCO( position ) );
tco->movePosition( position );
tco->changeLength( midiTime( 1, 0 ) );
}
}
}
#include "bb_track_container.moc"

View File

@@ -28,6 +28,7 @@
#include "engine.h"
#include "automation_editor.h"
#include "bb_editor.h"
#include "bb_track_container.h"
#include "config_mgr.h"
#include "fx_mixer.h"
#include "ladspa_2_lmms.h"

View File

@@ -1,5 +1,3 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* file_browser.cpp - implementation of the project-, preset- and
* sample-file-browser
@@ -26,17 +24,14 @@
*/
#include "file_browser.h"
#include <QtGui/QKeyEvent>
#include <QtGui/QMenu>
#include <QtGui/QPushButton>
#include <QtGui/QMdiArea>
#include <QtGui/QMdiSubWindow>
#include "bb_editor.h"
#include "file_browser.h"
#include "bb_track_container.h"
#include "config_mgr.h"
#include "debug.h"
#include "embed.h"
@@ -934,5 +929,3 @@ QString fileItem::extension( const QString & _file )
#include "file_browser.moc"
#endif

View File

@@ -61,16 +61,9 @@ public:
{
}
// implement pure-virtual functions...
virtual inline bool fixedTCOs( void ) const
virtual QString nodeName( void ) const
{
return( TRUE );
}
virtual inline QString nodeName( void ) const
{
return( "previewtc" );
return( "bbtrackcontainer" );
}
instrumentTrack * previewInstrumentTrack( void )

View File

@@ -46,6 +46,7 @@
#include "automation_editor.h"
#include "bb_editor.h"
#include "bb_track.h"
#include "bb_track_container.h"
#include "config_mgr.h"
#include "embed.h"
#include "envelope_and_lfo_parameters.h"

View File

@@ -42,6 +42,7 @@
#include "automatable_model_templates.h"
#include "bb_editor.h"
#include "bb_track.h"
#include "bb_track_container.h"
#include "clipboard.h"
#include "embed.h"
#include "engine.h"

View File

@@ -1,5 +1,3 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* track_container.cpp - implementation of base-class for all track-containers
* like Song-Editor, BB-Editor...
@@ -30,28 +28,11 @@
#include <QtGui/QApplication>
#include <QtGui/QMdiArea>
#include <QtGui/QProgressDialog>
#include <QtGui/QScrollBar>
#include <QtGui/QWheelEvent>
#include "bb_track.h"
#include "config_mgr.h"
#include "debug.h"
#include "engine.h"
#include "file_browser.h"
#include "import_filter.h"
#include "instrument.h"
#include "instrument_track.h"
#include "main_window.h"
#include "mixer.h"
#include "mmp.h"
#include "project_journal.h"
#include "rubberband.h"
#include "song.h"
#include "string_pair_drag.h"
#include "track.h"
trackContainer::trackContainer( void ) :
@@ -222,435 +203,5 @@ void trackContainer::setMutedOfAllTracks( bool _muted )
trackContainerView::trackContainerView( trackContainer * _tc ) :
QWidget(),
modelView( NULL ),
m_currentPosition( 0, 0 ),
m_tc( _tc ),
m_trackViews(),
m_scrollArea( new scrollArea( this ) ),
m_ppt( DEFAULT_PIXELS_PER_TACT ),
m_rubberBand( new rubberBand( m_scrollArea ) ),
m_origin()
{
QVBoxLayout * layout = new QVBoxLayout( this );
layout->setMargin( 0 );
layout->setSpacing( 0 );
layout->addWidget( m_scrollArea );
QWidget * scrollContent = new QWidget;
m_scrollLayout = new QVBoxLayout( scrollContent );
m_scrollLayout->setMargin( 0 );
m_scrollLayout->setSpacing( 0 );
m_scrollLayout->setSizeConstraint( QLayout::SetMinimumSize );
m_scrollArea->setWidget( scrollContent );
m_scrollArea->show();
m_rubberBand->hide();
setAcceptDrops( TRUE );
connect( m_tc, SIGNAL( trackAdded( track * ) ),
this, SLOT( createTrackView( track * ) ),
Qt::QueuedConnection );
}
trackContainerView::~trackContainerView()
{
while( !m_trackViews.empty() )
{
delete m_trackViews.takeLast();
}
}
trackView * trackContainerView::addTrackView( trackView * _tv )
{
QMap<QString, QVariant> map;
map["id"] = _tv->getTrack()->id();
addJournalEntry( journalEntry( AddTrack, map ) );
m_trackViews.push_back( _tv );
m_scrollLayout->addWidget( _tv );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
_tv->getTrackContentWidget(),
SLOT( changePosition( const midiTime & ) ) );
realignTracks();
return( _tv );
}
void trackContainerView::removeTrackView( trackView * _tv )
{
int index = m_trackViews.indexOf( _tv );
if( index != -1 )
{
QMap<QString, QVariant> map;
multimediaProject mmp( multimediaProject::JournalData );
_tv->getTrack()->saveState( mmp, mmp.content() );
map["id"] = _tv->getTrack()->id();
map["state"] = mmp.toString();
addJournalEntry( journalEntry( RemoveTrack, map ) );
m_trackViews.removeAt( index );
disconnect( _tv );
m_scrollLayout->removeWidget( _tv );
realignTracks();
if( engine::getSong() )
{
engine::getSong()->setModified();
}
}
}
void trackContainerView::moveTrackViewUp( trackView * _tv )
{
for( int i = 1; i < m_trackViews.size(); ++i )
{
trackView * t = m_trackViews[i];
if( t == _tv )
{
bbTrack::swapBBTracks( t->getTrack(),
m_trackViews[i - 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i - 1, t );
m_tc->m_tracks.swap( i - 1, i );
m_trackViews.swap( i - 1, i );
realignTracks();
break;
}
}
}
void trackContainerView::moveTrackViewDown( trackView * _tv )
{
for( int i = 0; i < m_trackViews.size()-1; ++i )
{
trackView * t = m_trackViews[i];
if( t == _tv )
{
bbTrack::swapBBTracks( t->getTrack(),
m_trackViews[i + 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i + 1, t );
m_tc->m_tracks.swap( i, i + 1 );
m_trackViews.swap( i, i + 1 );
realignTracks();
break;
}
}
}
void trackContainerView::realignTracks( void )
{
QWidget * content = m_scrollArea->widget();
content->setFixedWidth( width()
- m_scrollArea->verticalScrollBar()->width() );
content->setFixedHeight( content->minimumSizeHint().height() );
for( trackViewList::iterator it = m_trackViews.begin();
it != m_trackViews.end(); ++it )
{
( *it )->show();
( *it )->update();
}
}
void trackContainerView::createTrackView( track * _t )
{
_t->createView( this );
}
const trackView * trackContainerView::trackViewAt( const int _y ) const
{
const int abs_y = _y + m_scrollArea->viewport()->y();
int y_cnt = 0;
for( trackViewList::const_iterator it = m_trackViews.begin();
it != m_trackViews.end(); ++it )
{
const int y_cnt1 = y_cnt;
y_cnt += ( *it )->height();
if( abs_y >= y_cnt1 && abs_y < y_cnt )
{
return( *it );
}
}
return( NULL );
}
bool trackContainerView::allowRubberband( void ) const
{
return( FALSE );
}
void trackContainerView::setPixelsPerTact( int _ppt )
{
m_ppt = _ppt;
}
void trackContainerView::clearAllTracks( void )
{
while( !m_trackViews.empty() )
{
trackView * tv = m_trackViews.takeLast();
track * t = tv->getTrack();
delete tv;
delete t;
}
}
void trackContainerView::undoStep( journalEntry & _je )
{
saveJournallingState( FALSE );
switch( _je.actionID() )
{
case AddTrack:
{
QMap<QString, QVariant> map = _je.data().toMap();
track * t =
dynamic_cast<track *>(
engine::getProjectJournal()->getJournallingObject(
map["id"].toInt() ) );
assert( t != NULL );
multimediaProject mmp( multimediaProject::JournalData );
t->saveState( mmp, mmp.content() );
map["state"] = mmp.toString();
_je.data() = map;
t->deleteLater();
break;
}
case RemoveTrack:
{
multimediaProject mmp(
_je.data().toMap()["state"].toString(), FALSE );
track::create( mmp.content().firstChild().toElement(),
m_tc );
break;
}
}
restoreJournallingState();
}
void trackContainerView::redoStep( journalEntry & _je )
{
switch( _je.actionID() )
{
case AddTrack:
case RemoveTrack:
_je.actionID() = ( _je.actionID() == AddTrack ) ?
RemoveTrack : AddTrack;
undoStep( _je );
_je.actionID() = ( _je.actionID() == AddTrack ) ?
RemoveTrack : AddTrack;
break;
}
}
void trackContainerView::dragEnterEvent( QDragEnterEvent * _dee )
{
stringPairDrag::processDragEnterEvent( _dee,
QString( "presetfile,sampledata,samplefile,instrument,midifile,"
"track_%1,track_%2" ).
arg( track::InstrumentTrack ).
arg( track::SampleTrack ) );
}
void trackContainerView::dropEvent( QDropEvent * _de )
{
QString type = stringPairDrag::decodeKey( _de );
QString value = stringPairDrag::decodeValue( _de );
engine::getMixer()->lock();
if( type == "instrument" )
{
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
it->loadInstrument( value );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "sampledata" || type == "samplefile" )
{
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
QString iname = type == "sampledata" ? "audiofileprocessor" :
engine::sampleExtensions()[fileItem::extension(
value )];
instrument * i = it->loadInstrument( iname );
i->setParameter( type, value );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "presetfile" )
{
multimediaProject mmp( value );
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
it->loadTrackSpecificSettings( mmp.content().firstChild().
toElement() );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "midifile" )
{
importFilter::import( value, m_tc );
_de->accept();
}
else if( type.left( 6 ) == "track_" )
{
multimediaProject mmp( value, FALSE );
track::create( mmp.content().firstChild().toElement(), m_tc );
_de->accept();
}
engine::getMixer()->unlock();
}
void trackContainerView::mousePressEvent( QMouseEvent * _me )
{
if( allowRubberband() == TRUE )
{
m_origin = m_scrollArea->mapFromParent( _me->pos() );
m_rubberBand->setGeometry( QRect( m_origin, QSize() ) );
m_rubberBand->show();
}
QWidget::mousePressEvent( _me );
}
void trackContainerView::mouseMoveEvent( QMouseEvent * _me )
{
if( rubberBandActive() == TRUE )
{
m_rubberBand->setGeometry( QRect( m_origin,
m_scrollArea->mapFromParent( _me->pos() ) ).
normalized() );
}
QWidget::mouseMoveEvent( _me );
}
void trackContainerView::mouseReleaseEvent( QMouseEvent * _me )
{
m_rubberBand->hide();
QWidget::mouseReleaseEvent( _me );
}
void trackContainerView::resizeEvent( QResizeEvent * _re )
{
realignTracks();
QWidget::resizeEvent( _re );
}
trackContainerView::scrollArea::scrollArea( trackContainerView * _parent ) :
QScrollArea( _parent ),
m_trackContainerView( _parent )
{
setFrameStyle( QFrame::NoFrame );
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
}
trackContainerView::scrollArea::~scrollArea()
{
}
void trackContainerView::scrollArea::wheelEvent( QWheelEvent * _we )
{
// always pass wheel-event to parent-widget (song-editor
// bb-editor etc.) because they might want to use it for zooming
// or scrolling left/right if a modifier-key is pressed, otherwise
// they do not accept it and we pass it up to QScrollArea
m_trackContainerView->wheelEvent( _we );
if( !_we->isAccepted() )
{
QScrollArea::wheelEvent( _we );
}
}
#include "track_container.moc"
#endif

View File

@@ -1,5 +1,3 @@
#ifndef SINGLE_SOURCE_COMPILE
/*
* bb_editor.cpp - basic main-window for editing of beats and basslines
*
@@ -25,15 +23,12 @@
*/
#include "bb_editor.h"
#include <QtGui/QKeyEvent>
#include <QtGui/QLayout>
#include <QtGui/QMdiArea>
#include <QtGui/QPainter>
#include "bb_editor.h"
#include "bb_track_container.h"
#include "bb_track.h"
#include "combobox.h"
#include "embed.h"
@@ -44,270 +39,6 @@
#include "templates.h"
#include "tool_button.h"
#include "tooltip.h"
#include "track_container.h"
bbTrackContainer::bbTrackContainer( void ) :
trackContainer(),
m_bbComboBoxModel( this )
{
connect( &m_bbComboBoxModel, SIGNAL( dataChanged() ),
this, SLOT( currentBBChanged() ),
Qt::QueuedConnection );
// we *always* want to receive updates even in case BB actually did
// not change upon setCurrentBB()-call
connect( &m_bbComboBoxModel, SIGNAL( dataUnchanged() ),
this, SLOT( currentBBChanged() ),
Qt::QueuedConnection );
}
bbTrackContainer::~bbTrackContainer()
{
}
bool bbTrackContainer::play( midiTime _start, fpp_t _frames,
f_cnt_t _offset,
Sint16 _tco_num )
{
bool played_a_note = FALSE;
if( lengthOfBB( _tco_num ) <= 0 )
{
return( played_a_note );
}
_start = ( _start.getTact() % lengthOfBB( _tco_num ) ) * 64 +
_start.getTact64th();
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
if( tl[i]->play( _start, _frames, _offset, _tco_num ) == TRUE )
{
played_a_note = TRUE;
}
}
return( played_a_note );
}
/*
void bbTrackContainer::saveSettings( QDomDocument & _doc, QDomElement & _parent )
{
trackContainer::saveSettings( _doc, _parent );
}
void bbTrackContainer::loadSettings( const QDomElement & _this )
{
trackContainer::loadSettings( _this );
}
*/
void bbTrackContainer::updateAfterTrackAdd( void )
{
// make sure, new track(s) have TCOs for every beat/bassline
for( int i = 0; i < tMax<int>( 1, numOfBBs() ); ++i )
{
createTCOsForBB( i );
}
}
tact bbTrackContainer::lengthOfBB( int _bb )
{
midiTime max_length;
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
trackContentObject * tco = tl[i]->getTCO( _bb );
max_length = tMax( max_length, tco->length() );
}
if( max_length.getTact64th() == 0 )
{
return( max_length.getTact() );
}
return( max_length.getTact() + 1 );
}
int bbTrackContainer::numOfBBs( void ) const
{
return( engine::getSong()->countTracks( track::BBTrack ) );
}
void bbTrackContainer::removeBB( int _bb )
{
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
delete tl[i]->getTCO( _bb );
tl[i]->removeTact( _bb * 64 );
}
if( _bb <= currentBB() )
{
setCurrentBB( tMax( currentBB() - 1, 0 ) );
}
}
void bbTrackContainer::swapBB( int _bb1, int _bb2 )
{
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
tl[i]->swapPositionOfTCOs( _bb1, _bb2 );
}
updateComboBox();
}
void bbTrackContainer::updateBBTrack( trackContentObject * _tco )
{
bbTrack * t = bbTrack::findBBTrack( _tco->startPosition() / 64 );
if( t != NULL )
{
t->dataChanged();
//t->getTrackContentWidget()->update();
}
}
void bbTrackContainer::play( void )
{
if( engine::getSong()->playing() )
{
if( engine::getSong()->playMode() != song::Mode_PlayBB )
{
engine::getSong()->stop();
engine::getSong()->playBB();
}
else
{
engine::getSong()->pause();
}
}
else if( engine::getSong()->paused() )
{
engine::getSong()->resumeFromPause();
}
else
{
engine::getSong()->playBB();
}
}
void bbTrackContainer::stop( void )
{
engine::getSong()->stop();
}
void bbTrackContainer::updateComboBox( void )
{
const int cur_bb = currentBB();
m_bbComboBoxModel.clear();
for( int i = 0; i < numOfBBs(); ++i )
{
bbTrack * bbt = bbTrack::findBBTrack( i );
m_bbComboBoxModel.addItem( bbt->name(),
bbt->pixmap() ? new QPixmap( *bbt->pixmap() )
: NULL );
}
setCurrentBB( cur_bb );
}
void bbTrackContainer::currentBBChanged( void )
{
// first make sure, all channels have a TCO at current BB
createTCOsForBB( currentBB() );
// now update all track-labels (the current one has to become white,
// the others green)
for( int i = 0; i < numOfBBs(); ++i )
{
bbTrack::findBBTrack( i )->dataChanged();
//trackLabel()->update();
}
//emit dataChanged();
//emit positionChanged( NULL );
}
void bbTrackContainer::createTCOsForBB( int _bb )
{
if( numOfBBs() == 0 || engine::getSong()->isLoadingProject() )
{
return;
}
QList<track *> tl = tracks();
for( int i = 0; i < tl.size(); ++i )
{
while( tl[i]->numOfTCOs() < _bb + 1 )
{
midiTime position = midiTime( tl[i]->numOfTCOs(), 0 );
trackContentObject * tco = tl[i]->addTCO(
tl[i]->createTCO( position ) );
tco->movePosition( position );
tco->changeLength( midiTime( 1, 0 ) );
}
}
}
@@ -522,5 +253,3 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke )
#include "bb_editor.moc"
#endif

View File

@@ -0,0 +1,473 @@
/*
* track_container_view.cpp - view-component for trackContainer
*
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "track_container_view.h"
#include "track_container.h"
#include <QtGui/QApplication>
#include <QtGui/QMdiArea>
#include <QtGui/QProgressDialog>
#include <QtGui/QScrollBar>
#include <QtGui/QWheelEvent>
#include "bb_track.h"
#include "config_mgr.h"
#include "debug.h"
#include "file_browser.h"
#include "import_filter.h"
#include "instrument.h"
#include "instrument_track.h"
#include "mmp.h"
#include "project_journal.h"
#include "rubberband.h"
#include "song.h"
#include "string_pair_drag.h"
#include "track.h"
trackContainerView::trackContainerView( trackContainer * _tc ) :
QWidget(),
modelView( NULL ),
m_currentPosition( 0, 0 ),
m_tc( _tc ),
m_trackViews(),
m_scrollArea( new scrollArea( this ) ),
m_ppt( DEFAULT_PIXELS_PER_TACT ),
m_rubberBand( new rubberBand( m_scrollArea ) ),
m_origin()
{
QVBoxLayout * layout = new QVBoxLayout( this );
layout->setMargin( 0 );
layout->setSpacing( 0 );
layout->addWidget( m_scrollArea );
QWidget * scrollContent = new QWidget;
m_scrollLayout = new QVBoxLayout( scrollContent );
m_scrollLayout->setMargin( 0 );
m_scrollLayout->setSpacing( 0 );
m_scrollLayout->setSizeConstraint( QLayout::SetMinimumSize );
m_scrollArea->setWidget( scrollContent );
m_scrollArea->show();
m_rubberBand->hide();
setAcceptDrops( TRUE );
connect( m_tc, SIGNAL( trackAdded( track * ) ),
this, SLOT( createTrackView( track * ) ),
Qt::QueuedConnection );
}
trackContainerView::~trackContainerView()
{
while( !m_trackViews.empty() )
{
delete m_trackViews.takeLast();
}
}
trackView * trackContainerView::addTrackView( trackView * _tv )
{
QMap<QString, QVariant> map;
map["id"] = _tv->getTrack()->id();
addJournalEntry( journalEntry( AddTrack, map ) );
m_trackViews.push_back( _tv );
m_scrollLayout->addWidget( _tv );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
_tv->getTrackContentWidget(),
SLOT( changePosition( const midiTime & ) ) );
realignTracks();
return( _tv );
}
void trackContainerView::removeTrackView( trackView * _tv )
{
int index = m_trackViews.indexOf( _tv );
if( index != -1 )
{
QMap<QString, QVariant> map;
multimediaProject mmp( multimediaProject::JournalData );
_tv->getTrack()->saveState( mmp, mmp.content() );
map["id"] = _tv->getTrack()->id();
map["state"] = mmp.toString();
addJournalEntry( journalEntry( RemoveTrack, map ) );
m_trackViews.removeAt( index );
disconnect( _tv );
m_scrollLayout->removeWidget( _tv );
realignTracks();
if( engine::getSong() )
{
engine::getSong()->setModified();
}
}
}
void trackContainerView::moveTrackViewUp( trackView * _tv )
{
for( int i = 1; i < m_trackViews.size(); ++i )
{
trackView * t = m_trackViews[i];
if( t == _tv )
{
bbTrack::swapBBTracks( t->getTrack(),
m_trackViews[i - 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i - 1, t );
m_tc->m_tracks.swap( i - 1, i );
m_trackViews.swap( i - 1, i );
realignTracks();
break;
}
}
}
void trackContainerView::moveTrackViewDown( trackView * _tv )
{
for( int i = 0; i < m_trackViews.size()-1; ++i )
{
trackView * t = m_trackViews[i];
if( t == _tv )
{
bbTrack::swapBBTracks( t->getTrack(),
m_trackViews[i + 1]->getTrack() );
m_scrollLayout->removeWidget( t );
m_scrollLayout->insertWidget( i + 1, t );
m_tc->m_tracks.swap( i, i + 1 );
m_trackViews.swap( i, i + 1 );
realignTracks();
break;
}
}
}
void trackContainerView::realignTracks( void )
{
QWidget * content = m_scrollArea->widget();
content->setFixedWidth( width()
- m_scrollArea->verticalScrollBar()->width() );
content->setFixedHeight( content->minimumSizeHint().height() );
for( trackViewList::iterator it = m_trackViews.begin();
it != m_trackViews.end(); ++it )
{
( *it )->show();
( *it )->update();
}
}
void trackContainerView::createTrackView( track * _t )
{
_t->createView( this );
}
const trackView * trackContainerView::trackViewAt( const int _y ) const
{
const int abs_y = _y + m_scrollArea->viewport()->y();
int y_cnt = 0;
for( trackViewList::const_iterator it = m_trackViews.begin();
it != m_trackViews.end(); ++it )
{
const int y_cnt1 = y_cnt;
y_cnt += ( *it )->height();
if( abs_y >= y_cnt1 && abs_y < y_cnt )
{
return( *it );
}
}
return( NULL );
}
bool trackContainerView::allowRubberband( void ) const
{
return( FALSE );
}
void trackContainerView::setPixelsPerTact( int _ppt )
{
m_ppt = _ppt;
}
void trackContainerView::clearAllTracks( void )
{
while( !m_trackViews.empty() )
{
trackView * tv = m_trackViews.takeLast();
track * t = tv->getTrack();
delete tv;
delete t;
}
}
void trackContainerView::undoStep( journalEntry & _je )
{
saveJournallingState( FALSE );
switch( _je.actionID() )
{
case AddTrack:
{
QMap<QString, QVariant> map = _je.data().toMap();
track * t =
dynamic_cast<track *>(
engine::getProjectJournal()->getJournallingObject(
map["id"].toInt() ) );
assert( t != NULL );
multimediaProject mmp( multimediaProject::JournalData );
t->saveState( mmp, mmp.content() );
map["state"] = mmp.toString();
_je.data() = map;
t->deleteLater();
break;
}
case RemoveTrack:
{
multimediaProject mmp(
_je.data().toMap()["state"].toString(), FALSE );
track::create( mmp.content().firstChild().toElement(),
m_tc );
break;
}
}
restoreJournallingState();
}
void trackContainerView::redoStep( journalEntry & _je )
{
switch( _je.actionID() )
{
case AddTrack:
case RemoveTrack:
_je.actionID() = ( _je.actionID() == AddTrack ) ?
RemoveTrack : AddTrack;
undoStep( _je );
_je.actionID() = ( _je.actionID() == AddTrack ) ?
RemoveTrack : AddTrack;
break;
}
}
void trackContainerView::dragEnterEvent( QDragEnterEvent * _dee )
{
stringPairDrag::processDragEnterEvent( _dee,
QString( "presetfile,sampledata,samplefile,instrument,midifile,"
"track_%1,track_%2" ).
arg( track::InstrumentTrack ).
arg( track::SampleTrack ) );
}
void trackContainerView::dropEvent( QDropEvent * _de )
{
QString type = stringPairDrag::decodeKey( _de );
QString value = stringPairDrag::decodeValue( _de );
engine::getMixer()->lock();
if( type == "instrument" )
{
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
it->loadInstrument( value );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "sampledata" || type == "samplefile" )
{
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
QString iname = type == "sampledata" ? "audiofileprocessor" :
engine::sampleExtensions()[fileItem::extension(
value )];
instrument * i = it->loadInstrument( iname );
i->setParameter( type, value );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "presetfile" )
{
multimediaProject mmp( value );
instrumentTrack * it = dynamic_cast<instrumentTrack *>(
track::create( track::InstrumentTrack,
m_tc ) );
it->loadTrackSpecificSettings( mmp.content().firstChild().
toElement() );
//it->toggledInstrumentTrackButton( TRUE );
_de->accept();
}
else if( type == "midifile" )
{
importFilter::import( value, m_tc );
_de->accept();
}
else if( type.left( 6 ) == "track_" )
{
multimediaProject mmp( value, FALSE );
track::create( mmp.content().firstChild().toElement(), m_tc );
_de->accept();
}
engine::getMixer()->unlock();
}
void trackContainerView::mousePressEvent( QMouseEvent * _me )
{
if( allowRubberband() == TRUE )
{
m_origin = m_scrollArea->mapFromParent( _me->pos() );
m_rubberBand->setGeometry( QRect( m_origin, QSize() ) );
m_rubberBand->show();
}
QWidget::mousePressEvent( _me );
}
void trackContainerView::mouseMoveEvent( QMouseEvent * _me )
{
if( rubberBandActive() == TRUE )
{
m_rubberBand->setGeometry( QRect( m_origin,
m_scrollArea->mapFromParent( _me->pos() ) ).
normalized() );
}
QWidget::mouseMoveEvent( _me );
}
void trackContainerView::mouseReleaseEvent( QMouseEvent * _me )
{
m_rubberBand->hide();
QWidget::mouseReleaseEvent( _me );
}
void trackContainerView::resizeEvent( QResizeEvent * _re )
{
realignTracks();
QWidget::resizeEvent( _re );
}
trackContainerView::scrollArea::scrollArea( trackContainerView * _parent ) :
QScrollArea( _parent ),
m_trackContainerView( _parent )
{
setFrameStyle( QFrame::NoFrame );
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
}
trackContainerView::scrollArea::~scrollArea()
{
}
void trackContainerView::scrollArea::wheelEvent( QWheelEvent * _we )
{
// always pass wheel-event to parent-widget (song-editor
// bb-editor etc.) because they might want to use it for zooming
// or scrolling left/right if a modifier-key is pressed, otherwise
// they do not accept it and we pass it up to QScrollArea
m_trackContainerView->wheelEvent( _we );
if( !_we->isAccepted() )
{
QScrollArea::wheelEvent( _we );
}
}
#include "track_container_view.moc"

View File

@@ -31,8 +31,9 @@
#include <QtGui/QPainter>
#include "bb_track.h"
#include "bb_editor.h"
#include "bb_track.h"
#include "bb_track_container.h"
#include "embed.h"
#include "engine.h"
#include "gui_templates.h"

View File

@@ -49,7 +49,7 @@
#include "audio_sample_recorder.h"
#include "song.h"
#include "tooltip.h"
#include "bb_editor.h"
#include "bb_track_container.h"
#include "string_pair_drag.h"
#include "main_window.h"