diff --git a/data/themes/default/mixer_send_off.png b/data/themes/default/mixer_send_off.png new file mode 100644 index 000000000..6f426c36f Binary files /dev/null and b/data/themes/default/mixer_send_off.png differ diff --git a/data/themes/default/mixer_send_on.png b/data/themes/default/mixer_send_on.png new file mode 100644 index 000000000..6861c7acd Binary files /dev/null and b/data/themes/default/mixer_send_on.png differ diff --git a/include/FxLine.h b/include/FxLine.h new file mode 100644 index 000000000..1700ebba3 --- /dev/null +++ b/include/FxLine.h @@ -0,0 +1,38 @@ +#ifndef FXLINE_H +#define FXLINE_H + +#include +#include + +#include "knob.h" +#include "SendButtonIndicator.h" + +class FxMixerView; +class SendButtonIndicator; + +class FxLine : public QWidget +{ + Q_OBJECT +public: + FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex); + + virtual void paintEvent( QPaintEvent * ); + virtual void mousePressEvent( QMouseEvent * ); + virtual void mouseDoubleClickEvent( QMouseEvent * ); + + inline int channelIndex() { return m_channelIndex; } + + knob * m_sendKnob; + SendButtonIndicator * m_sendBtn; + + +private: + FxMixerView * m_mv; + + + int m_channelIndex; + +} ; + + +#endif // FXLINE_H diff --git a/include/FxMixerView.h b/include/FxMixerView.h index 297ab5061..461379728 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -29,60 +29,74 @@ #include #include +#include "FxLine.h" #include "FxMixer.h" #include "ModelView.h" +#include "engine.h" +#include "fader.h" +#include "pixmap_button.h" +#include "tooltip.h" +#include "embed.h" +#include "EffectRackView.h" class QStackedLayout; class QButtonGroup; -class fader; class FxLine; -class EffectRackView; -class pixmapButton; - class FxMixerView : public QWidget, public ModelView, public SerializingObjectHook { Q_OBJECT public: - FxMixerView(); - virtual ~FxMixerView(); - - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); - virtual void loadSettings( const QDomElement & _this ); - - FxLine * currentFxLine() - { - return m_currentFxLine; - } - void setCurrentFxLine( FxLine * _line ); - void setCurrentFxLine( int _line ); - - void clear(); - - -private slots: - void updateFaders(); - void addNewChannel(); - -private: struct FxChannelView { + FxChannelView(QWidget * _parent, FxMixerView * _mv, int _chIndex ); + FxLine * m_fxLine; EffectRackView * m_rackView; pixmapButton * m_muteBtn; fader * m_fader; } ; - QVector m_fxChannelViews; + + FxMixerView(); + virtual ~FxMixerView(); + + virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); + virtual void loadSettings( const QDomElement & _this ); + + inline FxLine * currentFxLine() + { + return m_currentFxLine; + } + + inline FxChannelView * channelView(int index) + { + return m_fxChannelViews[index]; + } + + void setCurrentFxLine( FxLine * _line ); + void setCurrentFxLine( int _line ); + + void clear(); + + + // display the send button and knob correctly + void updateFxLine(int i); + +private slots: + void updateFaders(); + void addNewChannel(); + +private: + + QVector m_fxChannelViews; QStackedLayout * m_fxRacksLayout; FxLine * m_currentFxLine; QScrollArea * channelArea; QHBoxLayout * chLayout; - - void addFxLine(int i, QWidget * parent, QLayout * layout); } ; #endif diff --git a/include/SendButtonIndicator.h b/include/SendButtonIndicator.h new file mode 100644 index 000000000..f2c7ef44d --- /dev/null +++ b/include/SendButtonIndicator.h @@ -0,0 +1,32 @@ +#ifndef SENDBUTTONINDICATOR_H +#define SENDBUTTONINDICATOR_H + +#include +#include +#include + +#include "FxLine.h" +#include "FxMixerView.h" + +class FxLine; +class FxMixerView; + +class SendButtonIndicator : public QLabel { + public: + SendButtonIndicator( QWidget * _parent, FxLine * _owner, + FxMixerView * _mv); + + virtual void mousePressEvent( QMouseEvent * e ); + void updateLightStatus(); + + private: + + FxLine * m_parent; + FxMixerView * m_mv; + QPixmap qpmOn; + QPixmap qpmOff; + + FloatModel * getSendModel(); +}; + +#endif // SENDBUTTONINDICATOR_H diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index 53c1152a7..b2dd852e2 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -74,7 +74,10 @@ FxMixer::~FxMixer() { for( int i = 0; i < m_fxChannels.size(); ++i ) { - delete m_fxChannels[i]->m_sendAmount[i]; + for( int j = 0; j < m_fxChannels[i]->m_sendAmount.size(); ++j) + { + delete m_fxChannels[i]->m_sendAmount[j]; + } delete m_fxChannels[i]; } } @@ -187,6 +190,11 @@ void FxMixer::processChannel( fx_ch_t _ch, sampleFrame * _buf ) { const fpp_t fpp = engine::getMixer()->framesPerPeriod(); FxChannel * thisCh = m_fxChannels[_ch]; + if( _buf == NULL ) + { + _buf = thisCh->m_buffer; + } + if( ! thisCh->m_muteModel.value() ) { // do mixer sends. loop through the channels that send to this one @@ -212,10 +220,7 @@ void FxMixer::processChannel( fx_ch_t _ch, sampleFrame * _buf ) } - if( _buf == NULL ) - { - _buf = thisCh->m_buffer; - } + const float v = thisCh->m_volumeModel.value(); thisCh->m_fxChain.startRunning(); diff --git a/src/gui/FxLine.cpp b/src/gui/FxLine.cpp new file mode 100644 index 000000000..fe92ba66b --- /dev/null +++ b/src/gui/FxLine.cpp @@ -0,0 +1,77 @@ +#include "FxLine.h" + +#include +#include +#include +#include + +#include "FxMixer.h" +#include "FxMixerView.h" +#include "embed.h" +#include "engine.h" +#include "lcd_spinbox.h" +#include "SendButtonIndicator.h" + +FxLine::FxLine( QWidget * _parent, FxMixerView * _mv, int _channelIndex) : + QWidget( _parent ), + m_mv( _mv ), + m_channelIndex( _channelIndex ) +{ + setFixedSize( 32, 287 ); + setAttribute( Qt::WA_OpaquePaintEvent, true ); + setCursor( QCursor( embed::getIconPixmap( "hand" ), 0, 0 ) ); + + // mixer sends knob + m_sendKnob = new knob(0, this, tr("Channel send amount")); + m_sendKnob->move(0, 22); + m_sendKnob->setVisible(false); + + // send button indicator + m_sendBtn = new SendButtonIndicator(this, this, m_mv); + m_sendBtn->setPixmap(embed::getIconPixmap("mixer_send_off", 23, 16)); + m_sendBtn->move(4,4); + + // channel number + lcdSpinBox * l = new lcdSpinBox( 2, this ); + l->model()->setRange( m_channelIndex, m_channelIndex ); + l->model()->setValue( m_channelIndex ); + l->move( 2, 58 ); + l->setMarginWidth( 1 ); +} + + +void FxLine::paintEvent( QPaintEvent * ) +{ + FxMixer * mix = engine::fxMixer(); + bool sendToThis = mix->channelSendModel( + m_mv->currentFxLine()->m_channelIndex, m_channelIndex) != NULL; + QPainter painter; + painter.begin( this ); + engine::getLmmsStyle()->drawFxLine( &painter, this, + mix->effectChannel(m_channelIndex)->m_name, + m_mv->currentFxLine() == this, sendToThis ); + painter.end(); +} + +void FxLine::mousePressEvent( QMouseEvent * ) +{ + m_mv->setCurrentFxLine( this ); +} + +void FxLine::mouseDoubleClickEvent( QMouseEvent * ) +{ + bool ok; + FxMixer * mix = engine::fxMixer(); + QString new_name = QInputDialog::getText( this, + FxMixerView::tr( "Rename FX channel" ), + FxMixerView::tr( "Enter the new name for this " + "FX channel" ), + QLineEdit::Normal, mix->effectChannel(m_channelIndex)->m_name, &ok ); + if( ok && !new_name.isEmpty() ) + { + mix->effectChannel(m_channelIndex)->m_name = new_name; + update(); + } +} + +#include "moc_FxLine.cxx" diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 3be23bcfe..cf2d5e72a 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -35,87 +36,13 @@ #include #include - #include "FxMixerView.h" -#include "fader.h" #include "knob.h" -#include "EffectRackView.h" #include "engine.h" #include "embed.h" #include "MainWindow.h" #include "lcd_spinbox.h" #include "gui_templates.h" -#include "tooltip.h" -#include "pixmap_button.h" - - -class SendIndicator : public QWidget -{ - public: - SendIndicator( QWidget * _parent ) : - QWidget( _parent ) - { - setFixedSize(23, 16); - } - -}; - -class FxLine : public QWidget -{ -public: - FxLine( QWidget * _parent, FxMixerView * _mv, QString & _name, - int _channelIndex) : - QWidget( _parent ), - m_channelIndex( _channelIndex ), - m_mv( _mv ), - m_name( _name ) - { - setFixedSize( 32, 287 ); - setAttribute( Qt::WA_OpaquePaintEvent, true ); - setCursor( QCursor( embed::getIconPixmap( "hand" ), 0, 0 ) ); - } - - virtual void paintEvent( QPaintEvent * ) - { - bool sendToThis = engine::fxMixer()->channelSendModel( - m_mv->currentFxLine()->m_channelIndex, m_channelIndex) != NULL; - QPainter painter; - painter.begin( this ); - engine::getLmmsStyle()->drawFxLine( &painter, this, m_name, - m_mv->currentFxLine() == this, sendToThis ); - painter.end(); - } - - virtual void mousePressEvent( QMouseEvent * ) - { - m_mv->setCurrentFxLine( this ); - } - - virtual void mouseDoubleClickEvent( QMouseEvent * ) - { - bool ok; - QString new_name = QInputDialog::getText( this, - FxMixerView::tr( "Rename FX channel" ), - FxMixerView::tr( "Enter the new name for this " - "FX channel" ), - QLineEdit::Normal, m_name, &ok ); - if( ok && !new_name.isEmpty() ) - { - m_name = new_name; - update(); - } - } - - knob * m_sendKnob; - int m_channelIndex; -private: - FxMixerView * m_mv; - QString & m_name; - -} ; - - - FxMixerView::FxMixerView() : QWidget(), @@ -144,13 +71,16 @@ FxMixerView::FxMixerView() : ml->setSpacing( 0 ); ml->addSpacing( 6 ); - m_fxChannelViews.resize(m->numChannels()); channelArea = new QScrollArea(this); chLayout = new QHBoxLayout(channelArea); // add master channel - FxChannelView * masterView = &m_fxChannelViews[0]; - addFxLine(0, this, ml); + m_fxChannelViews.resize(m->numChannels()); + m_fxChannelViews[0] = new FxChannelView(this, this, 0); + FxChannelView * masterView = m_fxChannelViews[0]; + m_fxRacksLayout->addWidget( masterView->m_rackView ); + + ml->addWidget(masterView->m_fxLine); ml->addSpacing(5); QSize fxLineSize = masterView->m_fxLine->size(); @@ -160,7 +90,9 @@ FxMixerView::FxMixerView() : // add mixer channels for( int i = 1; i < m_fxChannelViews.size(); ++i ) { - addFxLine(i, channelArea, chLayout); + m_fxChannelViews[i] = new FxChannelView(channelArea, this, i); + chLayout->addWidget(m_fxChannelViews[i]->m_fxLine); + m_fxRacksLayout->addWidget( m_fxChannelViews[i]->m_rackView ); } // add the scrolling section to the main layout ml->addLayout(chLayout); @@ -178,7 +110,7 @@ FxMixerView::FxMixerView() : setLayout( ml ); updateGeometry(); - setCurrentFxLine( m_fxChannelViews[0].m_fxLine ); + setCurrentFxLine( m_fxChannelViews[0]->m_fxLine ); // timer for updating faders connect( engine::mainWindow(), SIGNAL( periodicUpdate() ), @@ -200,57 +132,6 @@ FxMixerView::FxMixerView() : setModel( m ); } - -void FxMixerView::addFxLine(int i, QWidget * parent, QLayout * layout) -{ - FxMixer * m = engine::fxMixer(); - - FxChannelView * cv = &m_fxChannelViews[i]; - - cv->m_fxLine = new FxLine( parent, this, - m->m_fxChannels[i]->m_name, i ); - layout->addWidget(cv->m_fxLine); - - // mixer sends knob - cv->m_fxLine->m_sendKnob = new knob(0, cv->m_fxLine, - tr("Channel send amount")); - cv->m_fxLine->m_sendKnob->move(0, 22); - cv->m_fxLine->m_sendKnob->setVisible(false); - - // send light indicator - - - // channel number - lcdSpinBox * l = new lcdSpinBox( 2, cv->m_fxLine ); - l->model()->setRange( i, i ); - l->model()->setValue( i ); - l->move( 2, 58 ); - l->setMarginWidth( 1 ); - - - cv->m_fader = new fader( &m->m_fxChannels[i]->m_volumeModel, - tr( "FX Fader %1" ).arg( i ), - cv->m_fxLine ); - cv->m_fader->move( 15-cv->m_fader->width()/2, - cv->m_fxLine->height()- - cv->m_fader->height()-5 ); - - cv->m_muteBtn = new pixmapButton( cv->m_fxLine, tr( "Mute" ) ); - cv->m_muteBtn->setModel( &m->m_fxChannels[i]->m_muteModel ); - cv->m_muteBtn->setActiveGraphic( - embed::getIconPixmap( "led_off" ) ); - cv->m_muteBtn->setInactiveGraphic( - embed::getIconPixmap( "led_green" ) ); - cv->m_muteBtn->setCheckable( true ); - cv->m_muteBtn->move( 9, cv->m_fader->y()-16); - toolTip::add( cv->m_muteBtn, tr( "Mute this FX channel" ) ); - - cv->m_rackView = new EffectRackView( - &m->m_fxChannels[i]->m_fxChain, this ); - m_fxRacksLayout->addWidget( cv->m_rackView ); -} - - FxMixerView::~FxMixerView() { } @@ -263,9 +144,10 @@ void FxMixerView::addNewChannel() FxMixer * mix = engine::fxMixer(); int newChannelIndex = mix->createChannel(); - m_fxChannelViews.push_back(FxChannelView()); - - addFxLine(newChannelIndex, channelArea, chLayout); + m_fxChannelViews.push_back(new FxChannelView(channelArea, this, + newChannelIndex)); + chLayout->addWidget(m_fxChannelViews[newChannelIndex]->m_fxLine); + m_fxRacksLayout->addWidget( m_fxChannelViews[newChannelIndex]->m_rackView ); } @@ -284,42 +166,73 @@ void FxMixerView::loadSettings( const QDomElement & _this ) } +FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, + int _chIndex ) +{ + m_fxLine = new FxLine(_parent, _mv, _chIndex); + + FxMixer * m = engine::fxMixer(); + m_fader = new fader( &m->effectChannel(_chIndex)->m_volumeModel, + tr( "FX Fader %1" ).arg( _chIndex ), m_fxLine ); + m_fader->move( 15-m_fader->width()/2, + m_fxLine->height()- + m_fader->height()-5 ); + + m_muteBtn = new pixmapButton( m_fxLine, tr( "Mute" ) ); + m_muteBtn->setModel( &m->effectChannel(_chIndex)->m_muteModel ); + m_muteBtn->setActiveGraphic( + embed::getIconPixmap( "led_off" ) ); + m_muteBtn->setInactiveGraphic( + embed::getIconPixmap( "led_green" ) ); + m_muteBtn->setCheckable( true ); + m_muteBtn->move( 9, m_fader->y()-16); + toolTip::add( m_muteBtn, tr( "Mute this FX channel" ) ); + + m_rackView = new EffectRackView( + &m->m_fxChannels[_chIndex]->m_fxChain, _mv ); +} void FxMixerView::setCurrentFxLine( FxLine * _line ) { - FxMixer * mix = engine::fxMixer(); - // select m_currentFxLine = _line; - m_fxRacksLayout->setCurrentIndex( _line->m_channelIndex ); + m_fxRacksLayout->setCurrentIndex( _line->channelIndex() ); // set up send knob for(int i = 0; i < m_fxChannelViews.size(); ++i) { - // does current channel send to this channel? - FloatModel * sendModel = mix->channelSendModel(_line->m_channelIndex, i); - if( sendModel == NULL ) - { - // does not send, hide send knob - m_fxChannelViews[i].m_fxLine->m_sendKnob->setVisible(false); - } - else - { - // it does send, show knob and connect - m_fxChannelViews[i].m_fxLine->m_sendKnob->setVisible(true); - m_fxChannelViews[i].m_fxLine->m_sendKnob->setModel(sendModel); - } - - m_fxChannelViews[i].m_fxLine->update(); + updateFxLine(i); } } +void FxMixerView::updateFxLine(int i) +{ + FxMixer * mix = engine::fxMixer(); + + // does current channel send to this channel? + FloatModel * sendModel = mix->channelSendModel(m_currentFxLine->channelIndex(), i); + if( sendModel == NULL ) + { + // does not send, hide send knob + m_fxChannelViews[i]->m_fxLine->m_sendKnob->setVisible(false); + } + else + { + // it does send, show knob and connect + m_fxChannelViews[i]->m_fxLine->m_sendKnob->setVisible(true); + m_fxChannelViews[i]->m_fxLine->m_sendKnob->setModel(sendModel); + } + + + m_fxChannelViews[i]->m_fxLine->update(); + m_fxChannelViews[i]->m_fxLine->m_sendBtn->updateLightStatus(); +} void FxMixerView::setCurrentFxLine( int _line ) { - setCurrentFxLine( m_fxChannelViews[_line].m_fxLine ); + setCurrentFxLine( m_fxChannelViews[_line]->m_fxLine ); } @@ -329,7 +242,7 @@ void FxMixerView::clear() { for( int i = 0; i < m_fxChannelViews.size(); ++i ) { - m_fxChannelViews[i].m_rackView->clearViews(); + m_fxChannelViews[i]->m_rackView->clearViews(); } } @@ -341,26 +254,26 @@ void FxMixerView::updateFaders() FxMixer * m = engine::fxMixer(); for( int i = 0; i < m_fxChannelViews.size(); ++i ) { - const float opl = m_fxChannelViews[i].m_fader->getPeak_L(); - const float opr = m_fxChannelViews[i].m_fader->getPeak_R(); + const float opl = m_fxChannelViews[i]->m_fader->getPeak_L(); + const float opr = m_fxChannelViews[i]->m_fader->getPeak_R(); const float fall_off = 1.2; if( m->m_fxChannels[i]->m_peakLeft > opl ) { - m_fxChannelViews[i].m_fader->setPeak_L( + m_fxChannelViews[i]->m_fader->setPeak_L( m->m_fxChannels[i]->m_peakLeft ); } else { - m_fxChannelViews[i].m_fader->setPeak_L( opl/fall_off ); + m_fxChannelViews[i]->m_fader->setPeak_L( opl/fall_off ); } if( m->m_fxChannels[i]->m_peakRight > opr ) { - m_fxChannelViews[i].m_fader->setPeak_R( + m_fxChannelViews[i]->m_fader->setPeak_R( m->m_fxChannels[i]->m_peakRight ); } else { - m_fxChannelViews[i].m_fader->setPeak_R( opr/fall_off ); + m_fxChannelViews[i]->m_fader->setPeak_R( opr/fall_off ); } } } diff --git a/src/gui/SendButtonIndicator.cpp b/src/gui/SendButtonIndicator.cpp new file mode 100644 index 000000000..a932f136a --- /dev/null +++ b/src/gui/SendButtonIndicator.cpp @@ -0,0 +1,53 @@ +#include "SendButtonIndicator.h" + +#include "engine.h" +#include "FxMixer.h" +#include "Model.h" + +SendButtonIndicator:: SendButtonIndicator( QWidget * _parent, FxLine * _owner, + FxMixerView * _mv) : + QLabel( _parent ), + m_parent( _owner ), + m_mv( _mv ) +{ + qpmOff = embed::getIconPixmap("mixer_send_off", 23, 16); + qpmOn = embed::getIconPixmap("mixer_send_on", 23, 16); + + // don't do any initializing yet, because the FxMixerView and FxLine + // that were passed to this constructor are not done with their constructors + // yet. + +} + +void SendButtonIndicator::mousePressEvent( QMouseEvent * e ) +{ + FxMixer * mix = engine::fxMixer(); + int from = m_mv->currentFxLine()->channelIndex(); + int to = m_parent->channelIndex(); + FloatModel * sendModel = mix->channelSendModel(from, to); + if( sendModel == NULL ) + { + // not sending. create a mixer send. + mix->createChannelSend( from, to ); + } + else + { + // sending. delete the mixer send. + mix->deleteChannelSend( from, to ); + } + + m_mv->updateFxLine(m_parent->channelIndex()); + updateLightStatus(); +} + +FloatModel * SendButtonIndicator::getSendModel() +{ + FxMixer * mix = engine::fxMixer(); + return mix->channelSendModel( + m_mv->currentFxLine()->channelIndex(), m_parent->channelIndex()); +} + +void SendButtonIndicator::updateLightStatus() +{ + setPixmap( getSendModel() == NULL ? qpmOff : qpmOn ); +}