Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions data/themes/classic/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
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.
1 change: 1 addition & 0 deletions data/themes/default/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
28 changes: 24 additions & 4 deletions include/AutomationEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@
#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 "TimePos.h"
#include "AutomationClip.h"
#include "ComboBoxModel.h"
#include "lmms_basics.h"

class QPainter;
class QPixmap;
Expand Down Expand Up @@ -68,8 +69,10 @@ 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);

inline const AutomationClip * currentClip() const
{
Expand Down Expand Up @@ -159,6 +162,12 @@ protected slots:
/// Updates the clip's quantization using the current user selected value.
void setQuantization();

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

private:

enum class Action
Expand All @@ -183,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;
Expand Down Expand Up @@ -211,6 +224,8 @@ protected slots:
float m_bottomLevel;
float m_topLevel;

MidiClip* m_ghostNotes;

void centerTopBottomScroll();
void updateTopBottomLevels();

Expand Down Expand Up @@ -261,6 +276,7 @@ protected slots:
QBrush m_scaleColor;
QColor m_crossColor;
QColor m_backgroundShade;
QColor m_ghostNoteColor;

friend class AutomationEditorWindow;

Expand All @@ -284,6 +300,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;
Expand Down Expand Up @@ -337,6 +355,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 @@ -70,6 +70,7 @@ public slots:
protected slots:
void openInPianoRoll();
void setGhostInPianoRoll();
void setGhostInAutomationEditor();

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

QStaticText m_staticTextName;

bool m_legacySEPattern;
} ;

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

#include "MidiClipView.h"

#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 @@ -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(""); }

Expand Down Expand Up @@ -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("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()));

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

_cm->addAction( embed::getIconPixmap( "edit_erase" ),
Expand Down
69 changes: 63 additions & 6 deletions src/gui/editors/AutomationEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@

#include "AutomationEditor.h"

#include <cmath>

#include <QApplication>
#include <QInputDialog>
#include <QKeyEvent>
Expand All @@ -38,7 +36,10 @@
#include <QScrollBar>
#include <QStyleOption>
#include <QToolTip>
#include <cmath>

#include "MidiClip.h"
#include "qobjectdefs.h"
#ifndef __USE_XOPEN
#define __USE_XOPEN
#endif
Expand Down Expand Up @@ -110,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()),
Expand Down Expand Up @@ -1074,8 +1076,11 @@ 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 = newMidiClip;
}

void AutomationEditor::paintEvent(QPaintEvent * pe )
{
Expand Down Expand Up @@ -1261,6 +1266,48 @@ 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 != nullptr)
{
const NoteVector& notes = m_ghostNotes->notes();
int minKey = 128;
int maxKey = 0;

for (const Note* note : notes)
{
int noteKey = note->key();

maxKey = std::max(maxKey, noteKey);
minKey = std::min(minKey, noteKey);
}

for (const Note* note : notes)
{
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 keyRange = maxKey - minKey;

if (keyRange < MIN_NOTE_RANGE)
{
int padding = (MIN_NOTE_RANGE - keyRange) / 2.0f;
maxKey += padding;
minKey -= padding;
keyRange = MIN_NOTE_RANGE;
}

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.fillRect(xCoordOfTick(note->pos()), y, note_width, NOTE_HEIGHT, m_ghostNoteColor);
}
}

// and finally bars
for( tick = m_currentPosition - m_currentPosition % TimePos::ticksPerBar(),
x = xCoordOfTick( tick );
Expand Down Expand Up @@ -2159,8 +2206,18 @@ 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->addSeparator();
quantizationActionsToolBar->addWidget(m_resetGhostNotes);

// Setup our actual window
setFocusPolicy( Qt::StrongFocus );
setFocusPolicy(Qt::StrongFocus);
setFocus();
setWindowIcon( embed::getIconPixmap( "automation" ) );
setAcceptDrops( true );
Expand Down