summaryrefslogtreecommitdiff
path: root/muse2/muse/arranger/tlist.cpp
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2012-02-14 17:26:03 +0000
committerFlorian Jung <flo@windfisch.org>2012-02-14 17:26:03 +0000
commit3ffd0dacdd7447c6c377f95c1fa7fc45a2612d98 (patch)
treec8fa5ba7569d3001f3304f16f2f4a5c2546db8df /muse2/muse/arranger/tlist.cpp
parentbca65ae96031f8d6828cb0038ee768ae11c7cff8 (diff)
- added support for custom controller columns in the tracklist
they are stored in and read from the global config file. - tracklist header is now saved into global config, not in songfile. TODO: - allow the user to customize the custom columns - make recreating the Header work (graphical glitches currently)
Diffstat (limited to 'muse2/muse/arranger/tlist.cpp')
-rw-r--r--muse2/muse/arranger/tlist.cpp309
1 files changed, 266 insertions, 43 deletions
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index fe8b4731..2a1e1d72 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -46,6 +46,7 @@
#include "xml.h"
#include "mididev.h"
#include "midiport.h"
+#include "midictrl.h"
#include "midiseq.h"
#include "comment.h"
#include "track.h"
@@ -64,6 +65,8 @@
#include "popupmenu.h"
#include "filedialog.h"
#include "menutitleitem.h"
+#include "arranger.h"
+#include "undo.h"
#ifdef DSSI_SUPPORT
#include "dssihost.h"
@@ -92,6 +95,7 @@ TList::TList(Header* hdr, QWidget* parent, const char* name)
setObjectName(name);
ypos = 0;
editMode = false;
+ editJustFinished=false;
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);
header = hdr;
@@ -100,6 +104,7 @@ TList::TList(Header* hdr, QWidget* parent, const char* name)
editTrack = 0;
editor = 0;
chan_edit = NULL;
+ ctrl_edit = NULL;
mode = NORMAL;
//setBackgroundMode(Qt::NoBackground); // ORCAN - FIXME
@@ -117,7 +122,9 @@ TList::TList(Header* hdr, QWidget* parent, const char* name)
void TList::songChanged(int flags)
{
if (flags & (SC_MUTE | SC_SOLO | SC_RECFLAG | SC_TRACK_INSERTED
- | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | SC_ROUTE | SC_CHANNELS | SC_MIDI_TRACK_PROP))
+ | SC_TRACK_REMOVED | SC_TRACK_MODIFIED | SC_ROUTE | SC_CHANNELS | SC_MIDI_TRACK_PROP
+ | SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED
+ | SC_EVENT_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED ))
redraw();
if (flags & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED))
adjustScrollbar();
@@ -416,6 +423,22 @@ void TList::paint(const QRect& r)
}
break;
default:
+ if (section>=COL_CUSTOM_MIDICTRL_OFFSET)
+ {
+ if (track->isMidiTrack())
+ {
+ int col_ctrl_no=Arranger::custom_columns[section-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
+ MusECore::MidiTrack* mt=dynamic_cast<MusECore::MidiTrack*>(track);
+ MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+ MusECore::MidiController* mctl = mp->midiController(col_ctrl_no);
+ int val=mt->getFirstControllerValue(col_ctrl_no,MusECore::CTRL_VAL_UNKNOWN);
+ if (val!=MusECore::CTRL_VAL_UNKNOWN)
+ val-=mctl->bias();
+
+ p.drawText(r, Qt::AlignVCenter|Qt::AlignHCenter,
+ (val!=MusECore::CTRL_VAL_UNKNOWN)?QString::number(val):tr("off"));
+ }
+ }
break;
}
x += header->sectionSize(section);
@@ -495,6 +518,7 @@ void TList::returnPressed()
}
editMode = false;
+ editJustFinished = true;
if(editor->isVisible())
{
editor->blockSignals(true);
@@ -519,7 +543,6 @@ void TList::chanValueFinished()
{
MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(editTrack);
if (mt && mt->type() != MusECore::Track::DRUM)
- //if (mt && !mt->isDrumTrack()) // For Flo later with new drum tracks.
{
int channel = chan_edit->value() - 1;
if(channel >= MIDI_CHANNELS)
@@ -579,6 +602,7 @@ void TList::chanValueFinished()
}
editMode = false;
+ editJustFinished=true;
if(chan_edit->isVisible())
{
chan_edit->blockSignals(true);
@@ -588,6 +612,67 @@ void TList::chanValueFinished()
setFocus();
}
+void TList::ctrlValueFinished()
+{
+ if(editTrack && editTrack->isMidiTrack())
+ {
+ MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(editTrack);
+ if (mt && mt->type() != MusECore::Track::DRUM)
+ {
+ int val = ctrl_edit->value();
+ MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+ MusECore::MidiController* mctl = mp->midiController(ctrl_num);
+
+ if (val==ctrl_edit->minimum())
+ val=MusECore::CTRL_VAL_UNKNOWN;
+ else
+ val+=mctl->bias();
+
+ if (val!=MusECore::CTRL_VAL_UNKNOWN)
+ {
+ MusECore::Event a(MusECore::Controller);
+ a.setTick(0);
+ a.setA(ctrl_num);
+ a.setB(val);
+ MusEGlobal::song->recordEvent(mt, a);
+ }
+ else
+ {
+ MusECore::Undo operations;
+ for (MusECore::iPart p = mt->parts()->begin(); p!=mt->parts()->end(); p++)
+ {
+ if (p->second->tick()==0)
+ {
+ for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++)
+ {
+ if (ev->second.tick()!=0) break;
+ else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num)
+ {
+ using MusECore::UndoOp;
+ operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, p->second, false, false));
+ break;
+ }
+ }
+ }
+ }
+ MusEGlobal::song->applyOperationGroup(operations);
+ }
+ }
+
+ editTrack = 0;
+ }
+
+ editMode = false;
+ editJustFinished=true;
+ if(ctrl_edit->isVisible())
+ {
+ ctrl_edit->blockSignals(true);
+ ctrl_edit->hide();
+ ctrl_edit->blockSignals(false);
+ }
+ setFocus();
+}
+
//---------------------------------------------------------
// adjustScrollbar
//---------------------------------------------------------
@@ -704,6 +789,34 @@ void TList::mouseDoubleClickEvent(QMouseEvent* ev)
ev->accept();
}
}
+ else if (section >= COL_CUSTOM_MIDICTRL_OFFSET)
+ {
+ if (t->isMidiTrack())
+ {
+ editTrack=t;
+ if (ctrl_edit==0) {
+ ctrl_edit=new QSpinBox(this);
+ ctrl_edit->setSpecialValueText(tr("off"));
+ connect(ctrl_edit, SIGNAL(editingFinished()), SLOT(ctrlValueFinished()));
+ }
+
+ ctrl_num=Arranger::custom_columns[section-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
+
+ MusECore::MidiTrack* mt=(MusECore::MidiTrack*)t;
+ MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+ MusECore::MidiController* mctl = mp->midiController(ctrl_num);
+ ctrl_edit->setMinimum(mctl->minVal()-1); // -1 because of the specialValueText
+ ctrl_edit->setMaximum(mctl->maxVal());
+ ctrl_edit->setValue(((MusECore::MidiTrack*)editTrack)->getFirstControllerValue(ctrl_num)-mctl->bias());
+ int w=colw;
+ if (w < ctrl_edit->sizeHint().width()) w=ctrl_edit->sizeHint().width();
+ ctrl_edit->setGeometry(colx, coly, w, colh);
+ editMode = true;
+ ctrl_edit->show();
+ ctrl_edit->setFocus();
+ ev->accept();
+ }
+ }
else
mousePressEvent(ev);
}
@@ -1110,14 +1223,26 @@ void TList::keyPressEvent(QKeyEvent* e)
chan_edit->hide();
chan_edit->blockSignals(false);
}
+ if(ctrl_edit && ctrl_edit->isVisible())
+ {
+ ctrl_edit->blockSignals(true);
+ ctrl_edit->hide();
+ ctrl_edit->blockSignals(false);
+ }
editTrack = 0;
editMode = false;
setFocus();
return;
}
}
- emit keyPressExt(e); //redirect keypress events to main app
-
+ else if (!editJustFinished)
+ {
+ emit keyPressExt(e); //redirect keypress events to main app. don't call this when confirming an editor
+ }
+ else
+ editJustFinished=false;
+
+
// p4.0.10 Removed by Tim. keyPressExt are sent to part canvas, where they are
// ignored *only* if necessary.
//e->ignore();
@@ -1748,7 +1873,74 @@ void TList::mousePressEvent(QMouseEvent* ev)
break;
default:
- mode = START_DRAG;
+ if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
+ {
+ mode = START_DRAG;
+
+ int delta = 0;
+ if (button == Qt::RightButton)
+ delta = 1;
+ else if (button == Qt::MidButton)
+ delta = -1;
+
+ if (delta!=0 && t->isMidiTrack())
+ {
+ MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(t);
+ if (mt == 0)
+ break;
+
+ int ctrl_num = Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
+
+ MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+ MusECore::MidiController* mctl = mp->midiController(ctrl_num);
+
+ int minval=mctl->minVal()+mctl->bias();
+ int maxval=mctl->maxVal()+mctl->bias();
+
+ int val = mt->getFirstControllerValue(ctrl_num);
+ int oldval=val;
+ val += delta;
+ if(val > maxval)
+ val = maxval;
+ if(val < minval-1) // "-1" because of "off"
+ val = minval-1;
+
+ if (val != oldval)
+ {
+ if (val!=minval-1)
+ {
+ MusECore::Event a(MusECore::Controller);
+ a.setTick(0);
+ a.setA(ctrl_num);
+ a.setB(val);
+ MusEGlobal::song->recordEvent(mt, a);
+ }
+ else
+ {
+ MusECore::Undo operations;
+ for (MusECore::iPart p = mt->parts()->begin(); p!=mt->parts()->end(); p++)
+ {
+ if (p->second->tick()==0)
+ {
+ for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++)
+ {
+ if (ev->second.tick()!=0) break;
+ else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num)
+ {
+ using MusECore::UndoOp;
+ operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, p->second, false, false));
+ break;
+ }
+ }
+ }
+ }
+ MusEGlobal::song->applyOperationGroup(operations);
+ }
+ }
+ }
+ }
+ else
+ mode = START_DRAG;
}
redraw();
}
@@ -2006,7 +2198,7 @@ void TList::mouseReleaseEvent(QMouseEvent* ev)
}
if (editTrack && editor && editor->isVisible())
editor->setFocus();
- //else
+ //else // DELETETHIS or add the same for ctrl_edit!
//if (editTrack && chan_edit && chan_edit->isVisible()) // p4.0.46
// chan_edit->setFocus();
adjustScrollbar();
@@ -2122,49 +2314,74 @@ void TList::wheelEvent(QWheelEvent* ev)
}
break;
default:
- break;
- }
- }
-
-//---------------------------------------------------------
-// writeStatus
-//---------------------------------------------------------
-
-void TList::writeStatus(int level, MusECore::Xml& xml, const char* name) const
- {
- xml.tag(level++, name);
- header->writeStatus(level, xml);
- xml.etag(level, name);
- }
-
-//---------------------------------------------------------
-// readStatus
-//---------------------------------------------------------
+ if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
+ {
+ mode = START_DRAG;
-void TList::readStatus(MusECore::Xml& xml, const char* name)
- {
- for (;;) {
- MusECore::Xml::Token token(xml.parse());
- const QString& tag(xml.s1());
- switch (token) {
- case MusECore::Xml::Error:
- case MusECore::Xml::End:
- return;
- case MusECore::Xml::TagStart:
- if (tag == header->objectName())
- header->readStatus(xml);
- else
- xml.unknown("Tlist");
- break;
- case MusECore::Xml::TagEnd:
- if (tag == name)
- return;
- default:
+ if (t->isMidiTrack())
+ {
+ MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(t);
+ if (mt == 0)
break;
+
+ int ctrl_num = Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].ctrl;
+
+ MusECore::MidiPort* mp = &MusEGlobal::midiPorts[mt->outPort()];
+ MusECore::MidiController* mctl = mp->midiController(ctrl_num);
+
+ int minval=mctl->minVal()+mctl->bias();
+ int maxval=mctl->maxVal()+mctl->bias();
+
+ int val = mt->getFirstControllerValue(ctrl_num);
+ int oldval=val;
+ val += delta;
+ if(val > maxval)
+ val = maxval;
+ if(val < minval-1) // "-1" because of "off"
+ val = minval-1;
+
+ if (val != oldval)
+ {
+ if (val!=minval-1)
+ {
+ MusECore::Event a(MusECore::Controller);
+ a.setTick(0);
+ a.setA(ctrl_num);
+ a.setB(val);
+ MusEGlobal::song->recordEvent(mt, a);
+ }
+ else
+ {
+ MusECore::Undo operations;
+ for (MusECore::iPart p = mt->parts()->begin(); p!=mt->parts()->end(); p++)
+ {
+ if (p->second->tick()==0)
+ {
+ for (MusECore::iEvent ev=p->second->events()->begin(); ev!=p->second->events()->end(); ev++)
+ {
+ if (ev->second.tick()!=0) break;
+ else if (ev->second.type()==MusECore::Controller && ev->second.dataA()==ctrl_num)
+ {
+ using MusECore::UndoOp;
+ operations.push_back(UndoOp(UndoOp::DeleteEvent, ev->second, p->second, false, false));
+ break;
+ }
+ }
+ }
+ }
+ MusEGlobal::song->applyOperationGroup(operations);
+ }
+ }
+ }
}
+ else
+ mode = START_DRAG;
+
+ break;
}
}
+
//---------------------------------------------------------
// setYPos
//---------------------------------------------------------
@@ -2308,4 +2525,10 @@ void TList::classesPopupMenu(MusECore::Track* t, int x, int y)
}
}
+void TList::setHeader(Header* h)
+{
+ header=h;
+ redraw();
+}
+
} // namespace MusEGui