Support FX Mixer for sample tracks and add controls to sample track window (#3866)
This work is based on https://github.com/LMMS/lmms/pull/3632 by @grejppi.
This commit is contained in:
53
include/FxLineLcdSpinBox.h
Normal file
53
include/FxLineLcdSpinBox.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* FxLineLcdSpinBox.h - a specialization of LcdSpnBox for setting FX channels
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FX_LINE_LCD_SPIN_BOX_H
|
||||
#define FX_LINE_LCD_SPIN_BOX_H
|
||||
|
||||
#include "LcdSpinBox.h"
|
||||
|
||||
class TrackView;
|
||||
|
||||
|
||||
class FxLineLcdSpinBox : public LcdSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FxLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = NULL) :
|
||||
LcdSpinBox(numDigits, parent, name), m_tv(tv)
|
||||
{}
|
||||
virtual ~FxLineLcdSpinBox() {}
|
||||
|
||||
void setTrackView(TrackView * tv);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent* event);
|
||||
|
||||
private:
|
||||
TrackView * m_tv;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -52,6 +52,7 @@ class InstrumentTrackWindow;
|
||||
class InstrumentMidiIOView;
|
||||
class InstrumentMiscView;
|
||||
class Knob;
|
||||
class FxLineLcdSpinBox;
|
||||
class LcdSpinBox;
|
||||
class LeftRightNav;
|
||||
class midiPortMenu;
|
||||
@@ -440,7 +441,7 @@ private:
|
||||
QLabel * m_pitchLabel;
|
||||
LcdSpinBox* m_pitchRangeSpinBox;
|
||||
QLabel * m_pitchRangeLabel;
|
||||
LcdSpinBox * m_effectChannelNumber;
|
||||
FxLineLcdSpinBox * m_effectChannelNumber;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,13 +26,19 @@
|
||||
#define SAMPLE_TRACK_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLayout>
|
||||
|
||||
#include "AudioPort.h"
|
||||
#include "FxMixer.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "Track.h"
|
||||
|
||||
class EffectRackView;
|
||||
class Knob;
|
||||
class SampleBuffer;
|
||||
class SampleTrackWindow;
|
||||
class TrackLabelButton;
|
||||
class QLineEdit;
|
||||
|
||||
|
||||
class SampleTCO : public TrackContentObject
|
||||
@@ -140,6 +146,11 @@ public:
|
||||
QDomElement & _parent );
|
||||
virtual void loadTrackSpecificSettings( const QDomElement & _this );
|
||||
|
||||
inline IntModel * effectChannelModel()
|
||||
{
|
||||
return &m_effectChannelModel;
|
||||
}
|
||||
|
||||
inline AudioPort * audioPort()
|
||||
{
|
||||
return &m_audioPort;
|
||||
@@ -153,15 +164,18 @@ public:
|
||||
public slots:
|
||||
void updateTcos();
|
||||
void setPlayingTcos( bool isPlaying );
|
||||
void updateEffectChannel();
|
||||
|
||||
private:
|
||||
FloatModel m_volumeModel;
|
||||
FloatModel m_panningModel;
|
||||
IntModel m_effectChannelModel;
|
||||
AudioPort m_audioPort;
|
||||
|
||||
|
||||
|
||||
friend class SampleTrackView;
|
||||
friend class SampleTrackWindow;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -174,6 +188,24 @@ public:
|
||||
SampleTrackView( SampleTrack* Track, TrackContainerView* tcv );
|
||||
virtual ~SampleTrackView();
|
||||
|
||||
SampleTrackWindow * getSampleTrackWindow()
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
SampleTrack * model()
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
const SampleTrack * model() const
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
|
||||
virtual QMenu * createFxMenu( QString title, QString newFxLabel );
|
||||
|
||||
|
||||
public slots:
|
||||
void showEffects();
|
||||
@@ -187,12 +219,77 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
void assignFxLine( int channelIndex );
|
||||
void createFxLine();
|
||||
|
||||
|
||||
private:
|
||||
EffectRackView * m_effectRack;
|
||||
QWidget * m_effWindow;
|
||||
SampleTrackWindow * m_window;
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
|
||||
TrackLabelButton * m_tlb;
|
||||
|
||||
|
||||
friend class SampleTrackWindow;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class SampleTrackWindow : public QWidget, public ModelView, public SerializingObjectHook
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SampleTrackWindow(SampleTrackView * tv);
|
||||
virtual ~SampleTrackWindow();
|
||||
|
||||
SampleTrack * model()
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
const SampleTrack * model() const
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
void setSampleTrackView(SampleTrackView * tv);
|
||||
|
||||
SampleTrackView *sampleTrackView()
|
||||
{
|
||||
return m_stv;
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
void textChanged(const QString & new_name);
|
||||
void toggleVisibility(bool on);
|
||||
void updateName();
|
||||
|
||||
|
||||
protected:
|
||||
// capture close-events for toggling sample-track-button
|
||||
virtual void closeEvent(QCloseEvent * ce);
|
||||
|
||||
virtual void saveSettings(QDomDocument & doc, QDomElement & element);
|
||||
virtual void loadSettings(const QDomElement & element);
|
||||
|
||||
private:
|
||||
virtual void modelChanged();
|
||||
|
||||
SampleTrack * m_track;
|
||||
SampleTrackView * m_stv;
|
||||
|
||||
// widgets on the top of an sample-track-window
|
||||
QLineEdit * m_nameLineEdit;
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
FxLineLcdSpinBox * m_effectChannelNumber;
|
||||
|
||||
EffectRackView * m_effectRack;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -675,6 +675,10 @@ public:
|
||||
|
||||
virtual void update();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
// Currently instrument track and sample track supports it
|
||||
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "Song.h"
|
||||
|
||||
#include "InstrumentTrack.h"
|
||||
#include "SampleTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
|
||||
FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) :
|
||||
@@ -305,6 +306,22 @@ void FxMixer::deleteChannel( int index )
|
||||
inst->effectChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
else if( t->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack* strk = dynamic_cast<SampleTrack *>( t );
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
if( val == index )
|
||||
{
|
||||
// we are deleting this track's fx send
|
||||
// send to master
|
||||
strk->effectChannelModel()->setValue(0);
|
||||
}
|
||||
else if( val > index )
|
||||
{
|
||||
// subtract 1 to make up for the missing channel
|
||||
strk->effectChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FxChannel * ch = m_fxChannels[index];
|
||||
@@ -379,6 +396,19 @@ void FxMixer::moveChannelLeft( int index )
|
||||
inst->effectChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
if( val == a )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(b);
|
||||
}
|
||||
else if( val == b )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,4 +810,3 @@ void FxMixer::validateChannelName( int index, int oldIndex )
|
||||
m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1924,13 +1924,15 @@ void TrackOperationsWidget::updateMenu()
|
||||
{
|
||||
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
|
||||
}
|
||||
if( InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>( m_trackView ) )
|
||||
if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel")))
|
||||
{
|
||||
QMenu *fxMenu = trackView->createFxMenu( tr( "FX %1: %2" ), tr( "Assign to new FX Channel" ));
|
||||
toMenu->addMenu(fxMenu);
|
||||
}
|
||||
|
||||
if (InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>(m_trackView))
|
||||
{
|
||||
toMenu->addSeparator();
|
||||
toMenu->addMenu( trackView->midiMenu() );
|
||||
toMenu->addMenu(trackView->midiMenu());
|
||||
}
|
||||
if( dynamic_cast<AutomationTrackView *>( m_trackView ) )
|
||||
{
|
||||
@@ -2677,6 +2679,19 @@ void TrackView::update()
|
||||
|
||||
|
||||
|
||||
/*! \brief Create a menu for assigning/creating channels for this track.
|
||||
*
|
||||
*/
|
||||
QMenu * TrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(newFxLabel)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Close this track View.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,7 @@ SET(LMMS_SRCS
|
||||
gui/widgets/FadeButton.cpp
|
||||
gui/widgets/Fader.cpp
|
||||
gui/widgets/FxLine.cpp
|
||||
gui/widgets/FxLineLcdSpinBox.cpp
|
||||
gui/widgets/Graph.cpp
|
||||
gui/widgets/GroupBox.cpp
|
||||
gui/widgets/InstrumentFunctionViews.cpp
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "Mixer.h"
|
||||
#include "gui_templates.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "SampleTrack.h"
|
||||
#include "Song.h"
|
||||
#include "BBTrackContainer.h"
|
||||
|
||||
@@ -251,6 +252,12 @@ void FxMixerView::updateMaxChannelSelector()
|
||||
inst->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
strk->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
src/gui/widgets/FxLineLcdSpinBox.cpp
Normal file
66
src/gui/widgets/FxLineLcdSpinBox.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* FxLineLcdSpinBox.cpp - a specialization of LcdSpnBox for setting FX channels
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
|
||||
#include "CaptionMenu.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "Track.h"
|
||||
|
||||
void FxLineLcdSpinBox::setTrackView(TrackView * tv)
|
||||
{
|
||||
m_tv = tv;
|
||||
}
|
||||
|
||||
void FxLineLcdSpinBox::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
gui->fxMixerView()->setCurrentFxLine(model()->value());
|
||||
|
||||
gui->fxMixerView()->parentWidget()->show();
|
||||
gui->fxMixerView()->show();// show fxMixer window
|
||||
gui->fxMixerView()->setFocus();// set focus to fxMixer window
|
||||
//engine::getFxMixerView()->raise();
|
||||
}
|
||||
|
||||
void FxLineLcdSpinBox::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
// for the case, the user clicked right while pressing left mouse-
|
||||
// button, the context-menu appears while mouse-cursor is still hidden
|
||||
// and it isn't shown again until user does something which causes
|
||||
// an QApplication::restoreOverrideCursor()-call...
|
||||
mouseReleaseEvent(nullptr);
|
||||
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu(model()->displayName(), this);
|
||||
|
||||
if (QMenu *fxMenu = m_tv->createFxMenu(
|
||||
tr("Assign to:"), tr("New FX Channel")))
|
||||
{
|
||||
contextMenu->addMenu(fxMenu);
|
||||
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
addDefaultActions(contextMenu);
|
||||
contextMenu->exec(QCursor::pos());
|
||||
}
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "EffectRackView.h"
|
||||
#include "embed.h"
|
||||
#include "FileBrowser.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "FxMixer.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "GuiApplication.h"
|
||||
@@ -1249,52 +1250,6 @@ QMenu * InstrumentTrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
|
||||
|
||||
|
||||
class fxLineLcdSpinBox : public LcdSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
fxLineLcdSpinBox( int _num_digits, QWidget * _parent,
|
||||
const QString & _name ) :
|
||||
LcdSpinBox( _num_digits, _parent, _name ) {}
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent ( QMouseEvent * _me )
|
||||
{
|
||||
gui->fxMixerView()->setCurrentFxLine( model()->value() );
|
||||
|
||||
gui->fxMixerView()->parentWidget()->show();
|
||||
gui->fxMixerView()->show();// show fxMixer window
|
||||
gui->fxMixerView()->setFocus();// set focus to fxMixer window
|
||||
//engine::getFxMixerView()->raise();
|
||||
}
|
||||
|
||||
virtual void contextMenuEvent( QContextMenuEvent* event )
|
||||
{
|
||||
// for the case, the user clicked right while pressing left mouse-
|
||||
// button, the context-menu appears while mouse-cursor is still hidden
|
||||
// and it isn't shown again until user does something which causes
|
||||
// an QApplication::restoreOverrideCursor()-call...
|
||||
mouseReleaseEvent( NULL );
|
||||
|
||||
QPointer<CaptionMenu> contextMenu = new CaptionMenu( model()->displayName(), this );
|
||||
|
||||
// This condition is here just as a safety check, fxLineLcdSpinBox is aways
|
||||
// created inside a TabWidget inside an InstrumentTrackWindow
|
||||
if ( InstrumentTrackWindow* window = dynamic_cast<InstrumentTrackWindow*>( (QWidget *)this->parent()->parent() ) )
|
||||
{
|
||||
QMenu *fxMenu = window->instrumentTrackView()->createFxMenu( tr( "Assign to:" ), tr( "New FX channel" ) );
|
||||
contextMenu->addMenu( fxMenu );
|
||||
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
addDefaultActions( contextMenu );
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
// #### ITW:
|
||||
InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
|
||||
QWidget(),
|
||||
@@ -1415,7 +1370,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) :
|
||||
|
||||
|
||||
// setup spinbox for selecting FX-channel
|
||||
m_effectChannelNumber = new fxLineLcdSpinBox( 2, NULL, tr( "FX channel" ) );
|
||||
m_effectChannelNumber = new FxLineLcdSpinBox( 2, NULL, tr( "FX channel" ), m_itv );
|
||||
|
||||
basicControlsLayout->addWidget( m_effectChannelNumber, 0, 6 );
|
||||
basicControlsLayout->setAlignment( m_effectChannelNumber, widgetAlignment );
|
||||
@@ -1536,6 +1491,7 @@ void InstrumentTrackWindow::setInstrumentTrackView( InstrumentTrackView* view )
|
||||
}
|
||||
|
||||
m_itv = view;
|
||||
m_effectChannelNumber->setTrackView(m_itv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QMenu>
|
||||
#include <QLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMdiArea>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QPainter>
|
||||
@@ -48,6 +49,8 @@
|
||||
#include "MainWindow.h"
|
||||
#include "Mixer.h"
|
||||
#include "EffectRackView.h"
|
||||
#include "FxMixerView.h"
|
||||
#include "TabWidget.h"
|
||||
#include "TrackLabelButton.h"
|
||||
|
||||
SampleTCO::SampleTCO( Track * _track ) :
|
||||
@@ -471,7 +474,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
bool muted = m_tco->getTrack()->isMuted() || m_tco->isMuted();
|
||||
|
||||
// state: selected, muted, normal
|
||||
c = isSelected() ? selectedColor() : ( muted ? mutedBackgroundColor()
|
||||
c = isSelected() ? selectedColor() : ( muted ? mutedBackgroundColor()
|
||||
: painter.background().color() );
|
||||
|
||||
lingrad.setColorAt( 1, c.darker( 300 ) );
|
||||
@@ -515,7 +518,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
|
||||
// inner border
|
||||
p.setPen( c.lighter( 160 ) );
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
|
||||
rect().bottom() - TCO_BORDER_WIDTH );
|
||||
|
||||
// outer border
|
||||
@@ -531,7 +534,7 @@ void SampleTCOView::paintEvent( QPaintEvent * pe )
|
||||
embed::getIconPixmap( "muted", size, size ) );
|
||||
}
|
||||
|
||||
// recording sample tracks is not possible at the moment
|
||||
// recording sample tracks is not possible at the moment
|
||||
|
||||
/* if( m_tco->isRecord() )
|
||||
{
|
||||
@@ -562,10 +565,14 @@ SampleTrack::SampleTrack( TrackContainer* tc ) :
|
||||
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 )
|
||||
{
|
||||
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() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -693,6 +700,7 @@ void SampleTrack::saveTrackSpecificSettings( QDomDocument & _doc,
|
||||
#endif
|
||||
m_volumeModel.saveSettings( _doc, _this, "vol" );
|
||||
m_panningModel.saveSettings( _doc, _this, "pan" );
|
||||
m_effectChannelModel.saveSettings( _doc, _this, "fxch" );
|
||||
}
|
||||
|
||||
|
||||
@@ -715,6 +723,8 @@ void SampleTrack::loadTrackSpecificSettings( const QDomElement & _this )
|
||||
}
|
||||
m_volumeModel.loadSettings( _this, "vol" );
|
||||
m_panningModel.loadSettings( _this, "pan" );
|
||||
m_effectChannelModel.setRange( 0, Engine::fxMixer()->numChannels() - 1 );
|
||||
m_effectChannelModel.loadSettings( _this, "fxch" );
|
||||
}
|
||||
|
||||
|
||||
@@ -742,6 +752,14 @@ void SampleTrack::setPlayingTcos( bool isPlaying )
|
||||
|
||||
|
||||
|
||||
void SampleTrack::updateEffectChannel()
|
||||
{
|
||||
m_audioPort.setNextFxChannel( m_effectChannelModel.value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
|
||||
@@ -749,13 +767,13 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
|
||||
{
|
||||
setFixedHeight( 32 );
|
||||
|
||||
TrackLabelButton * tlb = new TrackLabelButton( this,
|
||||
getTrackSettingsWidget() );
|
||||
connect( tlb, SIGNAL( clicked( bool ) ),
|
||||
this, SLOT( showEffects() ) );
|
||||
tlb->setIcon( embed::getIconPixmap( "sample_track" ) );
|
||||
tlb->move( 3, 1 );
|
||||
tlb->show();
|
||||
m_tlb = new TrackLabelButton(this, getTrackSettingsWidget());
|
||||
m_tlb->setCheckable(true);
|
||||
connect(m_tlb, SIGNAL(clicked( bool )),
|
||||
this, SLOT(showEffects()));
|
||||
m_tlb->setIcon(embed::getIconPixmap("sample_track"));
|
||||
m_tlb->move(3, 1);
|
||||
m_tlb->show();
|
||||
|
||||
m_volumeKnob = new Knob( knobSmall_17, getTrackSettingsWidget(),
|
||||
tr( "Track volume" ) );
|
||||
@@ -779,16 +797,10 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
|
||||
m_panningKnob->setLabel( tr( "PAN" ) );
|
||||
m_panningKnob->show();
|
||||
|
||||
m_effectRack = new EffectRackView( _t->audioPort()->effects() );
|
||||
m_effectRack->setFixedSize( 240, 242 );
|
||||
|
||||
m_effWindow = gui->mainWindow()->addWindowedWidget( m_effectRack );
|
||||
m_effWindow->setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
m_effWindow->layout()->setSizeConstraint( QLayout::SetFixedSize );
|
||||
m_effWindow->setWindowTitle( _t->name() );
|
||||
m_effWindow->hide();
|
||||
|
||||
setModel( _t );
|
||||
|
||||
m_window = new SampleTrackWindow(this);
|
||||
m_window->toggleVisibility(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -796,7 +808,50 @@ SampleTrackView::SampleTrackView( SampleTrack * _t, TrackContainerView* tcv ) :
|
||||
|
||||
SampleTrackView::~SampleTrackView()
|
||||
{
|
||||
m_effWindow->deleteLater();
|
||||
if(m_window != NULL)
|
||||
{
|
||||
m_window->setSampleTrackView(NULL);
|
||||
m_window->parentWidget()->hide();
|
||||
}
|
||||
m_window = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QMenu * SampleTrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
{
|
||||
int channelIndex = model()->effectChannelModel()->value();
|
||||
|
||||
FxChannel *fxChannel = Engine::fxMixer()->effectChannel(channelIndex);
|
||||
|
||||
// If title allows interpolation, pass channel index and name
|
||||
if (title.contains("%2"))
|
||||
{
|
||||
title = title.arg(channelIndex).arg(fxChannel->m_name);
|
||||
}
|
||||
|
||||
QMenu *fxMenu = new QMenu(title);
|
||||
|
||||
QSignalMapper * fxMenuSignalMapper = new QSignalMapper(fxMenu);
|
||||
|
||||
fxMenu->addAction(newFxLabel, this, SLOT(createFxLine()));
|
||||
fxMenu->addSeparator();
|
||||
|
||||
for (int i = 0; i < Engine::fxMixer()->numChannels(); ++i)
|
||||
{
|
||||
FxChannel * currentChannel = Engine::fxMixer()->effectChannel(i);
|
||||
|
||||
if (currentChannel != fxChannel)
|
||||
{
|
||||
QString label = tr("FX %1: %2").arg(currentChannel->m_channelIndex).arg(currentChannel->m_name);
|
||||
QAction * action = fxMenu->addAction(label, fxMenuSignalMapper, SLOT(map()));
|
||||
fxMenuSignalMapper->setMapping(action, currentChannel->m_channelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
connect(fxMenuSignalMapper, SIGNAL(mapped(int)), this, SLOT(assignFxLine(int)));
|
||||
|
||||
return fxMenu;
|
||||
}
|
||||
|
||||
|
||||
@@ -804,16 +859,7 @@ SampleTrackView::~SampleTrackView()
|
||||
|
||||
void SampleTrackView::showEffects()
|
||||
{
|
||||
if( m_effWindow->isHidden() )
|
||||
{
|
||||
m_effectRack->show();
|
||||
m_effWindow->show();
|
||||
m_effWindow->raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_effWindow->hide();
|
||||
}
|
||||
m_window->toggleVisibility(m_window->parentWidget()->isHidden());
|
||||
}
|
||||
|
||||
|
||||
@@ -821,7 +867,261 @@ void SampleTrackView::showEffects()
|
||||
void SampleTrackView::modelChanged()
|
||||
{
|
||||
SampleTrack * st = castModel<SampleTrack>();
|
||||
m_volumeKnob->setModel( &st->m_volumeModel );
|
||||
m_volumeKnob->setModel(&st->m_volumeModel);
|
||||
|
||||
TrackView::modelChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
SampleTrackWindow::SampleTrackWindow(SampleTrackView * tv) :
|
||||
QWidget(),
|
||||
ModelView(NULL, this),
|
||||
m_track(tv->model()),
|
||||
m_stv(tv)
|
||||
{
|
||||
// init own layout + widgets
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
QVBoxLayout * vlayout = new QVBoxLayout(this);
|
||||
vlayout->setMargin(0);
|
||||
vlayout->setSpacing(0);
|
||||
|
||||
TabWidget* generalSettingsWidget = new TabWidget(tr("GENERAL SETTINGS"), this);
|
||||
|
||||
QVBoxLayout* generalSettingsLayout = new QVBoxLayout(generalSettingsWidget);
|
||||
|
||||
generalSettingsLayout->setContentsMargins(8, 18, 8, 8);
|
||||
generalSettingsLayout->setSpacing(6);
|
||||
|
||||
QWidget* nameWidget = new QWidget(generalSettingsWidget);
|
||||
QHBoxLayout* nameLayout = new QHBoxLayout(nameWidget);
|
||||
nameLayout->setContentsMargins(0, 0, 0, 0);
|
||||
nameLayout->setSpacing(2);
|
||||
|
||||
// setup line edit for changing sample track name
|
||||
m_nameLineEdit = new QLineEdit;
|
||||
m_nameLineEdit->setFont(pointSize<9>(m_nameLineEdit->font()));
|
||||
connect(m_nameLineEdit, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(textChanged(const QString &)));
|
||||
|
||||
m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
|
||||
nameLayout->addWidget(m_nameLineEdit);
|
||||
|
||||
|
||||
generalSettingsLayout->addWidget(nameWidget);
|
||||
|
||||
|
||||
QGridLayout* basicControlsLayout = new QGridLayout;
|
||||
basicControlsLayout->setHorizontalSpacing(3);
|
||||
basicControlsLayout->setVerticalSpacing(0);
|
||||
basicControlsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QString labelStyleSheet = "font-size: 6pt;";
|
||||
Qt::Alignment labelAlignment = Qt::AlignHCenter | Qt::AlignTop;
|
||||
Qt::Alignment widgetAlignment = Qt::AlignHCenter | Qt::AlignCenter;
|
||||
|
||||
// set up volume knob
|
||||
m_volumeKnob = new Knob(knobBright_26, NULL, tr("Sample volume"));
|
||||
m_volumeKnob->setVolumeKnob(true);
|
||||
m_volumeKnob->setHintText(tr("Volume:"), "%");
|
||||
|
||||
basicControlsLayout->addWidget(m_volumeKnob, 0, 0);
|
||||
basicControlsLayout->setAlignment(m_volumeKnob, widgetAlignment);
|
||||
|
||||
QLabel *label = new QLabel(tr("VOL"), this);
|
||||
label->setStyleSheet(labelStyleSheet);
|
||||
basicControlsLayout->addWidget(label, 1, 0);
|
||||
basicControlsLayout->setAlignment(label, labelAlignment);
|
||||
|
||||
|
||||
// set up panning knob
|
||||
m_panningKnob = new Knob(knobBright_26, NULL, tr("Panning"));
|
||||
m_panningKnob->setHintText(tr("Panning:"), "");
|
||||
|
||||
basicControlsLayout->addWidget(m_panningKnob, 0, 1);
|
||||
basicControlsLayout->setAlignment(m_panningKnob, widgetAlignment);
|
||||
|
||||
label = new QLabel(tr("PAN"),this);
|
||||
label->setStyleSheet(labelStyleSheet);
|
||||
basicControlsLayout->addWidget(label, 1, 1);
|
||||
basicControlsLayout->setAlignment(label, labelAlignment);
|
||||
|
||||
|
||||
basicControlsLayout->setColumnStretch(2, 1);
|
||||
|
||||
|
||||
// setup spinbox for selecting FX-channel
|
||||
m_effectChannelNumber = new FxLineLcdSpinBox(2, NULL, tr("FX channel"), m_stv);
|
||||
|
||||
basicControlsLayout->addWidget(m_effectChannelNumber, 0, 3);
|
||||
basicControlsLayout->setAlignment(m_effectChannelNumber, widgetAlignment);
|
||||
|
||||
label = new QLabel(tr("FX"), this);
|
||||
label->setStyleSheet(labelStyleSheet);
|
||||
basicControlsLayout->addWidget(label, 1, 3);
|
||||
basicControlsLayout->setAlignment(label, labelAlignment);
|
||||
|
||||
generalSettingsLayout->addLayout(basicControlsLayout);
|
||||
|
||||
m_effectRack = new EffectRackView(tv->model()->audioPort()->effects());
|
||||
m_effectRack->setFixedSize(240, 242);
|
||||
|
||||
vlayout->addWidget(generalSettingsWidget);
|
||||
vlayout->addWidget(m_effectRack);
|
||||
|
||||
|
||||
setModel(tv->model());
|
||||
|
||||
QMdiSubWindow * subWin = gui->mainWindow()->addWindowedWidget(this);
|
||||
Qt::WindowFlags flags = subWin->windowFlags();
|
||||
flags |= Qt::MSWindowsFixedSizeDialogHint;
|
||||
flags &= ~Qt::WindowMaximizeButtonHint;
|
||||
subWin->setWindowFlags(flags);
|
||||
|
||||
// Hide the Size and Maximize options from the system menu
|
||||
// since the dialog size is fixed.
|
||||
QMenu * systemMenu = subWin->systemMenu();
|
||||
systemMenu->actions().at(2)->setVisible(false); // Size
|
||||
systemMenu->actions().at(4)->setVisible(false); // Maximize
|
||||
|
||||
subWin->setWindowIcon(embed::getIconPixmap("sample_track"));
|
||||
subWin->setFixedSize(subWin->size());
|
||||
subWin->hide();
|
||||
}
|
||||
|
||||
|
||||
|
||||
SampleTrackWindow::~SampleTrackWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::setSampleTrackView(SampleTrackView* tv)
|
||||
{
|
||||
if(m_stv && tv)
|
||||
{
|
||||
m_stv->m_tlb->setChecked(false);
|
||||
}
|
||||
|
||||
m_stv = tv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::modelChanged()
|
||||
{
|
||||
m_track = castModel<SampleTrack>();
|
||||
|
||||
m_nameLineEdit->setText(m_track->name());
|
||||
|
||||
m_track->disconnect(SIGNAL(nameChanged()), this);
|
||||
|
||||
connect(m_track, SIGNAL(nameChanged()),
|
||||
this, SLOT(updateName()));
|
||||
|
||||
m_volumeKnob->setModel(&m_track->m_volumeModel);
|
||||
m_panningKnob->setModel(&m_track->m_panningModel);
|
||||
m_effectChannelNumber->setModel(&m_track->m_effectChannelModel);
|
||||
|
||||
updateName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \brief Create and assign a new FX Channel for this track */
|
||||
void SampleTrackView::createFxLine()
|
||||
{
|
||||
int channelIndex = gui->fxMixerView()->addNewChannel();
|
||||
|
||||
Engine::fxMixer()->effectChannel(channelIndex)->m_name = getTrack()->name();
|
||||
|
||||
assignFxLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Assign a specific FX Channel for this track */
|
||||
void SampleTrackView::assignFxLine(int channelIndex)
|
||||
{
|
||||
model()->effectChannelModel()->setValue(channelIndex);
|
||||
|
||||
gui->fxMixerView()->setCurrentFxLine(channelIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::updateName()
|
||||
{
|
||||
setWindowTitle(m_track->name().length() > 25 ? (m_track->name().left(24) + "...") : m_track->name());
|
||||
|
||||
if(m_nameLineEdit->text() != m_track->name())
|
||||
{
|
||||
m_nameLineEdit->setText(m_track->name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::textChanged(const QString& new_name)
|
||||
{
|
||||
m_track->setName(new_name);
|
||||
Engine::getSong()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::toggleVisibility(bool on)
|
||||
{
|
||||
if(on)
|
||||
{
|
||||
show();
|
||||
parentWidget()->show();
|
||||
parentWidget()->raise();
|
||||
}
|
||||
else
|
||||
{
|
||||
parentWidget()->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::closeEvent(QCloseEvent* ce)
|
||||
{
|
||||
ce->ignore();
|
||||
|
||||
if(gui->mainWindow()->workspace())
|
||||
{
|
||||
parentWidget()->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
hide();
|
||||
}
|
||||
|
||||
m_stv->m_tlb->setFocus();
|
||||
m_stv->m_tlb->setChecked(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::saveSettings(QDomDocument& doc, QDomElement & element)
|
||||
{
|
||||
MainWindow::saveWidgetState(this, element);
|
||||
Q_UNUSED(element)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SampleTrackWindow::loadSettings(const QDomElement& element)
|
||||
{
|
||||
MainWindow::restoreWidgetState(this, element);
|
||||
if(isVisible())
|
||||
{
|
||||
m_stv->m_tlb->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user