diff --git a/include/PatternEditor.h b/include/PatternEditor.h index d774ffe9ea7..5787f27ec12 100644 --- a/include/PatternEditor.h +++ b/include/PatternEditor.h @@ -28,8 +28,6 @@ #include "Editor.h" #include "TrackContainerView.h" -class QComboBox; - namespace lmms { @@ -38,6 +36,7 @@ class PatternStore; namespace gui { +class ComboBox; class PatternEditor : public TrackContainerView @@ -63,10 +62,10 @@ public slots: void addSampleTrack(); void addAutomationTrack(); void cloneClip(); - void updatePosition(); protected slots: void dropEvent(QDropEvent * de ) override; + void updatePosition(); private: PatternStore* m_ps; @@ -90,7 +89,7 @@ public slots: void stop() override; private: - QComboBox* m_patternComboBox; + ComboBox* m_patternComboBox; }; diff --git a/include/PatternStore.h b/include/PatternStore.h index c18b80017b1..fcb55e4117a 100644 --- a/include/PatternStore.h +++ b/include/PatternStore.h @@ -64,6 +64,7 @@ namespace gui class LMMS_EXPORT PatternStore : public TrackContainer { Q_OBJECT + mapPropertyFromModel(int, currentPattern, setCurrentPattern, m_patternComboBoxModel); public: PatternStore(); ~PatternStore() override = default; @@ -82,13 +83,7 @@ class LMMS_EXPORT PatternStore : public TrackContainer { return lengthOfPattern(currentPattern()); } - - int currentPattern() { return m_currentPattern; } - void setCurrentPattern(int pattern); - int numOfPatterns() const; - - void addPattern(int pattern, const QString& name); void removePattern(int pattern); void swapPattern(int p1, int p2); @@ -102,16 +97,13 @@ class LMMS_EXPORT PatternStore : public TrackContainer public slots: void play(); void stop(); + void updateComboBox(); + void currentPatternChanged(); -signals: - void patternAdded(int pattern, const QString& name); - void patternRemoved(int pattern); - void patternsSwapped(int first, int second); - void patternNameChanged(int pattern, const QString& name); - void currentPatternChanged(int pattern); private: - int m_currentPattern = 0; + ComboBoxModel m_patternComboBoxModel; + // Where the pattern selection combo box is friend class gui::PatternEditorWindow; diff --git a/src/core/PatternStore.cpp b/src/core/PatternStore.cpp index 1c45578f9e2..03409df4d5a 100644 --- a/src/core/PatternStore.cpp +++ b/src/core/PatternStore.cpp @@ -35,8 +35,15 @@ namespace lmms PatternStore::PatternStore() : - TrackContainer(Type::Pattern) + TrackContainer(Type::Pattern), + m_patternComboBoxModel(this) { + connect(&m_patternComboBoxModel, SIGNAL(dataChanged()), + this, SLOT(currentPatternChanged())); + // we *always* want to receive updates even in case pattern actually did + // not change upon setCurrentPattern()-call + connect(&m_patternComboBoxModel, SIGNAL(dataUnchanged()), + this, SLOT(currentPatternChanged())); } @@ -104,12 +111,8 @@ int PatternStore::numOfPatterns() const return Engine::getSong()->countTracks(Track::Type::Pattern); } -void PatternStore::addPattern(int pattern, const QString& name) -{ - createClipsForPattern(pattern); - emit patternAdded(pattern, name); - setCurrentPattern(pattern); -} + + void PatternStore::removePattern(int pattern) { @@ -124,7 +127,7 @@ void PatternStore::removePattern(int pattern) setCurrentPattern(std::max(currentPattern() - 1, 0)); } - emit patternRemoved(pattern); + updateComboBox(); } @@ -137,8 +140,7 @@ void PatternStore::swapPattern(int pattern1, int pattern2) { t->swapPositionOfClips(pattern1, pattern2); } - - emit patternsSwapped(pattern1, pattern2); + updateComboBox(); } @@ -191,9 +193,30 @@ void PatternStore::stop() Engine::getSong()->stop(); } -void PatternStore::setCurrentPattern(int pattern) + + + +void PatternStore::updateComboBox() +{ + const int curPattern = currentPattern(); + + m_patternComboBoxModel.clear(); + + for (int i = 0; i < numOfPatterns(); ++i) + { + PatternTrack* pt = PatternTrack::findPatternTrack(i); + if (!pt) { continue; } + m_patternComboBoxModel.addItem(pt->name()); + } + setCurrentPattern(curPattern); +} + + + + +void PatternStore::currentPatternChanged() { - m_currentPattern = pattern; + // now update all track-labels (the current one has to become white, the others gray) const TrackList& tl = Engine::getSong()->tracks(); for (Track * t : tl) { @@ -202,10 +225,11 @@ void PatternStore::setCurrentPattern(int pattern) t->dataChanged(); } } - - emit currentPatternChanged(pattern); } + + + void PatternStore::createClipsForPattern(int pattern) { const TrackList& tl = tracks(); diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index a84373ebc60..2915786981d 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -25,7 +25,6 @@ #include "PatternEditor.h" #include -#include #include "ClipView.h" #include "ComboBox.h" @@ -247,35 +246,13 @@ PatternEditorWindow::PatternEditorWindow(PatternStore* ps) : m_playAction->setToolTip(tr("Play/pause current pattern (Space)")); m_stopAction->setToolTip(tr("Stop playback of current pattern (Space)")); + // Pattern selector DropToolBar* patternSelectionToolBar = addDropToolBarToTop(tr("Pattern selector")); - m_patternComboBox = new QComboBox(m_toolBar); + m_patternComboBox = new ComboBox(m_toolBar); m_patternComboBox->setFixedSize(200, ComboBox::DEFAULT_HEIGHT); - - connect(Engine::patternStore(), &PatternStore::patternAdded, this, - [this](int pattern, const QString& name) { m_patternComboBox->addItem(name, pattern); }); - - connect(Engine::patternStore(), &PatternStore::patternRemoved, this, - [this](int pattern) { m_patternComboBox->removeItem(pattern); }); - - connect(Engine::patternStore(), &PatternStore::patternsSwapped, this, [&](int first, int second) - { - const auto tmp = m_patternComboBox->itemText(first); - m_patternComboBox->setItemText(first, m_patternComboBox->itemText(second)); - m_patternComboBox->setItemText(second, tmp); - }); - - connect(Engine::patternStore(), &PatternStore::currentPatternChanged, this, - [this](int pattern) { m_patternComboBox->setCurrentIndex(pattern); }); - - connect(Engine::patternStore(), &PatternStore::patternNameChanged, this, - [this](int pattern, const QString& name) { m_patternComboBox->setItemText(pattern, name); }); - - connect(m_patternComboBox, qOverload(&QComboBox::currentIndexChanged), m_editor, [this] { - Engine::patternStore()->setCurrentPattern(m_patternComboBox->currentIndex()); - m_editor->updatePosition(); - }); + m_patternComboBox->setModel(&ps->m_patternComboBoxModel); patternSelectionToolBar->addWidget(m_patternComboBox); @@ -306,21 +283,16 @@ PatternEditorWindow::PatternEditorWindow(PatternStore* ps) : trackAndStepActionsToolBar->addAction( embed::getIconPixmap("step_btn_duplicate"), tr("Clone Steps"), m_editor, SLOT(cloneSteps())); - auto viewNext = new QAction(this); - connect(viewNext, &QAction::triggered, m_patternComboBox, [this] { - if (m_patternComboBox->currentIndex() == m_patternComboBox->count() - 1) { return; } - m_patternComboBox->setCurrentIndex(m_patternComboBox->currentIndex() + 1); - }); + connect(&ps->m_patternComboBoxModel, SIGNAL(dataChanged()), + m_editor, SLOT(updatePosition())); + auto viewNext = new QAction(this); + connect(viewNext, SIGNAL(triggered()), m_patternComboBox, SLOT(selectNext())); viewNext->setShortcut(Qt::Key_Plus); addAction(viewNext); auto viewPrevious = new QAction(this); - connect(viewPrevious, &QAction::triggered, m_patternComboBox, [this] { - if (m_patternComboBox->currentIndex() == 0) { return; } - m_patternComboBox->setCurrentIndex(m_patternComboBox->currentIndex() - 1); - }); - + connect(viewPrevious, SIGNAL(triggered()), m_patternComboBox, SLOT(selectPrevious())); viewPrevious->setShortcut(Qt::Key_Minus); addAction(viewPrevious); } diff --git a/src/tracks/PatternTrack.cpp b/src/tracks/PatternTrack.cpp index a67b076a09e..9f58aadd10c 100644 --- a/src/tracks/PatternTrack.cpp +++ b/src/tracks/PatternTrack.cpp @@ -47,10 +47,12 @@ PatternTrack::PatternTrack() : s_infoMap[this] = patternNum; setName(tr("Pattern %1").arg(patternNum)); - Engine::patternStore()->addPattern(patternNum, name()); + Engine::patternStore()->createClipsForPattern(patternNum); + Engine::patternStore()->setCurrentPattern(patternNum); + Engine::patternStore()->updateComboBox(); - connect(this, &Track::nameChanged, this, - [this, patternNum] { emit Engine::patternStore() -> patternNameChanged(patternNum, name()); }); + connect( this, SIGNAL(nameChanged()), + Engine::patternStore(), SLOT(updateComboBox())); }