diff options
Diffstat (limited to 'muse/muse/tlwidget.cpp')
-rw-r--r-- | muse/muse/tlwidget.cpp | 641 |
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); + } + |