Skip to content

Commit

Permalink
FadeButtons now remain partially lit as a note plays out (LMMS#4969)
Browse files Browse the repository at this point in the history
  • Loading branch information
enp2s0 authored and PhysSong committed Jun 25, 2019
1 parent d3774a2 commit 4215e37
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 42 deletions.
16 changes: 13 additions & 3 deletions include/FadeButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,18 @@ class FadeButton : public QAbstractButton
{
Q_OBJECT
public:
FadeButton( const QColor & _normal_color, const QColor &
_activated_color, QWidget * _parent );
FadeButton( const QColor & _normal_color,
const QColor & _activated_color,
const QColor & _hold_color,
QWidget * _parent );

virtual ~FadeButton();
void setActiveColor( const QColor & activated_color );


public slots:
void activate();
void noteEnd();


protected:
Expand All @@ -53,13 +56,20 @@ public slots:

private:
QTime m_stateTimer;
QTime m_releaseTimer;

// the default color of the widget
QColor m_normalColor;
// the color on note play
QColor m_activatedColor;
// the color after the "play" fade is done but a note is still playing
QColor m_holdColor;
int activeNotes;

void signalUpdate();
QColor fadeToColor(QColor, QColor, QTime, float);

} ;


#endif

1 change: 1 addition & 0 deletions include/InstrumentTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor
void midiNoteOff( const Note& );
void nameChanged();
void newNote();
void endNote();


protected:
Expand Down
124 changes: 85 additions & 39 deletions src/gui/widgets/FadeButton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@
const float FadeDuration = 300;


FadeButton::FadeButton( const QColor & _normal_color,
const QColor & _activated_color, QWidget * _parent ) :
FadeButton::FadeButton(const QColor & _normal_color,
const QColor & _activated_color,
const QColor & holdColor,
QWidget * _parent) :
QAbstractButton( _parent ),
m_stateTimer(),
m_releaseTimer(),
m_normalColor( _normal_color ),
m_activatedColor( _activated_color )
m_activatedColor( _activated_color ),
m_holdColor( holdColor )
{
setAttribute( Qt::WA_OpaquePaintEvent, true );
setCursor( QCursor( embed::getIconPixmap( "hand" ), 3, 3 ) );
setFocusPolicy( Qt::NoFocus );
setAttribute(Qt::WA_OpaquePaintEvent, true);
setCursor(QCursor(embed::getIconPixmap("hand"), 3, 3));
setFocusPolicy(Qt::NoFocus);
activeNotes = 0;
}


Expand All @@ -54,7 +59,7 @@ FadeButton::~FadeButton()
{
}

void FadeButton::setActiveColor( const QColor & activated_color )
void FadeButton::setActiveColor(const QColor & activated_color)
{
m_activatedColor = activated_color;
}
Expand All @@ -65,63 +70,104 @@ void FadeButton::setActiveColor( const QColor & activated_color )
void FadeButton::activate()
{
m_stateTimer.restart();
activeNotes++;
signalUpdate();
}




void FadeButton::customEvent( QEvent * )
void FadeButton::noteEnd()
{
update();
if (activeNotes <= 0)
{
qWarning("noteEnd() triggered without a corresponding activate()!");
activeNotes = 0;
}
else
{
activeNotes--;
}

if (activeNotes == 0)
{
m_releaseTimer.restart();
}

signalUpdate();
}




void FadeButton::paintEvent( QPaintEvent * _pe )
void FadeButton::customEvent(QEvent *)
{
update();
}



void FadeButton::paintEvent(QPaintEvent * _pe)
{
QColor col = m_normalColor;
if( ! m_stateTimer.isNull() && m_stateTimer.elapsed() < FadeDuration )

if(!m_stateTimer.isNull() && m_stateTimer.elapsed() < FadeDuration)
{
// The first part of the fade, when a note is triggered.
col = fadeToColor(m_activatedColor, m_holdColor, m_stateTimer, FadeDuration);
QTimer::singleShot(20, this, SLOT(update()));
}
else if (!m_stateTimer.isNull()
&& m_stateTimer.elapsed() >= FadeDuration
&& activeNotes > 0)
{
// The fade is done, but at least one note is still held.
col = m_holdColor;
}
else if (!m_releaseTimer.isNull() && m_releaseTimer.elapsed() < FadeDuration)
{
// Last note just ended. Fade to default color.
col = fadeToColor(m_holdColor, m_normalColor, m_releaseTimer, FadeDuration);
QTimer::singleShot(20, this, SLOT(update()));
}
else
{
const float state = 1 - m_stateTimer.elapsed() / FadeDuration;
const int r = (int)( m_normalColor.red() *
( 1.0f - state ) +
m_activatedColor.red() * state );
const int g = (int)( m_normalColor.green() *
( 1.0f - state ) +
m_activatedColor.green() * state );
const int b = (int)( m_normalColor.blue() *
( 1.0f - state ) +
m_activatedColor.blue() * state );
col.setRgb( r, g, b );
QTimer::singleShot( 20, this, SLOT( update() ) );
// No fade, no notes. Set to default color.
col = m_normalColor;
}

QPainter p( this );
p.fillRect( rect(), col );
QPainter p(this);
p.fillRect(rect(), col);

int w = rect().right();
int h = rect().bottom();
p.setPen( m_normalColor.darker(130) );
p.drawLine( w, 1, w, h );
p.drawLine( 1, h, w, h );
p.setPen( m_normalColor.lighter(130) );
p.drawLine( 0, 0, 0, h-1 );
p.drawLine( 0, 0, w, 0 );
p.setPen(m_normalColor.darker(130));
p.drawLine(w, 1, w, h);
p.drawLine(1, h, w, h);
p.setPen(m_normalColor.lighter(130));
p.drawLine(0, 0, 0, h-1);
p.drawLine(0, 0, w, 0);
}


QColor FadeButton::fadeToColor(QColor startCol, QColor endCol, QTime timer, float duration)
{
QColor col;

const float state = 1 - timer.elapsed() / duration;
const int r = (int)(endCol.red() * (1.0f - state)
+ startCol.red() * state);
const int g = (int)(endCol.green() * (1.0f - state)
+ startCol.green() * state);
const int b = (int)(endCol.blue() * (1.0f - state)
+ startCol.blue() * state);
col.setRgb(r, g, b);

return col;
}


void FadeButton::signalUpdate()
{
QApplication::postEvent( this, new updateEvent() );
QApplication::postEvent(this, new updateEvent());
}







5 changes: 5 additions & 0 deletions src/tracks/InstrumentTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ void InstrumentTrack::processOutEvent( const MidiEvent& event, const MidiTime& t
m_instrument->handleMidiEvent( MidiEvent( MidiNoteOff, midiPort()->realOutputChannel(), key, 0 ), time, offset );
}
m_midiNotesMutex.unlock();
emit endNote();
break;

default:
Expand Down Expand Up @@ -976,6 +977,8 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
QPalette::Background),
QApplication::palette().color( QPalette::Active,
QPalette::BrightText ),
QApplication::palette().color( QPalette::Active,
QPalette::BrightText).darker(),
getTrackSettingsWidget() );
m_activityIndicator->setGeometry(
widgetWidth-2*24-11, 2, 8, 28 );
Expand All @@ -986,6 +989,8 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV
this, SLOT( activityIndicatorReleased() ) );
connect( _it, SIGNAL( newNote() ),
m_activityIndicator, SLOT( activate() ) );
connect( _it, SIGNAL( endNote() ),
m_activityIndicator, SLOT( noteEnd() ) );
connect( &_it->m_mutedModel, SIGNAL( dataChanged() ), this, SLOT( muteChanged() ) );

setModel( _it );
Expand Down

0 comments on commit 4215e37

Please sign in to comment.