From 91f4c57ac9868bac3140b31ed077c9e700a6569b Mon Sep 17 00:00:00 2001 From: Louis BOSSY Date: Sun, 3 May 2026 15:26:55 +0200 Subject: [PATCH 01/10] Change resize behavior of melody type midi clips in the pattern editor. I think this was an oversight, there is no reason for melody clips to behave differently than beat clips in the same pattern. --- src/tracks/MidiClip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracks/MidiClip.cpp b/src/tracks/MidiClip.cpp index f8556ec090b..813900dcf85 100644 --- a/src/tracks/MidiClip.cpp +++ b/src/tracks/MidiClip.cpp @@ -128,7 +128,7 @@ void MidiClip::updateLength() // If the clip hasn't already been manually resized, automatically resize it. if (getAutoResize()) { - if (m_clipType == Type::BeatClip) + if (m_instrumentTrack->trackContainer()->type() == TrackContainer::Type::Pattern) { changeLength(beatClipLength()); updatePatternTrack(); From 8c8c47490e13ca6677cd576a2df6e8e62147024e Mon Sep 17 00:00:00 2001 From: Louis BOSSY Date: Sun, 3 May 2026 20:33:48 +0200 Subject: [PATCH 02/10] Resize automation clips inside patterns to the pattern lenght --- src/core/AutomationClip.cpp | 6 ++++++ src/core/PatternStore.cpp | 2 +- src/gui/editors/PatternEditor.cpp | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index 32739482b74..539fdd3a5a9 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -197,6 +197,12 @@ void AutomationClip::updateLength() // checks if it has been resized from either direction. if (getAutoResize()) { + if ( m_autoTrack != nullptr && m_autoTrack->trackContainer() == Engine::patternStore() ) + { + // If inside a pattern, the clip is always the lenght of it. + changeLength(TimePos::ticksPerBar() * Engine::patternStore()->lengthOfPattern(m_autoTrack->getClipNum(this))); + return; + } // Using 1 bar as the min length for an un-resized clip. // This does not prevent the user from resizing the clip to be less than a bar later on. changeLength(std::max(TimePos::ticksPerBar(), static_cast(timeMapLength()))); diff --git a/src/core/PatternStore.cpp b/src/core/PatternStore.cpp index 57ec78c9321..8d337da5581 100644 --- a/src/core/PatternStore.cpp +++ b/src/core/PatternStore.cpp @@ -89,7 +89,7 @@ bar_t PatternStore::lengthOfPattern(int pattern) const for (Track * t : tl) { // Don't create Clips here if they don't exist - if (pattern < t->numOfClips()) + if (pattern < t->numOfClips() && t->type() == Track::Type::Instrument) { maxLength = std::max(maxLength, t->getClip(pattern)->length()); } diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index 6c3b66e29b5..3cf3d2e312a 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -221,6 +221,13 @@ void PatternEditor::updateMaxSteps() auto mClip = static_cast(track->getClip(m_ps->currentPattern())); m_maxClipLength = std::max(m_maxClipLength, static_cast(mClip->length())); } + else + { + // The length of automation and sample clips is updated here. + // "Why here ?" will you ask. The answer is: Because. + auto clip = track->getClip(m_ps->currentPattern()); + clip->updateLength(); + } } updatePixelsPerBar(); } From de7152130b86dbf03be21ca001bce6fec4eee8a4 Mon Sep 17 00:00:00 2001 From: Louis BOSSY Date: Sun, 3 May 2026 21:17:35 +0200 Subject: [PATCH 03/10] Fix automation clip views scale in pattern editor --- src/gui/clips/AutomationClipView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/clips/AutomationClipView.cpp b/src/gui/clips/AutomationClipView.cpp index 07d5a2c5f8b..2258297c35a 100644 --- a/src/gui/clips/AutomationClipView.cpp +++ b/src/gui/clips/AutomationClipView.cpp @@ -265,7 +265,7 @@ void AutomationClipView::paintEvent( QPaintEvent * ) // pixels per bar const float ppb = fixedClips() ? ( parentWidget()->width() - 2 * BORDER_WIDTH ) - / (float) m_clip->timeMapLength().getBar() : + / (float) m_clip->length().getBar() : pixelsPerBar(); const auto min = m_clip->firstObject()->minValue(); From 988d6acc15396adb50695e2342ef767844d5d0ec Mon Sep 17 00:00:00 2001 From: Louis BOSSY Date: Sun, 3 May 2026 21:35:52 +0200 Subject: [PATCH 04/10] Resize sample clips inside patterns to the pattern lenght --- include/SampleClip.h | 1 + src/core/SampleClip.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/include/SampleClip.h b/include/SampleClip.h index ea7853386e6..c7985286e07 100644 --- a/include/SampleClip.h +++ b/include/SampleClip.h @@ -95,6 +95,7 @@ public slots: SampleClip( const SampleClip& orig ); private: + Track* m_sampleTrack; Sample m_sample; BoolModel m_recordModel; bool m_isPlaying; diff --git a/src/core/SampleClip.cpp b/src/core/SampleClip.cpp index e279f76236e..d80153dea6d 100644 --- a/src/core/SampleClip.cpp +++ b/src/core/SampleClip.cpp @@ -27,6 +27,7 @@ #include #include +#include "PatternStore.h" #include "PathUtil.h" #include "SampleClipView.h" #include "SampleTrack.h" @@ -37,6 +38,7 @@ namespace lmms SampleClip::SampleClip(Track* _track, Sample sample, bool isPlaying) : Clip(_track) + , m_sampleTrack(_track) , m_sample(std::move(sample)) , m_isPlaying(false) { @@ -75,6 +77,7 @@ SampleClip::SampleClip(Track* track) SampleClip::SampleClip(const SampleClip& orig) : Clip(orig), + m_sampleTrack(orig.m_sampleTrack), m_sample(std::move(orig.m_sample)), m_isPlaying(orig.m_isPlaying) { @@ -227,6 +230,11 @@ void SampleClip::updateLength() // If the clip has already been manually resized, don't automatically resize it. if (getAutoResize()) { + if (m_sampleTrack->trackContainer() == Engine::patternStore()) + { + changeLength(TimePos::ticksPerBar() * Engine::patternStore()->lengthOfPattern(m_sampleTrack->getClipNum(this))); + return; + } changeLength(sampleLength()); setStartTimeOffset(0); } From d74cf3173da8ee7b4c168cbef339beee278a327a Mon Sep 17 00:00:00 2001 From: Louis BOSSY Date: Sat, 16 May 2026 22:11:35 +0200 Subject: [PATCH 05/10] Apply some reviewers suggestions --- include/SampleClip.h | 1 - src/core/SampleClip.cpp | 6 ++---- src/gui/editors/PatternEditor.cpp | 10 +++------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/include/SampleClip.h b/include/SampleClip.h index c7985286e07..ea7853386e6 100644 --- a/include/SampleClip.h +++ b/include/SampleClip.h @@ -95,7 +95,6 @@ public slots: SampleClip( const SampleClip& orig ); private: - Track* m_sampleTrack; Sample m_sample; BoolModel m_recordModel; bool m_isPlaying; diff --git a/src/core/SampleClip.cpp b/src/core/SampleClip.cpp index d80153dea6d..4285b2479eb 100644 --- a/src/core/SampleClip.cpp +++ b/src/core/SampleClip.cpp @@ -38,7 +38,6 @@ namespace lmms SampleClip::SampleClip(Track* _track, Sample sample, bool isPlaying) : Clip(_track) - , m_sampleTrack(_track) , m_sample(std::move(sample)) , m_isPlaying(false) { @@ -77,7 +76,6 @@ SampleClip::SampleClip(Track* track) SampleClip::SampleClip(const SampleClip& orig) : Clip(orig), - m_sampleTrack(orig.m_sampleTrack), m_sample(std::move(orig.m_sample)), m_isPlaying(orig.m_isPlaying) { @@ -230,9 +228,9 @@ void SampleClip::updateLength() // If the clip has already been manually resized, don't automatically resize it. if (getAutoResize()) { - if (m_sampleTrack->trackContainer() == Engine::patternStore()) + if (getTrack()->trackContainer() == Engine::patternStore()) { - changeLength(TimePos::ticksPerBar() * Engine::patternStore()->lengthOfPattern(m_sampleTrack->getClipNum(this))); + changeLength(TimePos::ticksPerBar() * Engine::patternStore()->lengthOfPattern(getTrack()->getClipNum(this))); return; } changeLength(sampleLength()); diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index 3cf3d2e312a..dbe189c45e9 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -216,18 +216,14 @@ void PatternEditor::updateMaxSteps() m_maxClipLength = 0; for (const auto& track : tl) { - if (track->type() == Track::Type::Instrument) - { - auto mClip = static_cast(track->getClip(m_ps->currentPattern())); - m_maxClipLength = std::max(m_maxClipLength, static_cast(mClip->length())); - } - else + auto clip = track->getClip(m_ps->currentPattern()); + if (track->type() == Track::Type::Automation || track->type() == Track::Type::Sample) { // The length of automation and sample clips is updated here. // "Why here ?" will you ask. The answer is: Because. - auto clip = track->getClip(m_ps->currentPattern()); clip->updateLength(); } + m_maxClipLength = std::max(m_maxClipLength, static_cast(clip->length())); } updatePixelsPerBar(); } From 07e9a1e2aa0d59ebdbcf538ee901fd178312b06d Mon Sep 17 00:00:00 2001 From: bratpeki Date: Mon, 18 May 2026 18:19:53 +0200 Subject: [PATCH 06/10] Changed the comment to be more future-proof --- src/gui/editors/PatternEditor.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index dbe189c45e9..70c83fd756a 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -219,8 +219,7 @@ void PatternEditor::updateMaxSteps() auto clip = track->getClip(m_ps->currentPattern()); if (track->type() == Track::Type::Automation || track->type() == Track::Type::Sample) { - // The length of automation and sample clips is updated here. - // "Why here ?" will you ask. The answer is: Because. + // The length of automation and sample clips is updated to match the pattern length. clip->updateLength(); } m_maxClipLength = std::max(m_maxClipLength, static_cast(clip->length())); @@ -380,4 +379,4 @@ void PatternEditorWindow::stop() } -} // namespace lmms::gui \ No newline at end of file +} // namespace lmms::gui From 552da11ae2bd64165f39d21d0e8ea4e63830974b Mon Sep 17 00:00:00 2001 From: bratpeki Date: Mon, 18 May 2026 18:24:39 +0200 Subject: [PATCH 07/10] Added the missing newline --- src/gui/editors/PatternEditor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index 70c83fd756a..c3f22f42204 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -380,3 +380,4 @@ void PatternEditorWindow::stop() } // namespace lmms::gui + From 8558b622d23a166d940edae894e297f46091fc93 Mon Sep 17 00:00:00 2001 From: bratpeki Date: Mon, 18 May 2026 18:25:36 +0200 Subject: [PATCH 08/10] Nvm, reverting that, this is just POSIX weirdness --- src/gui/editors/PatternEditor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp index c3f22f42204..70c83fd756a 100644 --- a/src/gui/editors/PatternEditor.cpp +++ b/src/gui/editors/PatternEditor.cpp @@ -380,4 +380,3 @@ void PatternEditorWindow::stop() } // namespace lmms::gui - From 045d2558abeb62a40069951a32aab7bb7b20593f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Kati=C4=87?= Date: Thu, 21 May 2026 16:54:17 +0200 Subject: [PATCH 09/10] Update src/core/AutomationClip.cpp Co-authored-by: Dalton Messmer --- src/core/AutomationClip.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index 539fdd3a5a9..7821e177fe8 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -197,9 +197,9 @@ void AutomationClip::updateLength() // checks if it has been resized from either direction. if (getAutoResize()) { - if ( m_autoTrack != nullptr && m_autoTrack->trackContainer() == Engine::patternStore() ) + if (m_autoTrack != nullptr && m_autoTrack->trackContainer() == Engine::patternStore()) { - // If inside a pattern, the clip is always the lenght of it. + // If inside a pattern, the clip is always the length of it. changeLength(TimePos::ticksPerBar() * Engine::patternStore()->lengthOfPattern(m_autoTrack->getClipNum(this))); return; } From 7bb4daba38de2348f94f00de51868b8cb7dc54e3 Mon Sep 17 00:00:00 2001 From: Itreza2 <87203566+Itreza2@users.noreply.github.com> Date: Mon, 25 May 2026 09:09:17 +0200 Subject: [PATCH 10/10] comments --- src/core/PatternStore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/PatternStore.cpp b/src/core/PatternStore.cpp index 8d337da5581..7049fb82f69 100644 --- a/src/core/PatternStore.cpp +++ b/src/core/PatternStore.cpp @@ -88,7 +88,8 @@ bar_t PatternStore::lengthOfPattern(int pattern) const const TrackList & tl = tracks(); for (Track * t : tl) { - // Don't create Clips here if they don't exist + // Don't create Clips here if they don't exist, and only takes into account MIDI clips + // because the length of Automation / Sample clips is defined based on this method's output. if (pattern < t->numOfClips() && t->type() == Track::Type::Instrument) { maxLength = std::max(maxLength, t->getClip(pattern)->length());