Skip to content

Commit

Permalink
Ghost notes for the automation editor (#6940)
Browse files Browse the repository at this point in the history
Show ghost notes or sample track as a visual aid in the Automation Editor.

---------

Co-authored-by: IanCaio <iancaio_dev@hotmail.com>
  • Loading branch information
DanielKauss and IanCaio authored Nov 25, 2023
1 parent 3a928d8 commit c2811ae
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 24 deletions.
Binary file added data/themes/classic/automation_ghost_note.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions data/themes/classic/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ 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);
qproperty-detuningNoteColor: rgba(248, 11, 11, 125);
qproperty-ghostSampleColor: rgba(125, 125, 125, 125);
}

/* text box */
Expand Down
Binary file added data/themes/default/automation_ghost_note.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions data/themes/default/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ 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);
qproperty-ghostSampleColor: rgba(125, 125, 125, 125);
}

/* text box */
Expand Down
40 changes: 36 additions & 4 deletions include/AutomationEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
#ifndef LMMS_GUI_AUTOMATION_EDITOR_H
#define LMMS_GUI_AUTOMATION_EDITOR_H

#include <QPushButton>
#include <QWidget>
#include <array>

#include "AutomationClip.h"
#include "ComboBoxModel.h"
#include "Editor.h"

#include "lmms_basics.h"
#include "JournallingObject.h"
#include "MidiClip.h"
#include "SampleClip.h"
#include "TimePos.h"
#include "AutomationClip.h"
#include "ComboBoxModel.h"
#include "lmms_basics.h"

class QPainter;
class QPixmap;
Expand Down Expand Up @@ -68,8 +70,13 @@ 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)
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
{
Expand Down Expand Up @@ -159,6 +166,13 @@ protected slots:
/// Updates the clip's quantization using the current user selected value.
void setQuantization();

void resetGhostNotes()
{
m_ghostNotes = nullptr;
m_ghostSample = nullptr;
update();
}

private:

enum class Action
Expand All @@ -183,6 +197,12 @@ 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
static const int SAMPLE_MARGIN = 40;
static constexpr int MAX_SAMPLE_HEIGHT = 400; // constexpr for use in min

AutomationEditor();
AutomationEditor( const AutomationEditor & );
~AutomationEditor() override;
Expand Down Expand Up @@ -211,6 +231,10 @@ protected slots:
float m_bottomLevel;
float m_topLevel;

MidiClip* m_ghostNotes = nullptr;
QPointer<SampleClip> m_ghostSample = nullptr; // QPointer to set to nullptr on deletion
bool m_renderSample = false;

void centerTopBottomScroll();
void updateTopBottomLevels();

Expand Down Expand Up @@ -261,6 +285,9 @@ protected slots:
QBrush m_scaleColor;
QColor m_crossColor;
QColor m_backgroundShade;
QColor m_ghostNoteColor;
QColor m_detuningNoteColor;
QColor m_ghostSampleColor;

friend class AutomationEditorWindow;

Expand All @@ -284,6 +311,9 @@ class AutomationEditorWindow : public Editor
~AutomationEditorWindow() override = default;

void setCurrentClip(AutomationClip* clip);
void setGhostMidiClip(MidiClip* clip) { m_editor->setGhostMidiClip(clip); };
void setGhostSample(SampleClip* newSample) { m_editor->setGhostSample(newSample); };

const AutomationClip* currentClip();

void dropEvent( QDropEvent * _de ) override;
Expand Down Expand Up @@ -337,6 +367,8 @@ private slots:
ComboBox * m_zoomingXComboBox;
ComboBox * m_zoomingYComboBox;
ComboBox * m_quantizeComboBox;

QPushButton* m_resetGhostNotes;
};

} // namespace gui
Expand Down
3 changes: 2 additions & 1 deletion include/MidiClipView.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public slots:
protected slots:
void openInPianoRoll();
void setGhostInPianoRoll();
void setGhostInAutomationEditor();

void resetName();
void changeName();
Expand Down Expand Up @@ -100,7 +101,7 @@ protected slots:
QColor m_mutedNoteBorderColor;

QStaticText m_staticTextName;

bool m_legacySEPattern;
} ;

Expand Down
1 change: 1 addition & 0 deletions include/SampleClipView.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class SampleClipView : public ClipView
public slots:
void updateSample();
void reverseSample();
void setAutomationGhost();



Expand Down
39 changes: 28 additions & 11 deletions src/gui/clips/MidiClipView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@

#include "MidiClipView.h"


#include <algorithm>
#include <cmath>
#include <QApplication>
#include <QInputDialog>
#include <QMenu>
#include <QPainter>
#include <cmath>

#include "AutomationEditor.h"
#include "ConfigManager.h"
#include "DeprecationHelper.h"
#include "GuiApplication.h"
Expand Down Expand Up @@ -85,10 +88,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();
}


Expand All @@ -97,14 +101,21 @@ 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()
{
auto aEditor = getGUI()->automationEditor();
aEditor->setGhostMidiClip(m_clip);
aEditor->parentWidget()->show();
aEditor->show();
aEditor->setFocus();
}

void MidiClipView::resetName() { m_clip->setName(""); }

Expand Down Expand Up @@ -192,7 +203,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("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, &QAction::triggered, this, &MidiClipView::setGhostInAutomationEditor);

_cm->insertSeparator(_cm->actions()[3]);
_cm->addSeparator();

_cm->addAction( embed::getIconPixmap( "edit_erase" ),
Expand Down
16 changes: 16 additions & 0 deletions src/gui/clips/SampleClipView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <QMenu>
#include <QPainter>

#include "GuiApplication.h"
#include "AutomationEditor.h"
#include "embed.h"
#include "PathUtil.h"
#include "SampleBuffer.h"
Expand Down Expand Up @@ -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())
);

}

Expand Down Expand Up @@ -321,6 +329,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 */
Expand Down
Loading

0 comments on commit c2811ae

Please sign in to comment.