diff --git a/include/PianoRoll.h b/include/PianoRoll.h index 7a99e7b1f80..e3e4b312085 100644 --- a/include/PianoRoll.h +++ b/include/PianoRoll.h @@ -195,12 +195,13 @@ protected slots: void zoomingYChanged(); void quantizeChanged(); void noteLengthChanged(); + void keyChanged(); void quantizeNotes(); void updateSemiToneMarkerMenu(); void changeNoteEditMode( int i ); - void markSemiTone( int i ); + void markSemiTone(int i, bool fromMenu = true); void hidePattern( Pattern* pattern ); @@ -311,6 +312,7 @@ protected slots: ComboBoxModel m_zoomingYModel; ComboBoxModel m_quantizeModel; ComboBoxModel m_noteLenModel; + ComboBoxModel m_keyModel; ComboBoxModel m_scaleModel; ComboBoxModel m_chordModel; @@ -507,6 +509,7 @@ private slots: ComboBox * m_zoomingYComboBox; ComboBox * m_quantizeComboBox; ComboBox * m_noteLenComboBox; + ComboBox * m_keyComboBox; ComboBox * m_scaleComboBox; ComboBox * m_chordComboBox; QPushButton * m_clearGhostButton; diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index c63225440dc..0eb049ddcae 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -374,6 +374,13 @@ PianoRoll::PianoRoll() : connect( &m_noteLenModel, SIGNAL( dataChanged() ), this, SLOT( noteLengthChanged() ) ); + // Set up key selection dropdown + m_keyModel.addItem(tr("No key")); + // Use piano roll note strings for key dropdown + for (int i = 0; i < 12; i++) { m_keyModel.addItem(s_noteStrings[i]); } + m_keyModel.setValue(0); // start with "No key" + connect(&m_keyModel, &ComboBoxModel::dataChanged, this, &PianoRoll::keyChanged); + // Set up scale model const InstrumentFunctionNoteStacking::ChordTable& chord_table = InstrumentFunctionNoteStacking::ChordTable::getInstance(); @@ -388,6 +395,8 @@ PianoRoll::PianoRoll() : } m_scaleModel.setValue( 0 ); + // connect scale change to key change so it auto-highlights with scale as well + connect(&m_scaleModel, &ComboBoxModel::dataChanged, this, &PianoRoll::keyChanged); // change can update m_semiToneMarkerMenu connect( &m_scaleModel, SIGNAL( dataChanged() ), this, SLOT( updateSemiToneMarkerMenu() ) ); @@ -485,11 +494,17 @@ void PianoRoll::changeNoteEditMode( int i ) } -void PianoRoll::markSemiTone( int i ) +void PianoRoll::markSemiTone(int i, bool fromMenu) { - const int key = m_pianoKeySelected; + const int key = fromMenu + ? getKey(mapFromGlobal(m_semiToneMarkerMenu->pos()).y()) + : m_keyModel.value() - 1; const InstrumentFunctionNoteStacking::Chord * chord = nullptr; + // if "No key" is selected, key is -1, unmark all semitones + // or if scale changed from toolbar to "No scale", unmark all semitones + if (!fromMenu && (key < 0 || m_scaleModel.value() == 0)) { i = stmaUnmarkAll; } + switch( static_cast( i ) ) { case stmaUnmarkAll: @@ -578,6 +593,8 @@ void PianoRoll::markSemiTone( int i ) std::sort( m_markedSemiTones.begin(), m_markedSemiTones.end(), std::greater() ); QList::iterator new_end = std::unique( m_markedSemiTones.begin(), m_markedSemiTones.end() ); m_markedSemiTones.erase( new_end, m_markedSemiTones.end() ); + // until we move the mouse the window won't update, force redraw + update(); } @@ -4139,6 +4156,10 @@ void PianoRoll::noteLengthChanged() update(); } +void PianoRoll::keyChanged() +{ + markSemiTone(stmaMarkCurrentScale, false); +} int PianoRoll::quantization() const { @@ -4380,6 +4401,12 @@ PianoRollWindow::PianoRollWindow() : m_noteLenComboBox->setFixedSize( 105, ComboBox::DEFAULT_HEIGHT ); m_noteLenComboBox->setToolTip( tr( "Note length") ); + // setup key-stuff + m_keyComboBox = new ComboBox(m_toolBar); + m_keyComboBox->setModel(&m_editor->m_keyModel); + m_keyComboBox->setFixedSize(72, ComboBox::DEFAULT_HEIGHT); + m_keyComboBox->setToolTip(tr("Key")); + // setup scale-stuff QLabel * scale_lbl = new QLabel( m_toolBar ); scale_lbl->setPixmap( embed::getIconPixmap( "scale" ) ); @@ -4406,27 +4433,61 @@ PianoRollWindow::PianoRollWindow() : connect( m_clearGhostButton, SIGNAL( clicked() ), m_editor, SLOT( clearGhostPattern() ) ); connect( m_editor, SIGNAL( ghostPatternSet( bool ) ), this, SLOT( ghostPatternSet( bool ) ) ); - zoomAndNotesToolBar->addWidget( zoom_lbl ); - zoomAndNotesToolBar->addWidget( m_zoomingComboBox ); - - zoomAndNotesToolBar->addWidget(zoom_y_lbl); - zoomAndNotesToolBar->addWidget(m_zoomingYComboBox); - + // Wrap label icons and comboboxes in a single widget so when + // the window is resized smaller in width it hides both + QWidget * zoom_widget = new QWidget(); + QHBoxLayout * zoom_hbox = new QHBoxLayout(); + zoom_hbox->setContentsMargins(0, 0, 0, 0); + zoom_hbox->addWidget(zoom_lbl); + zoom_hbox->addWidget(m_zoomingComboBox); + zoom_widget->setLayout(zoom_hbox); + zoomAndNotesToolBar->addWidget(zoom_widget); + + QWidget * zoomY_widget = new QWidget(); + QHBoxLayout * zoomY_hbox = new QHBoxLayout(); + zoomY_hbox->setContentsMargins(0, 0, 0, 0); + zoomY_hbox->addWidget(zoom_y_lbl); + zoomY_hbox->addWidget(m_zoomingYComboBox); + zoomY_widget->setLayout(zoomY_hbox); + zoomAndNotesToolBar->addWidget(zoomY_widget); + + QWidget * quantize_widget = new QWidget(); + QHBoxLayout * quantize_hbox = new QHBoxLayout(); + quantize_hbox->setContentsMargins(0, 0, 0, 0); + quantize_hbox->addWidget(quantize_lbl); + quantize_hbox->addWidget(m_quantizeComboBox); + quantize_widget->setLayout(quantize_hbox); zoomAndNotesToolBar->addSeparator(); - zoomAndNotesToolBar->addWidget( quantize_lbl ); - zoomAndNotesToolBar->addWidget( m_quantizeComboBox ); - + zoomAndNotesToolBar->addWidget(quantize_widget); + + QWidget * note_widget = new QWidget(); + QHBoxLayout * note_hbox = new QHBoxLayout(); + note_hbox->setContentsMargins(0, 0, 0, 0); + note_hbox->addWidget(note_len_lbl); + note_hbox->addWidget(m_noteLenComboBox); + note_widget->setLayout(note_hbox); zoomAndNotesToolBar->addSeparator(); - zoomAndNotesToolBar->addWidget( note_len_lbl ); - zoomAndNotesToolBar->addWidget( m_noteLenComboBox ); - + zoomAndNotesToolBar->addWidget(note_widget); + + QWidget * scale_widget = new QWidget(); + QHBoxLayout * scale_hbox = new QHBoxLayout(); + scale_hbox->setContentsMargins(0, 0, 0, 0); + scale_hbox->addWidget(scale_lbl); + // Add the key selection between scale label and key + scale_hbox->addWidget(m_keyComboBox); + scale_hbox->addWidget(m_scaleComboBox); + scale_widget->setLayout(scale_hbox); zoomAndNotesToolBar->addSeparator(); - zoomAndNotesToolBar->addWidget( scale_lbl ); - zoomAndNotesToolBar->addWidget( m_scaleComboBox ); - + zoomAndNotesToolBar->addWidget(scale_widget); + + QWidget * chord_widget = new QWidget(); + QHBoxLayout * chord_hbox = new QHBoxLayout(); + chord_hbox->setContentsMargins(0, 0, 0, 0); + chord_hbox->addWidget(chord_lbl); + chord_hbox->addWidget(m_chordComboBox); + chord_widget->setLayout(chord_hbox); zoomAndNotesToolBar->addSeparator(); - zoomAndNotesToolBar->addWidget( chord_lbl ); - zoomAndNotesToolBar->addWidget( m_chordComboBox ); + zoomAndNotesToolBar->addWidget(chord_widget); zoomAndNotesToolBar->addSeparator(); zoomAndNotesToolBar->addWidget( m_clearGhostButton );