summaryrefslogtreecommitdiff
path: root/muse2/muse
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2012-10-27 09:58:29 +0000
committerTim E. Real <termtech@rogers.com>2012-10-27 09:58:29 +0000
commitb1776f093d4b87ad2635990f429f4503157f6288 (patch)
treea18bcc5e23674d74037c87e0541f9feefdc7b9ca /muse2/muse
parentb297348e8e2cd76be6f1d546fb458865cc4d263b (diff)
Improved: Velocity graphs. Icon for showing per-note or all velocities. Also found in Settings.
Improved: Piano KB has current selected note (yellow). For velocity/polyaftertouch/other per-note ctrls. Bad timing warning now has "don't show again". Added 'speaker' icon to drum edit. And drum list and piano keyboard now obey the 'speaker' icon.
Diffstat (limited to 'muse2/muse')
-rw-r--r--muse2/muse/arranger/tlist.cpp355
-rw-r--r--muse2/muse/conf.cpp6
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp42
-rw-r--r--muse2/muse/ctrl/ctrlpanel.cpp79
-rw-r--r--muse2/muse/ctrl/ctrlpanel.h9
-rw-r--r--muse2/muse/driver/alsamidi.cpp5
-rw-r--r--muse2/muse/driver/jackmidi.cpp8
-rw-r--r--muse2/muse/gconfig.cpp4
-rw-r--r--muse2/muse/gconfig.h2
-rw-r--r--muse2/muse/helper.cpp14
-rw-r--r--muse2/muse/icons.cpp8
-rw-r--r--muse2/muse/icons.h2
-rw-r--r--muse2/muse/midictrl.cpp31
-rw-r--r--muse2/muse/midictrl.h12
-rw-r--r--muse2/muse/mididev.cpp3
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp15
-rw-r--r--muse2/muse/midiedit/dlist.cpp9
-rw-r--r--muse2/muse/midiedit/dlist.h2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp37
-rw-r--r--muse2/muse/midiedit/drumedit.h3
-rw-r--r--muse2/muse/midiedit/piano.cpp265
-rw-r--r--muse2/muse/midiedit/piano.h17
-rw-r--r--muse2/muse/midiedit/pianoroll.cpp59
-rw-r--r--muse2/muse/midiedit/pianoroll.h2
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp14
-rw-r--r--muse2/muse/midiport.cpp2
-rw-r--r--muse2/muse/midiseq.cpp23
-rw-r--r--muse2/muse/widgets/CMakeLists.txt3
-rw-r--r--muse2/muse/widgets/genset.cpp4
-rw-r--r--muse2/muse/widgets/gensetbase.ui91
-rw-r--r--muse2/muse/widgets/midi_warn_init_pending_impl.h2
-rw-r--r--muse2/muse/widgets/musewidgetsplug.cpp4
-rw-r--r--muse2/muse/widgets/warn_bad_timing.cpp33
-rw-r--r--muse2/muse/widgets/warn_bad_timing.h41
-rw-r--r--muse2/muse/widgets/warn_bad_timing.ui111
35 files changed, 912 insertions, 405 deletions
diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp
index b3be35ea..3bc13934 100644
--- a/muse2/muse/arranger/tlist.cpp
+++ b/muse2/muse/arranger/tlist.cpp
@@ -2497,181 +2497,186 @@ void TList::mouseReleaseEvent(QMouseEvent* ev)
void TList::wheelEvent(QWheelEvent* ev)
{
- int x = ev->x();
- int y = ev->y();
- MusECore::Track* t = y2Track(y + ypos);
- if (t == 0) {
- emit redirectWheelEvent(ev);
- return;
- }
- TrackColumn col = TrackColumn(header->logicalIndexAt(x));
- int delta = ev->delta() / WHEEL_DELTA;
- ev->accept();
-
- switch (col) {
- case COL_RECORD:
- case COL_NONE:
- case COL_CLASS:
- case COL_NAME:
- case COL_AUTOMATION:
- break;
- case COL_MUTE:
- // p3.3.29
- if (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)
- t->setOff(!t->off());
- else
- {
- if (t->off())
- t->setOff(false);
- else
- t->setMute(!t->mute());
- }
- MusEGlobal::song->update(SC_MUTE);
- break;
-
- case COL_SOLO:
- MusEGlobal::audio->msgSetSolo(t, !t->solo());
- MusEGlobal::song->update(SC_SOLO);
- break;
-
- case COL_TIMELOCK:
- t->setLocked(!t->locked());
- break;
-
- case COL_OPORT:
- if (t->isMidiTrack()) {
- MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
- int port = mt->outPort() + delta;
-
- if (port >= MIDI_PORTS)
- port = MIDI_PORTS-1;
- else if (port < 0)
- port = 0;
- if (port != ((MusECore::MidiTrack*)t)->outPort()) {
- MusEGlobal::audio->msgIdle(true);
- mt->setOutPortAndUpdate(port);
- MusEGlobal::audio->msgIdle(false);
-
- MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
- MusEGlobal::song->update(SC_MIDI_TRACK_PROP); // p4.0.17
- }
- }
- break;
-
- case COL_OCHANNEL:
- if (t->isMidiTrack()) {
- MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
- if (mt && mt->type() == MusECore::Track::DRUM)
- break;
-
- int channel = mt->outChannel() + delta;
-
- if (channel >= MIDI_CHANNELS)
- channel = MIDI_CHANNELS-1;
- else if (channel < 0)
- channel = 0;
- if (channel != ((MusECore::MidiTrack*)t)->outChannel()) {
- MusEGlobal::audio->msgIdle(true);
- mt->setOutChanAndUpdate(channel);
- MusEGlobal::audio->msgIdle(false);
-
- // may result in adding/removing mixer strip:
- //MusEGlobal::song->update(-1);
- MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
- MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
- }
- }
- else {
- int n = t->channels() + delta;
- if (n > MAX_CHANNELS)
- n = MAX_CHANNELS;
- else if (n < 1)
- n = 1;
- if (n != t->channels()) {
- MusEGlobal::audio->msgSetChannels((MusECore::AudioTrack*)t, n);
- MusEGlobal::song->update(SC_CHANNELS);
- }
- }
- break;
- default:
- if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
- {
- mode = START_DRAG;
-
- 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->getControllerChangeAtTick(0,ctrl_num);
- int oldval=val;
-
- if (ctrl_num!=MusECore::CTRL_PROGRAM)
- {
- val += delta;
- if(val > maxval)
- val = maxval;
- if(val < minval-1) // "-1" because of "off"
- val = minval-1;
- }
- else
- {
- MusECore::MidiInstrument* instr = mp->instrument();
- if (delta>0) val=instr->getNextPatch(mt->outChannel(), val, false);
- else if (delta<0) val=instr->getPrevPatch(mt->outChannel(), val, false);
- }
-
- if (val != oldval)
- {
- if (val!=minval-1)
- {
- int at_tick;
- if (Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].affected_pos ==
- Arranger::custom_col_t::AFFECT_BEGIN)
- at_tick=0;
- else
- at_tick=MusEGlobal::song->cpos();
-
- record_controller_change_and_maybe_send(at_tick, ctrl_num, val, mt);
- }
- 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;
- }
+ emit redirectWheelEvent(ev);
+
+// REMOVE Tim. Hate to just kill all this, so remove later if all tests OK.
+// int x = ev->x();
+// int y = ev->y();
+// MusECore::Track* t = y2Track(y + ypos);
+// if (t == 0) {
+// emit redirectWheelEvent(ev);
+// return;
+// }
+//
+// TrackColumn col = TrackColumn(header->logicalIndexAt(x));
+// int delta = ev->delta() / WHEEL_DELTA;
+// ev->accept();
+//
+// switch (col) {
+// case COL_RECORD:
+// case COL_NONE:
+// case COL_CLASS:
+// case COL_NAME:
+// case COL_AUTOMATION:
+// break;
+// case COL_MUTE:
+// // p3.3.29
+// if (((QInputEvent*)ev)->modifiers() & Qt::ShiftModifier)
+// t->setOff(!t->off());
+// else
+// {
+// if (t->off())
+// t->setOff(false);
+// else
+// t->setMute(!t->mute());
+// }
+// MusEGlobal::song->update(SC_MUTE);
+// break;
+//
+// case COL_SOLO:
+// MusEGlobal::audio->msgSetSolo(t, !t->solo());
+// MusEGlobal::song->update(SC_SOLO);
+// break;
+//
+// case COL_TIMELOCK:
+// t->setLocked(!t->locked());
+// break;
+//
+// case COL_OPORT:
+// if (t->isMidiTrack()) {
+// MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
+// int port = mt->outPort() + delta;
+//
+// if (port >= MIDI_PORTS)
+// port = MIDI_PORTS-1;
+// else if (port < 0)
+// port = 0;
+// if (port != ((MusECore::MidiTrack*)t)->outPort()) {
+// MusEGlobal::audio->msgIdle(true);
+// mt->setOutPortAndUpdate(port);
+// MusEGlobal::audio->msgIdle(false);
+//
+// MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
+// MusEGlobal::song->update(SC_MIDI_TRACK_PROP); // p4.0.17
+// }
+// }
+// break;
+//
+// case COL_OCHANNEL:
+// if (t->isMidiTrack()) {
+// MusECore::MidiTrack* mt = (MusECore::MidiTrack*)t;
+// if (mt && mt->type() == MusECore::Track::DRUM)
+// break;
+//
+// int channel = mt->outChannel() + delta;
+//
+// if (channel >= MIDI_CHANNELS)
+// channel = MIDI_CHANNELS-1;
+// else if (channel < 0)
+// channel = 0;
+// if (channel != ((MusECore::MidiTrack*)t)->outChannel()) {
+// MusEGlobal::audio->msgIdle(true);
+// mt->setOutChanAndUpdate(channel);
+// MusEGlobal::audio->msgIdle(false);
+//
+// // may result in adding/removing mixer strip:
+// //MusEGlobal::song->update(-1);
+// MusEGlobal::audio->msgUpdateSoloStates(); // p4.0.14
+// MusEGlobal::song->update(SC_MIDI_TRACK_PROP);
+// }
+// }
+// else {
+// int n = t->channels() + delta;
+// if (n > MAX_CHANNELS)
+// n = MAX_CHANNELS;
+// else if (n < 1)
+// n = 1;
+// if (n != t->channels()) {
+// MusEGlobal::audio->msgSetChannels((MusECore::AudioTrack*)t, n);
+// MusEGlobal::song->update(SC_CHANNELS);
+// }
+// }
+// break;
+// default:
+// if (col>=COL_CUSTOM_MIDICTRL_OFFSET)
+// {
+// mode = START_DRAG;
+//
+// 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->getControllerChangeAtTick(0,ctrl_num);
+// int oldval=val;
+//
+// if (ctrl_num!=MusECore::CTRL_PROGRAM)
+// {
+// val += delta;
+// if(val > maxval)
+// val = maxval;
+// if(val < minval-1) // "-1" because of "off"
+// val = minval-1;
+// }
+// else
+// {
+// MusECore::MidiInstrument* instr = mp->instrument();
+// if (delta>0) val=instr->getNextPatch(mt->outChannel(), val, false);
+// else if (delta<0) val=instr->getPrevPatch(mt->outChannel(), val, false);
+// }
+//
+// if (val != oldval)
+// {
+// if (val!=minval-1)
+// {
+// int at_tick;
+// if (Arranger::custom_columns[col-COL_CUSTOM_MIDICTRL_OFFSET].affected_pos ==
+// Arranger::custom_col_t::AFFECT_BEGIN)
+// at_tick=0;
+// else
+// at_tick=MusEGlobal::song->cpos();
+//
+// record_controller_change_and_maybe_send(at_tick, ctrl_num, val, mt);
+// }
+// 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;
+// }
+
}
diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp
index 4c14cff0..54a02265 100644
--- a/muse2/muse/conf.cpp
+++ b/muse2/muse/conf.cpp
@@ -894,6 +894,8 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon
MusEGlobal::config.warnInitPending = xml.parseInt();
else if (tag == "midiSendCtlDefaults")
MusEGlobal::config.midiSendCtlDefaults = xml.parseInt();
+ else if (tag == "warnIfBadTiming")
+ MusEGlobal::config.warnIfBadTiming = xml.parseInt();
else if (tag == "minMeter")
MusEGlobal::config.minMeter = xml.parseInt();
else if (tag == "minSlider")
@@ -946,6 +948,8 @@ void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalCon
MusEGlobal::config.unhideTracks = xml.parseInt();
else if (tag == "smartFocus")
MusEGlobal::config.smartFocus = xml.parseInt();
+ else if (tag == "velocityPerNote")
+ MusEGlobal::config.velocityPerNote = xml.parseInt();
else if (tag == "plugin_groups")
MusEGlobal::readPluginGroupConfiguration(xml);
@@ -1215,6 +1219,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "midiSendInit", MusEGlobal::config.midiSendInit);
xml.intTag(level, "warnInitPending", MusEGlobal::config.warnInitPending);
xml.intTag(level, "midiSendCtlDefaults", MusEGlobal::config.midiSendCtlDefaults);
+ xml.intTag(level, "warnIfBadTiming", MusEGlobal::config.warnIfBadTiming);
xml.intTag(level, "minMeter", MusEGlobal::config.minMeter);
xml.doubleTag(level, "minSlider", MusEGlobal::config.minSlider);
xml.intTag(level, "freewheelMode", MusEGlobal::config.freewheelMode);
@@ -1266,6 +1271,7 @@ void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease);
xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB);
xml.intTag(level, "smartFocus", MusEGlobal::config.smartFocus);
+ xml.intTag(level, "velocityPerNote", MusEGlobal::config.velocityPerNote);
xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks);
xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks);
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp
index 1774174f..6e92f3c6 100644
--- a/muse2/muse/ctrl/ctrlcanvas.cpp
+++ b/muse2/muse/ctrl/ctrlcanvas.cpp
@@ -511,16 +511,14 @@ void CtrlCanvas::partControllers(const MusECore::MidiPart* part, int num, int* d
int di;
int n;
- if(!mt->isDrumTrack() && curDrumPitch != -1)
- printf("keyfilter != -1 in non drum track?\n");
-
if((mt->type() == MusECore::Track::DRUM) && (curDrumPitch >= 0) && ((num & 0xff) == 0xff))
{
di = (num & ~0xff) | curDrumPitch;
n = (num & ~0xff) | MusEGlobal::drumMap[curDrumPitch].anote; // construct real controller number
mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
}
- else if ((mt->type() == MusECore::Track::NEW_DRUM) && (curDrumPitch >= 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work?
+ else if ((mt->type() == MusECore::Track::NEW_DRUM || mt->type() == MusECore::Track::MIDI) &&
+ (curDrumPitch >= 0) && ((num & 0xff) == 0xff)) //FINDMICHJETZT does this work?
{
di = (num & ~0xff) | curDrumPitch;
n = (num & ~0xff) | curDrumPitch;
@@ -599,12 +597,8 @@ void CtrlCanvas::updateItems()
if(_cnum == MusECore::CTRL_VELOCITY && e.type() == MusECore::Note)
{
newev = 0;
- if (curDrumPitch == -1) // and NOT >=0
- {
- // This is interesting - it would allow ALL drum note velocities to be shown.
- // But currently the drum list ALWAYS has a selected item so this is not supposed to happen.
+ if (curDrumPitch == -1 || !MusEGlobal::config.velocityPerNote) // and NOT >=0
items.add(newev = new CEvent(e, part, e.velo()));
- }
else if (e.dataA() == curDrumPitch) //same note. if curDrumPitch==-2, this never is true
items.add(newev = new CEvent(e, part, e.velo()));
if(newev && e.selected())
@@ -615,32 +609,16 @@ void CtrlCanvas::updateItems()
int ctl = e.dataA();
if(part->track() && part->track()->type() == MusECore::Track::DRUM && (_cnum & 0xff) == 0xff)
{
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[part->track()->outPort()];
if(curDrumPitch < 0)
- //if(curDrumPitch >= 0)
continue;
- //{
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
- //MusECore::MidiPort* port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[ctl & 0x7f].port];
- int port = MusEGlobal::drumMap[ctl & 0x7f].port;
- int chan = MusEGlobal::drumMap[ctl & 0x7f].channel;
- //MusECore::MidiPort* cur_port = &MusEGlobal::midiPorts[MusEGlobal::drumMap[curDrumPitch].port];
- int cur_port = MusEGlobal::drumMap[curDrumPitch].port;
- int cur_chan = MusEGlobal::drumMap[curDrumPitch].channel;
- if((port != cur_port) || (chan != cur_chan))
- continue;
- // Is it a drum controller event, according to the track port's instrument?
- //MusECore::MidiController *mc = port->drumController(ctl);
- //if(!mc)
- // continue;
- //if(mc)
- //{
- //if(MusEGlobal::drumMap[ctl & 0x7f].channel != e.
- // continue;
- ctl = (ctl & ~0xff) | MusEGlobal::drumMap[ctl & 0x7f].anote;
- //}
- //}
+ int port = MusEGlobal::drumMap[ctl & 0x7f].port;
+ int chan = MusEGlobal::drumMap[ctl & 0x7f].channel;
+ int cur_port = MusEGlobal::drumMap[curDrumPitch].port;
+ int cur_chan = MusEGlobal::drumMap[curDrumPitch].channel;
+ if((port != cur_port) || (chan != cur_chan))
+ continue;
+ ctl = (ctl & ~0xff) | MusEGlobal::drumMap[ctl & 0x7f].anote;
}
if(ctl == _dnum)
{
diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp
index c6adc778..8e380356 100644
--- a/muse2/muse/ctrl/ctrlpanel.cpp
+++ b/muse2/muse/ctrl/ctrlpanel.cpp
@@ -57,6 +57,7 @@
#include "menutitleitem.h"
#include "popupmenu.h"
#include "helper.h"
+#include "pixmap_button.h"
namespace MusEGui {
@@ -87,7 +88,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
kbox->setContentsMargins(0, 0, 0, 0);
dbox->setContentsMargins(0, 0, 0, 0);
- selCtrl = new QPushButton(tr("S"));
+ selCtrl = new QPushButton(tr("S"), this);
selCtrl->setFocusPolicy(Qt::NoFocus);
selCtrl->setFont(MusEGlobal::config.fonts[3]);
selCtrl->setFixedHeight(20);
@@ -96,7 +97,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
selCtrl->setToolTip(tr("select controller"));
// destroy button
- QPushButton* destroy = new QPushButton(tr("X"));
+ QPushButton* destroy = new QPushButton(tr("X"), this);
destroy->setFocusPolicy(Qt::NoFocus);
destroy->setFont(MusEGlobal::config.fonts[3]);
destroy->setFixedHeight(20);
@@ -112,7 +113,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
_val = MusECore::CTRL_VAL_UNKNOWN;
_dnum = -1;
- _knob = new MusEGui::Knob;
+ _knob = new Knob(this);
_knob->setFixedWidth(25);
_knob->setFixedHeight(25);
_knob->setToolTip(tr("manual adjust"));
@@ -122,7 +123,7 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
_knob->hide();
_knob->setAltFaceColor(Qt::red);
- _dl = new MusEGui::DoubleLabel(-1.0, 0.0, +127.0);
+ _dl = new DoubleLabel(-1.0, 0.0, +127.0, this);
_dl->setPrecision(0);
_dl->setToolTip(tr("ctrl-double-click on/off"));
_dl->setSpecialText(tr("off"));
@@ -139,16 +140,28 @@ CtrlPanel::CtrlPanel(QWidget* parent, MidiEditor* e, CtrlCanvas* c, const char*
connect(_dl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double)));
connect(_dl, SIGNAL(ctrlDoubleClicked(int)), SLOT(labelDoubleClicked()));
+ _veloPerNoteButton = new PixmapButton(veloPerNote_OnIcon, veloPerNote_OffIcon, 2, this); // Margin = 2
+ _veloPerNoteButton->setFocusPolicy(Qt::NoFocus);
+ _veloPerNoteButton->setCheckable(true);
+ _veloPerNoteButton->setToolTip(tr("all/per-note velocity mode"));
+ _veloPerNoteButton->setEnabled(false);
+ _veloPerNoteButton->hide();
+ connect(_veloPerNoteButton, SIGNAL(clicked()), SLOT(velPerNoteClicked()));
+
bbox->addStretch();
bbox->addWidget(selCtrl);
bbox->addWidget(destroy);
bbox->addStretch();
kbox->addStretch();
kbox->addWidget(_knob);
+ kbox->addWidget(_veloPerNoteButton);
kbox->addStretch();
dbox->addStretch();
dbox->addWidget(_dl);
dbox->addStretch();
+
+ connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(songChanged(MusECore::SongChangedFlags_t)));
+ connect(MusEGlobal::muse, SIGNAL(configChanged()), SLOT(configChanged()));
connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat()));
inHeartBeat = false;
setLayout(vbox);
@@ -227,6 +240,35 @@ void CtrlPanel::heartBeat()
}
//---------------------------------------------------------
+// configChanged
+//---------------------------------------------------------
+
+void CtrlPanel::configChanged()
+{
+ songChanged(SC_CONFIG);
+}
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void CtrlPanel::songChanged(MusECore::SongChangedFlags_t type)
+{
+ if(editor->deleting()) // Ignore while while deleting to prevent crash.
+ return;
+
+ // Is it simply a midi controller value adjustment? Forget it.
+ if(type == SC_MIDI_CONTROLLER)
+ return;
+
+ if(type & SC_CONFIG)
+ {
+ if(_veloPerNoteButton->isChecked() != MusEGlobal::config.velocityPerNote)
+ _veloPerNoteButton->setChecked(MusEGlobal::config.velocityPerNote);
+ }
+}
+
+//---------------------------------------------------------
// labelDoubleClicked
//---------------------------------------------------------
@@ -424,7 +466,7 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController
mp = &MusEGlobal::midiPorts[MusEGlobal::drumMap[cdp].port];
ch = MusEGlobal::drumMap[cdp].channel;
}
- else if(_track->type() == MusECore::Track::NEW_DRUM && ((_dnum & 0xff) == 0xff) && cdp != -1)
+ else if((_track->type() == MusECore::Track::NEW_DRUM || _track->type() == MusECore::Track::MIDI) && ((_dnum & 0xff) == 0xff) && cdp != -1)
{
_dnum = (_dnum & ~0xff) | cdp; //FINDMICHJETZT does that work?
mp = &MusEGlobal::midiPorts[_track->outPort()];
@@ -442,11 +484,15 @@ void CtrlPanel::setHWController(MusECore::MidiTrack* t, MusECore::MidiController
_dl->setEnabled(false);
_knob->hide();
_dl->hide();
+ _veloPerNoteButton->setEnabled(true);
+ _veloPerNoteButton->show();
}
else
{
_knob->setEnabled(true);
_dl->setEnabled(true);
+ _veloPerNoteButton->setEnabled(false);
+ _veloPerNoteButton->hide();
double dlv;
int mn; int mx; int v;
if(_dnum == MusECore::CTRL_PROGRAM)
@@ -573,7 +619,7 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
int curDrumPitch = ctrlcanvas->getCurDrumPitch();
bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -586,20 +632,12 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
emit controllerChanged(MusECore::CTRL_VELOCITY);
}
- else if (rv == polyafter) { // special case
- emit controllerChanged(MusECore::CTRL_POLYAFTER);
- }
- else if (rv == after) { // special case
- emit controllerChanged(MusECore::CTRL_AFTERTOUCH);
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -736,5 +774,18 @@ void CtrlPanel::ctrlRightClicked(const QPoint& p, int /*id*/)
MusEGlobal::song->execMidiAutomationCtlPopup(0, part, p, ctlnum);
}
+//---------------------------------------------------------
+// velPerNoteClicked
+//---------------------------------------------------------
+
+void CtrlPanel::velPerNoteClicked()
+{
+ if(MusEGlobal::config.velocityPerNote != _veloPerNoteButton->isChecked())
+ {
+ MusEGlobal::config.velocityPerNote = _veloPerNoteButton->isChecked();
+ MusEGlobal::muse->changeConfig(false); // Save settings? No, wait till close.
+ }
+}
+
} // namespace MusEGui
diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h
index 58b8d8c7..261f982f 100644
--- a/muse2/muse/ctrl/ctrlpanel.h
+++ b/muse2/muse/ctrl/ctrlpanel.h
@@ -25,6 +25,8 @@
#include <QWidget>
+#include "type_defs.h"
+
class QPushButton;
class QAction;
@@ -39,6 +41,7 @@ class DoubleLabel;
class Knob;
class MidiEditor;
class CtrlCanvas;
+class PixmapButton;
//---------------------------------------------------------
// CtrlPanel
@@ -58,8 +61,7 @@ class CtrlPanel: public QWidget {
MusEGui::Knob* _knob;
MusEGui::DoubleLabel* _dl;
int _val;
-
-
+ PixmapButton* _veloPerNoteButton;
signals:
void destroyPanel();
@@ -70,6 +72,9 @@ class CtrlPanel: public QWidget {
void labelDoubleClicked();
void ctrlRightClicked(const QPoint& p, int id);
void ctrlPopupTriggered(QAction* act);
+ void velPerNoteClicked();
+ void songChanged(MusECore::SongChangedFlags_t type);
+ void configChanged();
protected slots:
virtual void heartBeat();
diff --git a/muse2/muse/driver/alsamidi.cpp b/muse2/muse/driver/alsamidi.cpp
index 80595fb0..f140224c 100644
--- a/muse2/muse/driver/alsamidi.cpp
+++ b/muse2/muse/driver/alsamidi.cpp
@@ -327,6 +327,11 @@ bool MidiAlsaDevice::putMidiEvent(const MidiPlayEvent& e)
snd_seq_ev_set_pitchbend(&event, chn, b);
break;
}
+ else if((a | 0xff) == CTRL_POLYAFTER)
+ {
+ snd_seq_ev_set_keypress(&event, chn, a & 0x7f, b & 0x7f);
+ break;
+ }
else if(a == CTRL_AFTERTOUCH)
{
snd_seq_ev_set_chanpress(&event, chn, b);
diff --git a/muse2/muse/driver/jackmidi.cpp b/muse2/muse/driver/jackmidi.cpp
index a088290a..7306b93c 100644
--- a/muse2/muse/driver/jackmidi.cpp
+++ b/muse2/muse/driver/jackmidi.cpp
@@ -846,7 +846,13 @@ bool MidiJackDevice::processEvent(const MidiPlayEvent& event)
}
}
- if(a == CTRL_AFTERTOUCH)
+ if((a | 0xff) == CTRL_POLYAFTER)
+ {
+ //printf("MidiJackDevice::processEvent CTRL_AFTERTOUCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
+ if(!queueEvent(MidiPlayEvent(t, port, chn, ME_POLYAFTER, a & 0x7f, b & 0x7f)))
+ return false;
+ }
+ else if(a == CTRL_AFTERTOUCH)
{
//printf("MidiJackDevice::processEvent CTRL_AFTERTOUCH v:%d time:%d type:%d ch:%d A:%d B:%d\n", v, event.time(), event.type(), event.channel(), event.dataA(), event.dataB());
if(!queueEvent(MidiPlayEvent(t, port, chn, ME_AFTERTOUCH, b & 0x7f, 0)))
diff --git a/muse2/muse/gconfig.cpp b/muse2/muse/gconfig.cpp
index c88c3fc5..0da8ccf7 100644
--- a/muse2/muse/gconfig.cpp
+++ b/muse2/muse/gconfig.cpp
@@ -26,7 +26,7 @@
namespace MusEGlobal {
GlobalConfigValues config = {
- 190, // globalAlphaBlend
+ 170, // globalAlphaBlend
{
QColor(0xff, 0xff, 0xff), // palette
QColor(0xff, 0xff, 0xff),
@@ -130,6 +130,8 @@ GlobalConfigValues config = {
true, // midiSendInit Send instrument initialization sequences
true, // warnInitPending Warn instrument initialization sequences pending
false, // midiSendCtlDefaults Send instrument controller defaults at position 0 if none in song
+ true, // warnIfBadTiming Warn if timer res not good
+ false, // velocityPerNote Whether to show per-note or all velocities
-60, // int minMeter;
-60.0, // double minSlider;
false, // use Jack freewheel
diff --git a/muse2/muse/gconfig.h b/muse2/muse/gconfig.h
index 6fa85846..af45ed92 100644
--- a/muse2/muse/gconfig.h
+++ b/muse2/muse/gconfig.h
@@ -139,6 +139,8 @@ struct GlobalConfigValues {
bool midiSendInit; // Send instrument initialization sequences
bool warnInitPending; // Warn instrument initialization sequences pending
bool midiSendCtlDefaults; // Send instrument controller defaults at position 0 if none in song
+ bool warnIfBadTiming; // Warn if timer res not good
+ bool velocityPerNote; // Whether to show per-note or all velocities
int minMeter;
double minSlider;
bool freewheelMode;
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index 986d38aa..e2186af9 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -888,7 +888,7 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ bool isNewDrum = (track->type() == MusECore::Track::NEW_DRUM) || (track->type() == MusECore::Track::MIDI);
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -1030,18 +1030,6 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor
est_width = fmw;
menu->addAction(stext)->setData(velo);
-// stext = QWidget::tr("PolyAftertouch");
-// fmw = menu->fontMetrics().width(stext);
-// if(fmw > est_width)
-// est_width = fmw;
-// menu->addAction(stext)->setData(polyafter);
-//
-// stext = QWidget::tr("Aftertouch");
-// fmw = menu->fontMetrics().width(stext);
-// if(fmw > est_width)
-// est_width = fmw;
-// menu->addAction(stext)->setData(after);
-
// Add global default controllers (all controllers not found in instrument).
for (isList i = sList.begin(); i != sList.end(); ++i)
{
diff --git a/muse2/muse/icons.cpp b/muse2/muse/icons.cpp
index dab1067b..a3dfbf50 100644
--- a/muse2/muse/icons.cpp
+++ b/muse2/muse/icons.cpp
@@ -212,6 +212,8 @@
#include "xpm/initS.xpm"
#include "xpm/delta_on.xpm"
#include "xpm/delta_off.xpm"
+#include "xpm/velo_all.xpm"
+#include "xpm/velo_per_note.xpm"
#include "xpm/addtrack_addmiditrack.xpm"
#include "xpm/addtrack_audiogroup.xpm"
@@ -294,6 +296,8 @@ QPixmap* mixerAudioSIcon;
QPixmap* initSIcon;
QPixmap* deltaOnIcon;
QPixmap* deltaOffIcon;
+QPixmap* veloPerNote_OnIcon;
+QPixmap* veloPerNote_OffIcon;
QPixmap* exitIcon;
QPixmap* exit1Icon;
@@ -678,6 +682,8 @@ void initIcons()
initSIcon = new MPIXMAP(initS_xpm, NULL);
deltaOnIcon = new MPIXMAP(delta_on_xpm, NULL);
deltaOffIcon = new MPIXMAP(delta_off_xpm, NULL);
+ veloPerNote_OnIcon = new MPIXMAP(velo_per_note_xpm, NULL);
+ veloPerNote_OffIcon = new MPIXMAP(velo_all_xpm, NULL);
addtrack_addmiditrackIcon = new MPIXMAP(addtrack_addmiditrack_xpm, NULL);
addtrack_audiogroupIcon = new MPIXMAP(addtrack_audiogroup_xpm, NULL);
@@ -917,6 +923,8 @@ void deleteIcons()
delete initSIcon;
delete deltaOnIcon;
delete deltaOffIcon;
+ delete veloPerNote_OnIcon;
+ delete veloPerNote_OffIcon;
delete addtrack_addmiditrackIcon;
delete addtrack_audiogroupIcon;
diff --git a/muse2/muse/icons.h b/muse2/muse/icons.h
index a6c95577..36a780ae 100644
--- a/muse2/muse/icons.h
+++ b/muse2/muse/icons.h
@@ -195,6 +195,8 @@ extern QPixmap* mixerAudioSIcon;
extern QPixmap* initSIcon;
extern QPixmap* deltaOnIcon;
extern QPixmap* deltaOffIcon;
+extern QPixmap* veloPerNote_OnIcon;
+extern QPixmap* veloPerNote_OffIcon;
extern QPixmap* addtrack_addmiditrackIcon;
extern QPixmap* addtrack_audiogroupIcon;
diff --git a/muse2/muse/midictrl.cpp b/muse2/muse/midictrl.cpp
index 2cf4f790..b87ea8d1 100644
--- a/muse2/muse/midictrl.cpp
+++ b/muse2/muse/midictrl.cpp
@@ -87,9 +87,6 @@ static MidiController programCtrl("Program", CTRL_PROGRAM, 0, 0xf
static MidiController mastervolCtrl("MasterVolume", CTRL_MASTER_VOLUME, 0, 0x3fff, 0x3000);
static MidiController volumeCtrl("MainVolume", CTRL_VOLUME, 0, 127, 100);
static MidiController panCtrl("Pan", CTRL_PANPOT, -64, 63, 0);
-static MidiController polyAfterCtrl("PolyAftertouch", CTRL_POLYAFTER, 0, 127, 0);
-static MidiController afterCtrl("Aftertouch", CTRL_AFTERTOUCH, 0, 127, 0);
-
//---------------------------------------------------------
// ctrlType2Int
@@ -149,8 +146,6 @@ const QString& int2ctrlType(int n)
void initMidiController()
{
defaultMidiController.add(&veloCtrl);
- defaultMidiController.add(&polyAfterCtrl);
- defaultMidiController.add(&afterCtrl);
defaultMidiController.add(&pitchCtrl);
defaultMidiController.add(&programCtrl);
defaultMidiController.add(&mastervolCtrl);
@@ -432,7 +427,7 @@ void MidiController::updateBias()
void MidiController::write(int level, Xml& xml) const
{
ControllerType t = midiControllerType(_num);
- if(t == Velo || t == PolyAftertouch || t == Aftertouch)
+ if(t == Velo)
return;
QString type(int2ctrlType(t));
@@ -475,10 +470,16 @@ void MidiController::write(int level, Xml& xml) const
mn = -8192;
mx = 8191;
break;
- case Program:
- case Velo: // Cannot happen
case PolyAftertouch:
+ mn = 0;
+ mx = 127;
+ break;
case Aftertouch:
+ mn = 0;
+ mx = 127;
+ break;
+ case Program:
+ case Velo: // Cannot happen
break;
}
@@ -599,9 +600,21 @@ void MidiController::read(Xml& xml)
_maxVal = 0xffffff;
_num = CTRL_PROGRAM;
break;
- case Velo: // cannot happen
case PolyAftertouch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ if (_minVal == NOT_SET)
+ _minVal = 0;
+ _num = CTRL_POLYAFTER;
+ break;
case Aftertouch:
+ if (_maxVal == NOT_SET)
+ _maxVal = 127;
+ if (_minVal == NOT_SET)
+ _minVal = 0;
+ _num = CTRL_AFTERTOUCH;
+ break;
+ case Velo: // cannot happen
break;
}
if (_minVal == NOT_SET)
diff --git a/muse2/muse/midictrl.h b/muse2/muse/midictrl.h
index 5e197dc0..5ff3f129 100644
--- a/muse2/muse/midictrl.h
+++ b/muse2/muse/midictrl.h
@@ -81,11 +81,13 @@ const int CTRL_LOCAL_OFF = 0x7a; // 122
const int CTRL_INTERNAL_OFFSET = 0x40000;
const int CTRL_PITCH = CTRL_INTERNAL_OFFSET;
-const int CTRL_PROGRAM = CTRL_INTERNAL_OFFSET + 1;
-const int CTRL_VELOCITY = CTRL_INTERNAL_OFFSET + 2;
-const int CTRL_MASTER_VOLUME = CTRL_INTERNAL_OFFSET + 3;
-const int CTRL_POLYAFTER = CTRL_INTERNAL_OFFSET + 4;
-const int CTRL_AFTERTOUCH = CTRL_INTERNAL_OFFSET + 5;
+const int CTRL_PROGRAM = CTRL_INTERNAL_OFFSET + 0x01;
+const int CTRL_VELOCITY = CTRL_INTERNAL_OFFSET + 0x02;
+const int CTRL_MASTER_VOLUME = CTRL_INTERNAL_OFFSET + 0x03;
+const int CTRL_AFTERTOUCH = CTRL_INTERNAL_OFFSET + 0x04;
+// NOTE: The range from CTRL_INTERNAL_OFFSET + 0x100 to CTRL_INTERNAL_OFFSET + 0x1ff is reserved
+// for this control. (The low byte is reserved because this is a per-note control.)
+const int CTRL_POLYAFTER = CTRL_INTERNAL_OFFSET + 0x1FF; // 100 to 1FF !
const int CTRL_VAL_UNKNOWN = 0x10000000; // used as unknown hwVal
diff --git a/muse2/muse/mididev.cpp b/muse2/muse/mididev.cpp
index 96fee89a..3703def2 100644
--- a/muse2/muse/mididev.cpp
+++ b/muse2/muse/mididev.cpp
@@ -456,6 +456,9 @@ bool MidiDevice::putEvent(const MidiPlayEvent& ev)
if (a == CTRL_PITCH) {
return putMidiEvent(MidiPlayEvent(t, port, chn, ME_PITCHBEND, b, 0));
}
+ if ((a | 0xff) == CTRL_POLYAFTER) {
+ return putMidiEvent(MidiPlayEvent(t, port, chn, ME_POLYAFTER, a & 0x7f, b & 0x7f));
+ }
if (a == CTRL_AFTERTOUCH) {
return putMidiEvent(MidiPlayEvent(t, port, chn, ME_AFTERTOUCH, b, 0));
}
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 42eda0fd..9189b0d8 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -871,9 +871,11 @@ void DrumCanvas::keyPressed(int index, int velocity)
int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch;
// play note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
-
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
if (_steprec) /* && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record] */
{
@@ -909,8 +911,11 @@ void DrumCanvas::keyReleased(int index, bool)
int pitch = old_style_drummap_mode ? ourDrumMap[index].anote : instrument_map[index].pitch;
// release note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp
index a77fb810..3222e278 100644
--- a/muse2/muse/midiedit/dlist.cpp
+++ b/muse2/muse/midiedit/dlist.cpp
@@ -1123,6 +1123,15 @@ void DList::viewMouseReleaseEvent(QMouseEvent* ev)
}
//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void DList::wheelEvent(QWheelEvent* ev)
+ {
+ emit redirectWheelEvent(ev);
+ }
+
+//---------------------------------------------------------
// getSelectedInstrument
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h
index b4c757e8..28b4af27 100644
--- a/muse2/muse/midiedit/dlist.h
+++ b/muse2/muse/midiedit/dlist.h
@@ -137,6 +137,7 @@ class DList : public View {
virtual void viewMouseReleaseEvent(QMouseEvent* event);
virtual void viewMouseDoubleClickEvent(QMouseEvent*);
virtual void viewMouseMoveEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent* e);
int x2col(int x) const;
void devicesPopupMenu(MusECore::DrumMap* t, int x, int y, bool changeAll);
@@ -155,6 +156,7 @@ class DList : public View {
void keyPressed(int, int);
void keyReleased(int, bool);
void curDrumInstrumentChanged(int);
+ void redirectWheelEvent(QWheelEvent*);
public slots:
void tracklistChanged();
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 238b37fd..03f246cf 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -166,6 +166,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
lastSelections = 0;
split1w1 = 0;
//selPart = 0;
+ _playEvents = false;
QSignalMapper *signalMapper = new QSignalMapper(this);
_group_mode = GROUP_SAME_CHANNEL;
@@ -419,7 +420,13 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
midiin->setFocusPolicy(Qt::NoFocus);
tools->addWidget(midiin);
-
+ speaker = new QToolButton();
+ speaker->setToolTip(tr("Play Events"));
+ speaker->setIcon(*speakerIcon);
+ speaker->setCheckable(true);
+ speaker->setFocusPolicy(Qt::NoFocus);
+ tools->addWidget(speaker);
+
tools2 = new MusEGui::EditToolBar(this, drumeditTools);
addToolBar(tools2);
@@ -554,6 +561,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
connect(dlist, SIGNAL(keyPressed(int, int)), canvas, SLOT(keyPressed(int, int)));
connect(dlist, SIGNAL(keyReleased(int, bool)), canvas, SLOT(keyReleased(int, bool)));
connect(dlist, SIGNAL(mapChanged(int, int)), canvas, SLOT(mapChanged(int, int)));
+ connect(dlist, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*)));
gridS1->setRowStretch(1, 100);
gridS1->setColumnStretch(0, 100);
@@ -568,11 +576,12 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), dlist, SLOT(songChanged(MusECore::SongChangedFlags_t)));
connect(vscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setYPos(int)));
connect(vscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setYMag(int)));
- connect(vscroll, SIGNAL(scaleChanged(int)), dlist, SLOT(setYMag(int)));
+ connect(vscroll, SIGNAL(scaleChanged(int)), dlist, SLOT(setYMag(int)));
connect(hscroll, SIGNAL(scrollChanged(int)), canvas, SLOT(setXPos(int)));
connect(hscroll, SIGNAL(scaleChanged(int)), canvas, SLOT(setXMag(int)));
connect(srec, SIGNAL(toggled(bool)), canvas, SLOT(setSteprec(bool)));
connect(midiin, SIGNAL(toggled(bool)), canvas, SLOT(setMidiin(bool)));
+ connect(speaker, SIGNAL(toggled(bool)), SLOT(setSpeaker(bool)));
connect(vscroll, SIGNAL(scrollChanged(int)), dlist, SLOT(setYPos(int)));
connect(hscroll, SIGNAL(scrollChanged(int)), time, SLOT(setXPos(int)));
@@ -930,6 +939,7 @@ void DrumEdit::writeStatus(int level, MusECore::Xml& xml) const
header->writeStatus(level, xml);
xml.intTag(level, "steprec", canvas->steprec());
xml.intTag(level, "midiin", canvas->midiin());
+ xml.intTag(level, "playEvents", _playEvents);
xml.intTag(level, "xpos", hscroll->pos());
xml.intTag(level, "xmag", hscroll->mag());
xml.intTag(level, "ypos", vscroll->pos());
@@ -974,6 +984,11 @@ void DrumEdit::readStatus(MusECore::Xml& xml)
MidiEditor::readStatus(xml);
else if (tag == header->objectName())
header->readStatus(xml);
+ else if (tag == "playEvents") {
+ _playEvents = xml.parseInt();
+ canvas->playEvents(_playEvents);
+ speaker->setChecked(_playEvents);
+ }
else if (tag == "xmag")
hscroll->setMag(xml.parseInt());
else if (tag == "xpos")
@@ -1253,20 +1268,12 @@ void DrumEdit::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == polyafter) { // special case
- newCtlNum = MusECore::CTRL_POLYAFTER;
- }
- else if (rv == after) { // special case
- newCtlNum = MusECore::CTRL_AFTERTOUCH;
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -1708,6 +1715,16 @@ void DrumEdit::keyPressEvent(QKeyEvent* event)
//---------------------------------------------------------
+// setSpeaker
+//---------------------------------------------------------
+
+void DrumEdit::setSpeaker(bool val)
+ {
+ _playEvents = val;
+ canvas->playEvents(_playEvents);
+ }
+
+//---------------------------------------------------------
// initShortcuts
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h
index 63246e2e..4b9d391a 100644
--- a/muse2/muse/midiedit/drumedit.h
+++ b/muse2/muse/midiedit/drumedit.h
@@ -103,7 +103,9 @@ class DrumEdit : public MidiEditor {
MusEGui::NoteInfo* info;
QToolButton* srec;
QToolButton* midiin;
+ QToolButton* speaker;
MusEGui::EditToolBar* tools2;
+ bool _playEvents;
MusEGui::Toolbar1* toolbar;
MusEGui::Splitter* split1;
@@ -152,6 +154,7 @@ class DrumEdit : public MidiEditor {
void configChanged();
void songChanged1(MusECore::SongChangedFlags_t);
void setStep(QString);
+ void setSpeaker(bool);
void addCtrlClicked();
void ctrlPopupTriggered(QAction* act);
diff --git a/muse2/muse/midiedit/piano.cpp b/muse2/muse/midiedit/piano.cpp
index 1000ffe9..afbf8328 100644
--- a/muse2/muse/midiedit/piano.cpp
+++ b/muse2/muse/midiedit/piano.cpp
@@ -26,7 +26,11 @@
#include <stdio.h>
#include "piano.h"
+#include "globals.h"
+#include "song.h"
+namespace MusEGui {
+
static const char *oct_xpm[] = {
// w h colors
"40 91 2 1",
@@ -120,134 +124,125 @@ static const char *oct_xpm[] = {
".........................#...#.........#",
".........................#.............#",
".........................#.............#",
- ".........................#...#.........#", // 10
+ ".........................#...#.........#", // 9
"..........................###..........#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC1[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###.....#....#",
".........................#...#...##....#",
".........................#........#....#",
".........................#........#....#",
- ".........................#...#....#....#", // 10
+ ".........................#...#....#....#", // 9
"..........................###....###...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC2[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
".........................#...#..#..#...#",
".........................#........#....#",
".........................#.......#.....#",
- ".........................#...#..#......#", // 10
+ ".........................#...#..#......#", // 9
"..........................###...####...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC3[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
".........................#...#..#..#...#",
".........................#........#....#",
".........................#.........#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###....##....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC4[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...#..#...#",
".........................#...#..#..#...#",
".........................#......####...#",
".........................#.........#...#",
- ".........................#...#.....#...#", // 10
+ ".........................#...#.....#...#", // 9
"..........................###......#...#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC5[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...####...#",
".........................#...#..#......#",
".........................#......###....#",
".........................#.........#...#",
- ".........................#...#.....#...#", // 10
+ ".........................#...#.....#...#", // 9
"..........................###...###....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC6[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....###...#",
".........................#...#..#......#",
".........................#......###....#",
".........................#......#..#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###...###....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC7[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###...####...#",
".........................#...#.....#...#",
".........................#........#....#",
".........................#.......#.....#",
- ".........................#...#..#......#", // 10
+ ".........................#...#..#......#", // 9
"..........................###...#......#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpmC8[] = {
- "40 10 2 1",
- ". c #c0c0c0",
+ "40 9 2 1",
+ ". c none",
"# c #000000",
".......................................#",
"..........................###....##....#",
- ".........................#...#..#..#....#",
+ ".........................#...#..#..#...#",
".........................#.......##....#",
".........................#......#..#...#",
- ".........................#...#..#..#...#", // 10
+ ".........................#...#..#..#...#", // 9
"..........................###....##....#",
".......................................#",
".......................................#",
- ".......................................#",
};
static const char *mk1_xpm[] = {
@@ -266,7 +261,7 @@ static const char *mk1_xpm[] = {
"#######################................#",
"########################...............#",
"########################...............#",
- "####################################### ",
+ "########################################",
};
static const char *mk2_xpm[] = {
@@ -285,7 +280,7 @@ static const char *mk2_xpm[] = {
"#######################................#",
"########################...............#",
"########################...............#", // 7
- "####################################### ",
+ "########################################",
};
static const char *mk3_xpm[] = {
@@ -325,6 +320,83 @@ static const char *mk4_xpm[] = {
"........................................",
"........................................",
};
+
+static const char *mk5_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ "#######################................#",
+ "########################...............#",
+ "########################...............#",
+ "########################################",
+ };
+
+static const char *mk6_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ "########################...............#",
+ "########################...............#",
+ "#######################................#", //------------------------
+ ".......................................#",
+ ".......................................#",
+ ".......................................#", // 6
+ ".......................................#",
+ ".......................................#",
+ ".......................................#", //--------------------------
+ "#######################................#",
+ "########################...............#",
+ "########################...............#", // 7
+ "########################################",
+ };
+
+static const char *mk7_xpm[] = {
+ "40 13 2 1",
+ ". c #ffff00",
+ "# c none",
+ "########################...............#",
+ "########################...............#",
+ "#######################................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ ".......................................#",
+ "########################################",
+ };
+
+static const char *mk8_xpm[] = {
+ "40 13 2 1",
+ "# c #ffff00",
+ ". c none",
+ "........................................",
+ "........................................",
+ "........................................",
+ "#######################.................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "########################................",
+ "#######################.................",
+ "........................................",
+ "........................................",
+ "........................................",
+ };
+
/*
0 1 2 3 4 5 6 7 8 9 10
c-2 c-1 C0 C1 C2 C3 C4 C5 C6 C7 C8 - G8
@@ -367,10 +439,11 @@ static const char *mk4_xpm[] = {
//---------------------------------------------------------
Piano::Piano(QWidget* parent, int ymag)
- : MusEGui::View(parent, 1, ymag)
+ : View(parent, 1, ymag)
{
setMouseTracking(true);
curPitch = -1;
+ _curSelectedPitch = 60; // Start with 'C3"
octave = new QPixmap(oct_xpm);
c_keys[0] = new QPixmap(mk1_xpmC8);
c_keys[1] = new QPixmap(mk1_xpmC7);
@@ -385,6 +458,12 @@ Piano::Piano(QWidget* parent, int ymag)
mk2 = new QPixmap(mk2_xpm);
mk3 = new QPixmap(mk3_xpm);
mk4 = new QPixmap(mk4_xpm);
+
+ mk5 = new QPixmap(mk5_xpm);
+ mk6 = new QPixmap(mk6_xpm);
+ mk7 = new QPixmap(mk7_xpm);
+ mk8 = new QPixmap(mk8_xpm);
+
keyDown = -1;
button = Qt::NoButton;
}
@@ -398,39 +477,67 @@ void Piano::draw(QPainter& p, const QRect& r)
QPoint offset(0, KH*2);
p.drawTiledPixmap(r, *octave, r.topLeft()+offset);
+ if (_curSelectedPitch != -1 && _curSelectedPitch != curPitch)
+ {
+ int y = pitch2y(_curSelectedPitch);
+ QPixmap* pm;
+ switch(_curSelectedPitch % 12) {
+ case 0:
+ case 5:
+ pm = mk7;
+ break;
+ case 2:
+ case 7:
+ case 9:
+ pm = mk6;
+ break;
+ case 4:
+ case 11:
+ pm = mk5;
+ break;
+ default:
+ pm = mk8;
+ break;
+ }
+ p.drawPixmap(0, y, *pm);
+ }
+
+ if (curPitch != -1)
+ {
+ int y = pitch2y(curPitch);
+ QPixmap* pm;
+ switch(curPitch % 12) {
+ case 0:
+ case 5:
+ pm = mk3;
+ break;
+ case 2:
+ case 7:
+ case 9:
+ pm = mk2;
+ break;
+ case 4:
+ case 11:
+ pm = mk1;
+ break;
+ default:
+ pm = mk4;
+ break;
+ }
+ p.drawPixmap(0, y, *pm);
+ }
+
// draw C notes
for (int drawKey = 0; drawKey < 8;drawKey++) {
int octaveSize=91;
- int drawY = octaveSize * drawKey + 81 - KH*2;
+ int drawY = octaveSize * drawKey + 82 - KH*2;
if (drawY > r.y() && drawY < r.y() + r.height()) {
p.drawPixmap(0,drawY,*c_keys[drawKey]);
}
}
-
- if (curPitch == -1)
- return;
- int y = pitch2y(curPitch);
- QPixmap* pm;
- switch(curPitch % 12) {
- case 0:
- case 5:
- pm = mk3;
- break;
- case 2:
- case 7:
- case 9:
- pm = mk2;
- break;
- case 4:
- case 11:
- pm = mk1;
- break;
- default:
- pm = mk4;
- break;
- }
- p.drawPixmap(0, y, *pm);
+
+
}
//---------------------------------------------------------
@@ -547,6 +654,13 @@ void Piano::viewMousePressEvent(QMouseEvent* event)
int velocity = event->x()*127/40;
emit keyPressed(keyDown, velocity>127 ? 127 : velocity, shift); //emit keyPressed(keyDown, shift);
}
+
+ if (keyDown != -1 && keyDown != _curSelectedPitch) {
+ _curSelectedPitch = keyDown;
+ emit curSelectedPitchChanged(_curSelectedPitch);
+ redraw();
+ MusEGlobal::song->update(SC_DRUMMAP);
+ }
}
//---------------------------------------------------------
@@ -563,3 +677,28 @@ void Piano::viewMouseReleaseEvent(QMouseEvent* event)
}
}
+//---------------------------------------------------------
+// setCurSelectedPitch
+//---------------------------------------------------------
+
+void Piano::setCurSelectedPitch(int pitch)
+ {
+ if (pitch < 0 || pitch >= 128)
+ return;
+ if (pitch != _curSelectedPitch) {
+ _curSelectedPitch = pitch;
+ emit curSelectedPitchChanged(_curSelectedPitch);
+ redraw();
+ }
+ }
+
+//---------------------------------------------------------
+// wheelEvent
+//---------------------------------------------------------
+
+void Piano::wheelEvent(QWheelEvent* ev)
+ {
+ emit redirectWheelEvent(ev);
+ }
+
+} // namespace MusEGui
diff --git a/muse2/muse/midiedit/piano.h b/muse2/muse/midiedit/piano.h
index ea032189..f42037ec 100644
--- a/muse2/muse/midiedit/piano.h
+++ b/muse2/muse/midiedit/piano.h
@@ -27,26 +27,34 @@
class QEvent;
class QMouseEvent;
+class QWheelEvent;
class QPainter;
class QPixmap;
#define KH 13
+namespace MusEGui {
+
//---------------------------------------------------------
// Piano
//---------------------------------------------------------
-class Piano : public MusEGui::View
+class Piano : public View
{
Q_OBJECT
int curPitch;
+ int _curSelectedPitch;
QPixmap* octave;
QPixmap* c_keys[10];
QPixmap* mk1;
QPixmap* mk2;
QPixmap* mk3;
QPixmap* mk4;
+ QPixmap* mk5;
+ QPixmap* mk6;
+ QPixmap* mk7;
+ QPixmap* mk8;
int keyDown;
bool shift;
int button;
@@ -59,6 +67,7 @@ class Piano : public MusEGui::View
virtual void viewMousePressEvent(QMouseEvent* event);
virtual void viewMouseReleaseEvent(QMouseEvent*);
+ virtual void wheelEvent(QWheelEvent* e);
protected:
virtual void draw(QPainter&, const QRect&);
@@ -67,13 +76,19 @@ class Piano : public MusEGui::View
void pitchChanged(int);
void keyPressed(int, int, bool);
void keyReleased(int, bool);
+ void curSelectedPitchChanged(int);
+ void redirectWheelEvent(QWheelEvent*);
public slots:
void setPitch(int);
public:
Piano(QWidget*, int);
+ int curSelectedPitch() const { return _curSelectedPitch; }
+ void setCurSelectedPitch(int pitch);
};
+} // namespace MusEGui
+
#endif
diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp
index 1701f537..97c5ecc3 100644
--- a/muse2/muse/midiedit/pianoroll.cpp
+++ b/muse2/muse/midiedit/pianoroll.cpp
@@ -359,9 +359,10 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
gridS1->setSpacing(0);
time = new MusEGui::MTScale(&_raster, split1, xscale);
- Piano* piano = new Piano(split1, yscale);
+ piano = new Piano(split1, yscale);
canvas = new PianoCanvas(this, split1, xscale, yscale);
vscroll = new MusEGui::ScrollScale(-3, 7, yscale, KH * 75, Qt::Vertical, split1);
+ setCurDrumInstrument(piano->curSelectedPitch());
int offset = -(MusEGlobal::config.division/4);
canvas->setOrigin(offset, 0);
@@ -428,6 +429,7 @@ PianoRoll::PianoRoll(MusECore::PartList* pl, QWidget* parent, const char* name,
connect(piano, SIGNAL(keyPressed(int, int, bool)), canvas, SLOT(pianoPressed(int, int, bool)));
connect(piano, SIGNAL(keyReleased(int, bool)), canvas, SLOT(pianoReleased(int, bool)));
+ connect(piano, SIGNAL(redirectWheelEvent(QWheelEvent*)), canvas, SLOT(redirectedWheelEvent(QWheelEvent*)));
connect(srec, SIGNAL(toggled(bool)), SLOT(setSteprec(bool)));
connect(midiin, SIGNAL(toggled(bool)), canvas, SLOT(setMidiin(bool)));
connect(speaker, SIGNAL(toggled(bool)), SLOT(setSpeaker(bool)));
@@ -811,9 +813,7 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
MusECore::MidiTrack* track = (MusECore::MidiTrack*)(part->track());
int channel = track->outChannel();
MusECore::MidiPort* port = &MusEGlobal::midiPorts[track->outPort()];
- int curDrumPitch = curDrumInstrument();
- bool isDrum = track->type() == MusECore::Track::DRUM;
- bool isNewDrum = track->type() == MusECore::Track::NEW_DRUM;
+ int curPitch = curDrumInstrument();
MusECore::MidiInstrument* instr = port->instrument();
MusECore::MidiControllerList* mcl = instr->controller();
@@ -826,20 +826,12 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
const int edit_ins = max + 3;
const int velo = max + 0x101;
- const int polyafter = max + 0x102;
- const int after = max + 0x103;
int rv = act->data().toInt();
if (rv == velo) { // special case velocity
newCtlNum = MusECore::CTRL_VELOCITY;
}
- else if (rv == polyafter) { // special case
- newCtlNum = MusECore::CTRL_POLYAFTER;
- }
- else if (rv == after) { // special case
- newCtlNum = MusECore::CTRL_AFTERTOUCH;
- }
else if (rv == add_ins_def) { // add new instrument controller
PopupMenu * ctrlSubPop = new PopupMenu(this, true); // true = enable stay open
@@ -855,10 +847,11 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
int num = ci->second->num();
if((num & 0xff) == 0xff)
{
- if (isDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICH does this work?
+ //if (curPitch!=-1)
+ // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
+ //else
+ if(curPitch!=-1)
+ num = (num & ~0xff) + curPitch; //FINDMICH does this work?
else // dont show drum specific controller if not a drum track
continue;
}
@@ -885,10 +878,11 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
{
c = ci->second;
int num = c->num();
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- else if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
+ //if (((num & 0xff) == 0xff) && curPitch!=-1)
+ // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
+ //else
+ if (((num & 0xff) == 0xff) && curPitch!=-1)
+ num = (num & ~0xff) + curPitch; //FINDMICHJETZT does this work?
if(num != rv2)
continue;
@@ -923,10 +917,10 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)
if (act2) {
int rv2 = act2->data().toInt();
int num = rv2;
- if (isDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + MusEGlobal::drumMap[curDrumPitch].anote;
- if (isNewDrum && ((num & 0xff) == 0xff) && curDrumPitch!=-1)
- num = (num & ~0xff) + curDrumPitch; //FINDMICHJETZT does this work?
+ //if (((num & 0xff) == 0xff) && curPitch!=-1)
+ // num = (num & ~0xff) + MusEGlobal::drumMap[curPitch].anote;
+ if (((num & 0xff) == 0xff) && curPitch!=-1)
+ num = (num & ~0xff) + curPitch; //FINDMICHJETZT does this work?
if(cll->find(channel, num) == cll->end())
{
@@ -972,7 +966,7 @@ void PianoRoll::addCtrlClicked()
PopupMenu* pup = new PopupMenu(true); // true = enable stay open. Don't bother with parent.
connect(pup, SIGNAL(triggered(QAction*)), SLOT(ctrlPopupTriggered(QAction*)));
- int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), -1); // _curDrumInstrument);
+ int est_width = populateMidiCtrlMenu(pup, parts(), curCanvasPart(), curDrumInstrument());
QPoint ep = ctrl->mapToGlobal(QPoint(0,0));
//int newx = ep.x() - ctrlMainPop->width(); // Too much! Width says 640. Maybe because it hasn't been shown yet .
@@ -1010,7 +1004,11 @@ void PianoRoll::setupNewCtrl(CtrlEdit* ctrlEdit)
connect(ctrlEdit, SIGNAL(timeChanged(unsigned)), SLOT(setTime(unsigned)));
connect(ctrlEdit, SIGNAL(destroyedCtrl(CtrlEdit*)), SLOT(removeCtrl(CtrlEdit*)));
connect(ctrlEdit, SIGNAL(yposChanged(int)), toolbar, SLOT(setInt(int)));
+ connect(piano, SIGNAL(curSelectedPitchChanged(int)), SLOT(setCurDrumInstrument(int)));
+ //connect(piano, SIGNAL(curSelectedPitchChanged(int)), canvas, SLOT(setCurDrumInstrument(int)));
+ setCurDrumInstrument(piano->curSelectedPitch());
+
ctrlEdit->setTool(tools2->curTool());
ctrlEdit->setXPos(hscroll->pos());
ctrlEdit->setXMag(hscroll->getScaleValue());
@@ -1275,6 +1273,17 @@ void PianoRoll::keyPressEvent(QKeyEvent* event)
tools2->set(MusEGui::DrawTool);
return;
}
+ else if (key == shortcuts[SHRT_INSTRUMENT_STEP_UP].key) {
+ piano->setCurSelectedPitch(piano->curSelectedPitch()+1);
+ MusEGlobal::song->update(SC_DRUMMAP);
+ return;
+ }
+ else if (key == shortcuts[SHRT_INSTRUMENT_STEP_DOWN].key) {
+ piano->setCurSelectedPitch(piano->curSelectedPitch()-1);
+ MusEGlobal::song->update(SC_DRUMMAP);
+ return;
+ }
+
else if (key == shortcuts[SHRT_POS_INC].key) {
pc->pianoCmd(CMD_RIGHT);
return;
diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h
index 75e3c9af..87ea1d3d 100644
--- a/muse2/muse/midiedit/pianoroll.h
+++ b/muse2/muse/midiedit/pianoroll.h
@@ -66,6 +66,7 @@ class ScrollScale;
class Splitter;
class TimeLabel;
class Toolbar1;
+class Piano;
//---------------------------------------------------------
// PianoRoll
@@ -126,6 +127,7 @@ class PianoRoll : public MidiEditor {
QToolButton* srec;
QToolButton* midiin;
+ Piano* piano;
MusEGui::Toolbar1* toolbar;
MusEGui::Splitter* splitter;
MusEGui::Splitter* hsplitter;
diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp
index 99c2ea8c..7670abb2 100644
--- a/muse2/muse/midiedit/prcanvas.cpp
+++ b/muse2/muse/midiedit/prcanvas.cpp
@@ -718,8 +718,11 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift)
pitch += track()->transposition;
// play note:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
if (_steprec && curPart) // && pos[0] >= start_tick && pos[0] < end_tick [removed by flo93: this is handled in steprec->record]
steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,MusEGlobal::globalKeyState&Qt::ControlModifier,shift, -1 /* anything which is != rcSteprecNote */);
@@ -736,8 +739,11 @@ void PianoCanvas::pianoReleased(int pitch, bool)
pitch += track()->transposition;
// release key:
- MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
- MusEGlobal::audio->msgPlayMidiEvent(&e);
+ if(_playEvents)
+ {
+ MusECore::MidiPlayEvent e(0, port, channel, 0x90, pitch, 0);
+ MusEGlobal::audio->msgPlayMidiEvent(&e);
+ }
}
//---------------------------------------------------------
diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp
index 2f3898ff..4365d698 100644
--- a/muse2/muse/midiport.cpp
+++ b/muse2/muse/midiport.cpp
@@ -742,8 +742,6 @@ void MidiPort::addDefaultControllers()
addManagedController(i, CTRL_PROGRAM);
addManagedController(i, CTRL_VOLUME);
addManagedController(i, CTRL_PANPOT);
- addManagedController(i, CTRL_POLYAFTER);
- addManagedController(i, CTRL_AFTERTOUCH);
_automationType[i] = AUTO_READ;
}
}
diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp
index 32e9de4c..8e636658 100644
--- a/muse2/muse/midiseq.cpp
+++ b/muse2/muse/midiseq.cpp
@@ -46,6 +46,7 @@
#include "synth.h"
#include "song.h"
#include "gconfig.h"
+#include "warn_bad_timing.h"
namespace MusEGlobal {
MusECore::MidiSeq* midiSeq;
@@ -507,13 +508,23 @@ void MidiSeq::checkAndReportTimingResolution()
{
int freq = timer->getTimerFreq();
if (freq < 500) {
- QMessageBox::warning( MusEGlobal::muse,
- qApp->translate("@default", QT_TRANSLATE_NOOP("@default", "Bad timing")),
- qApp->translate("@default", QT_TRANSLATE_NOOP("@default",
- "Timing source frequency is %1hz, which is below the recommended minimum: 500hz!\n" \
- "This could lead to audible timing problems for MIDI.\n" \
- "Please see the FAQ on http://muse-sequencer.org for remedies.\n" \
+ if(MusEGlobal::config.warnIfBadTiming)
+ {
+ MusEGui::WarnBadTimingDialog dlg;
+ dlg.setLabelText(qApp->translate("@default", QT_TRANSLATE_NOOP("@default",
+ "Timing source frequency is %1hz, which is below the recommended minimum: 500hz!\n"
+ "This could lead to audible timing problems for MIDI.\n"
+ "Please see the FAQ on http://muse-sequencer.org for remedies.\n"
"Also please check console output for any further error messages.\n ")).arg(freq) );
+
+ dlg.exec();
+ bool warn = !dlg.dontAsk();
+ if(warn != MusEGlobal::config.warnIfBadTiming)
+ {
+ MusEGlobal::config.warnIfBadTiming = warn;
+ //MusEGlobal::muse->changeConfig(true); // Save settings? No, wait till close.
+ }
+ }
}
}
diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt
index 3aad8b92..3808a99f 100644
--- a/muse2/muse/widgets/CMakeLists.txt
+++ b/muse2/muse/widgets/CMakeLists.txt
@@ -105,6 +105,7 @@ QT4_WRAP_CPP (widget_mocs
view.h
vscale.h
visibletracks.h
+ warn_bad_timing.h
)
##
@@ -142,6 +143,7 @@ file (GLOB widgets_ui_files
tracks_duplicate_base.ui
transformbase.ui
unusedwavefiles.ui
+ warn_bad_timing.ui
)
QT4_WRAP_UI (widget_ui_headers ${widgets_ui_files})
@@ -229,6 +231,7 @@ file (GLOB widgets_source_files
view.cpp
vscale.cpp
visibletracks.cpp
+ warn_bad_timing.cpp
)
##
diff --git a/muse2/muse/widgets/genset.cpp b/muse2/muse/widgets/genset.cpp
index 5c4b2dfb..7063b960 100644
--- a/muse2/muse/widgets/genset.cpp
+++ b/muse2/muse/widgets/genset.cpp
@@ -153,6 +153,7 @@ void GlobalSettingsConfig::updateSettings()
}
}
+ warnIfBadTimingCheckBox->setChecked(MusEGlobal::config.warnIfBadTiming);
midiSendInit->setChecked(MusEGlobal::config.midiSendInit);
midiWarnInitPending->setChecked(MusEGlobal::config.warnInitPending);
midiSendCtlDefaults->setChecked(MusEGlobal::config.midiSendCtlDefaults);
@@ -220,6 +221,7 @@ void GlobalSettingsConfig::updateSettings()
lmbDecreasesCheckBox->setChecked(MusEGlobal::config.leftMouseButtonCanDecrease);
rangeMarkerWithoutMMBCheckBox->setChecked(MusEGlobal::config.rangeMarkerWithoutMMB);
smartFocusCheckBox->setChecked(MusEGlobal::config.smartFocus);
+ velocityPerNoteCheckBox->setChecked(MusEGlobal::config.velocityPerNote);
addHiddenCheckBox->setChecked(MusEGlobal::config.addHiddenTracks);
unhideTracksCheckBox->setChecked(MusEGlobal::config.unhideTracks);
@@ -272,6 +274,7 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.useOutputLimiter = outputLimiterCheckBox->isChecked();
MusEGlobal::config.vstInPlace = vstInPlaceCheckBox->isChecked();
MusEGlobal::config.rtcTicks = rtcResolutions[rtcticks];
+ MusEGlobal::config.warnIfBadTiming = warnIfBadTimingCheckBox->isChecked();
MusEGlobal::config.midiSendInit = midiSendInit->isChecked();
MusEGlobal::config.warnInitPending = midiWarnInitPending->isChecked();
MusEGlobal::config.midiSendCtlDefaults = midiSendCtlDefaults->isChecked();
@@ -335,6 +338,7 @@ void GlobalSettingsConfig::apply()
MusEGlobal::config.leftMouseButtonCanDecrease = lmbDecreasesCheckBox->isChecked();
MusEGlobal::config.rangeMarkerWithoutMMB = rangeMarkerWithoutMMBCheckBox->isChecked();
MusEGlobal::config.smartFocus = smartFocusCheckBox->isChecked();
+ MusEGlobal::config.velocityPerNote = velocityPerNoteCheckBox->isChecked();
MusEGlobal::config.addHiddenTracks = addHiddenCheckBox->isChecked();
MusEGlobal::config.unhideTracks = unhideTracksCheckBox->isChecked();
diff --git a/muse2/muse/widgets/gensetbase.ui b/muse2/muse/widgets/gensetbase.ui
index 30d823ec..35c2d2b2 100644
--- a/muse2/muse/widgets/gensetbase.ui
+++ b/muse2/muse/widgets/gensetbase.ui
@@ -1116,7 +1116,7 @@ Adjusts responsiveness of audio controls and
<string>Ticks</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0" rowspan="2">
+ <item row="1" column="0" rowspan="2">
<widget class="QLabel" name="TextLabel3">
<property name="text">
<string>RTC Resolution
@@ -1127,7 +1127,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="1" column="1">
<widget class="QComboBox" name="rtcResolutionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1167,7 +1167,7 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
- <item row="1" column="1" rowspan="2">
+ <item row="2" column="1" rowspan="2">
<widget class="QComboBox" name="midiDivisionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1225,7 +1225,7 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="midiResLabel">
<property name="text">
<string>Midi Resolution
@@ -1236,7 +1236,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="TextLabel4">
<property name="text">
<string>Displayed Resolution
@@ -1247,7 +1247,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="4" column="1">
<widget class="QComboBox" name="guiDivisionSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1305,6 +1305,13 @@ Adjusts responsiveness of audio controls and
</item>
</widget>
</item>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="warnIfBadTimingCheckBox">
+ <property name="text">
+ <string>Warn if timer frequency is inadequate</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -1326,7 +1333,7 @@ Adjusts responsiveness of audio controls and
<property name="title">
<string>Behavior</string>
</property>
- <layout class="QGridLayout">
+ <layout class="QGridLayout" name="gridLayout7">
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1">
<property name="text">
@@ -1337,7 +1344,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="0" column="1">
+ <item row="0" column="2">
<widget class="QSpinBox" name="guiRefreshSelect">
<property name="suffix">
<string>/sec</string>
@@ -1363,7 +1370,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="1" column="1">
+ <item row="1" column="2">
<widget class="QCheckBox" name="oldStyleStopCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1376,7 +1383,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="2" column="0">
+ <item row="2" column="0" colspan="2">
<widget class="QLabel" name="textLabel1_4_2">
<property name="text">
<string>Move single armed track with selection</string>
@@ -1386,7 +1393,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="2" column="1">
+ <item row="2" column="2">
<widget class="QCheckBox" name="moveArmedCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1409,7 +1416,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="3" column="1">
+ <item row="3" column="2">
<widget class="QCheckBox" name="projectSaveCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1422,7 +1429,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="4" column="0" colspan="2">
<widget class="QLabel" name="TextLabel1_3">
<property name="toolTip">
<string/>
@@ -1432,7 +1439,7 @@ Adjusts responsiveness of audio controls and
</property>
</widget>
</item>
- <item row="4" column="1">
+ <item row="4" column="2">
<widget class="QCheckBox" name="popsDefStayOpenCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1449,7 +1456,7 @@ Otherwise, hold Ctrl to keep them open.</string>
</property>
</widget>
</item>
- <item row="5" column="0">
+ <item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="toolTip">
<string>In some areas, the middle mouse button decreases
@@ -1462,7 +1469,7 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="5" column="1">
+ <item row="5" column="2">
<widget class="QCheckBox" name="lmbDecreasesCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1475,7 +1482,14 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="6" column="1">
+ <item row="6" column="0" colspan="2">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Shift + Right click sets left range marker</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="2">
<widget class="QCheckBox" name="rangeMarkerWithoutMMBCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1488,42 +1502,35 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="6" column="0">
- <widget class="QLabel" name="label_3">
+ <item row="7" column="0" colspan="2">
+ <widget class="QLabel" name="label_4">
<property name="text">
- <string>Shift + Right click sets left range marker</string>
+ <string>Allow adding hidden tracks in track list menu</string>
</property>
</widget>
</item>
- <item row="7" column="1">
+ <item row="7" column="2">
<widget class="QCheckBox" name="addHiddenCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="7" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Allow adding hidden tracks in track list menu</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
+ <item row="8" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Unhide tracks when adding hidden tracks</string>
</property>
</widget>
</item>
- <item row="8" column="1">
+ <item row="8" column="2">
<widget class="QCheckBox" name="unhideTracksCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
- <item row="9" column="0">
+ <item row="9" column="0" colspan="2">
<widget class="QLabel" name="label5">
<property name="text">
<string>Smart focus</string>
@@ -1533,7 +1540,7 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="9" column="1">
+ <item row="9" column="2">
<widget class="QCheckBox" name="smartFocusCheckBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
@@ -1553,7 +1560,21 @@ left button behave like the middle button in such areas.</string>
</property>
</widget>
</item>
- <item row="10" column="0">
+ <item row="10" column="0" colspan="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Show midi velocity graphs per-note</string>
+ </property>
+ </widget>
+ </item>
+ <item row="10" column="2">
+ <widget class="QCheckBox" name="velocityPerNoteCheckBox">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1677,8 +1698,8 @@ left button behave like the middle button in such areas.</string>
<rect>
<x>0</x>
<y>0</y>
- <width>96</width>
- <height>26</height>
+ <width>474</width>
+ <height>410</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
diff --git a/muse2/muse/widgets/midi_warn_init_pending_impl.h b/muse2/muse/widgets/midi_warn_init_pending_impl.h
index d24ee129..3a4b8c50 100644
--- a/muse2/muse/widgets/midi_warn_init_pending_impl.h
+++ b/muse2/muse/widgets/midi_warn_init_pending_impl.h
@@ -37,4 +37,4 @@ public:
} // namespace MusEGui
-#endif \ No newline at end of file
+#endif
diff --git a/muse2/muse/widgets/musewidgetsplug.cpp b/muse2/muse/widgets/musewidgetsplug.cpp
index 70cdcd0f..967ab9ac 100644
--- a/muse2/muse/widgets/musewidgetsplug.cpp
+++ b/muse2/muse/widgets/musewidgetsplug.cpp
@@ -54,7 +54,7 @@ static const char* valu[] = {
};
MusEGlobal::GlobalConfigValues config = {
- 190, // globalAlphaBlend
+ 170, // globalAlphaBlend
{
QColor(0xff, 0xff, 0xff), // palette
QColor(0xff, 0xff, 0xff),
@@ -158,6 +158,8 @@ MusEGlobal::GlobalConfigValues config = {
true, // midiSendInit Send instrument initialization sequences
true, // warnInitPending Warn instrument initialization sequences pending
false, // midiSendCtlDefaults Send instrument controller defaults at position 0 if none in song
+ true, // warnIfBadTiming Warn if timer res not good
+ false, // velocityPerNote Whether to show per-note or all velocities
-60, // int minMeter;
-60.0, // double minSlider;
false, // use Jack freewheel
diff --git a/muse2/muse/widgets/warn_bad_timing.cpp b/muse2/muse/widgets/warn_bad_timing.cpp
new file mode 100644
index 00000000..38721d36
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.cpp
@@ -0,0 +1,33 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// warn_bad_timing.cpp
+// (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// 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; 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; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+
+#include "warn_bad_timing.h"
+
+namespace MusEGui {
+
+WarnBadTimingDialog::WarnBadTimingDialog()
+{
+ setupUi(this);
+}
+
+} // namespace MusEGui
+
diff --git a/muse2/muse/widgets/warn_bad_timing.h b/muse2/muse/widgets/warn_bad_timing.h
new file mode 100644
index 00000000..4e6ce77e
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.h
@@ -0,0 +1,41 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// warn_bad_timing.h
+// (C) Copyright 2012 Tim E. Real (terminator356 on users dot sourceforge dot net)
+//
+// 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; 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; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+#ifndef __WARN_BAD_TIMING_H__
+#define __WARN_BAD_TIMING_H__
+
+#include "ui_warn_bad_timing.h"
+
+namespace MusEGui {
+
+class WarnBadTimingDialog : public QDialog, public Ui::warnBadTimingBase
+{
+ Q_OBJECT
+
+public:
+ WarnBadTimingDialog();
+ bool dontAsk() const { return dontAskAgain->isChecked(); }
+ void setLabelText(const QString& s) { label->setText(s); }
+};
+
+} // namespace MusEGui
+
+#endif
diff --git a/muse2/muse/widgets/warn_bad_timing.ui b/muse2/muse/widgets/warn_bad_timing.ui
new file mode 100644
index 00000000..7c92850f
--- /dev/null
+++ b/muse2/muse/widgets/warn_bad_timing.ui
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>warnBadTimingBase</class>
+ <widget class="QDialog" name="warnBadTimingBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>371</width>
+ <height>207</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Bad timing</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Message here</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="dontAskAgain">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Don't ask me again</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Ok</set>
+ </property>
+ <property name="centerButtons">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>warnBadTimingBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>warnBadTimingBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>