diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index 53177b1c4..339520f2e 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -2,7 +2,7 @@ * InstrumentTrack.h - declaration of class InstrumentTrack, a track + window * which holds an instrument-plugin * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -41,6 +41,7 @@ class QLineEdit; template class QQueue; +template class QStack; class ArpeggiatorView; class ChordCreatorView; class EffectRackView; @@ -258,6 +259,10 @@ public: return castModel(); } + static InstrumentTrackWindow * topLevelInstrumentTrackWindow() + { + return s_windowStack.isEmpty() ? NULL : s_windowStack.top(); + } QMenu * midiMenu() { @@ -266,7 +271,7 @@ public: void freeInstrumentTrackWindow(); - static void cleanupWindowPool(); + static void cleanupWindowCache(); protected: @@ -287,7 +292,8 @@ private slots: private: InstrumentTrackWindow * m_window; - static QQueue s_windows; + static QQueue s_windowCache; + static QStack s_windowStack; // widgets in track-settings-widget trackLabelButton * m_tlb; @@ -334,9 +340,11 @@ public: return castModel(); } - void setInstrumentTrackView( InstrumentTrackView * _tv ) + void setInstrumentTrackView( InstrumentTrackView * _tv ); + + PianoView * pianoView() { - m_itv = _tv; + return m_pianoView; } static void dragEnterEventGeneric( QDragEnterEvent * _dee ); diff --git a/include/PianoView.h b/include/PianoView.h index 4acc12daa..3f99fbc00 100644 --- a/include/PianoView.h +++ b/include/PianoView.h @@ -1,7 +1,7 @@ /* * PianoView.h - declaration of PianoView, an interactive piano/keyboard-widget * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -43,10 +43,13 @@ public: static int getKeyFromKeyEvent( QKeyEvent * _ke ); -protected: - virtual void modelChanged(); +public: virtual void keyPressEvent( QKeyEvent * ke ); virtual void keyReleaseEvent( QKeyEvent * ke ); + + +protected: + virtual void modelChanged(); virtual void contextMenuEvent( QContextMenuEvent * _me ); virtual void paintEvent( QPaintEvent * ); virtual void mousePressEvent( QMouseEvent * me ); diff --git a/include/setup_dialog.h b/include/setup_dialog.h index 416543a67..31c26ed95 100644 --- a/include/setup_dialog.h +++ b/include/setup_dialog.h @@ -1,7 +1,7 @@ /* * setup_dialog.h - dialog for setting up LMMS * - * Copyright (c) 2005-2009 Tobias Doerffel + * Copyright (c) 2005-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -104,6 +104,7 @@ private slots: void toggleDisableChActInd( bool _disabled ); void toggleManualChPiano( bool _enabled ); + void toggleOneInstrumentTrackWindow( bool _enabled ); private: @@ -148,6 +149,7 @@ private: bool m_disableChActInd; bool m_manualChPiano; + bool m_oneInstrumentTrackWindow; typedef QMap AswMap; typedef QMap MswMap; diff --git a/src/core/engine.cpp b/src/core/engine.cpp index 1affe4912..14a586d9d 100644 --- a/src/core/engine.cpp +++ b/src/core/engine.cpp @@ -123,7 +123,7 @@ void engine::destroy() deleteHelper( &s_fxMixerView ); presetPreviewPlayHandle::cleanup(); - InstrumentTrackView::cleanupWindowPool(); + InstrumentTrackView::cleanupWindowCache(); s_song->clearProject(); diff --git a/src/gui/AutomationEditor.cpp b/src/gui/AutomationEditor.cpp index 67919d470..3a597e784 100644 --- a/src/gui/AutomationEditor.cpp +++ b/src/gui/AutomationEditor.cpp @@ -2,7 +2,7 @@ * AutomationEditor.cpp - implementation of AutomationEditor which is used for * actual setting of dynamic values * - * Copyright (c) 2008 Tobias Doerffel + * Copyright (c) 2008-2010 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -517,37 +517,35 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) case Qt::Key_Up: m_topBottomScroll->setValue( m_topBottomScroll->value() - 1 ); + _ke->accept(); break; case Qt::Key_Down: m_topBottomScroll->setValue( m_topBottomScroll->value() + 1 ); + _ke->accept(); break; case Qt::Key_Left: - { if( ( m_timeLine->pos() -= 16 ) < 0 ) { m_timeLine->pos().setTicks( 0 ); } m_timeLine->updatePosition(); + _ke->accept(); break; - } + case Qt::Key_Right: - { m_timeLine->pos() += 16; m_timeLine->updatePosition(); + _ke->accept(); break; - } case Qt::Key_C: if( _ke->modifiers() & Qt::ControlModifier ) { copySelectedValues(); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -555,10 +553,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ControlModifier ) { cutSelectedValues(); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -566,10 +561,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ControlModifier ) { pasteValues(); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -579,10 +571,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) m_selectButton->setChecked( TRUE ); selectAll(); update(); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -590,10 +579,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ShiftModifier ) { m_drawButton->setChecked( TRUE ); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -601,10 +587,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ShiftModifier ) { m_eraseButton->setChecked( TRUE ); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -612,10 +595,7 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ShiftModifier ) { m_selectButton->setChecked( TRUE ); - } - else - { - _ke->ignore(); + _ke->accept(); } break; @@ -623,15 +603,13 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & Qt::ShiftModifier ) { m_moveButton->setChecked( TRUE ); - } - else - { - _ke->ignore(); + _ke->accept(); } break; case Qt::Key_Delete: deleteSelectedValues(); + _ke->accept(); break; case Qt::Key_Space: @@ -643,15 +621,16 @@ void AutomationEditor::keyPressEvent( QKeyEvent * _ke ) { play(); } + _ke->accept(); break; case Qt::Key_Home: m_timeLine->pos().setTicks( 0 ); m_timeLine->updatePosition(); + _ke->accept(); break; default: - _ke->ignore(); break; } } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 81e6d92c0..ddaf84ceb 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -3,7 +3,7 @@ /* * main_window.cpp - implementation of LMMS-main-window * - * Copyright (c) 2004-2008 Tobias Doerffel + * Copyright (c) 2004-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -46,6 +46,8 @@ #include "embed.h" #include "engine.h" #include "FxMixerView.h" +#include "InstrumentTrack.h" +#include "PianoView.h" #include "about_dialog.h" #include "ControllerRackView.h" #include "file_browser.h" @@ -928,7 +930,15 @@ void MainWindow::keyPressEvent( QKeyEvent * _ke ) case Qt::Key_Shift: m_keyMods.m_shift = TRUE; break; case Qt::Key_Alt: m_keyMods.m_alt = TRUE; break; default: - QMainWindow::keyPressEvent( _ke ); + if( InstrumentTrackView::topLevelInstrumentTrackWindow() ) + { + InstrumentTrackView::topLevelInstrumentTrackWindow()-> + pianoView()->keyPressEvent( _ke ); + } + if( !_ke->isAccepted() ) + { + QMainWindow::keyPressEvent( _ke ); + } } } @@ -943,7 +953,15 @@ void MainWindow::keyReleaseEvent( QKeyEvent * _ke ) case Qt::Key_Shift: m_keyMods.m_shift = FALSE; break; case Qt::Key_Alt: m_keyMods.m_alt = FALSE; break; default: - QMainWindow::keyReleaseEvent( _ke ); + if( InstrumentTrackView::topLevelInstrumentTrackWindow() ) + { + InstrumentTrackView::topLevelInstrumentTrackWindow()-> + pianoView()->keyReleaseEvent( _ke ); + } + if( !_ke->isAccepted() ) + { + QMainWindow::keyReleaseEvent( _ke ); + } } } diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp index 915f3d9ae..d5a96f850 100644 --- a/src/gui/PianoView.cpp +++ b/src/gui/PianoView.cpp @@ -2,7 +2,7 @@ * Piano.cpp - implementation of piano-widget used in instrument-track-window * for testing + according model class * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -644,6 +644,7 @@ void PianoView::keyPressEvent( QKeyEvent * _ke ) if( m_piano != NULL ) { m_piano->handleKeyPress( key_num ); + _ke->accept(); update(); } } @@ -671,6 +672,7 @@ void PianoView::keyReleaseEvent( QKeyEvent * _ke ) if( m_piano != NULL ) { m_piano->handleKeyRelease( key_num ); + _ke->accept(); update(); } } diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index 2a7353ddb..afbc4a2f0 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -2,7 +2,7 @@ * piano_roll.cpp - implementation of piano-roll which is used for actual * writing of melodies * - * Copyright (c) 2004-2009 Tobias Doerffel + * Copyright (c) 2004-2010 Tobias Doerffel * Copyright (c) 2008 Andrew Kelley * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -900,6 +900,7 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) { m_pattern->instrumentTrack()-> getPiano()->handleKeyPress( key_num ); + _ke->accept(); } } @@ -930,7 +931,9 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) Qt::AltModifier ); } } + _ke->accept(); break; + case Qt::Key_Down: if( _ke->modifiers() & Qt::ControlModifier && m_action == ActionNone ) @@ -956,10 +959,10 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) Qt::AltModifier ); } } + _ke->accept(); break; case Qt::Key_Left: - { if( _ke->modifiers() & Qt::ControlModifier && m_action == ActionNone ) { @@ -997,10 +1000,10 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) } } + _ke->accept(); break; - } + case Qt::Key_Right: - { if( _ke->modifiers() & Qt::ControlModifier && m_action == ActionNone) { @@ -1035,103 +1038,78 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) } } - - + _ke->accept(); break; - } case Qt::Key_C: if( _ke->modifiers() & Qt::ControlModifier ) { + _ke->accept(); copySelectedNotes(); } - else - { - _ke->ignore(); - } break; case Qt::Key_X: if( _ke->modifiers() & Qt::ControlModifier ) { + _ke->accept(); cutSelectedNotes(); } - else - { - _ke->ignore(); - } break; case Qt::Key_V: if( _ke->modifiers() & Qt::ControlModifier ) { + _ke->accept(); pasteNotes(); } - else - { - _ke->ignore(); - } break; case Qt::Key_A: if( _ke->modifiers() & Qt::ControlModifier ) { + _ke->accept(); m_selectButton->setChecked( true ); selectAll(); update(); } - else - { - _ke->ignore(); - } break; case Qt::Key_D: if( _ke->modifiers() & Qt::ShiftModifier ) { + _ke->accept(); m_drawButton->setChecked( true ); } - else - { - _ke->ignore(); - } break; case Qt::Key_E: if( _ke->modifiers() & Qt::ShiftModifier ) { + _ke->accept(); m_eraseButton->setChecked( true ); } - else - { - _ke->ignore(); - } break; case Qt::Key_S: if( _ke->modifiers() & Qt::ShiftModifier ) { + _ke->accept(); m_selectButton->setChecked( true ); } - else - { - _ke->ignore(); - } break; case Qt::Key_T: if( _ke->modifiers() & Qt::ShiftModifier ) { + _ke->accept(); m_detuneButton->setChecked( true ); } - else - { - _ke->ignore(); - } break; case Qt::Key_Delete: deleteSelectedNotes(); + _ke->accept(); break; case Qt::Key_Space: @@ -1143,11 +1121,13 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) { play(); } + _ke->accept(); break; case Qt::Key_Home: m_timeLine->pos().setTicks( 0 ); m_timeLine->updatePosition(); + _ke->accept(); break; case Qt::Key_0: @@ -1167,11 +1147,13 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) if( _ke->modifiers() & ( Qt::ControlModifier | Qt::KeypadModifier ) ) { - m_noteLenModel.setValue( len ); + m_noteLenModel.setValue( len ); + _ke->accept(); } else if( _ke->modifiers() & Qt::AltModifier ) { - m_quantizeModel.setValue( len ); + m_quantizeModel.setValue( len ); + _ke->accept(); } break; } @@ -1181,9 +1163,9 @@ void pianoRoll::keyPressEvent( QKeyEvent * _ke ) m_editMode = ModeSelect; QApplication::changeOverrideCursor( Qt::ArrowCursor ); update(); + _ke->accept(); break; default: - _ke->ignore(); break; } } @@ -1202,6 +1184,7 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * _ke ) { m_pattern->instrumentTrack()-> getPiano()->handleKeyRelease( key_num ); + _ke->accept(); } } switch( _ke->key() ) @@ -1213,7 +1196,6 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * _ke ) update(); break; } - _ke->ignore(); } diff --git a/src/gui/setup_dialog.cpp b/src/gui/setup_dialog.cpp index e205d9561..d15f95818 100644 --- a/src/gui/setup_dialog.cpp +++ b/src/gui/setup_dialog.cpp @@ -1,7 +1,7 @@ /* * setup_dialog.cpp - dialog for setting up LMMS * - * Copyright (c) 2005-2009 Tobias Doerffel + * Copyright (c) 2005-2010 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -111,7 +111,9 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : m_disableChActInd( configManager::inst()->value( "ui", "disablechannelactivityindicators" ).toInt() ), m_manualChPiano( configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ) + "manualchannelpiano" ).toInt() ), + m_oneInstrumentTrackWindow( configManager::inst()->value( "ui", + "oneinstrumenttrackwindow" ).toInt() ) { setWindowIcon( embed::getIconPixmap( "setup_general" ) ); setWindowTitle( tr( "Setup LMMS" ) ); @@ -180,7 +182,7 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : tabWidget * misc_tw = new tabWidget( tr( "MISC" ), general ); - misc_tw->setFixedHeight( 120 ); + misc_tw->setFixedHeight( 138 ); ledCheckBox * enable_tooltips = new ledCheckBox( tr( "Enable tooltips" ), @@ -216,10 +218,18 @@ setupDialog::setupDialog( ConfigTabs _tab_to_open ) : connect( mmpz, SIGNAL( toggled( bool ) ), this, SLOT( toggleMMPZ( bool ) ) ); + ledCheckBox * oneitw = new ledCheckBox( + tr( "One instrument track window mode" ), + misc_tw ); + oneitw->move( 10, 90 ); + oneitw->setChecked( m_oneInstrumentTrackWindow ); + connect( oneitw, SIGNAL( toggled( bool ) ), + this, SLOT( toggleOneInstrumentTrackWindow( bool ) ) ); + ledCheckBox * hqaudio = new ledCheckBox( tr( "HQ-mode for output audio-device" ), misc_tw ); - hqaudio->move( 10, 90 ); + hqaudio->move( 10, 108 ); hqaudio->setChecked( m_hqAudioDev ); connect( hqaudio, SIGNAL( toggled( bool ) ), this, SLOT( toggleHQAudioDev( bool ) ) ); @@ -729,6 +739,8 @@ void setupDialog::accept() QString::number( m_disableChActInd ) ); configManager::inst()->setValue( "ui", "manualchannelpiano", QString::number( m_manualChPiano ) ); + configManager::inst()->setValue( "ui", "oneinstrumenttrackwindow", + QString::number( m_oneInstrumentTrackWindow ) ); configManager::inst()->setWorkingDir( m_workingDir ); configManager::inst()->setVSTDir( m_vstDir ); @@ -885,6 +897,15 @@ void setupDialog::toggleManualChPiano( bool _enabled ) +void setupDialog::toggleOneInstrumentTrackWindow( bool _enabled ) +{ + m_oneInstrumentTrackWindow = _enabled; +} + + + + + void setupDialog::openWorkingDir() { QString new_dir = QFileDialog::getExistingDirectory( this, diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index fbc20123c..260f2ba76 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -859,7 +860,8 @@ Instrument * InstrumentTrack::loadInstrument( const QString & _plugin_name ) // #### ITV: -QQueue InstrumentTrackView::s_windows; +QQueue InstrumentTrackView::s_windowCache; +QStack InstrumentTrackView::s_windowStack; @@ -977,16 +979,26 @@ void InstrumentTrackView::freeInstrumentTrackWindow() { if( m_window != NULL ) { + if( qFind( s_windowStack.begin(), s_windowStack.end(), m_window ) != + s_windowStack.end() ) + { + s_windowStack.erase( + qFind( s_windowStack.begin(), s_windowStack.end(), m_window ) ); + } m_lastPos = m_window->parentWidget()->pos(); - if( s_windows.count() < INSTRUMENT_WINDOW_CACHE_SIZE ) + + if( configManager::inst()->value( "ui", + "oneinstrumenttrackwindow" ).toInt() || + s_windowCache.count() < INSTRUMENT_WINDOW_CACHE_SIZE ) { model()->setHook( NULL ); + m_window->setInstrumentTrackView( NULL ); m_window->parentWidget()->hide(); m_window->setModel( engine::dummyTrackContainer()-> dummyInstrumentTrack() ); m_window->updateInstrumentView(); - s_windows.enqueue( m_window ); + s_windowCache << m_window; } else { @@ -1000,11 +1012,11 @@ void InstrumentTrackView::freeInstrumentTrackWindow() -void InstrumentTrackView::cleanupWindowPool() +void InstrumentTrackView::cleanupWindowCache() { - while( s_windows.count() ) + while( !s_windowCache.isEmpty() ) { - delete s_windows.dequeue(); + delete s_windowCache.dequeue(); } } @@ -1016,16 +1028,21 @@ InstrumentTrackWindow * InstrumentTrackView::getInstrumentTrackWindow() if( m_window != NULL ) { } - else if( !s_windows.isEmpty() ) + else if( !s_windowCache.isEmpty() ) { - m_window = s_windows.dequeue(); + m_window = s_windowCache.dequeue(); m_window->setInstrumentTrackView( this ); m_window->setModel( model() ); m_window->updateInstrumentView(); model()->setHook( m_window ); - if( m_lastPos.x() > 0 || m_lastPos.y() > 0 ) + if( configManager::inst()-> + value( "ui", "oneinstrumenttrackwindow" ).toInt() ) + { + s_windowCache << m_window; + } + else if( m_lastPos.x() > 0 || m_lastPos.y() > 0 ) { m_window->parentWidget()->move( m_lastPos ); } @@ -1033,6 +1050,12 @@ InstrumentTrackWindow * InstrumentTrackView::getInstrumentTrackWindow() else { m_window = new InstrumentTrackWindow( this ); + if( configManager::inst()-> + value( "ui", "oneinstrumenttrackwindow" ).toInt() ) + { + // first time, an InstrumentTrackWindow is opened + s_windowCache << m_window; + } } return m_window; @@ -1064,12 +1087,23 @@ void InstrumentTrackView::dropEvent( QDropEvent * _de ) void InstrumentTrackView::toggleInstrumentWindow( bool _on ) { - getInstrumentTrackWindow()->toggleVisibility( _on ); + InstrumentTrackWindow * w = getInstrumentTrackWindow(); + w->toggleVisibility( _on ); if( !_on ) { freeInstrumentTrackWindow(); } + else + { + if( qFind( s_windowStack.begin(), s_windowStack.end(), w ) != + s_windowStack.end() ) + { + s_windowStack.erase( + qFind( s_windowStack.begin(), s_windowStack.end(), w ) ); + } + s_windowStack.push( w ); + } } @@ -1247,7 +1281,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_tabWidget->addTab( m_midiView, tr( "MIDI" ), 4 ); // setup piano-widget - m_pianoView= new PianoView( this ); + m_pianoView = new PianoView( this ); m_pianoView->setFixedSize( INSTRUMENT_WIDTH, PIANO_HEIGHT ); vlayout->addWidget( m_generalSettingsWidget ); @@ -1278,7 +1312,10 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : InstrumentTrackWindow::~InstrumentTrackWindow() { + InstrumentTrackView::s_windowCache.removeAll( this ); + delete m_instrumentView; + if( engine::mainWindow()->workspace() ) { parentWidget()->hide(); @@ -1289,6 +1326,18 @@ InstrumentTrackWindow::~InstrumentTrackWindow() +void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView * _tv ) +{ + if( m_itv && _tv ) + { + m_itv->m_tlb->setChecked( false ); + } + m_itv = _tv; +} + + + + void InstrumentTrackWindow::modelChanged() { m_track = castModel();