Pretty interface in default theme for fx sends

Created a user interface so you can add and remove FX sends as
well as tweak how much you are sending. The gui does not
yet prevent the user from creating endless render loops.
Additionally, there seems to be some issues to work out regarding
rendering with multiple sends.
This commit is contained in:
Andrew Kelley
2009-09-16 17:43:28 -07:00
parent 89d5be7855
commit 289f004c28
9 changed files with 324 additions and 192 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

38
include/FxLine.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef FXLINE_H
#define FXLINE_H
#include <QWidget>
#include <QLabel>
#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

View File

@@ -29,60 +29,74 @@
#include <QtGui/QHBoxLayout>
#include <QtGui/QScrollArea>
#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<FxChannelView> 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<FxChannelView *> m_fxChannelViews;
QStackedLayout * m_fxRacksLayout;
FxLine * m_currentFxLine;
QScrollArea * channelArea;
QHBoxLayout * chLayout;
void addFxLine(int i, QWidget * parent, QLayout * layout);
} ;
#endif

View File

@@ -0,0 +1,32 @@
#ifndef SENDBUTTONINDICATOR_H
#define SENDBUTTONINDICATOR_H
#include <QLabel>
#include <QDebug>
#include <QPixmap>
#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

View File

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

77
src/gui/FxLine.cpp Normal file
View File

@@ -0,0 +1,77 @@
#include "FxLine.h"
#include <QDebug>
#include <QPainter>
#include <QInputDialog>
#include <QLineEdit>
#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"

View File

@@ -23,6 +23,7 @@
*/
#include <QtGlobal>
#include <QDebug>
#include <QtGui/QButtonGroup>
#include <QtGui/QInputDialog>
@@ -35,87 +36,13 @@
#include <QtGui/QStackedLayout>
#include <QtGui/QScrollArea>
#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 );
}
}
}

View File

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