From e99f963dd92623958c40a121a4354bebc4427a9e Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 15 Oct 2023 16:16:34 +0200 Subject: [PATCH 01/14] Set ghost notes in automation --- include/AutomationEditor.h | 22 ++++++++-- include/MidiClipView.h | 3 +- src/gui/clips/MidiClipView.cpp | 20 +++++++-- src/gui/editors/AutomationEditor.cpp | 66 +++++++++++++++++++++++++--- 4 files changed, 97 insertions(+), 14 deletions(-) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index dad0e4916f4..e906869aff6 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -26,16 +26,17 @@ #ifndef LMMS_GUI_AUTOMATION_EDITOR_H #define LMMS_GUI_AUTOMATION_EDITOR_H +#include #include #include +#include "AutomationClip.h" +#include "ComboBoxModel.h" #include "Editor.h" - -#include "lmms_basics.h" #include "JournallingObject.h" +#include "MidiClip.h" #include "TimePos.h" -#include "AutomationClip.h" -#include "ComboBoxModel.h" +#include "lmms_basics.h" class QPainter; class QPixmap; @@ -70,6 +71,7 @@ class AutomationEditor : public QWidget, public JournallingObject Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade) public: void setCurrentClip(AutomationClip * new_clip); + void setGhostMidiClip(MidiClip* newMidiClip); inline const AutomationClip * currentClip() const { @@ -159,6 +161,12 @@ protected slots: /// Updates the clip's quantization using the current user selected value. void setQuantization(); + void resetGhostNotes() + { + m_ghostNotes.clear(); + update(); + } + private: enum class Action @@ -211,6 +219,8 @@ protected slots: float m_bottomLevel; float m_topLevel; + NoteVector m_ghostNotes; + void centerTopBottomScroll(); void updateTopBottomLevels(); @@ -284,6 +294,8 @@ class AutomationEditorWindow : public Editor ~AutomationEditorWindow() override = default; void setCurrentClip(AutomationClip* clip); + void setGhostMidiClip(MidiClip* clip) { m_editor->setGhostMidiClip(clip); }; + const AutomationClip* currentClip(); void dropEvent( QDropEvent * _de ) override; @@ -337,6 +349,8 @@ private slots: ComboBox * m_zoomingXComboBox; ComboBox * m_zoomingYComboBox; ComboBox * m_quantizeComboBox; + + QPushButton* m_resetGhostNotes; }; } // namespace gui diff --git a/include/MidiClipView.h b/include/MidiClipView.h index 6558688b49b..13874996427 100644 --- a/include/MidiClipView.h +++ b/include/MidiClipView.h @@ -70,6 +70,7 @@ public slots: protected slots: void openInPianoRoll(); void setGhostInPianoRoll(); + void setGhostInAutomationEditor(); void resetName(); void changeName(); @@ -99,7 +100,7 @@ protected slots: QColor m_mutedNoteBorderColor; QStaticText m_staticTextName; - + bool m_legacySEPattern; } ; diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 151df8d3c3c..4aa1cd185b1 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -25,12 +25,13 @@ #include "MidiClipView.h" -#include #include #include #include #include +#include +#include "AutomationEditor.h" #include "ConfigManager.h" #include "DeprecationHelper.h" #include "GuiApplication.h" @@ -127,8 +128,13 @@ void MidiClipView::setGhostInPianoRoll() getGUI()->pianoRoll()->setFocus(); } - - +void MidiClipView::setGhostInAutomationEditor() +{ + getGUI()->automationEditor()->setGhostMidiClip(m_clip); + getGUI()->automationEditor()->parentWidget()->show(); + getGUI()->automationEditor()->show(); + getGUI()->automationEditor()->setFocus(); +} void MidiClipView::resetName() { m_clip->setName(""); } @@ -216,7 +222,13 @@ void MidiClipView::constructContextMenu( QMenu * _cm ) _cm->insertAction( _cm->actions()[1], b ); connect( b, SIGNAL(triggered(bool)), this, SLOT(setGhostInPianoRoll())); - _cm->insertSeparator( _cm->actions()[2] ); + + auto c = new QAction(embed::getIconPixmap("ghost_note"), tr("Set as ghost in automation editor"), _cm); + if (m_clip->empty()) { c->setEnabled(false); } + _cm->insertAction(_cm->actions()[2], c); + connect(c, SIGNAL(triggered(bool)), this, SLOT(setGhostInAutomationEditor())); + + _cm->insertSeparator(_cm->actions()[3]); _cm->addSeparator(); _cm->addAction( embed::getIconPixmap( "edit_erase" ), diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 282c335dfe1..e17e6de0281 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -27,8 +27,6 @@ #include "AutomationEditor.h" -#include - #include #include #include @@ -38,7 +36,9 @@ #include #include #include +#include +#include "MidiClip.h" #ifndef __USE_XOPEN #define __USE_XOPEN #endif @@ -1074,8 +1074,19 @@ inline void AutomationEditor::drawAutomationTangents(QPainter& p, timeMap::itera p.drawEllipse(tx - 3, ty - 3, 6, 6); } - - +void AutomationEditor::setGhostMidiClip(MidiClip* newMidiClip) +{ + // Expects a pointer to a MIDI clip or nullptr. + m_ghostNotes.clear(); + if (newMidiClip != nullptr) + { + for (Note* note : newMidiClip->notes()) + { + auto new_note = new Note(note->length(), note->pos(), note->key()); + m_ghostNotes.push_back(new_note); + } + } +} void AutomationEditor::paintEvent(QPaintEvent * pe ) { @@ -1261,6 +1272,42 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) p.drawLine( x, grid_bottom, x, x_line_end ); } + // draw ghost notes + // const NoteVector* currentMidiNotes = &(getGUI()->pianoRoll()->currentMidiClip()->notes()); + if (!m_ghostNotes.empty()) + { + int minKey = 128; + int maxKey = 0; + + for (const Note* note : m_ghostNotes) + { + int noteKey = note->key(); + + maxKey = std::max(maxKey, noteKey); + minKey = std::min(minKey, noteKey); + } + + for (const Note* note : m_ghostNotes) + { + int len_ticks = note->length(); + + if (len_ticks == 0) { continue; } + else if (len_ticks < 0) { len_ticks = 4; } + + int note_width = len_ticks * m_ppb / TimePos::ticksPerBar(); + + int noteMargin = 40; + int noteHeight = 10; + + float absLevel = (float)(note->key() - minKey) / (maxKey - minKey); + int graphHeight = grid_bottom - TOP_MARGIN - noteMargin - noteHeight; + const int y = (graphHeight - graphHeight * absLevel) + noteMargin / 2 + TOP_MARGIN; + + // p.setPen(QColor(248, 248, 255)); + p.fillRect(xCoordOfTick(note->pos()), y, note_width, noteHeight, QColor(248, 248, 255, 125)); + } + } + // and finally bars for( tick = m_currentPosition - m_currentPosition % TimePos::ticksPerBar(), x = xCoordOfTick( tick ); @@ -2159,8 +2206,17 @@ AutomationEditorWindow::AutomationEditorWindow() : quantizationActionsToolBar->addWidget( quantize_lbl ); quantizationActionsToolBar->addWidget( m_quantizeComboBox ); + m_resetGhostNotes = new QPushButton(m_toolBar); + m_resetGhostNotes->setIcon(embed::getIconPixmap("clear_ghost_note")); + m_resetGhostNotes->setToolTip(tr("Clear ghost notes")); + m_resetGhostNotes->setEnabled(true); + + connect(m_resetGhostNotes, SIGNAL(pressed()), m_editor, SLOT(resetGhostNotes())); + + quantizationActionsToolBar->addWidget(m_resetGhostNotes); + // Setup our actual window - setFocusPolicy( Qt::StrongFocus ); + setFocusPolicy(Qt::StrongFocus); setFocus(); setWindowIcon( embed::getIconPixmap( "automation" ) ); setAcceptDrops( true ); From 862eba0c9802e896f4106b4a0f6633ef7cd15c25 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 15 Oct 2023 16:50:54 +0200 Subject: [PATCH 02/14] Small GUI fixes --- data/themes/default/automation_ghost_note.png | Bin 0 -> 4467 bytes src/gui/clips/MidiClipView.cpp | 2 +- src/gui/editors/AutomationEditor.cpp | 2 ++ 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 data/themes/default/automation_ghost_note.png diff --git a/data/themes/default/automation_ghost_note.png b/data/themes/default/automation_ghost_note.png new file mode 100644 index 0000000000000000000000000000000000000000..d14c047d7aed311ea74bb7e725bc2b1681556b4e GIT binary patch literal 4467 zcmeHKdsGzH8J}Gca2qJ(sR2(n6K#YzJCA*jECks_R$QdA5~4OR%-mT9cXyWE0Ty#G zMn#dfrcE)8N=;5o4T(fat26~q#cGb2m}uK$Vnq$bM6D$$Hi?>8rFUkRSDSNsIH&oK z*>m^4e)o63?{~lZ?at<+!i9;N2Q>(SBs%l$OJRM#ToU5o_tE{{`LH?#N}asZnSmt0 z4n(SA5tWRAMK!LiR>dGOaBL$icf+=fk;{XsX-fTL*iMbMTVQ)`6eF)8Rca&=)~&Em zuzfGAUx!856xr+duq{6c%IAGGg4_dpBlSY3t4K@fNJ6JK!1V;Br%8e)jat$~>&-M_ zfcvXn8nZ}dT36Ct1?}4)+!kV>jby?E8@;46` zXt0V*%V)>BpL({tZtbZy;`Cs%>UDnR-|Q<-Tq=2c=i{--3$iy78D#N`1;2W3D6Q&joIZLjIOlhyg@rRn`o$L-zUdFU*{XFK=(_CRk+^4U1u-oEVz<5zx$ ztY6Z_ zc_XH2M{wV}N$$fi2E&58R4R2XrdiRaV>qz_=)%5$d|*gsb~wPWtAM1f03N|_L;ulz z2-OOl4Sn3`B3yx7P$}fE4uayH8BD%Q%O*;$&*FbxTOKw`9EpVuFv!!}gmrD0nh z#!;;TkyhEzQW!_MVi0HzI)jeD9ATlBLbEj5%pk|pOYM143fQxum68;oalEdsPFJVb zi9rueTCG-`pm2)9AOZ{3`z0of`9lxO6cG+P2(dvSAPJ&hD|0dxVvS@&Q8=$1vCkK9 zxkl;zp{NQ_4?N5Sa8gI$J|8}QMM!egLXxOK-?$>=t`7iwDF}%*K^8b_fnR!fJcWFN zMj2$6Jc2KvI0eO%=h(cGLbzb@=_fW1UVk4Bh(6pr}7J>ovWN+`b2bHC6JE?3WkvcMjHQ9Fg)ro zF6WF9k2CTA(j-#>j7u_bU1SU|YimquEr0d-^P6Tp6HE45G7IeAJB}vq>3iTD{=>lVi8b@* z-%7rga0Su#-*-lJ;CAN+JJhp|rx5BjO@B`f7d95Iefm$!VlK|uufEg!VagTZ`MzC^ zP15=4KOuL&mi$TfnKv&qn_ZurDLqlPsppZcH&tIe^GJOE=Sv>y_@L*W&%fHRdT>YJ zg^R~B?!?CRB;Q;#v@gS?EA_WL6>RQ&Y;Uuv{1;oVhO6;;zZ*Dpcj$W0E3GXnmM=T^ zoq{SyYES!)5AVPE-u0^82X{5O(WTA3IbY$X8@A3L9QyijT*>v$_qUo4Tv$~9Y)@9~ k&iTW0I=sCr)Sz;3CfYZ2w*Tk9mQ_WZjzat11?B7h4YN`c=>Px# literal 0 HcmV?d00001 diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 4aa1cd185b1..123e244beac 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -223,7 +223,7 @@ void MidiClipView::constructContextMenu( QMenu * _cm ) connect( b, SIGNAL(triggered(bool)), this, SLOT(setGhostInPianoRoll())); - auto c = new QAction(embed::getIconPixmap("ghost_note"), tr("Set as ghost in automation editor"), _cm); + auto c = new QAction(embed::getIconPixmap("automation_ghost_note"), tr("Set as ghost in automation editor"), _cm); if (m_clip->empty()) { c->setEnabled(false); } _cm->insertAction(_cm->actions()[2], c); connect(c, SIGNAL(triggered(bool)), this, SLOT(setGhostInAutomationEditor())); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index e17e6de0281..81c56856b2e 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1300,6 +1300,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int noteHeight = 10; float absLevel = (float)(note->key() - minKey) / (maxKey - minKey); + if (maxKey == minKey) { absLevel = 0.5f; } // center if one key int graphHeight = grid_bottom - TOP_MARGIN - noteMargin - noteHeight; const int y = (graphHeight - graphHeight * absLevel) + noteMargin / 2 + TOP_MARGIN; @@ -2213,6 +2214,7 @@ AutomationEditorWindow::AutomationEditorWindow() : connect(m_resetGhostNotes, SIGNAL(pressed()), m_editor, SLOT(resetGhostNotes())); + quantizationActionsToolBar->addSeparator(); quantizationActionsToolBar->addWidget(m_resetGhostNotes); // Setup our actual window From 6cc7db7b8cc2537ba239afa740d687668fa5b2bd Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 15 Oct 2023 17:33:27 +0200 Subject: [PATCH 03/14] Live clip update --- include/AutomationEditor.h | 4 ++-- src/gui/editors/AutomationEditor.cpp | 18 ++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index e906869aff6..a7870d6ae08 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -163,7 +163,7 @@ protected slots: void resetGhostNotes() { - m_ghostNotes.clear(); + m_ghostNotes = nullptr; update(); } @@ -219,7 +219,7 @@ protected slots: float m_bottomLevel; float m_topLevel; - NoteVector m_ghostNotes; + MidiClip* m_ghostNotes; void centerTopBottomScroll(); void updateTopBottomLevels(); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 81c56856b2e..f67b9e31531 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -39,6 +39,7 @@ #include #include "MidiClip.h" +#include "qobjectdefs.h" #ifndef __USE_XOPEN #define __USE_XOPEN #endif @@ -1077,15 +1078,7 @@ inline void AutomationEditor::drawAutomationTangents(QPainter& p, timeMap::itera void AutomationEditor::setGhostMidiClip(MidiClip* newMidiClip) { // Expects a pointer to a MIDI clip or nullptr. - m_ghostNotes.clear(); - if (newMidiClip != nullptr) - { - for (Note* note : newMidiClip->notes()) - { - auto new_note = new Note(note->length(), note->pos(), note->key()); - m_ghostNotes.push_back(new_note); - } - } + m_ghostNotes = newMidiClip; } void AutomationEditor::paintEvent(QPaintEvent * pe ) @@ -1274,12 +1267,13 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) // draw ghost notes // const NoteVector* currentMidiNotes = &(getGUI()->pianoRoll()->currentMidiClip()->notes()); - if (!m_ghostNotes.empty()) + if (m_ghostNotes != nullptr) { + const NoteVector& notes = m_ghostNotes->notes(); int minKey = 128; int maxKey = 0; - for (const Note* note : m_ghostNotes) + for (const Note* note : notes) { int noteKey = note->key(); @@ -1287,7 +1281,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) minKey = std::min(minKey, noteKey); } - for (const Note* note : m_ghostNotes) + for (const Note* note : notes) { int len_ticks = note->length(); From b0a39fabfdb56e96cd446eb3fc6750a5a65d9b53 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 15 Oct 2023 20:53:24 +0200 Subject: [PATCH 04/14] Added fixed min vert scaling --- data/themes/classic/style.css | 2 ++ data/themes/default/style.css | 1 + include/AutomationEditor.h | 6 ++++++ src/gui/editors/AutomationEditor.cpp | 23 ++++++++++++++--------- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 2b853395dc5..d757e706ed8 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -33,6 +33,8 @@ lmms--gui--AutomationEditor { qproperty-scaleColor: qlineargradient(spread:reflect, x1:0, y1:0.5, x2:1, y2:0.5, stop:0 #333, stop:1 #202020); + + qproperty-ghostNoteColor: rgba(248, 248, 255, 125); } /* text box */ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 9cbf5885be8..abc874009cf 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -66,6 +66,7 @@ lmms--gui--AutomationEditor { qproperty-graphColor: rgba(69,42,153,180); qproperty-scaleColor: #262b30; + qproperty-ghostNoteColor: rgba(248, 248, 255, 125); } /* text box */ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index a7870d6ae08..ce73f7839de 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -69,6 +69,7 @@ class AutomationEditor : public QWidget, public JournallingObject Q_PROPERTY(QBrush graphColor MEMBER m_graphColor) Q_PROPERTY(QColor crossColor MEMBER m_crossColor) Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade) + Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor) public: void setCurrentClip(AutomationClip * new_clip); void setGhostMidiClip(MidiClip* newMidiClip); @@ -191,6 +192,10 @@ protected slots: static const int VALUES_WIDTH = 64; + static const int NOTE_HEIGHT = 10; // height of individual notes + static const int NOTE_MARGIN = 40; // total border margin for notes + static const int MIN_NOTE_RANGE = 20; // min number of keys for fixed size + AutomationEditor(); AutomationEditor( const AutomationEditor & ); ~AutomationEditor() override; @@ -271,6 +276,7 @@ protected slots: QBrush m_scaleColor; QColor m_crossColor; QColor m_backgroundShade; + QColor m_ghostNoteColor; friend class AutomationEditorWindow; diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index f67b9e31531..e4f88bb8258 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -111,7 +111,8 @@ AutomationEditor::AutomationEditor() : m_nodeTangentLineColor(0, 0, 0), m_scaleColor(Qt::SolidPattern), m_crossColor(0, 0, 0), - m_backgroundShade(0, 0, 0) + m_backgroundShade(0, 0, 0), + m_ghostNoteColor(0, 0, 0) { connect( this, SIGNAL(currentClipChanged()), this, SLOT(updateAfterClipChange()), @@ -1289,17 +1290,21 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) else if (len_ticks < 0) { len_ticks = 4; } int note_width = len_ticks * m_ppb / TimePos::ticksPerBar(); + int keyRange = maxKey - minKey; - int noteMargin = 40; - int noteHeight = 10; + if (keyRange < MIN_NOTE_RANGE) + { + int padding = (MIN_NOTE_RANGE - keyRange) / 2.0f; + maxKey += padding; + minKey -= padding; + keyRange = MIN_NOTE_RANGE; + } - float absLevel = (float)(note->key() - minKey) / (maxKey - minKey); - if (maxKey == minKey) { absLevel = 0.5f; } // center if one key - int graphHeight = grid_bottom - TOP_MARGIN - noteMargin - noteHeight; - const int y = (graphHeight - graphHeight * absLevel) + noteMargin / 2 + TOP_MARGIN; + float absNoteHeight = (float)(note->key() - minKey) / (maxKey - minKey); + int graphHeight = grid_bottom - NOTE_HEIGHT - NOTE_MARGIN - TOP_MARGIN; + const int y = (graphHeight - graphHeight * absNoteHeight) + NOTE_HEIGHT / 2.0f + TOP_MARGIN; - // p.setPen(QColor(248, 248, 255)); - p.fillRect(xCoordOfTick(note->pos()), y, note_width, noteHeight, QColor(248, 248, 255, 125)); + p.fillRect(xCoordOfTick(note->pos()), y, note_width, NOTE_HEIGHT, m_ghostNoteColor); } } From 680e653f96701bc4ee0459c2f4ca3dda55c54c57 Mon Sep 17 00:00:00 2001 From: DanielKauss <47889291+DanielKauss@users.noreply.github.com> Date: Mon, 16 Oct 2023 01:49:32 +0200 Subject: [PATCH 05/14] cleanup menu interaction code Co-authored-by: IanCaio --- src/gui/clips/MidiClipView.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 123e244beac..c10773a605d 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -130,10 +130,11 @@ void MidiClipView::setGhostInPianoRoll() void MidiClipView::setGhostInAutomationEditor() { - getGUI()->automationEditor()->setGhostMidiClip(m_clip); - getGUI()->automationEditor()->parentWidget()->show(); - getGUI()->automationEditor()->show(); - getGUI()->automationEditor()->setFocus(); + auto aEditor = getGUI()->automationEditor(); + aEditor->setGhostMidiClip(m_clip); + aEditor->parentWidget()->show(); + aEditor->show(); + aEditor->setFocus(); } void MidiClipView::resetName() { m_clip->setName(""); } From 02d844d5b2c1eb3cbeb8c711fdb82ce9cb63eb33 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Mon, 16 Oct 2023 01:59:33 +0200 Subject: [PATCH 06/14] review changes --- src/gui/clips/MidiClipView.cpp | 18 ++++++++++-------- src/gui/editors/AutomationEditor.cpp | 1 - 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index c10773a605d..0e0657221aa 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -110,10 +110,11 @@ void MidiClipView::update() void MidiClipView::openInPianoRoll() { - getGUI()->pianoRoll()->setCurrentMidiClip( m_clip ); - getGUI()->pianoRoll()->parentWidget()->show(); - getGUI()->pianoRoll()->show(); - getGUI()->pianoRoll()->setFocus(); + auto pRoll = getGUI()->pianoRoll(); + pRoll->setCurrentMidiClip(m_clip); + pRoll->parentWidget()->show(); + pRoll->show(); + pRoll->setFocus(); } @@ -122,10 +123,11 @@ void MidiClipView::openInPianoRoll() void MidiClipView::setGhostInPianoRoll() { - getGUI()->pianoRoll()->setGhostMidiClip( m_clip ); - getGUI()->pianoRoll()->parentWidget()->show(); - getGUI()->pianoRoll()->show(); - getGUI()->pianoRoll()->setFocus(); + auto pRoll = getGUI()->pianoRoll(); + pRoll->setGhostMidiClip(m_clip); + pRoll->parentWidget()->show(); + pRoll->show(); + pRoll->setFocus(); } void MidiClipView::setGhostInAutomationEditor() diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index e4f88bb8258..f5445f30fd0 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1267,7 +1267,6 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) } // draw ghost notes - // const NoteVector* currentMidiNotes = &(getGUI()->pianoRoll()->currentMidiClip()->notes()); if (m_ghostNotes != nullptr) { const NoteVector& notes = m_ghostNotes->notes(); From 00fbe796263dfcc89b2f6689b148a2f4c5be7558 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Wed, 18 Oct 2023 19:38:12 +0200 Subject: [PATCH 07/14] detuning support --- data/themes/classic/style.css | 1 + data/themes/default/style.css | 1 + include/AutomationEditor.h | 5 ++++- src/gui/editors/AutomationEditor.cpp | 28 +++++++++++++++++++++++----- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index d757e706ed8..a394666e2c4 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -35,6 +35,7 @@ lmms--gui--AutomationEditor { stop:0 #333, stop:1 #202020); qproperty-ghostNoteColor: rgba(248, 248, 255, 125); + qproperty-detuningNoteColor: rgba(248, 11, 11, 125); } /* text box */ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index abc874009cf..3b7117a4130 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -67,6 +67,7 @@ lmms--gui--AutomationEditor { qproperty-graphColor: rgba(69,42,153,180); qproperty-scaleColor: #262b30; qproperty-ghostNoteColor: rgba(248, 248, 255, 125); + qproperty-detuningNoteColor: rgba(248, 11, 11, 125); } /* text box */ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index ce73f7839de..825afb86936 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -37,6 +37,7 @@ #include "MidiClip.h" #include "TimePos.h" #include "lmms_basics.h" +#include "qcolor.h" class QPainter; class QPixmap; @@ -70,6 +71,7 @@ class AutomationEditor : public QWidget, public JournallingObject Q_PROPERTY(QColor crossColor MEMBER m_crossColor) Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade) Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor) + Q_PROPERTY(QColor detuningNoteColor MEMBER m_detuningNoteColor) public: void setCurrentClip(AutomationClip * new_clip); void setGhostMidiClip(MidiClip* newMidiClip); @@ -224,7 +226,7 @@ protected slots: float m_bottomLevel; float m_topLevel; - MidiClip* m_ghostNotes; + MidiClip* m_ghostNotes = nullptr; void centerTopBottomScroll(); void updateTopBottomLevels(); @@ -277,6 +279,7 @@ protected slots: QColor m_crossColor; QColor m_backgroundShade; QColor m_ghostNoteColor; + QColor m_detuningNoteColor; friend class AutomationEditorWindow; diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index f5445f30fd0..46ba3ff31d0 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -49,6 +49,7 @@ #include "ComboBox.h" #include "debug.h" #include "DeprecationHelper.h" +#include "DetuningHelper.h" #include "embed.h" #include "Engine.h" #include "GuiApplication.h" @@ -1272,23 +1273,35 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) const NoteVector& notes = m_ghostNotes->notes(); int minKey = 128; int maxKey = 0; + int detuningOffset = 0; + const Note* detuningNote = nullptr; for (const Note* note : notes) { int noteKey = note->key(); + if (note->detuning()->automationClip() == m_clip) { + detuningOffset = note->pos(); + detuningNote = note; + } + maxKey = std::max(maxKey, noteKey); minKey = std::min(minKey, noteKey); } for (const Note* note : notes) { - int len_ticks = note->length(); + int lenTicks = note->length(); + int notePos = note->pos(); - if (len_ticks == 0) { continue; } - else if (len_ticks < 0) { len_ticks = 4; } + // offset note if detuning + if (notePos < detuningOffset) { continue; } + notePos -= detuningOffset; - int note_width = len_ticks * m_ppb / TimePos::ticksPerBar(); + if (lenTicks == 0) { continue; } + else if (lenTicks < 0) { lenTicks = 4; } + + int note_width = lenTicks * m_ppb / TimePos::ticksPerBar(); int keyRange = maxKey - minKey; if (keyRange < MIN_NOTE_RANGE) @@ -1302,8 +1315,13 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) float absNoteHeight = (float)(note->key() - minKey) / (maxKey - minKey); int graphHeight = grid_bottom - NOTE_HEIGHT - NOTE_MARGIN - TOP_MARGIN; const int y = (graphHeight - graphHeight * absNoteHeight) + NOTE_HEIGHT / 2.0f + TOP_MARGIN; + const int x = xCoordOfTick(notePos); - p.fillRect(xCoordOfTick(note->pos()), y, note_width, NOTE_HEIGHT, m_ghostNoteColor); + if (note == detuningNote) { + p.fillRect(x, y, note_width, NOTE_HEIGHT, m_detuningNoteColor); + } else { + p.fillRect(x, y, note_width, NOTE_HEIGHT, m_ghostNoteColor); + } } } From 9b012664cbb35525b0722cdf37ee0831387176a8 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 22 Oct 2023 12:00:21 +0200 Subject: [PATCH 08/14] Review changes connect + c cast --- src/gui/clips/MidiClipView.cpp | 2 +- src/gui/editors/AutomationEditor.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 0e0657221aa..f078364facb 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -229,7 +229,7 @@ void MidiClipView::constructContextMenu( QMenu * _cm ) auto c = new QAction(embed::getIconPixmap("automation_ghost_note"), tr("Set as ghost in automation editor"), _cm); if (m_clip->empty()) { c->setEnabled(false); } _cm->insertAction(_cm->actions()[2], c); - connect(c, SIGNAL(triggered(bool)), this, SLOT(setGhostInAutomationEditor())); + connect(c, &QAction::triggered, this, &MidiClipView::setGhostInAutomationEditor); _cm->insertSeparator(_cm->actions()[3]); _cm->addSeparator(); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 46ba3ff31d0..48354d18b12 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1312,7 +1312,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) keyRange = MIN_NOTE_RANGE; } - float absNoteHeight = (float)(note->key() - minKey) / (maxKey - minKey); + float absNoteHeight = static_cast(note->key() - minKey) / (maxKey - minKey); int graphHeight = grid_bottom - NOTE_HEIGHT - NOTE_MARGIN - TOP_MARGIN; const int y = (graphHeight - graphHeight * absNoteHeight) + NOTE_HEIGHT / 2.0f + TOP_MARGIN; const int x = xCoordOfTick(notePos); @@ -2228,7 +2228,7 @@ AutomationEditorWindow::AutomationEditorWindow() : m_resetGhostNotes->setToolTip(tr("Clear ghost notes")); m_resetGhostNotes->setEnabled(true); - connect(m_resetGhostNotes, SIGNAL(pressed()), m_editor, SLOT(resetGhostNotes())); + connect(m_resetGhostNotes, &QPushButton::pressed, m_editor, &AutomationEditor::resetGhostNotes); quantizationActionsToolBar->addSeparator(); quantizationActionsToolBar->addWidget(m_resetGhostNotes); From 780e80cc40e77eaa29d71b21ee799935704e149f Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Sun, 22 Oct 2023 12:13:50 +0200 Subject: [PATCH 09/14] open on detune + detune fix --- src/gui/editors/AutomationEditor.cpp | 3 ++- src/gui/editors/PianoRoll.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 48354d18b12..016b5572092 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1295,9 +1295,10 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int notePos = note->pos(); // offset note if detuning - if (notePos < detuningOffset) { continue; } + if (notePos+lenTicks < detuningOffset) { continue; } notePos -= detuningOffset; + // remove/change after #5902 if (lenTicks == 0) { continue; } else if (lenTicks < 0) { lenTicks = 4; } diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index cef2205d266..3028ce85a7d 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1670,6 +1670,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) } detuningClip = n->detuning()->automationClip(); connect(detuningClip.data(), SIGNAL(dataChanged()), this, SLOT(update())); + getGUI()->automationEditor()->setGhostMidiClip(m_midiClip); getGUI()->automationEditor()->open(detuningClip); return; } From 7735d5913047b76c43d06d9d75bb920747d63a59 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Tue, 31 Oct 2023 16:04:47 +0100 Subject: [PATCH 10/14] include cleanup + icon to classic theme --- data/themes/classic/automation_ghost_note.png | Bin 0 -> 4467 bytes include/AutomationEditor.h | 1 - src/gui/editors/AutomationEditor.cpp | 3 +-- 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 data/themes/classic/automation_ghost_note.png diff --git a/data/themes/classic/automation_ghost_note.png b/data/themes/classic/automation_ghost_note.png new file mode 100644 index 0000000000000000000000000000000000000000..d14c047d7aed311ea74bb7e725bc2b1681556b4e GIT binary patch literal 4467 zcmeHKdsGzH8J}Gca2qJ(sR2(n6K#YzJCA*jECks_R$QdA5~4OR%-mT9cXyWE0Ty#G zMn#dfrcE)8N=;5o4T(fat26~q#cGb2m}uK$Vnq$bM6D$$Hi?>8rFUkRSDSNsIH&oK z*>m^4e)o63?{~lZ?at<+!i9;N2Q>(SBs%l$OJRM#ToU5o_tE{{`LH?#N}asZnSmt0 z4n(SA5tWRAMK!LiR>dGOaBL$icf+=fk;{XsX-fTL*iMbMTVQ)`6eF)8Rca&=)~&Em zuzfGAUx!856xr+duq{6c%IAGGg4_dpBlSY3t4K@fNJ6JK!1V;Br%8e)jat$~>&-M_ zfcvXn8nZ}dT36Ct1?}4)+!kV>jby?E8@;46` zXt0V*%V)>BpL({tZtbZy;`Cs%>UDnR-|Q<-Tq=2c=i{--3$iy78D#N`1;2W3D6Q&joIZLjIOlhyg@rRn`o$L-zUdFU*{XFK=(_CRk+^4U1u-oEVz<5zx$ ztY6Z_ zc_XH2M{wV}N$$fi2E&58R4R2XrdiRaV>qz_=)%5$d|*gsb~wPWtAM1f03N|_L;ulz z2-OOl4Sn3`B3yx7P$}fE4uayH8BD%Q%O*;$&*FbxTOKw`9EpVuFv!!}gmrD0nh z#!;;TkyhEzQW!_MVi0HzI)jeD9ATlBLbEj5%pk|pOYM143fQxum68;oalEdsPFJVb zi9rueTCG-`pm2)9AOZ{3`z0of`9lxO6cG+P2(dvSAPJ&hD|0dxVvS@&Q8=$1vCkK9 zxkl;zp{NQ_4?N5Sa8gI$J|8}QMM!egLXxOK-?$>=t`7iwDF}%*K^8b_fnR!fJcWFN zMj2$6Jc2KvI0eO%=h(cGLbzb@=_fW1UVk4Bh(6pr}7J>ovWN+`b2bHC6JE?3WkvcMjHQ9Fg)ro zF6WF9k2CTA(j-#>j7u_bU1SU|YimquEr0d-^P6Tp6HE45G7IeAJB}vq>3iTD{=>lVi8b@* z-%7rga0Su#-*-lJ;CAN+JJhp|rx5BjO@B`f7d95Iefm$!VlK|uufEg!VagTZ`MzC^ zP15=4KOuL&mi$TfnKv&qn_ZurDLqlPsppZcH&tIe^GJOE=Sv>y_@L*W&%fHRdT>YJ zg^R~B?!?CRB;Q;#v@gS?EA_WL6>RQ&Y;Uuv{1;oVhO6;;zZ*Dpcj$W0E3GXnmM=T^ zoq{SyYES!)5AVPE-u0^82X{5O(WTA3IbY$X8@A3L9QyijT*>v$_qUo4Tv$~9Y)@9~ k&iTW0I=sCr)Sz;3CfYZ2w*Tk9mQ_WZjzat11?B7h4YN`c=>Px# literal 0 HcmV?d00001 diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 825afb86936..1f94dfae27b 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -37,7 +37,6 @@ #include "MidiClip.h" #include "TimePos.h" #include "lmms_basics.h" -#include "qcolor.h" class QPainter; class QPixmap; diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 016b5572092..af17318cdac 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -38,8 +38,6 @@ #include #include -#include "MidiClip.h" -#include "qobjectdefs.h" #ifndef __USE_XOPEN #define __USE_XOPEN #endif @@ -56,6 +54,7 @@ #include "gui_templates.h" #include "Knob.h" #include "MainWindow.h" +#include "MidiClip.h" #include "PatternStore.h" #include "PianoRoll.h" #include "ProjectJournal.h" From 6921ce5d3c4d0131edc88a177de67c7dec6a25fe Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Thu, 16 Nov 2023 23:52:10 +0100 Subject: [PATCH 11/14] Add sample ghost for automation --- data/themes/classic/style.css | 1 + data/themes/default/style.css | 1 + include/AutomationEditor.h | 10 ++++++++ include/SampleClipView.h | 1 + src/gui/clips/SampleClipView.cpp | 16 +++++++++++++ src/gui/editors/AutomationEditor.cpp | 35 ++++++++++++++++++++++++---- 6 files changed, 60 insertions(+), 4 deletions(-) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index a394666e2c4..4e304bf478f 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -36,6 +36,7 @@ lmms--gui--AutomationEditor { qproperty-ghostNoteColor: rgba(248, 248, 255, 125); qproperty-detuningNoteColor: rgba(248, 11, 11, 125); + qproperty-ghostSampleColor: rgba(125, 125, 125, 125); } /* text box */ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 3b7117a4130..3433a54caef 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -68,6 +68,7 @@ lmms--gui--AutomationEditor { qproperty-scaleColor: #262b30; qproperty-ghostNoteColor: rgba(248, 248, 255, 125); qproperty-detuningNoteColor: rgba(248, 11, 11, 125); + qproperty-ghostSampleColor: rgba(125, 125, 125, 125); } /* text box */ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 1f94dfae27b..255270fd30f 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -35,6 +35,7 @@ #include "Editor.h" #include "JournallingObject.h" #include "MidiClip.h" +#include "SampleClip.h" #include "TimePos.h" #include "lmms_basics.h" @@ -71,9 +72,11 @@ class AutomationEditor : public QWidget, public JournallingObject Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade) Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor) Q_PROPERTY(QColor detuningNoteColor MEMBER m_detuningNoteColor) + Q_PROPERTY(QColor ghostSampleColor MEMBER m_ghostSampleColor) public: void setCurrentClip(AutomationClip * new_clip); void setGhostMidiClip(MidiClip* newMidiClip); + void setGhostSample(SampleClip* newSample); inline const AutomationClip * currentClip() const { @@ -166,6 +169,7 @@ protected slots: void resetGhostNotes() { m_ghostNotes = nullptr; + m_ghostSample = nullptr; update(); } @@ -196,6 +200,8 @@ protected slots: static const int NOTE_HEIGHT = 10; // height of individual notes static const int NOTE_MARGIN = 40; // total border margin for notes static const int MIN_NOTE_RANGE = 20; // min number of keys for fixed size + static const int SAMPLE_MARGIN = 40; + static const int MAX_SAMPLE_HEIGHT = 400; AutomationEditor(); AutomationEditor( const AutomationEditor & ); @@ -226,6 +232,8 @@ protected slots: float m_topLevel; MidiClip* m_ghostNotes = nullptr; + QPointer m_ghostSample = nullptr; // QPointer to set to nullptr on deletion + bool m_renderSample = false; void centerTopBottomScroll(); void updateTopBottomLevels(); @@ -279,6 +287,7 @@ protected slots: QColor m_backgroundShade; QColor m_ghostNoteColor; QColor m_detuningNoteColor; + QColor m_ghostSampleColor; friend class AutomationEditorWindow; @@ -303,6 +312,7 @@ class AutomationEditorWindow : public Editor void setCurrentClip(AutomationClip* clip); void setGhostMidiClip(MidiClip* clip) { m_editor->setGhostMidiClip(clip); }; + void setGhostSample(SampleClip* newSample) { m_editor->setGhostSample(newSample); }; const AutomationClip* currentClip(); diff --git a/include/SampleClipView.h b/include/SampleClipView.h index b3f53d79092..4ff218fb0ef 100644 --- a/include/SampleClipView.h +++ b/include/SampleClipView.h @@ -47,6 +47,7 @@ class SampleClipView : public ClipView public slots: void updateSample(); void reverseSample(); + void setAutomationGhost(); diff --git a/src/gui/clips/SampleClipView.cpp b/src/gui/clips/SampleClipView.cpp index e21a7e30be1..6c6e48da0e4 100644 --- a/src/gui/clips/SampleClipView.cpp +++ b/src/gui/clips/SampleClipView.cpp @@ -28,6 +28,8 @@ #include #include +#include "GuiApplication.h" +#include "AutomationEditor.h" #include "embed.h" #include "PathUtil.h" #include "SampleBuffer.h" @@ -83,6 +85,12 @@ void SampleClipView::constructContextMenu(QMenu* cm) SLOT(reverseSample()) ); + cm->addAction( + embed::getIconPixmap("automation_ghost_note"), + tr("Set as ghost in automation editor"), + this, + SLOT(setAutomationGhost()) + ); } @@ -325,6 +333,14 @@ void SampleClipView::reverseSample() +void SampleClipView::setAutomationGhost() +{ + auto aEditor = gui::getGUI()->automationEditor(); + aEditor->setGhostSample(m_clip); + aEditor->parentWidget()->show(); + aEditor->show(); + aEditor->setFocus(); +} //! Split this Clip. /*! \param pos the position of the split, relative to the start of the clip */ diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index af17318cdac..21bcce7ac3f 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -38,6 +38,8 @@ #include #include +#include "SampleClip.h" + #ifndef __USE_XOPEN #define __USE_XOPEN #endif @@ -45,22 +47,23 @@ #include "ActionGroup.h" #include "AutomationNode.h" #include "ComboBox.h" -#include "debug.h" #include "DeprecationHelper.h" #include "DetuningHelper.h" -#include "embed.h" #include "Engine.h" #include "GuiApplication.h" -#include "gui_templates.h" #include "Knob.h" #include "MainWindow.h" #include "MidiClip.h" #include "PatternStore.h" #include "PianoRoll.h" #include "ProjectJournal.h" +#include "SampleBuffer.h" #include "StringPairDrag.h" #include "TextFloat.h" #include "TimeLineWidget.h" +#include "debug.h" +#include "embed.h" +#include "gui_templates.h" namespace lmms::gui @@ -1080,6 +1083,14 @@ void AutomationEditor::setGhostMidiClip(MidiClip* newMidiClip) { // Expects a pointer to a MIDI clip or nullptr. m_ghostNotes = newMidiClip; + m_renderSample = false; +} + +void AutomationEditor::setGhostSample(SampleClip* newGhostSample) +{ + // Expects a pointer to a Sample buffer or nullptr. + m_ghostSample = newGhostSample; + m_renderSample = true; } void AutomationEditor::paintEvent(QPaintEvent * pe ) @@ -1266,8 +1277,24 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) p.drawLine( x, grid_bottom, x, x_line_end ); } + // draw ghost sample + if (m_ghostSample != nullptr && m_ghostSample->sampleBuffer()->frames() > 1 && m_renderSample) + { + int sampleFrames = m_ghostSample->sampleBuffer()->frames(); + int length = static_cast(sampleFrames) / Engine::framesPerTick(); + int editorHeight = grid_bottom - TOP_MARGIN; + + int startPos = xCoordOfTick(0); + int sampleWidth = xCoordOfTick(length) - startPos; + int sampleHeight = std::min(editorHeight - SAMPLE_MARGIN, MAX_SAMPLE_HEIGHT); + int yOffset = (editorHeight - sampleHeight) / 2.0f + TOP_MARGIN; + + p.setPen(m_ghostSampleColor); + m_ghostSample->sampleBuffer()->visualize(p, QRect(startPos, yOffset, sampleWidth, sampleHeight), 0, sampleFrames); + } + // draw ghost notes - if (m_ghostNotes != nullptr) + if (m_ghostNotes != nullptr && !m_renderSample) { const NoteVector& notes = m_ghostNotes->notes(); int minKey = 128; From b39659cd73a7fef55839c273f114e143d933bc77 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Mon, 20 Nov 2023 22:48:28 +0100 Subject: [PATCH 12/14] Fix weird debug mode error --- src/gui/editors/AutomationEditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index c8ef19b79bd..4a7dee2dc52 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1244,7 +1244,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int startPos = xCoordOfTick(0); int sampleWidth = xCoordOfTick(length) - startPos; - int sampleHeight = std::min(editorHeight - SAMPLE_MARGIN, MAX_SAMPLE_HEIGHT); + int sampleHeight = editorHeight - SAMPLE_MARGIN < MAX_SAMPLE_HEIGHT ? editorHeight - SAMPLE_MARGIN : MAX_SAMPLE_HEIGHT; int yOffset = (editorHeight - sampleHeight) / 2.0f + TOP_MARGIN; p.setPen(m_ghostSampleColor); From 64a2e93e11689191fec90d6bd30e9cfac54e4df6 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Mon, 20 Nov 2023 23:49:34 +0100 Subject: [PATCH 13/14] Add comment to ternary workaround --- src/gui/editors/AutomationEditor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 4a7dee2dc52..97068546fc0 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1244,6 +1244,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int startPos = xCoordOfTick(0); int sampleWidth = xCoordOfTick(length) - startPos; + // workaround due to weird behaviour with std::min() int sampleHeight = editorHeight - SAMPLE_MARGIN < MAX_SAMPLE_HEIGHT ? editorHeight - SAMPLE_MARGIN : MAX_SAMPLE_HEIGHT; int yOffset = (editorHeight - sampleHeight) / 2.0f + TOP_MARGIN; From f4b9a3738d4a23bf6f8e3466291e645fb6575c96 Mon Sep 17 00:00:00 2001 From: Daniel Kauss Date: Tue, 21 Nov 2023 00:02:22 +0100 Subject: [PATCH 14/14] Use constexpr for std::min --- include/AutomationEditor.h | 2 +- src/gui/editors/AutomationEditor.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 46a7b8dc8fd..1110e8e4c9e 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -201,7 +201,7 @@ protected slots: static const int NOTE_MARGIN = 40; // total border margin for notes static const int MIN_NOTE_RANGE = 20; // min number of keys for fixed size static const int SAMPLE_MARGIN = 40; - static const int MAX_SAMPLE_HEIGHT = 400; + static constexpr int MAX_SAMPLE_HEIGHT = 400; // constexpr for use in min AutomationEditor(); AutomationEditor( const AutomationEditor & ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 97068546fc0..c8ef19b79bd 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -1244,8 +1244,7 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) int startPos = xCoordOfTick(0); int sampleWidth = xCoordOfTick(length) - startPos; - // workaround due to weird behaviour with std::min() - int sampleHeight = editorHeight - SAMPLE_MARGIN < MAX_SAMPLE_HEIGHT ? editorHeight - SAMPLE_MARGIN : MAX_SAMPLE_HEIGHT; + int sampleHeight = std::min(editorHeight - SAMPLE_MARGIN, MAX_SAMPLE_HEIGHT); int yOffset = (editorHeight - sampleHeight) / 2.0f + TOP_MARGIN; p.setPen(m_ghostSampleColor);