summaryrefslogtreecommitdiff
path: root/muse/muse/tlwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse/muse/tlwidget.cpp')
-rw-r--r--muse/muse/tlwidget.cpp641
1 files changed, 641 insertions, 0 deletions
diff --git a/muse/muse/tlwidget.cpp b/muse/muse/tlwidget.cpp
new file mode 100644
index 00000000..fdf08d0b
--- /dev/null
+++ b/muse/muse/tlwidget.cpp
@@ -0,0 +1,641 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// 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; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "song.h"
+#include "track.h"
+#include "tlwidget.h"
+#include "tlwlayout.h"
+#include "tllineedit.h"
+#include "icons.h"
+#include "arranger.h"
+#include "widgets/simplebutton.h"
+#include "muse.h"
+#include "trelement.h"
+#include "gconfig.h"
+#include "widgets/utils.h"
+#include "trackdrag.h"
+#include "synth.h"
+#include "widgets/outportcombo.h"
+#include "audio.h"
+#include "midioutport.h"
+#include "instruments/minstrument.h"
+
+//---------------------------------------------------------
+// TLWidget
+//---------------------------------------------------------
+
+TLWidget::TLWidget(Track* t, TrGroupList* tgl)
+ {
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAutoFillBackground(true);
+
+ setMouseTracking(true);
+
+ state = S_NORMAL;
+ off = 0;
+ tel = tgl;
+ _track = t;
+ outPort = 0;
+
+ bgColor = _track->ccolor();
+ selectBgColor = bgColor.light();
+
+ QPalette p(palette());
+ p.setColor(QPalette::Window, bgColor);
+ p.setColor(QPalette::Base, bgColor);
+ setPalette(p);
+
+ l = new TLWidgetLayout(this);
+ configChanged();
+
+ connect(_track, SIGNAL(selectionChanged(bool)), SLOT(selectionChanged()));
+ setAcceptDrops(true);
+ connect(muse, SIGNAL(configChanged()), SLOT(configChanged()));
+ }
+
+//---------------------------------------------------------
+// selectionChanged
+//---------------------------------------------------------
+
+void TLWidget::selectionChanged()
+ {
+ update();
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void TLWidget::nameChanged(QString s)
+ {
+ song->changeTrackName(_track, s);
+ nameEdit->setCursorPosition(0);
+ }
+
+//---------------------------------------------------------
+// selectTL
+//---------------------------------------------------------
+
+void TLWidget::select()
+ {
+ setFocus();
+ song->selectTrack(_track);
+ }
+
+//---------------------------------------------------------
+// labelPlusClicked
+//---------------------------------------------------------
+
+void TLWidget::labelPlusClicked()
+ {
+ emit plusClicked(this);
+ }
+
+//---------------------------------------------------------
+// mousePressEvent
+//---------------------------------------------------------
+
+void TLWidget::mousePressEvent(QMouseEvent* ev)
+ {
+ enum {
+ CMD_REMOVE_TRACK, CMD_COPY_TRACK, CMD_SHOW_AUDIO_GUI,
+ CMD_SHOW_MIDI_GUI
+ };
+ int button = ev->button();
+ if (button == Qt::RightButton) {
+ QMenu* menu = new QMenu(this);
+ QAction* a = getAction("delete", this);
+ menu->addAction(a);
+ a->setData(CMD_REMOVE_TRACK);
+ if (_track->type() == Track::MIDI || _track->type() == Track::WAVE) {
+ a = menu->addAction(tr("Copy Track"));
+ a->setData(CMD_COPY_TRACK);
+ }
+ if (_track->type() == Track::AUDIO_SOFTSYNTH) {
+ SynthI* s = (SynthI*) _track;
+ if (s->hasGui()) {
+ menu->addSeparator();
+ a = menu->addAction(tr("Show Gui"));
+ a->setData(CMD_SHOW_AUDIO_GUI);
+ a->setCheckable(true);
+ a->setChecked(s->guiVisible());
+ }
+ }
+ else if (_track->type() == Track::MIDI_SYNTI) {
+ MidiSynti* s = (MidiSynti*) _track;
+ if (s->hasGui()) {
+ menu->addSeparator();
+ a = menu->addAction(tr("Show Gui"));
+ a->setData(CMD_SHOW_MIDI_GUI);
+ a->setCheckable(true);
+ a->setChecked(s->guiVisible());
+ }
+ }
+
+ a = menu->exec(ev->globalPos());
+ if (!a)
+ return;
+ int rv = a->data().toInt();
+ switch (rv) {
+ default:
+ break;
+ case CMD_REMOVE_TRACK:
+ song->removeTrack(_track);
+ break;
+ case CMD_COPY_TRACK:
+ {
+ int idx = song->tracks()->indexOf(_track);
+ if (_track->type() == Track::MIDI) {
+ MidiTrack* t = new MidiTrack();
+ t->clone((MidiTrack*)_track);
+ song->cmdInsertTrack(t, idx);
+ }
+ else {
+ WaveTrack* t = new WaveTrack();
+ t->clone((WaveTrack*)_track);
+ song->cmdInsertTrack(t, idx);
+ }
+ }
+ break;
+ case CMD_SHOW_AUDIO_GUI:
+ {
+ SynthI* s = (SynthI*) _track;
+ s->showGui(!s->guiVisible());
+ }
+ break;
+ case CMD_SHOW_MIDI_GUI:
+ {
+ MidiSynti* s = (MidiSynti*) _track;
+ s->showGui(!s->guiVisible());
+ }
+ break;
+ }
+ return;
+ }
+ int y = ev->pos().y();
+ int wh = height();
+ starty = ev->globalPos().y();
+ if (y > (wh - splitWidth)) {
+ state = S_DRAGBOTTOM;
+ emit startDrag(trackIdx);
+ }
+ else {
+ state = S_DRAG;
+ startDragPos = ev->pos();
+ startDragTime = QTime::currentTime();
+ select();
+ }
+ }
+
+//---------------------------------------------------------
+// mouseReleaseEvent
+//---------------------------------------------------------
+
+void TLWidget::mouseReleaseEvent(QMouseEvent*)
+ {
+ state = S_NORMAL;
+ }
+
+//---------------------------------------------------------
+// mouseMoveEvent
+//---------------------------------------------------------
+
+void TLWidget::mouseMoveEvent(QMouseEvent* ev)
+ {
+ QPoint pos(ev->pos());
+
+ if (state == S_DRAGBOTTOM)
+ emit drag(trackIdx, ev->globalPos().y() - starty);
+ else if (state == S_DRAG) {
+ int t = startDragTime.msecsTo(QTime::currentTime());
+ bool dragActive = (startDragPos - pos).manhattanLength() >
+ QApplication::startDragDistance()
+ || t > QApplication::startDragTime();
+ if (dragActive) {
+ QDrag* d = new TrackDrag(_track, this);
+ d->start(Qt::MoveAction);
+ state = S_NORMAL;
+ }
+ }
+ else {
+ int y = pos.y();
+ int wh = height();
+ if (y > (wh - splitWidth))
+ setCursor(Qt::SizeVerCursor);
+ else
+ setCursor(Qt::ArrowCursor);
+ }
+ }
+
+//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void TLWidget::configChanged()
+ {
+ l->clear();
+ wlist.clear();
+ nameEdit = 0;
+ record = 0;
+ off = 0;
+ outChannel = 0;
+ outPort = 0;
+
+ label = new QLabel;
+ label->setObjectName("trackLabel");
+ l->addWidget(label);
+ label->setIndent(3);
+
+ label->setText(_track->cname());
+ label->setFixedHeight(11);
+
+ plus = newPlusButton();
+ l->addWidget(plus);
+ plus->setToolTip(tr("Add Subtrack"));
+ connect(plus, SIGNAL(clicked()), SLOT(labelPlusClicked()));
+
+ for (iTrGroup i = tel->begin(); i != tel->end(); ++i) {
+ TrElementList& el = *i;
+ iTrElement k;
+ for (k = el.begin(); k != el.end(); ++k) {
+ int id = (*k)->id;
+ switch(id) {
+ case TR_NAME:
+ nameEdit = new TLLineEdit(_track->name(), this);
+ nameEdit->setFixedHeight(trackRowHeight);
+ connect(nameEdit, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString)));
+ connect(nameEdit, SIGNAL(mousePress()), SLOT(select()));
+ connect(_track, SIGNAL(nameChanged(const QString&)), nameEdit, SLOT(setText(const QString&)));
+ nameEdit->setToolTip(_track->clname() + " Name");
+ l->addWidget(nameEdit);
+ wlist.push_back(nameEdit);
+ break;
+
+ case TR_INSTRUMENT:
+ {
+ instrument = new QComboBox(this);
+ instrument->setFixedHeight(trackRowHeight);
+ MidiOutPort* op = (MidiOutPort*)_track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ int curIdx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ instrument->addItem((*i)->iname());
+ if ((*i)->iname() == mi->iname())
+ curIdx = idx;
+ }
+ instrument->setCurrentIndex(curIdx);
+ connect(instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int)));
+ connect(op, SIGNAL(instrumentChanged()), SLOT(instrumentChanged()));
+ l->addWidget(instrument);
+ wlist.push_back(instrument);
+ }
+ break;
+
+ case TR_PATCH:
+ {
+ // Ctrl* ctrl = _track->getController(CTRL_PROGRAM);
+ }
+ break;
+
+ case TR_OFF:
+ {
+ off = newOffButton();
+ off->setFixedSize(trackRowHeight, trackRowHeight);
+ off->setChecked(_track->off());
+ connect(off, SIGNAL(clicked(bool)), SLOT(offToggled(bool)));
+ connect(_track, SIGNAL(offChanged(bool)), this, SLOT(updateOffState()));
+ l->addWidget(off);
+ wlist.push_back(off);
+ }
+ break;
+
+ case TR_DRUMMAP:
+ {
+ SimpleButton* dm = newDrumMapButton();
+ dm->setFixedSize(trackRowHeight, trackRowHeight);
+ dm->setChecked(((MidiTrack*)_track)->useDrumMap());
+ connect(dm, SIGNAL(clicked(bool)), SLOT(drumMapToggled(bool)));
+ connect(_track, SIGNAL(useDrumMapChanged(bool)), dm, SLOT(setChecked(bool)));
+ l->addWidget(dm);
+ wlist.push_back(dm);
+ }
+ break;
+
+ case TR_MUTE:
+ {
+ SimpleButton* mute = newMuteButton();
+ mute->setFixedSize(trackRowHeight, trackRowHeight);
+ mute->setChecked(_track->isMute());
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+ connect(_track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ l->addWidget(mute);
+ wlist.push_back(mute);
+ }
+ break;
+
+ case TR_SOLO:
+ {
+ SimpleButton* solo = newSoloButton();
+ solo->setFixedSize(trackRowHeight, trackRowHeight);
+ solo->setChecked(_track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+ connect(_track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ l->addWidget(solo);
+ wlist.push_back(solo);
+ }
+ break;
+
+ case TR_MONITOR:
+ {
+ SimpleButton* monitor = newMonitorButton();
+ monitor->setFixedSize(trackRowHeight+4, trackRowHeight);
+ monitor->setChecked(_track->monitor());
+ connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool)));
+ connect(_track, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool)));
+ l->addWidget(monitor);
+ wlist.push_back(monitor);
+ }
+ break;
+
+ case TR_RECORD:
+ {
+ record = newRecordButton();
+ record->setFixedSize(trackRowHeight, trackRowHeight);
+ record->setChecked(_track->recordFlag());
+ connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool)));
+ connect(_track, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool)));
+ l->addWidget(record);
+ wlist.push_back(record);
+ }
+ break;
+
+ case TR_AREAD:
+ {
+ SimpleButton* b = newAutoReadButton();
+ b->setFixedSize(trackRowHeight, trackRowHeight);
+ b->setChecked(_track->autoRead());
+ connect(b, SIGNAL(clicked(bool)), SLOT(autoReadToggled(bool)));
+ connect(_track, SIGNAL(autoReadChanged(bool)), b, SLOT(setChecked(bool)));
+ l->addWidget(b);
+ wlist.push_back(b);
+ }
+ break;
+
+ case TR_AWRITE:
+ {
+ SimpleButton* b = newAutoWriteButton();
+ b->setFixedSize(trackRowHeight, trackRowHeight);
+ b->setChecked(_track->autoWrite());
+ connect(b, SIGNAL(clicked(bool)), SLOT(autoWriteToggled(bool)));
+ connect(_track, SIGNAL(autoWriteChanged(bool)), b, SLOT(setChecked(bool)));
+ l->addWidget(b);
+ wlist.push_back(b);
+ }
+ break;
+
+ case TR_OCHANNEL:
+ {
+ outChannel = new QSpinBox(this);
+ outChannel->setFixedSize(45, trackRowHeight);
+ outChannel->setRange(1, 16);
+ outChannel->setValue(((MidiTrack*)_track)->channelNo() + 1);
+ outChannel->setToolTip(tr("Midi Output Channel"));
+ l->addWidget(outChannel);
+ wlist.push_back(outChannel);
+ connect(outChannel, SIGNAL(valueChanged(int)), SLOT(setChannel(int)));
+ connect((MidiTrack*)_track, SIGNAL(channelChanged(int)), SLOT(channelChanged(int)));
+ }
+ break;
+
+ default:
+ printf("TLWidget:: unknown element %d\n", id);
+ break;
+ }
+ }
+ }
+ updateOffState();
+ selectionChanged(); // update selection state
+ l->update();
+ }
+
+//---------------------------------------------------------
+// recordToggled
+//---------------------------------------------------------
+
+void TLWidget::recordToggled(bool val)
+ {
+ song->setRecordFlag(_track, !val);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void TLWidget::muteToggled(bool val)
+ {
+ song->setMute(_track, val);
+ }
+
+//---------------------------------------------------------
+// monitorToggled
+//---------------------------------------------------------
+
+void TLWidget::monitorToggled(bool val)
+ {
+ _track->setMonitor(val);
+ }
+
+//---------------------------------------------------------
+// drumMapToggled
+//---------------------------------------------------------
+
+void TLWidget::drumMapToggled(bool val)
+ {
+ ((MidiTrack*)_track)->setUseDrumMap(val);
+ }
+
+//---------------------------------------------------------
+// offToggled
+//---------------------------------------------------------
+
+void TLWidget::offToggled(bool val)
+ {
+ song->setOff(_track, !val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void TLWidget::soloToggled(bool val)
+ {
+ song->setSolo(_track, val);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void TLWidget::autoReadToggled(bool val)
+ {
+ song->setAutoRead(_track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void TLWidget::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(_track, val);
+ }
+
+//---------------------------------------------------------
+// setOutPort
+//---------------------------------------------------------
+
+void TLWidget::setOutPort(int n)
+ {
+ outPort->setCurrentIndex(n);
+ }
+
+//---------------------------------------------------------
+// dragEnterEvent
+//---------------------------------------------------------
+
+void TLWidget::dragEnterEvent(QDragEnterEvent* event)
+ {
+ if (TrackDrag::canDecode(event))
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// dropEvent
+//---------------------------------------------------------
+
+void TLWidget::dropEvent(QDropEvent* event)
+ {
+ Track* t;
+ TrackDrag::decode(event, t);
+ if (_track != t)
+ emit moveTrack(t, _track);
+ event->acceptProposedAction();
+ }
+
+//---------------------------------------------------------
+// updateOffState
+//---------------------------------------------------------
+
+void TLWidget::updateOffState()
+ {
+ bool val = !_track->off();
+ std::vector<QWidget*>::iterator i = wlist.begin();
+ for (; i != wlist.end(); ++i) {
+ if ((*i) != off)
+ (*i)->setEnabled(val);
+ }
+ if (off)
+ off->setChecked(!val);
+ }
+
+//---------------------------------------------------------
+// instrumentSelected
+//---------------------------------------------------------
+
+void TLWidget::instrumentSelected(int n)
+ {
+ MidiOutPort* op = (MidiOutPort*)_track;
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (idx == n) {
+ op->setInstrument(*i);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void TLWidget::instrumentChanged()
+ {
+ MidiOutPort* op = (MidiOutPort*)_track;
+ MidiInstrument* mi = op->instrument();
+ int idx = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) {
+ if (*i == mi) {
+ instrument->setCurrentIndex(idx);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// paintEvent
+//---------------------------------------------------------
+
+void TLWidget::paintEvent(QPaintEvent* ev)
+ {
+ QPainter p(this);
+ QRect r(ev->rect());
+ QColor color(_track->selected() ? selectBgColor : bgColor);
+ p.fillRect(r, color);
+
+ paintHLine(p, r.x(), r.x() + r.width(), height() - splitWidth);
+ QPalette pl = nameEdit->palette();
+ pl.setColor(QPalette::Window, color);
+ pl.setColor(QPalette::Base, color);
+ nameEdit->setPalette(pl);
+
+ // The selected track will get a 4 pixel red bar to the left
+ if ( _track->selected()) {
+ QColor color(200,10,10);
+ QRect qr(0, 0, 4, r.height()-splitWidth);
+ p.fillRect(qr, color);
+ }
+ }
+
+//---------------------------------------------------------
+// channelChanged
+// SLOT: callend when channel routing of track has
+// changed
+// - channel starts counting at 0
+//---------------------------------------------------------
+
+void TLWidget::channelChanged(int channel)
+ {
+ if (outChannel->value() == channel + 1)
+ return;
+ outChannel->setValue(channel + 1);
+ }
+
+//---------------------------------------------------------
+// setChannel
+// - called when channel spinbox value changed
+// - channel starts counting at 1
+//---------------------------------------------------------
+
+void TLWidget::setChannel(int channel)
+ {
+ ((MidiTrack*)_track)->setChannel(channel - 1);
+ }
+