diff --git a/ChangeLog b/ChangeLog index e3d6aad96..b577d87f0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-02-01 Andrew Kelley + + * include/piano_roll.h: + * include/song_editor.h: + * include/main_window.h: + * src/gui/piano_roll.cpp: + * src/gui/main_window.cpp: + * src/gui/song_editor.cpp: + * src/gui/bb_editor.cpp: + * TODO: + Added global playback support. Press space to play/pause from any + window in LMMS. + 2009-02-01 Andrew Kelley * src/core/track.cpp: diff --git a/TODO b/TODO index 707e3e466..d328c38d0 100644 --- a/TODO +++ b/TODO @@ -52,15 +52,17 @@ - add FLAC as export-format? Andrew Kelley's todo: +- pencil tool icon doesn't set right. selection arrow cursor doesn't set right +- bug: you can use shift+left to move notes past the beginning - add a Modulator class and a Humanizer tool to the piano roll - global playback buttons, like in FL Studio - when you add VSTi, have it automatically pop the find VST plugin dialog -- bug: you can use shift+left to move notes past the beginning - make pitch bend range adjustable - monophonic mode on 3xosc -- integrate pitanga's patch - add dithering - +- add global playback mode to .mmp file format +- when a song goes past the end of the song, make it stop or loop +- allow increasing the width of song editor things, it will make the BB repeat - when looking at a piano roll, if the song is playing that pattern, move the position ticker to where it should be - multiview button - show notes from every instrument in the current beat+bassline with different colors - undo/redo for piano roll diff --git a/include/main_window.h b/include/main_window.h index 160346509..73c869276 100644 --- a/include/main_window.h +++ b/include/main_window.h @@ -36,6 +36,8 @@ class QDomElement; class QGridLayout; class QHBoxLayout; class QMdiArea; +class QCheckBox; +class QRadioButton; class lcdSpinBox; class meterDialog; @@ -46,7 +48,12 @@ class configManager; class pluginView; class toolButton; - +enum ProjectPlaybackMode +{ + PPM_Song = 0, + PPM_BB = 1, + PPM_PianoRoll +}; class mainWindow : public QMainWindow { @@ -92,6 +99,13 @@ public: static void saveWidgetState( QWidget * _w, QDomElement & _de ); static void restoreWidgetState( QWidget * _w, const QDomElement & _de ); + inline ProjectPlaybackMode playbackMode() const + { + return m_playbackMode; + } + + void setPlaybackMode( ProjectPlaybackMode _playbackMode ); + public slots: void resetWindowTitle( void ); @@ -145,7 +159,14 @@ private: QWidget * m_toolBar; QHBoxLayout * m_toolBarLayout; - + QCheckBox * m_chkrAudio; + QCheckBox * m_chkrAutomation; + QCheckBox * m_chkrMidi; + QRadioButton * m_radpSong; + QRadioButton * m_radpBB; + QRadioButton * m_radpPianoRoll; + + ProjectPlaybackMode m_playbackMode; lcdSpinBox * m_tempoSpinBox; meterDialog * m_timeSigDisplay; @@ -200,6 +221,14 @@ private slots: void showTool( QAction * _idx ); void updateRecentlyOpenedProjectsMenu( void ); + void playbackSongClicked( bool ); + void playbackBBClicked( bool ); + void playbackPianoRollClicked( bool ); + void spacePressed( void ); + + void play( void ); + void record( void ); + void playAndRecord( void ); signals: void periodicUpdate( void ); diff --git a/include/piano_roll.h b/include/piano_roll.h index a4fd75bc0..065a279e6 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -81,6 +81,11 @@ public: { return "pianoroll"; } +public slots: + void play( void ); + void record( void ); + void recordAccompany( void ); + void stop( void ); protected: @@ -105,11 +110,7 @@ protected: protected slots: - void play( void ); - void record( void ); - void recordAccompany( void ); - void stop( void ); - + void recordNote( const note & _n ); void horScrolled( int _new_pos ); diff --git a/include/song_editor.h b/include/song_editor.h index de64420ad..80239c0cb 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -58,16 +58,16 @@ public: public slots: void scrolled( int _new_pos ); - - -private slots: - void play( void ); void record( void ); void recordAccompany( void ); void stop( void ); - void updatePosition( const midiTime & _t ); + + +private slots: + + void updatePosition( const midiTime & _t ); void zoomingChanged( void ); diff --git a/src/gui/bb_editor.cpp b/src/gui/bb_editor.cpp index 5760c22be..166f365f4 100644 --- a/src/gui/bb_editor.cpp +++ b/src/gui/bb_editor.cpp @@ -149,6 +149,8 @@ void bbEditor::removeBBView( int _bb ) void bbEditor::play( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_BB ); + if( engine::getSong()->isPlaying() ) { if( engine::getSong()->playMode() != song::Mode_PlayBB ) diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp index f55466807..1336c9f20 100644 --- a/src/gui/main_window.cpp +++ b/src/gui/main_window.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "lmmsversion.h" @@ -632,7 +634,7 @@ void mainWindow::finalize( void ) m_toolBarLayout->addWidget( vc_w, 0, Qt::AlignLeft ); m_toolBarLayout->insertSpacing( -1, 10 ); - /* + // global playback and record controls // main box QWidget * gpbr_w = new QWidget( m_toolBar ); @@ -647,23 +649,24 @@ void mainWindow::finalize( void ) QWidget * btns = new QWidget( gpb_w ); QHBoxLayout * btns_layout = new QHBoxLayout( btns ); - - - + btns_layout->setMargin(0); + btns_layout->setSpacing(0); + + toolButton * m_playButton = new toolButton( embed::getIconPixmap( "play" ), - tr( "Play/pause the current window (Space)" ), - engine::getSong(), - SLOT( play() ), + tr( "Play/pause the project (Space)" ), + this, + SLOT(play()), btns ); toolButton * m_recordButton = new toolButton( embed::getIconPixmap( "record" ), tr( "Record from the checked items to the right" ), - engine::getSong(), - SLOT( record() ), + this, + SLOT(record()), btns ); toolButton * m_recordAccompanyButton = @@ -671,8 +674,8 @@ void mainWindow::finalize( void ) embed::getIconPixmap( "record_accompany" ), tr( "Record from the checked items to " "the right while playing" ), - engine::getSong(), - SLOT( playAndRecord() ), + this, + SLOT(playAndRecord()), btns ); toolButton * m_stopButton = @@ -683,8 +686,6 @@ void mainWindow::finalize( void ) SLOT( stop() ), btns ); - btns_layout->setMargin(0); - btns_layout->setSpacing(0); btns_layout->addWidget( m_playButton ); btns_layout->addWidget( m_recordButton ); btns_layout->addWidget( m_recordAccompanyButton ); @@ -692,13 +693,39 @@ void mainWindow::finalize( void ) gpbw_layout->addWidget( btns ); + // choose between song or BB to playback + QWidget * pbopt_w = new QWidget( gpb_w ); + QHBoxLayout * pbopt_layout = new QHBoxLayout( pbopt_w ); + pbopt_layout->setSpacing(0); + pbopt_layout->setMargin(0); + + m_radpSong = new QRadioButton( tr( "Song" ), pbopt_w ); + m_radpSong->setToolTip( tr("Playback: song mode") ); + connect(m_radpSong, SIGNAL(clicked(bool)), SLOT(playbackSongClicked(bool))); + m_radpBB = new QRadioButton( tr( "B+B" ), pbopt_w ); + m_radpBB->setToolTip( tr("Playback: beat+bassline mode") ); + connect(m_radpBB, SIGNAL(clicked(bool)), SLOT(playbackBBClicked(bool))); + m_radpPianoRoll = new QRadioButton( tr( "Piano Roll" ), pbopt_w ); + m_radpPianoRoll->setToolTip( tr("Playback: piano roll mode") ); + connect(m_radpPianoRoll, SIGNAL(clicked(bool)), SLOT(playbackPianoRollClicked(bool))); + + + pbopt_layout->setMargin(0); + pbopt_layout->setSpacing(0); + pbopt_layout->addWidget( m_radpSong ); + pbopt_layout->addWidget( m_radpBB ); + pbopt_layout->addWidget( m_radpPianoRoll ); + + gpbw_layout->addWidget( pbopt_w ); + gpbw_layout->addStretch(); QWidget * gr_w = new QWidget( gpbr_w ); QVBoxLayout * grw_layout = new QVBoxLayout( gr_w ); grw_layout->setMargin( 0 ); grw_layout->setSpacing( 0 ); - + + m_chkrAudio = new QCheckBox( tr( "Audio-device" ), gr_w ); m_chkrAutomation = new QCheckBox( tr( "Automation" ), gr_w ); m_chkrMidi = new QCheckBox( tr( "MIDI" ), gr_w ); @@ -717,8 +744,16 @@ void mainWindow::finalize( void ) gpbrw_layout->addStretch(); - m_toolBarLayout->addWidget( gpbr_w );*/ + m_toolBarLayout->addWidget( gpbr_w ); + // initial toolbar settings + m_chkrAutomation->click(); + m_chkrMidi->click(); + m_radpSong->click(); + + // global keyboard shortcuts + QShortcut * space = new QShortcut(QKeySequence(Qt::Key_Space), this); + connect(space, SIGNAL(activated()), SLOT(spacePressed())); // setup-dialog opened before? if( !configManager::inst()->value( "app", "configured" ).toInt() ) @@ -942,8 +977,22 @@ void mainWindow::updateRecentlyOpenedProjectsMenu( void ) } } +void mainWindow::playbackSongClicked( bool checked ) +{ + m_playbackMode = PPM_Song; +} +void mainWindow::playbackBBClicked( bool checked ) +{ + m_playbackMode = PPM_BB; +} + +void mainWindow::playbackPianoRollClicked( bool checked ) +{ + m_playbackMode = PPM_PianoRoll; +} + void mainWindow::openRecentlyOpenedProject( QAction * _action ) { @@ -1163,6 +1212,78 @@ void mainWindow::keyPressEvent( QKeyEvent * _ke ) } } +void mainWindow::spacePressed( void ) +{ + play(); +} + +void mainWindow::play( void ) +{ + if( m_playbackMode == PPM_BB ) + { + engine::getBBEditor()->play(); + } + else if( m_playbackMode == PPM_PianoRoll ) + { + engine::getPianoRoll()->play(); + } + else + { + engine::getSongEditor()->play(); + } +} + +void mainWindow::record( void ) +{ + if( m_playbackMode == PPM_BB ) + { + printf("beat+bassline does not support recording\n"); + } + else if( m_playbackMode == PPM_PianoRoll ) + { + engine::getPianoRoll()->record(); + } + else + { + engine::getSongEditor()->record(); + } + +} + +void mainWindow::playAndRecord( void ) +{ + if( m_playbackMode == PPM_BB ) + { + printf("bb editor does not support record accompany\n"); + } + else if( m_playbackMode == PPM_PianoRoll ) + { + engine::getPianoRoll()->recordAccompany(); + } + else + { + engine::getSongEditor()->recordAccompany(); + } + +} + + + +void mainWindow::setPlaybackMode( ProjectPlaybackMode _playbackMode ) +{ + if( _playbackMode == PPM_BB ) + { + m_radpBB->click(); + } + else if( _playbackMode == PPM_Song ) + { + m_radpSong->click(); + } + else + { + m_radpPianoRoll->click(); + } +} diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 375a117ba..fee942049 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -2956,6 +2956,8 @@ int pianoRoll::getKey( int _y ) const void pianoRoll::play( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_PianoRoll ); + if( validPattern() == false ) { return; @@ -2993,6 +2995,8 @@ void pianoRoll::play( void ) void pianoRoll::record( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_PianoRoll ); + if( engine::getSong()->isPlaying() ) { stop(); @@ -3012,6 +3016,8 @@ void pianoRoll::record( void ) void pianoRoll::recordAccompany( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_PianoRoll ); + if( engine::getSong()->isPlaying() ) { stop(); diff --git a/src/gui/song_editor.cpp b/src/gui/song_editor.cpp index 95b97447f..2649d54fe 100644 --- a/src/gui/song_editor.cpp +++ b/src/gui/song_editor.cpp @@ -277,6 +277,8 @@ void songEditor::scrolled( int _new_pos ) void songEditor::play( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_Song ); + m_s->play(); if( m_s->playMode() == song::Mode_PlaySong ) { @@ -293,6 +295,8 @@ void songEditor::play( void ) void songEditor::record( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_Song ); + m_s->record(); } @@ -301,6 +305,8 @@ void songEditor::record( void ) void songEditor::recordAccompany( void ) { + engine::getMainWindow()->setPlaybackMode( PPM_Song ); + m_s->playAndRecord(); }