diff --git a/include/FadeButton.h b/include/FadeButton.h index 57d8ba1e6..54703d194 100644 --- a/include/FadeButton.h +++ b/include/FadeButton.h @@ -46,6 +46,7 @@ public: public slots: void activate(); + void activateOnce(); void noteEnd(); diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index d72331e52..f2602686b 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -333,7 +333,6 @@ private slots: void midiInSelected(); void midiOutSelected(); void midiConfigChanged(); - void muteChanged(); void assignFxLine( int channelIndex ); void createFxLine(); @@ -357,6 +356,10 @@ private: QPoint m_lastPos; + FadeButton * getActivityIndicator() + { + return m_activityIndicator; + } friend class InstrumentTrackWindow; diff --git a/include/SampleTrack.h b/include/SampleTrack.h index 2bad4d910..47cc0df39 100644 --- a/include/SampleTrack.h +++ b/include/SampleTrack.h @@ -29,6 +29,7 @@ #include #include "AudioPort.h" +#include "FadeButton.h" #include "FxMixer.h" #include "FxLineLcdSpinBox.h" #include "Track.h" @@ -161,6 +162,20 @@ public: return "sampletrack"; } + bool isPlaying() + { + return m_isPlaying; + } + + void setPlaying(bool playing) + { + if (m_isPlaying != playing) { emit playingChanged(); } + m_isPlaying = playing; + } + +signals: + void playingChanged(); + public slots: void updateTcos(); void setPlayingTcos( bool isPlaying ); @@ -171,6 +186,7 @@ private: FloatModel m_panningModel; IntModel m_effectChannelModel; AudioPort m_audioPort; + bool m_isPlaying; @@ -209,6 +225,7 @@ public: public slots: void showEffects(); + void updateIndicator(); protected: @@ -230,9 +247,14 @@ private: SampleTrackWindow * m_window; Knob * m_volumeKnob; Knob * m_panningKnob; + FadeButton * m_activityIndicator; TrackLabelButton * m_tlb; + FadeButton * getActivityIndicator() + { + return m_activityIndicator; + } friend class SampleTrackWindow; diff --git a/include/Track.h b/include/Track.h index de622d0fb..07cee8ffd 100644 --- a/include/Track.h +++ b/include/Track.h @@ -39,6 +39,7 @@ #include "AutomatableModel.h" #include "ModelView.h" #include "DataFile.h" +#include "FadeButton.h" class QMenu; @@ -739,12 +740,19 @@ private: Actions m_action; + virtual FadeButton * getActivityIndicator() + { + return nullptr; + } + + void setIndicatorMute(FadeButton* indicator, bool muted); friend class TrackLabelButton; private slots: void createTCOView( TrackContentObject * tco ); + void muteChanged(); } ; diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 0c046a504..f6b109280 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -2719,6 +2719,9 @@ TrackView::TrackView( Track * track, TrackContainerView * tcv ) : connect( &m_track->m_mutedModel, SIGNAL( dataChanged() ), &m_trackContentWidget, SLOT( update() ) ); + connect(&m_track->m_mutedModel, SIGNAL(dataChanged()), + this, SLOT(muteChanged())); + connect( &m_track->m_soloModel, SIGNAL( dataChanged() ), m_track, SLOT( toggleSolo() ), Qt::DirectConnection ); // create views for already existing TCOs @@ -3051,3 +3054,21 @@ void TrackView::createTCOView( TrackContentObject * tco ) } tco->selectViewOnCreate( false ); } + + + + +void TrackView::muteChanged() +{ + FadeButton * indicator = getActivityIndicator(); + if (indicator) { setIndicatorMute(indicator, m_track->m_mutedModel.value()); } +} + + + + +void TrackView::setIndicatorMute(FadeButton* indicator, bool muted) +{ + QPalette::ColorRole role = muted ? QPalette::Highlight : QPalette::BrightText; + indicator->setActiveColor(QApplication::palette().color(QPalette::Active, role)); +} diff --git a/src/gui/widgets/FadeButton.cpp b/src/gui/widgets/FadeButton.cpp index 8f75ea33b..43f806144 100644 --- a/src/gui/widgets/FadeButton.cpp +++ b/src/gui/widgets/FadeButton.cpp @@ -2,7 +2,7 @@ * FadeButton.cpp - implementation of fade-button * * Copyright (c) 2005-2009 Tobias Doerffel - * + * * This file is part of LMMS - https://lmms.io * * This program is free software; you can redistribute it and/or @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA. * */ - + #include #include @@ -75,6 +75,14 @@ void FadeButton::activate() +void FadeButton::activateOnce() +{ + if (activeNotes == 0) { activate(); } +} + + + + void FadeButton::noteEnd() { if (activeNotes <= 0) @@ -97,6 +105,7 @@ void FadeButton::noteEnd() + void FadeButton::paintEvent(QPaintEvent * _pe) { QColor col = m_normalColor; @@ -145,7 +154,7 @@ QColor FadeButton::fadeToColor(QColor startCol, QColor endCol, QTime timer, floa QColor col; const float state = 1 - timer.elapsed() / duration; - const int r = (int)(endCol.red() * (1.0f - state) + const int r = (int)(endCol.red() * (1.0f - state) + startCol.red() * state); const int g = (int)(endCol.green() * (1.0f - state) + startCol.green() * state); diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index ac2a7f451..52fb1044a 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -996,7 +996,6 @@ InstrumentTrackView::InstrumentTrackView( InstrumentTrack * _it, TrackContainerV m_activityIndicator, SLOT( activate() ) ); connect( _it, SIGNAL( endNote() ), m_activityIndicator, SLOT( noteEnd() ) ); - connect( &_it->m_mutedModel, SIGNAL( dataChanged() ), this, SLOT( muteChanged() ) ); setModel( _it ); } @@ -1225,22 +1224,6 @@ void InstrumentTrackView::midiConfigChanged() -void InstrumentTrackView::muteChanged() -{ - if(model()->m_mutedModel.value() ) - { - m_activityIndicator->setActiveColor( QApplication::palette().color( QPalette::Active, - QPalette::Highlight ) ); - } else - { - m_activityIndicator->setActiveColor( QApplication::palette().color( QPalette::Active, - QPalette::BrightText ) ); - } -} - - - - //FIXME: This is identical to SampleTrackView::createFxMenu QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel) { diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 72f63bb05..f377e35cf 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -585,20 +585,19 @@ void SampleTCOView::paintEvent( QPaintEvent * pe ) -SampleTrack::SampleTrack( TrackContainer* tc ) : - Track( Track::SampleTrack, tc ), - m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 0.1f, this, - tr( "Volume" ) ), - m_panningModel( DefaultPanning, PanningLeft, PanningRight, 0.1f, - this, tr( "Panning" ) ), - m_effectChannelModel( 0, 0, 0, this, tr( "FX channel" ) ), - m_audioPort( tr( "Sample track" ), true, &m_volumeModel, &m_panningModel, &m_mutedModel ) +SampleTrack::SampleTrack(TrackContainer* tc) : + Track(Track::SampleTrack, tc), + m_volumeModel(DefaultVolume, MinVolume, MaxVolume, 0.1f, this, tr("Volume")), + m_panningModel(DefaultPanning, PanningLeft, PanningRight, 0.1f, this, tr("Panning")), + m_effectChannelModel(0, 0, 0, this, tr("FX channel")), + m_audioPort(tr("Sample track"), true, &m_volumeModel, &m_panningModel, &m_mutedModel), + m_isPlaying(false) { - setName( tr( "Sample track" ) ); - m_panningModel.setCenterValue( DefaultPanning ); - m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels()-1, 1); + setName(tr("Sample track")); + m_panningModel.setCenterValue(DefaultPanning); + m_effectChannelModel.setRange(0, Engine::fxMixer()->numChannels()-1, 1); - connect( &m_effectChannelModel, SIGNAL( dataChanged() ), this, SLOT( updateEffectChannel() ) ); + connect(&m_effectChannelModel, SIGNAL(dataChanged()), this, SLOT(updateEffectChannel())); } @@ -622,6 +621,10 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, ::BBTrack * bb_track = NULL; if( _tco_num >= 0 ) { + if (_start > getTCO(_tco_num)->length()) + { + setPlaying(false); + } if( _start != 0 ) { return false; @@ -630,10 +633,12 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, if (trackContainer() == (TrackContainer*)Engine::getBBTrackContainer()) { bb_track = BBTrack::findBBTrack( _tco_num ); + setPlaying(true); } } else { + bool nowPlaying = false; for( int i = 0; i < numOfTCOs(); ++i ) { TrackContentObject * tco = getTCO( i ); @@ -657,6 +662,7 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, sTco->setSamplePlayLength( samplePlayLength ); tcos.push_back( sTco ); sTco->setIsPlaying( true ); + nowPlaying = true; } } } @@ -664,7 +670,9 @@ bool SampleTrack::play( const MidiTime & _start, const fpp_t _frames, { sTco->setIsPlaying( false ); } + nowPlaying = nowPlaying || sTco->isPlaying(); } + setPlaying(nowPlaying); } for( tcoVector::Iterator it = tcos.begin(); it != tcos.end(); ++it ) @@ -826,6 +834,18 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : m_panningKnob->setLabel( tr( "PAN" ) ); m_panningKnob->show(); + m_activityIndicator = new FadeButton( + QApplication::palette().color(QPalette::Active, QPalette::Background), + QApplication::palette().color(QPalette::Active, QPalette::BrightText), + QApplication::palette().color(QPalette::Active, QPalette::BrightText).darker(), + getTrackSettingsWidget() + ); + m_activityIndicator->setGeometry(settingsWidgetWidth - 2 * 24 - 11, 2, 8, 28); + m_activityIndicator->show(); + connect(_t, SIGNAL(playingChanged()), this, SLOT(updateIndicator())); + connect(Engine::getSong(), SIGNAL(stopped()), + this, SLOT(stopPlaying())); + setModel( _t ); m_window = new SampleTrackWindow(this); @@ -835,6 +855,15 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) : +void SampleTrackView::updateIndicator() +{ + if (model()->isPlaying()) { m_activityIndicator->activateOnce(); } + else { m_activityIndicator->noteEnd(); } +} + + + + SampleTrackView::~SampleTrackView() { if(m_window != NULL)