Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic ghost notes feature. #4575

Merged
merged 9 commits into from Jan 17, 2019
Binary file added data/themes/classic/clear_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.
Binary file added data/themes/classic/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 @@ -127,6 +127,10 @@ PianoRoll {
qproperty-noteOpacity: 128;
qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */
qproperty-selectedNoteColor: rgb( 0, 125, 255 );
qproperty-ghostNoteColor: #000000;
qproperty-ghostNoteTextColor: #ffffff;
qproperty-ghostNoteOpacity: 50;
qproperty-ghostNoteBorders: true;
qproperty-barColor: #4afd85;
qproperty-markedSemitoneColor: rgba( 0, 255, 200, 60 );
/* Grid colors */
Expand Down
Binary file added data/themes/default/clear_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.
Binary file added data/themes/default/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/default/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ PianoRoll {
qproperty-noteOpacity: 165;
qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */
qproperty-selectedNoteColor: #064d79;
qproperty-ghostNoteColor: #000000;
qproperty-ghostNoteTextColor: #ffffff;
qproperty-ghostNoteOpacity: 50;
qproperty-ghostNoteBorders: false;
qproperty-barColor: #078f3a;
qproperty-markedSemitoneColor: rgba(255, 255, 255, 30);
/* Grid colors */
Expand Down
1 change: 1 addition & 0 deletions include/Pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ public slots:

protected slots:
void openInPianoRoll();
void setGhostInPianoRoll();

void resetName();
void changeName();
Expand Down
26 changes: 25 additions & 1 deletion include/PianoRoll.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class PianoRoll : public QWidget
Q_PROPERTY( QColor lineColor READ lineColor WRITE setLineColor )
Q_PROPERTY( QColor noteModeColor READ noteModeColor WRITE setNoteModeColor )
Q_PROPERTY( QColor noteColor READ noteColor WRITE setNoteColor )
Q_PROPERTY( QColor ghostNoteColor READ ghostNoteColor WRITE setGhostNoteColor )
Q_PROPERTY( QColor noteTextColor READ noteTextColor WRITE setNoteTextColor )
Q_PROPERTY( QColor ghostNoteTextColor READ ghostNoteTextColor WRITE setGhostNoteTextColor )
Q_PROPERTY( QColor barColor READ barColor WRITE setBarColor )
Q_PROPERTY( QColor selectedNoteColor READ selectedNoteColor WRITE setSelectedNoteColor )
Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor )
Expand All @@ -68,6 +70,8 @@ class PianoRoll : public QWidget
Q_PROPERTY( QColor markedSemitoneColor READ markedSemitoneColor WRITE setMarkedSemitoneColor )
Q_PROPERTY( int noteOpacity READ noteOpacity WRITE setNoteOpacity )
Q_PROPERTY( bool noteBorders READ noteBorders WRITE setNoteBorders )
Q_PROPERTY( int ghostNoteOpacity READ ghostNoteOpacity WRITE setGhostNoteOpacity )
Q_PROPERTY( bool ghostNoteBorders READ ghostNoteBorders WRITE setGhostNoteBorders )
Q_PROPERTY( QColor backgroundShade READ backgroundShade WRITE setBackgroundShade )
public:
enum EditModes
Expand All @@ -87,6 +91,7 @@ class PianoRoll : public QWidget
void showPanTextFloat(panning_t pan, const QPoint &pos, int timeout=-1);

void setCurrentPattern( Pattern* newPattern );
void setGhostPattern( Pattern* newPattern );

inline void stopRecording()
{
Expand Down Expand Up @@ -141,6 +146,14 @@ class PianoRoll : public QWidget
void setNoteOpacity( const int i );
bool noteBorders() const;
void setNoteBorders( const bool b );
QColor ghostNoteColor() const;
void setGhostNoteColor( const QColor & c );
QColor ghostNoteTextColor() const;
void setGhostNoteTextColor( const QColor & c );
int ghostNoteOpacity() const;
void setGhostNoteOpacity( const int i );
bool ghostNoteBorders() const;
void setGhostNoteBorders( const bool b );
QColor backgroundShade() const;
void setBackgroundShade( const QColor & c );

Expand Down Expand Up @@ -206,9 +219,12 @@ protected slots:

void selectRegionFromPixels( int xStart, int xEnd );

void clearGhostPattern();


signals:
void currentPatternChanged();
void ghostPatternSet(bool);
void semiToneMarkerMenuScaleSetEnabled(bool);
void semiToneMarkerMenuChordSetEnabled(bool);

Expand Down Expand Up @@ -309,6 +325,7 @@ protected slots:
static const QVector<double> m_zoomLevels;

Pattern* m_pattern;
Pattern* m_ghostPattern;
QScrollBar * m_leftRightScroll;
QScrollBar * m_topBottomScroll;

Expand Down Expand Up @@ -388,14 +405,18 @@ protected slots:
QColor m_noteModeColor;
QColor m_noteColor;
QColor m_noteTextColor;
QColor m_ghostNoteColor;
QColor m_ghostNoteTextColor;
QColor m_barColor;
QColor m_selectedNoteColor;
QColor m_textColor;
QColor m_textColorLight;
QColor m_textShadow;
QColor m_markedSemitoneColor;
int m_noteOpacity;
int m_ghostNoteOpacity;
bool m_noteBorders;
bool m_ghostNoteBorders;
QColor m_backgroundShade;

signals:
Expand All @@ -412,7 +433,8 @@ class PianoRollWindow : public Editor, SerializingObject
PianoRollWindow();

const Pattern* currentPattern() const;
void setCurrentPattern(Pattern* pattern);
void setCurrentPattern( Pattern* pattern );
void setGhostPattern( Pattern* pattern );

int quantization() const;

Expand Down Expand Up @@ -445,6 +467,7 @@ class PianoRollWindow : public Editor, SerializingObject

private slots:
void patternRenamed();
void ghostPatternSet( bool state );

private:
void focusInEvent(QFocusEvent * event);
Expand All @@ -456,6 +479,7 @@ private slots:
ComboBox * m_noteLenComboBox;
ComboBox * m_scaleComboBox;
ComboBox * m_chordComboBox;
QPushButton * m_clearGhostButton;

};

Expand Down
122 changes: 120 additions & 2 deletions src/gui/editors/PianoRoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,18 @@ PianoRoll::PianoRoll() :
m_lineColor( 0, 0, 0 ),
m_noteModeColor( 0, 0, 0 ),
m_noteColor( 0, 0, 0 ),
m_ghostNoteColor( 0, 0, 0 ),
m_ghostNoteTextColor( 0, 0, 0 ),
m_barColor( 0, 0, 0 ),
m_selectedNoteColor( 0, 0, 0 ),
m_textColor( 0, 0, 0 ),
m_textColorLight( 0, 0, 0 ),
m_textShadow( 0, 0, 0 ),
m_markedSemitoneColor( 0, 0, 0 ),
m_noteOpacity( 255 ),
m_ghostNoteOpacity( 255 ),
m_noteBorders( true ),
m_ghostNoteBorders( true ),
m_backgroundShade( 0, 0, 0 )
{
// gui names of edit modes
Expand Down Expand Up @@ -599,6 +603,26 @@ PianoRoll::~PianoRoll()
}


void PianoRoll::setGhostPattern( Pattern* newPattern )
{
m_ghostPattern = newPattern;
if( newPattern != nullptr )
{
// make sure to always get informed about the pattern being destroyed
connect( m_ghostPattern, SIGNAL( destroyedPattern( Pattern* ) ), this, SLOT( clearGhostPattern() ) );
emit ghostPatternSet( true );
}
}


void PianoRoll::clearGhostPattern()
{
setGhostPattern( nullptr );
emit ghostPatternSet( false );
update();
}


void PianoRoll::setCurrentPattern( Pattern* newPattern )
{
if( hasValidPattern() )
Expand Down Expand Up @@ -801,6 +825,30 @@ bool PianoRoll::noteBorders() const
void PianoRoll::setNoteBorders( const bool b )
{ m_noteBorders = b; }

QColor PianoRoll::ghostNoteColor() const
{ return m_ghostNoteColor; }

void PianoRoll::setGhostNoteColor( const QColor & c )
{ m_ghostNoteColor = c; }

QColor PianoRoll::ghostNoteTextColor() const
{ return m_ghostNoteTextColor; }

void PianoRoll::setGhostNoteTextColor( const QColor & c )
{ m_ghostNoteTextColor = c; }

int PianoRoll::ghostNoteOpacity() const
{ return m_ghostNoteOpacity; }

void PianoRoll::setGhostNoteOpacity( const int i )
{ m_ghostNoteOpacity = i; }

bool PianoRoll::ghostNoteBorders() const
{ return m_ghostNoteBorders; }

void PianoRoll::setGhostNoteBorders( const bool b )
{ m_ghostNoteBorders = b; }

QColor PianoRoll::backgroundShade() const
{ return m_backgroundShade; }

Expand All @@ -810,7 +858,6 @@ void PianoRoll::setBackgroundShade( const QColor & c )




void PianoRoll::drawNoteRect( QPainter & p, int x, int y,
int width, const Note * n, const QColor & noteCol, const QColor & noteTextColor,
const QColor & selCol, const int noteOpc, const bool borders, bool drawNoteName )
Expand Down Expand Up @@ -3024,6 +3071,50 @@ void PianoRoll::paintEvent(QPaintEvent * pe )

QPolygonF editHandles;

// -- Begin ghost pattern
if( m_ghostPattern != nullptr )
{
for( const Note *note : m_ghostPattern->notes() )
{
int len_ticks = note->length();

if( len_ticks == 0 )
{
continue;
}
else if( len_ticks < 0 )
{
len_ticks = 4;
}
const int key = note->key() - m_startKey + 1;

int pos_ticks = note->pos();

int note_width = len_ticks * m_ppt / MidiTime::ticksPerTact();
const int x = ( pos_ticks - m_currentPosition ) *
m_ppt / MidiTime::ticksPerTact();
// skip this note if not in visible area at all
if( !( x + note_width >= 0 && x <= width() - WHITE_KEY_WIDTH ) )
{
continue;
}

// is the note in visible area?
if( key > 0 && key <= visible_keys )
{

// we've done and checked all, let's draw the
// note
drawNoteRect( p, x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT,
note_width, note, ghostNoteColor(), ghostNoteTextColor(), selectedNoteColor(),
ghostNoteOpacity(), ghostNoteBorders(), drawNoteNames );
}

}
}
// -- End ghost pattern

for( const Note *note : m_pattern->notes() )
{
int len_ticks = note->length();
Expand Down Expand Up @@ -4221,8 +4312,15 @@ PianoRollWindow::PianoRollWindow() :
m_chordComboBox = new ComboBox( m_toolBar );
m_chordComboBox->setModel( &m_editor->m_chordModel );
m_chordComboBox->setFixedSize( 105, 22 );
m_chordComboBox->setToolTip( tr( "Chord") );
m_chordComboBox->setToolTip( tr( "Chord" ) );

// -- Clear ghost pattern button
m_clearGhostButton = new QPushButton( m_toolBar );
m_clearGhostButton->setIcon( embed::getIconPixmap( "clear_ghost_note" ) );
m_clearGhostButton->setToolTip( tr( "Clear ghost notes" ) );
m_clearGhostButton->setEnabled( false );
connect( m_clearGhostButton, SIGNAL( clicked() ), m_editor, SLOT( clearGhostPattern() ) );
connect( m_editor, SIGNAL( ghostPatternSet( bool ) ), this, SLOT( ghostPatternSet( bool ) ) );

zoomAndNotesToolBar->addWidget( zoom_lbl );
zoomAndNotesToolBar->addWidget( m_zoomingComboBox );
Expand All @@ -4243,6 +4341,9 @@ PianoRollWindow::PianoRollWindow() :
zoomAndNotesToolBar->addWidget( chord_lbl );
zoomAndNotesToolBar->addWidget( m_chordComboBox );

zoomAndNotesToolBar->addSeparator();
zoomAndNotesToolBar->addWidget( m_clearGhostButton );

// setup our actual window
setFocusPolicy( Qt::StrongFocus );
setFocus();
Expand All @@ -4265,8 +4366,17 @@ const Pattern* PianoRollWindow::currentPattern() const



void PianoRollWindow::setGhostPattern( Pattern* pattern )
{
m_editor->setGhostPattern( pattern );
}




void PianoRollWindow::setCurrentPattern( Pattern* pattern )
{
m_editor->clearGhostPattern();
m_editor->setCurrentPattern( pattern );

if ( pattern )
Expand Down Expand Up @@ -4387,6 +4497,14 @@ void PianoRollWindow::patternRenamed()



void PianoRollWindow::ghostPatternSet( bool state )
{
m_clearGhostButton->setEnabled( state );
}




void PianoRollWindow::focusInEvent( QFocusEvent * event )
{
// when the window is given focus, also give focus to the actual piano roll
Expand Down
30 changes: 29 additions & 1 deletion src/tracks/Pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,19 @@ void PatternView::openInPianoRoll()




void PatternView::setGhostInPianoRoll()
{
gui->pianoRoll()->setGhostPattern( m_pat );
gui->pianoRoll()->parentWidget()->show();
gui->pianoRoll()->show();
gui->pianoRoll()->setFocus();
}





void PatternView::resetName()
{
m_pat->setName( m_pat->m_instrumentTrack->name() );
Expand All @@ -663,7 +676,22 @@ void PatternView::constructContextMenu( QMenu * _cm )
_cm->insertAction( _cm->actions()[0], a );
connect( a, SIGNAL( triggered( bool ) ),
this, SLOT( openInPianoRoll() ) );
_cm->insertSeparator( _cm->actions()[1] );

if( gui->pianoRoll()->currentPattern() &&
gui->pianoRoll()->currentPattern() != m_pat &&
not m_pat->empty() )
{
QAction * b = new QAction( embed::getIconPixmap( "ghost_note" ),
tr( "Set as ghost in piano-roll" ), _cm );
_cm->insertAction( _cm->actions()[1], b );
connect( b, SIGNAL( triggered( bool ) ),
this, SLOT( setGhostInPianoRoll() ) );
_cm->insertSeparator( _cm->actions()[2] );
}
else
{
_cm->insertSeparator( _cm->actions()[1] );
}

_cm->addSeparator();

Expand Down