diff options
31 files changed, 767 insertions, 326 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog index 106035de..bb156365 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,3 +1,23 @@ +03.06.2010 + * Fixed: Time signature editing problems in master track list and gui. (T356) + - Fixed SigEdit::outOfRange(). Added Sig::isValid(), and check it in LMaster::returnPressed() to fix crash with 0 n or z. + * Fixed: Marker/list problems. Double entries. Pianoroll/arranger timescale 'shift-left/right-click-to-add/del-marker' fixed. + Marker 'lock' (smpte/ticks) works now. Up/down buttons fixed. Marker list selection 'stays put' now + when adding or deleting markers. (T356) + * Fixed: Graphics corruption in arranger and track list when vertically scrolling. (T356) + - Changed rectangle to full w/h in 'shift down' section of View::setYPos() and TList::setYPos(). + Should not have to do this, but it cured my problems. No noticable change in speed. + - Arranger corruption occured on more than one machine with xorg nv, ati drivers. More severe arranger AND track list + corruption occured with proprietary drivers. Corruption is also observed in several other windows (ex. ladspa browser) + but there's not much I can do, the corruption is found in ordinary usage of QListView for example. + * Changed: Increased arranger vertical scroll step, was too slow to scroll. (T356) + * Possible fix: Auto-scroll in pianoroll and arranger take waaay too long to stop scrolling. (T356) + - Increased timer timeout from 40 to 80 ms in Canvas::scrollTimerDone(). Helped for me, on a 1.6Ghz P4... + * Changed: Ladspa plugin guis now have scroll bars. Helps when there are many controls. (T356) + - Still toying with the code a bit, please bear with me while I try to get it right. + * Started: Addition of MusE-native ladspa guis for dssi synths. (T356) + - No visible changes yet, just under the hood. Added class PluginIBase which is inherited by + DssiSynthIF and PluginI. Changed class PluginGui and DssiSynthIF to fit. 07.05.2010 * Fixed: Xml file trouble: Tag attributes not storing xml-friendly entities, trouble reloading song. (T356) - Fixed all usages of Xml::nput, ::put, ::tag, and ::etag. Discovered by Geoff B. diff --git a/muse/muse/app.cpp b/muse/muse/app.cpp index c896ff51..db4013e0 100644 --- a/muse/muse/app.cpp +++ b/muse/muse/app.cpp @@ -1583,6 +1583,55 @@ void MusE::loadProjectFile1(const QString& name, bool songTemplate, bool loadAll //showMixer(config.mixerVisible); showMixer1(config.mixer1Visible); showMixer2(config.mixer1Visible); + + // Added p3.3.43 Make sure the geometry is correct because showMixerX() will NOT + // set the geometry if the mixer has already been created, which caused a very + // skinny mixer if enough strips were added to cause a horizontal scrollbar to appear. + // If no horizontal scrollbar had appeared, then everything was displayed OK. + // FIXME: Resize not working for some reason if mixer is already created ! + if(mixer1) + { + if(mixer1->geometry().size() != config.mixer1.geometry.size()) + { + //printf("MusE::loadProjectFile1 resizing mixer1 x:%d y:%d w:%d h:%d\n", config.mixer1.geometry.x(), + // config.mixer1.geometry.y(), + // config.mixer1.geometry.width(), + // config.mixer1.geometry.height() + // ); + mixer1->resize(config.mixer1.geometry.size()); + } + if(mixer1->geometry().topLeft() != config.mixer1.geometry.topLeft()) + { + //printf("MusE::loadProjectFile1 moving mixer1 x:%d y:%d w:%d h:%d\n", config.mixer1.geometry.x(), + // config.mixer1.geometry.y(), + // config.mixer1.geometry.width(), + // config.mixer1.geometry.height() + // ); + mixer1->move(config.mixer1.geometry.topLeft()); + } + } + if(mixer2) + { + if(mixer2->geometry().size() != config.mixer2.geometry.size()) + { + //printf("MusE::loadProjectFile1 resizing mixer2 x:%d y:%d w:%d h:%d\n", config.mixer2.geometry.x(), + // config.mixer2.geometry.y(), + // config.mixer2.geometry.width(), + // config.mixer2.geometry.height() + // ); + mixer2->resize(config.mixer2.geometry.size()); + } + if(mixer2->geometry().topLeft() != config.mixer2.geometry.topLeft()) + { + //printf("MusE::loadProjectFile1 moving mixer2 x:%d y:%d w:%d h:%d\n", config.mixer2.geometry.x(), + // config.mixer2.geometry.y(), + // config.mixer2.geometry.width(), + // config.mixer2.geometry.height() + // ); + mixer2->move(config.mixer2.geometry.topLeft()); + } + } + showMarker(config.markerVisible); resize(config.geometryMain.size()); move(config.geometryMain.topLeft()); @@ -1880,7 +1929,10 @@ void MusE::showMarker(bool flag) if (markerView == 0) { markerView = new MarkerView(this); - connect(arranger, SIGNAL(addMarker(int)), markerView, SLOT(addMarker(int))); + // Removed p3.3.43 + // Song::addMarker() already emits a 'markerChanged'. + //connect(arranger, SIGNAL(addMarker(int)), markerView, SLOT(addMarker(int))); + connect(markerView, SIGNAL(closed()), SLOT(markerClosed())); toplevels.push_back(Toplevel(Toplevel::MARKER, (unsigned long)(markerView), markerView)); markerView->show(); diff --git a/muse/muse/arranger/arranger.cpp b/muse/muse/arranger/arranger.cpp index 6cd44af7..ba26a167 100644 --- a/muse/muse/arranger/arranger.cpp +++ b/muse/muse/arranger/arranger.cpp @@ -284,7 +284,10 @@ Arranger::Arranger(QMainWindow* parent, const char* name) hscroll = new ScrollScale(-1000, -10, xscale, song->len(), Horizontal, editor, -offset); ib->setFixedHeight(hscroll->sizeHint().height()); - vscroll = new QScrollBar(1, 20*20, 1, 5, 0, Vertical, editor); + // Changed p3.3.43 Too small steps for me... + //vscroll = new QScrollBar(1, 20*20, 1, 5, 0, Vertical, editor); + vscroll = new QScrollBar(1, 20*20, 5, 25, 0, Vertical, editor); + list->setScroll(vscroll); QValueList<int> vallist; @@ -342,7 +345,9 @@ Arranger::Arranger(QMainWindow* parent, const char* name) connect(canvas, SIGNAL(toolChanged(int)), SIGNAL(toolChanged(int))); // connect(song, SIGNAL(posChanged(int, unsigned, bool)), SLOT(seek())); - connect(time, SIGNAL(addMarker(int)), SIGNAL(addMarker(int))); + // Removed p3.3.43 + // Song::addMarker() already emits a 'markerChanged'. + //connect(time, SIGNAL(addMarker(int)), SIGNAL(addMarker(int))); configChanged(); // set configuration values showTrackInfo(showTrackinfoFlag); diff --git a/muse/muse/arranger/arranger.h b/muse/muse/arranger/arranger.h index c43320cb..5621a7ca 100644 --- a/muse/muse/arranger/arranger.h +++ b/muse/muse/arranger/arranger.h @@ -177,7 +177,7 @@ class Arranger : public QWidget { void dropMidiFile(const QString&); void startEditor(PartList*, int); void toolChanged(int); - void addMarker(int); + //void addMarker(int); void setUsedTool(int); diff --git a/muse/muse/arranger/tlist.cpp b/muse/muse/arranger/tlist.cpp index e3c1a680..a0379e1b 100644 --- a/muse/muse/arranger/tlist.cpp +++ b/muse/muse/arranger/tlist.cpp @@ -177,6 +177,8 @@ void TList::paint(const QRect& r) p.drawTiledPixmap(rect, bgPixmap, QPoint(rect.x(), ypos + rect.y())); p.setClipRegion(rect); + //printf("TList::paint hasClipping:%d\n", p.hasClipping()); // Tested true. + int y = rect.y(); int w = rect.width(); int h = rect.height(); @@ -185,7 +187,7 @@ void TList::paint(const QRect& r) //--------------------------------------------------- // Tracks - //--------------------------------------------------- + //--------------------------------------------------- TrackList* l = song->tracks(); int idx = 0; @@ -1371,21 +1373,41 @@ void TList::setYPos(int y) if (pm.isNull()) return; if (!pmValid) { + //printf("TList::setYPos y:%d delta:%d pmValid is false - redrawing...\n", y, delta); redraw(); return; } int w = width(); int h = height(); QRect r; + //printf("TList::setYPos y:%d delta:%d w:%d h:%d\n", y, delta, w, h); + if (delta >= h || delta <= -h) + { + //printf("TList::setYPos delta >= h || delta <= -h\n"); r = QRect(0, 0, w, h); + } else if (delta < 0) { // shift up + //printf("TList::setYPos delta < 0 : shift up\n"); bitBlt(&pm, 0, 0, &pm, 0, -delta, w, h + delta, CopyROP, true); r = QRect(0, h + delta, w, -delta); } else { // shift down + //printf("TList::setYPos delta !< 0 : shift down\n"); bitBlt(&pm, 0, delta, &pm, 0, 0, w, h-delta, CopyROP, true); - r = QRect(0, 0, w, delta); + + // NOTE: June 2 2010: On my machine with an old NV V8200 + prop drivers (curr 96.43.11), + // this is a problem. There is severe graphical corruption. + // Not just here but several other windows (ex. ladspa browser), + // and I believe (?) other QT3 apps. QT4 apps don't do it. + // Neither does it happen when xorg drivers used. + // + // FIXME: This change cures it for me, but we shouldn't leave this in - shouldn't need to do this... + // + //r = QRect(0, 0, w, delta); + // Changed p3.3.43 + r = QRect(0, 0, w, h); + } paint(r); update(); diff --git a/muse/muse/audio.cpp b/muse/muse/audio.cpp index 5172447e..9a7029db 100644 --- a/muse/muse/audio.cpp +++ b/muse/muse/audio.cpp @@ -339,7 +339,6 @@ void Audio::process(unsigned frames) int jackState = audioDevice->getState(); - // Added by Tim. p3.3.20 //if(debugMsg) // printf("Audio::process Current state:%s jackState:%s\n", audioStates[state], audioStates[jackState]); @@ -356,6 +355,16 @@ void Audio::process(unsigned frames) startRolling(); } else if (isPlaying() && jackState == STOP) { + // p3.3.43 Make sure to stop bounce and freewheel mode, for example if user presses stop + // in QJackCtl before right-hand marker is reached (which is handled below). + //printf("Audio::process isPlaying() && jackState == STOP\n"); + //if (_bounce) + //{ + //printf(" stopping bounce...\n"); + // _bounce = false; + // write(sigFd, "F", 1); + //} + stopRolling(); } else if (state == START_PLAY && jackState == STOP) { @@ -414,7 +423,6 @@ void Audio::process(unsigned frames) && !(song->record() || _bounce || song->loop())) { - // Added by Tim. p3.3.20 //if(debugMsg) // printf("Audio::process curTickPos >= song->len\n"); @@ -484,7 +492,6 @@ void Audio::process(unsigned frames) syncTime = curTime(); frameOffset = syncFrame - samplePos; - // Added by Tim. p3.3.13 //printf("Audio::process calling process1:\n"); process1(samplePos, offset, frames); @@ -593,7 +600,6 @@ void Audio::process1(unsigned samplePos, unsigned offset, unsigned frames) float data[frames * channels]; for (int i = 0; i < channels; ++i) buffer[i] = data + i * frames; - // Added by Tim. p3.3.13 //printf("Audio::process1 calling track->copyData for track:%s\n", track->name().latin1()); // p3.3.38 @@ -638,7 +644,9 @@ void Audio::processMsg(AudioMsg* msg) msg->snode->addPlugin(msg->plugin, msg->ival); break; case AUDIO_SET_PLUGIN_CTRL_VAL: - msg->plugin->track()->setPluginCtrlVal(msg->ival, msg->dval); + //msg->plugin->track()->setPluginCtrlVal(msg->ival, msg->dval); + // p3.3.43 + msg->snode->setPluginCtrlVal(msg->ival, msg->dval); break; case AUDIO_SWAP_CONTROLLER_IDX: msg->snode->swapControllerIDX(msg->a, msg->b); diff --git a/muse/muse/audio.h b/muse/muse/audio.h index cd0af154..fb51ca03 100644 --- a/muse/muse/audio.h +++ b/muse/muse/audio.h @@ -243,7 +243,8 @@ class Audio { void msgResetMidiDevices(); void msgIdle(bool); void msgBounce(); - void msgSetPluginCtrlVal(PluginI* plugin, int param, double val); + //void msgSetPluginCtrlVal(PluginI* /*plugin*/, int /*param*/, double /*val*/); + void msgSetPluginCtrlVal(AudioTrack*, int /*param*/, double /*val*/); void msgSwapControllerIDX(AudioTrack*, int, int); void msgClearControllerEvents(AudioTrack*, int); void msgSeekPrevACEvent(AudioTrack*, int); diff --git a/muse/muse/driver/jack.cpp b/muse/muse/driver/jack.cpp index 2926e281..3d0d021d 100644 --- a/muse/muse/driver/jack.cpp +++ b/muse/muse/driver/jack.cpp @@ -306,7 +306,6 @@ static int processSync(jack_transport_state_t state, jack_position_t* pos, void* audioState = Audio::PLAY; break; case JackTransportStarting: - // Added by Tim. p3.3.6 //printf("processSync JackTransportStarting\n"); audioState = Audio::START_PLAY; @@ -315,7 +314,6 @@ static int processSync(jack_transport_state_t state, jack_position_t* pos, void* // FIXME: Quick and dirty hack to support both Jack-1 and Jack-2 // Really need a config check of version... case 4: - // Added by Tim. p3.3.6 //printf("processSync JackTransportNetStarting\n"); audioState = Audio::START_PLAY; @@ -323,14 +321,12 @@ static int processSync(jack_transport_state_t state, jack_position_t* pos, void* } unsigned frame = pos->frame; - // Added by Tim. p3.3.6 //printf("processSync valid:%d frame:%d\n", pos->valid, frame); // p3.3.23 //printf("Jack processSync() before audio->sync frame:%d\n", frame); //return audio->sync(audioState, frame); int rv = audio->sync(audioState, frame); - // p3.3.23 //printf("Jack processSync() after audio->sync frame:%d\n", frame); return rv; } @@ -345,7 +341,6 @@ static void timebase_callback(jack_transport_state_t /* state */, int /* new_pos */, void*) { - // p3.3.29 //printf("Jack timebase_callback pos->frame:%u audio->tickPos:%d song->cpos:%d\n", pos->frame, audio->tickPos(), song->cpos()); // p3.3.27 @@ -1759,7 +1754,6 @@ int JackAudioDevice::getState() case JackTransportRolling: return Audio::PLAY; case JackTransportStarting: - // Added by Tim. p3.3.6 //printf("JackAudioDevice::getState JackTransportStarting\n"); return Audio::START_PLAY; @@ -1767,7 +1761,6 @@ int JackAudioDevice::getState() // FIXME: Quick and dirty hack to support both Jack-1 and Jack-2 // Really need a config check of version... case 4: - // Added by Tim. p3.3.6 //printf("JackAudioDevice::getState JackTransportNetStarting\n"); return Audio::START_PLAY; diff --git a/muse/muse/dssihost.cpp b/muse/muse/dssihost.cpp index ec2e94a7..25b5b9b2 100644 --- a/muse/muse/dssihost.cpp +++ b/muse/muse/dssihost.cpp @@ -1207,7 +1207,7 @@ DssiSynthIF::~DssiSynthIF() // getParameter //--------------------------------------------------------- -float DssiSynthIF::getParameter(unsigned long n) +float DssiSynthIF::getParameter(unsigned long n) const { if(n >= synth->_controlInPorts) { @@ -3023,6 +3023,31 @@ int DssiSynthIF::totalInChannels() const return synth->_inports; } +//-------------------------------- +// Methods for PluginIBase: +//-------------------------------- + +bool DssiSynthIF::on() const { return true; } // Synth is not part of a rack plugin chain. Always on. +void DssiSynthIF::setOn(bool /*val*/) { } +int DssiSynthIF::pluginID() { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->UniqueID : 0; } +int DssiSynthIF::id() { return 0; } // Synth is not part of a rack plugin chain. Always 0. +QString DssiSynthIF::pluginLabel() const { return (synth && synth->dssi) ? QString(synth->dssi->LADSPA_Plugin->Label) : QString(); } +QString DssiSynthIF::name() const { return synti->name(); } +AudioTrack* DssiSynthIF::track() { return (AudioTrack*)synti; } +void DssiSynthIF::enableController(int i, bool v) { controls[i].enCtrl = v; } +bool DssiSynthIF::controllerEnabled(int i) const { return controls[i].enCtrl; } +bool DssiSynthIF::controllerEnabled2(int i) const { return controls[i].en2Ctrl; } +void DssiSynthIF::updateControllers() { } +void DssiSynthIF::writeConfiguration(int /*level*/, Xml& /*xml*/) { } +bool DssiSynthIF::readConfiguration(Xml& /*xml*/, bool /*readPreset*/) { return false; } +int DssiSynthIF::parameters() const { return synth ? synth->_controlInPorts : 0; } +void DssiSynthIF::setParam(int i, double val) { setParameter(i, val); } +double DssiSynthIF::param(int i) const { return getParameter(i); } +const char* DssiSynthIF::paramName(int i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[i] : 0; } +//LADSPA_PortRangeHint DssiSynthIF::range(int i) { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } +LADSPA_PortRangeHint DssiSynthIF::range(int i) { return synth->dssi->LADSPA_Plugin->PortRangeHints[i]; } + + #else //DSSI_SUPPORT void initDSSI() {} #endif diff --git a/muse/muse/dssihost.h b/muse/muse/dssihost.h index deaa87b9..47884515 100644 --- a/muse/muse/dssihost.h +++ b/muse/muse/dssihost.h @@ -32,6 +32,7 @@ #include "osc.h" #endif +#include "ladspa.h" #include <dssi.h> #include <alsa/asoundlib.h> @@ -39,7 +40,7 @@ #include "synth.h" #include "stringparam.h" -//#include "plugin.h" +#include "plugin.h" #define DSSI_PARAMSAVE_VERSION_MAJOR 0 #define DSSI_PARAMSAVE_VERSION_MINOR 1 @@ -110,7 +111,8 @@ class DssiSynth : public Synth { // VSTi synthesizer instance //--------------------------------------------------------- -class DssiSynthIF : public SynthIF +//class DssiSynthIF : public SynthIF +class DssiSynthIF : public SynthIF, public PluginIBase { //bool _guiVisible; DssiSynth* synth; @@ -192,7 +194,7 @@ class DssiSynthIF : public SynthIF //virtual void write(Xml& xml) const; virtual void write(int level, Xml& xml) const; - virtual float getParameter(unsigned long /*idx*/); + virtual float getParameter(unsigned long /*idx*/) const; virtual void setParameter(unsigned long /*idx*/, float /*value*/); //virtual int getControllerInfo(int, const char**, int*, int*, int*) { return 0; } @@ -221,6 +223,28 @@ class DssiSynthIF : public SynthIF //int oscExiting(); #endif + //------------------------- + // Methods for PluginIBase: + //------------------------- + bool on() const; + void setOn(bool /*val*/); + int pluginID(); + int id(); + QString pluginLabel() const; + QString name() const; + AudioTrack* track(); + void enableController(int /*i*/, bool v = true); + bool controllerEnabled(int /*i*/) const; + bool controllerEnabled2(int /*i*/) const; + void updateControllers(); + void writeConfiguration(int /*level*/, Xml& /*xml*/); + bool readConfiguration(Xml& /*xml*/, bool readPreset=false); + int parameters() const; + void setParam(int /*i*/, double /*val*/); + double param(int /*i*/) const; + const char* paramName(int /*i*/); + LADSPA_PortRangeHint range(int /*i*/); + friend class DssiSynth; }; diff --git a/muse/muse/marker/marker.cpp b/muse/muse/marker/marker.cpp index 28de52d9..eee0be02 100644 --- a/muse/muse/marker/marker.cpp +++ b/muse/muse/marker/marker.cpp @@ -47,8 +47,6 @@ void Marker::read(Xml& xml) else if (tag == "name") { _name = xml.s2(); - //p3.3.42 - //printf("Marker::read name:%s\n", _name.latin1()); } break; case Xml::TagEnd: diff --git a/muse/muse/marker/markerview.cpp b/muse/muse/marker/markerview.cpp index 281f0872..1c9eee77 100644 --- a/muse/muse/marker/markerview.cpp +++ b/muse/muse/marker/markerview.cpp @@ -306,9 +306,14 @@ void MarkerView::addMarker() void MarkerView::addMarker(int i) { if( i==-1 ) i = song->cpos(); - Marker* m = song->addMarker(QString(""), i, false); - MarkerItem* newItem = new MarkerItem(table, m); - table->setSelected(newItem, true); + + // Changed p3.3.43 Let Song::addMarker emit markerChanged(MARKER_ADD) + // and handle it in MarkerView::markerChanged(int) + //Marker* m = song->addMarker(QString(""), i, false); + //MarkerItem* newItem = new MarkerItem(table, m); + //table->setSelected(newItem, true); + // + song->addMarker(QString(""), i, false); } //--------------------------------------------------------- @@ -320,7 +325,10 @@ void MarkerView::deleteMarker() MarkerItem* item = (MarkerItem*)table->selectedItem(); if (item) { song->removeMarker(item->marker()); - delete item; + + // Removed p3.3.43 Let Song::removeMarker emit markerChanged(MARKER_REMOVE) + // and handle it in MarkerView::markerChanged(int) + //delete item; } } @@ -329,16 +337,57 @@ void MarkerView::deleteMarker() //--------------------------------------------------------- void MarkerView::updateList() +{ + + // Added p3.3.43 + // Remember the next selected item, or else any new item added. + MarkerList* marker = song->marker(); + MarkerItem* item = (MarkerItem*)table->selectedItem(); + MarkerItem* nextitem = item ? (MarkerItem*)item->nextSibling() : 0; + //Marker* selm = item->marker(); + //Marker* nextselm = nextitem->marker(); + Marker* selm = nextitem ? nextitem->marker() : 0; + for (iMarker i = marker->begin(); i != marker->end(); ++i) { + Marker* m = &i->second; + bool found = false; + MarkerItem* item = (MarkerItem*)table->firstChild(); + while (item) + { + if (item->marker() == m) + { + found = true; + break; + } + item = (MarkerItem*)item->nextSibling(); + } + // Anything new found in the marker list? + if(!found) + selm = m; + } + table->clear(); - MarkerList* marker = song->marker(); - for (iMarker i = marker->begin(); i != marker->end(); ++i) { + //MarkerList* marker = song->marker(); + for (iMarker i = marker->begin(); i != marker->end(); ++i) + { Marker* m = &i->second; - QString tick; - tick.setNum(i->first); - new MarkerItem(table, m); + + // Changed p3.3.43 + //QString tick; + //tick.setNum(i->first); + //new MarkerItem(table, m); + MarkerItem* item = new MarkerItem(table, m); + if(m == selm) + { + m->setCurrent(true); + table->setSelected(item, true); + } + else + { + m->setCurrent(false); } } +} //--------------------------------------------------------- // markerSelected @@ -364,6 +413,9 @@ void MarkerView::markerSelectionChanged() editName->setEnabled(true); lock->setOn(item->lock()); lock->setEnabled(true); + + //printf("MarkerView::markerSelectionChanged item->lock:%d\n", item->lock()); + editSMPTE->setEnabled(item->lock()); editTick->setEnabled(!item->lock()); } @@ -426,23 +478,42 @@ void MarkerView::lockChanged(bool lck) //--------------------------------------------------------- void MarkerView::markerChanged(int val) +{ + //if (val != Song::MARKER_CUR) + // return; + // p3.3.43 + switch(val) { - if (val != Song::MARKER_CUR) - return; - MarkerList* marker = song->marker(); - for (iMarker i = marker->begin(); i != marker->end(); ++i) { - if (i->second.current()) { - MarkerItem* item = (MarkerItem*)table->firstChild(); - while (item) { - if (item->marker() == &i->second) { - table->setSelected(item, true); - return; - } - item = (MarkerItem*)item->nextSibling(); - } - } - } - } + // MARKER_CUR, MARKER_ADD, MARKER_REMOVE, MARKER_NAME, + // MARKER_TICK, MARKER_LOCK + case Song::MARKER_ADD: + case Song::MARKER_REMOVE: + updateList(); + break; // Try falling through and let it try to select something. No, let updateList() do it... + + case Song::MARKER_CUR: + { + + MarkerList* marker = song->marker(); + for (iMarker i = marker->begin(); i != marker->end(); ++i) { + if (i->second.current()) { + MarkerItem* item = (MarkerItem*)table->firstChild(); + while (item) { + if (item->marker() == &i->second) { + table->setSelected(item, true); + return; + } + item = (MarkerItem*)item->nextSibling(); + } + } + } + } + break; + + default: + break; + } +} void MarkerView::nextMarker() { diff --git a/muse/muse/master/lmaster.cpp b/muse/muse/master/lmaster.cpp index f0a2704f..f27976e7 100644 --- a/muse/muse/master/lmaster.cpp +++ b/muse/muse/master/lmaster.cpp @@ -506,21 +506,29 @@ void LMaster::returnPressed() // // SigEvent, value changed: // - else if (editedItem->getType() == LMASTER_SIGEVENT && editorColumn == LMASTER_VAL_COL) { + else if (editedItem->getType() == LMASTER_SIGEVENT && editorColumn == LMASTER_VAL_COL) + { Sig newSig = sig_editor->sig(); + sig_editor->hide(); - LMasterSigEventItem* e = (LMasterSigEventItem*) editedItem; - int tick = e->tick(); - if (!editingNewItem) { - song->startUndo(); - if (tick > 0) - audio->msgRemoveSig(tick, e->z(), e->n(), false); - audio->msgAddSig(tick, newSig.z, newSig.n, false); - song->endUndo(SC_SIG); - } - else - audio->msgAddSig(tick, newSig.z, newSig.n, true); - } + + // Added p3.3.43 Prevents aborting with 0 z or n. + if(newSig.isValid()) + { + + LMasterSigEventItem* e = (LMasterSigEventItem*) editedItem; + int tick = e->tick(); + if (!editingNewItem) { + song->startUndo(); + if (tick > 0) + audio->msgRemoveSig(tick, e->z(), e->n(), false); + audio->msgAddSig(tick, newSig.z, newSig.n, false); + song->endUndo(SC_SIG); + } + else + audio->msgAddSig(tick, newSig.z, newSig.n, true); + } + } view->setFocus(); // No item edited now: diff --git a/muse/muse/mixer/amixer.cpp b/muse/muse/mixer/amixer.cpp index da51f8f6..07def5cc 100644 --- a/muse/muse/mixer/amixer.cpp +++ b/muse/muse/mixer/amixer.cpp @@ -392,7 +392,6 @@ void AudioMixerApp::updateMixer(UpdateAction action) void AudioMixerApp::configChanged() { - // Added by Tim. p3.3.6 //printf("AudioMixerApp::configChanged\n"); songChanged(SC_CONFIG); diff --git a/muse/muse/plugin.cpp b/muse/muse/plugin.cpp index a8b7fa5a..9f32b70d 100644 --- a/muse/muse/plugin.cpp +++ b/muse/muse/plugin.cpp @@ -18,6 +18,7 @@ #include <qlabel.h> #include <qsignalmapper.h> #include <qpushbutton.h> +#include <qscrollview.h> #include <qlistview.h> #include <qtoolbar.h> #include <qtoolbutton.h> @@ -1486,8 +1487,13 @@ void PluginI::setID(int i) void PluginI::updateControllers() { + if(!_track) + return; + for(int i = 0; i < controlPorts; ++i) - audio->msgSetPluginCtrlVal(this, genACnum(_id, i), controls[i].val); + //audio->msgSetPluginCtrlVal(this, genACnum(_id, i), controls[i].val); + // p3.3.43 + audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); } //--------------------------------------------------------- @@ -2204,6 +2210,8 @@ void PluginI::apply(int n) // Since we are now in the audio thread context, there's no need to send a message, // just modify directly. //audio->msgSetPluginCtrlVal(this, genACnum(_id, k), controls[k].val); + // p3.3.43 + //audio->msgSetPluginCtrlVal(_track, genACnum(_id, k), controls[k].val); _track->setPluginCtrlVal(genACnum(_id, k), v.value); // Record automation. @@ -2802,7 +2810,9 @@ const char* presetBypassText = "Click this button to bypass effect unit"; // PluginGui //--------------------------------------------------------- -PluginGui::PluginGui(PluginI* p) +//PluginGui::PluginGui(PluginI* p) +// p3.3.43 +PluginGui::PluginGui(PluginIBase* p) : QMainWindow(0) { gw = 0; @@ -2839,7 +2849,8 @@ PluginGui::PluginGui(PluginI* p) QWhatsThis::add(fileSave, tr(presetSaveText)); QString id; - id.setNum(plugin->plugin()->id()); + //id.setNum(plugin->plugin()->id()); + id.setNum(plugin->pluginID()); QString name(museGlobalShare + QString("/plugins/") + id + QString(".ui")); QFile uifile(name); if (uifile.exists()) { @@ -2940,15 +2951,28 @@ PluginGui::PluginGui(PluginI* p) updateValues(); // otherwise the GUI won't have valid data } else { - mw = new QWidget(this); - setCentralWidget(mw); + //mw = new QWidget(this); + //setCentralWidget(mw); + // p3.4.43 + view = new QScrollView(this); + setCentralWidget(view); + mw = new QWidget(view); + view->setResizePolicy(QScrollView::AutoOneFit); + //view->setVScrollBarMode(QScrollView::AlwaysOff); + view->addChild(mw); + QGridLayout* grid = new QGridLayout(mw); grid->setSpacing(2); int n = plugin->parameters(); params = new GuiParam[n]; - resize(280, n*20+30); + // Changed p3.3.43 + //resize(280, n*20+30); + //int nh = n*20+40; + //if(nh > 760) + // nh = 760; + //resize(280, nh); //int style = Slider::BgTrough | Slider::BgSlot; QFontMetrics fm = fontMetrics(); @@ -3045,6 +3069,9 @@ PluginGui::PluginGui(PluginI* p) connect(params[i].actuator, SIGNAL(checkboxRightClicked(const QPoint &, int)), SLOT(ctrlRightClicked(const QPoint &, int))); } } + // p3.3.43 + resize(280, height()); + grid->setColStretch(2, 10); } connect(heartBeatTimer, SIGNAL(timeout()), SLOT(heartBeat())); @@ -3078,12 +3105,9 @@ void PluginGui::heartBeat() void PluginGui::ctrlPressed(int param) { AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at != AUTO_OFF) plugin->enableController(param, false); @@ -3104,17 +3128,33 @@ void PluginGui::ctrlPressed(int param) val = rint(val); plugin->setParam(param, val); ((DoubleLabel*)params[param].label)->setValue(val); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + + // p3.3.43 + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + if(track) + { + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + track->startAutoRecord(id, val); + } } else if(params[param].type == GuiParam::GUI_SWITCH) { double val = (double)((CheckBox*)params[param].actuator)->isChecked(); plugin->setParam(param, val); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + + // p3.3.43 + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + if(track) + { + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + track->startAutoRecord(id, val); + } } } @@ -3125,12 +3165,9 @@ void PluginGui::ctrlPressed(int param) void PluginGui::ctrlReleased(int param) { AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } // Special for switch - don't enable controller until transport stopped. if(at != AUTO_WRITE && ((params[param].type != GuiParam::GUI_SWITCH @@ -3168,7 +3205,8 @@ void PluginGui::ctrlRightClicked(const QPoint &p, int param) { int id = plugin->id(); if(id != -1) - song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); + //song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); + song->execAutomationCtlPopup(plugin->track(), p, genACnum(id, param)); } //--------------------------------------------------------- @@ -3176,14 +3214,11 @@ void PluginGui::ctrlRightClicked(const QPoint &p, int param) //--------------------------------------------------------- void PluginGui::sliderChanged(double val, int param) - { +{ AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) plugin->enableController(param, false); @@ -3202,25 +3237,28 @@ void PluginGui::sliderChanged(double val, int param) return; id = genACnum(id, param); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + // p3.3.43 + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); if(track) + { + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + track->recordAutomation(id, val); - } + } +} //--------------------------------------------------------- // labelChanged //--------------------------------------------------------- void PluginGui::labelChanged(double val, int param) - { +{ AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) plugin->enableController(param, false); @@ -3240,10 +3278,18 @@ void PluginGui::labelChanged(double val, int param) return; id = genACnum(id, param); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + + // p3.3.43 + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + if(track) + { + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + track->startAutoRecord(id, val); - } + } +} //--------------------------------------------------------- // load @@ -3252,7 +3298,8 @@ void PluginGui::labelChanged(double val, int param) void PluginGui::load() { QString s("presets/plugins/"); - s += plugin->plugin()->label(); + //s += plugin->plugin()->label(); + s += plugin->pluginLabel(); s += "/"; QString fn = getOpenFileName(s, preset_file_pattern, @@ -3316,7 +3363,8 @@ ende: void PluginGui::save() { QString s("presets/plugins/"); - s += plugin->plugin()->label(); + //s += plugin->plugin()->label(); + s += plugin->pluginLabel(); s += "/"; //QString fn = getSaveFileName(s, preset_file_pattern, this, @@ -3541,18 +3589,15 @@ void PluginGui::updateControls() //--------------------------------------------------------- void PluginGui::guiParamChanged(int idx) - { +{ QWidget* w = gw[idx].widget; int param = gw[idx].param; int type = gw[idx].type; AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) plugin->enableController(param, false); @@ -3595,12 +3640,18 @@ void PluginGui::guiParamChanged(int idx) } int id = plugin->id(); - if(id != -1) - { + if(track && id != -1) + { id = genACnum(id, param); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); - if(track) - { + + // p3.3.43 + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + + //if(track) + //{ + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + switch(type) { case GuiWidgets::DOUBLE_LABEL: @@ -3611,10 +3662,10 @@ void PluginGui::guiParamChanged(int idx) track->recordAutomation(id, val); break; } - } - } + //} + } plugin->setParam(param, val); - } +} //--------------------------------------------------------- // guiParamPressed @@ -3625,12 +3676,9 @@ void PluginGui::guiParamPressed(int idx) int param = gw[idx].param; AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at != AUTO_OFF) plugin->enableController(param, false); @@ -3669,12 +3717,9 @@ void PluginGui::guiParamReleased(int idx) int type = gw[idx].type; AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } // Special for switch - don't enable controller until transport stopped. if(at != AUTO_WRITE && (type != GuiWidgets::QCHECKBOX @@ -3717,12 +3762,9 @@ void PluginGui::guiSliderPressed(int idx) QWidget *w = gw[idx].widget; AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } int id = plugin->id(); @@ -3736,7 +3778,11 @@ void PluginGui::guiSliderPressed(int idx) double val = ((Slider*)w)->value(); plugin->setParam(param, val); - audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + + //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val); + // p3.3.43 + audio->msgSetPluginCtrlVal(track, id, val); + track->startAutoRecord(id, val); // Needed so that paging a slider updates a label or other buddy control. @@ -3772,12 +3818,9 @@ void PluginGui::guiSliderReleased(int idx) QWidget *w = gw[idx].widget; AutomationType at = AUTO_OFF; - AudioTrack* track = 0; - if(plugin->track()) - { - track = plugin->track(); + AudioTrack* track = plugin->track(); + if(track) at = track->automationType(); - } if(at != AUTO_WRITE || (!audio->isPlaying() && at == AUTO_TOUCH)) plugin->enableController(param, true); @@ -3802,7 +3845,8 @@ void PluginGui::guiSliderRightClicked(const QPoint &p, int idx) int param = gw[idx].param; int id = plugin->id(); if(id != -1) - song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); + //song->execAutomationCtlPopup((AudioTrack*)plugin->track(), p, genACnum(id, param)); + song->execAutomationCtlPopup(plugin->track(), p, genACnum(id, param)); } //--------------------------------------------------------- diff --git a/muse/muse/plugin.h b/muse/muse/plugin.h index 8461b7f8..5212e179 100644 --- a/muse/muse/plugin.h +++ b/muse/muse/plugin.h @@ -43,6 +43,7 @@ class QWidget; // class QLabel; class Slider; class QListView; +class QScrollView; class QToolButton; class DoubleLabel; class AudioTrack; @@ -226,6 +227,69 @@ struct GuiWidgets { class PluginI; +/* +class PluginBase +{ + public: + bool on() const { return _on; } + void setOn(bool val) { _on = val; } + int pluginID() { return plugin()->id(); } + int id() { return _id; } + QString pluginLabel() const { return _plugin->label(); } + QString name() const { return _name; } + + AudioTrack* track() { return _track; } + + void enableController(int i, bool v = true) { controls[i].enCtrl = v; } + bool controllerEnabled(int i) const { return controls[i].enCtrl; } + bool controllerEnabled2(int i) const { return controls[i].en2Ctrl; } + void updateControllers(); + + void writeConfiguration(int level, Xml& xml); + bool readConfiguration(Xml& xml, bool readPreset=false); + + int parameters() const { return controlPorts; } + void setParam(int i, double val) { controls[i].tmpVal = val; } + double param(int i) const { return controls[i].val; } + const char* paramName(int i) { return _plugin->portName(controls[i].idx); } + LADSPA_PortRangeHint range(int i) + { + return _plugin->range(controls[i].idx); + } +}; +*/ + +//--------------------------------------------------------- +// PluginIBase +//--------------------------------------------------------- + +class PluginIBase +{ + public: + virtual bool on() const = 0; + virtual void setOn(bool /*val*/) = 0; + virtual int pluginID() = 0; + virtual int id() = 0; + virtual QString pluginLabel() const = 0; + virtual QString name() const = 0; + + virtual AudioTrack* track() = 0; + + virtual void enableController(int /*i*/, bool v = true) = 0; + virtual bool controllerEnabled(int /*i*/) const = 0; + virtual bool controllerEnabled2(int /*i*/) const = 0; + virtual void updateControllers() = 0; + + virtual void writeConfiguration(int /*level*/, Xml& /*xml*/) = 0; + virtual bool readConfiguration(Xml& /*xml*/, bool readPreset=false) = 0; + + virtual int parameters() const = 0; + virtual void setParam(int /*i*/, double /*val*/) = 0; + virtual double param(int /*i*/) const = 0; + virtual const char* paramName(int /*i*/) = 0; + virtual LADSPA_PortRangeHint range(int /*i*/) = 0; +}; + //--------------------------------------------------------- // PluginGui //--------------------------------------------------------- @@ -233,13 +297,16 @@ class PluginI; class PluginGui : public QMainWindow { Q_OBJECT - PluginI* plugin; // plugin instance + //PluginI* plugin; // plugin instance + PluginIBase* plugin; // plugin instance + GuiParam* params; int nobj; // number of widgets in gw GuiWidgets* gw; QToolButton* onOff; QWidget* mw; // main widget + QScrollView* view; void updateControls(); @@ -263,7 +330,9 @@ class PluginGui : public QMainWindow { void heartBeat(); public: - PluginGui(PluginI*); + //PluginGui(PluginI*); + PluginGui(PluginIBase*); + ~PluginGui(); void setOn(bool); void updateValues(); @@ -277,7 +346,8 @@ class PluginGui : public QMainWindow { #define AUDIO_IN (LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT) #define AUDIO_OUT (LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT) -class PluginI { +//class PluginI { +class PluginI : public PluginIBase { Plugin* _plugin; int channel; int instances; @@ -320,6 +390,7 @@ class PluginI { void setTrack(AudioTrack* t) { _track = t; } AudioTrack* track() { return _track; } + int pluginID() { return _plugin->id(); } void setID(int i); int id() { return _id; } void updateControllers(); @@ -338,6 +409,7 @@ class PluginI { void activate(); void deactivate(); + QString pluginLabel() const { return _plugin->label(); } QString label() const { return _label; } QString name() const { return _name; } CtrlValueType valueType() const; diff --git a/muse/muse/seqmsg.cpp b/muse/muse/seqmsg.cpp index 02fbdf01..c9c3b3a5 100644 --- a/muse/muse/seqmsg.cpp +++ b/muse/muse/seqmsg.cpp @@ -412,14 +412,17 @@ void Audio::msgSetChannels(AudioTrack* node, int n) // msgSetPluginCtrlVal //--------------------------------------------------------- -void Audio::msgSetPluginCtrlVal(PluginI* plugin, int param, double val) +//void Audio::msgSetPluginCtrlVal(PluginI* plugin, int param, double val) +// p3.3.43 +void Audio::msgSetPluginCtrlVal(AudioTrack* track, int param, double val) { AudioMsg msg; msg.id = AUDIO_SET_PLUGIN_CTRL_VAL; msg.ival = param; - msg.dval = val; - msg.plugin = plugin; + msg.dval = val; + //msg.plugin = plugin; + msg.snode = track; sendMsg(&msg); } diff --git a/muse/muse/sig.cpp b/muse/muse/sig.cpp index 841a3369..8bbebfae 100644 --- a/muse/muse/sig.cpp +++ b/muse/muse/sig.cpp @@ -32,7 +32,10 @@ SigList::SigList() void SigList::add(unsigned tick, int z, int n) { if (z == 0 || n == 0) { - printf("illegal signature %d/%d\n", z, n); + printf("SigList::add illegal signature %d/%d\n", z, n); + + // Added p3.3.43 + return; } tick = raster1(tick, 0); iSigEvent e = upper_bound(tick); diff --git a/muse/muse/synth.h b/muse/muse/synth.h index 0bca9a75..173be3d1 100644 --- a/muse/muse/synth.h +++ b/muse/muse/synth.h @@ -132,7 +132,7 @@ class SynthIF { virtual const char* getPatchName(int, int, MType, bool) = 0; virtual void populatePatchPopup(QPopupMenu*, int, MType, bool) = 0; virtual void write(int level, Xml& xml) const = 0; - virtual float getParameter(unsigned long idx) = 0; + virtual float getParameter(unsigned long idx) const = 0; virtual void setParameter(unsigned long idx, float value) = 0; virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval) = 0; }; @@ -278,7 +278,7 @@ class MessSynthIF : public SynthIF { virtual const char* getPatchName(int, int, MType, bool); virtual void populatePatchPopup(QPopupMenu*, int, MType, bool); virtual void write(int level, Xml& xml) const; - virtual float getParameter(unsigned long) { return 0.0; } + virtual float getParameter(unsigned long) const { return 0.0; } virtual void setParameter(unsigned long, float) {} virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval); }; diff --git a/muse/muse/ticksynth.cpp b/muse/muse/ticksynth.cpp index eb360c17..e4772db5 100644 --- a/muse/muse/ticksynth.cpp +++ b/muse/muse/ticksynth.cpp @@ -84,7 +84,7 @@ class MetronomeSynthIF : public SynthIF virtual const char* getPatchName(int, int, MType, bool) { return ""; } virtual void populatePatchPopup(QPopupMenu*, int, MType, bool) {}; virtual void write(int, Xml&) const {} - virtual float getParameter(unsigned long) { return 0.0; } + virtual float getParameter(unsigned long) const { return 0.0; } virtual void setParameter(unsigned long, float) {} virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) { return 0; } }; diff --git a/muse/muse/undo.cpp b/muse/muse/undo.cpp index b078196f..021069f3 100644 --- a/muse/muse/undo.cpp +++ b/muse/muse/undo.cpp @@ -27,7 +27,7 @@ const char* UndoOp::typeName() "AddPart", "DeletePart", "ModifyPart", "AddEvent", "DeleteEvent", "ModifyEvent", "AddTempo", "DeleteTempo", "AddSig", "DeleteSig", - "SwapTrack" + "SwapTrack", "ModifyClip" }; return name[type]; } diff --git a/muse/muse/vst.cpp b/muse/muse/vst.cpp index 74e34efa..ddb2e87d 100644 --- a/muse/muse/vst.cpp +++ b/muse/muse/vst.cpp @@ -517,7 +517,7 @@ void VstSynthIF::deactivate3() // getParameter //--------------------------------------------------------- -float VstSynthIF::getParameter(unsigned long idx) +float VstSynthIF::getParameter(unsigned long idx) const { return _fst->plugin->getParameter(_fst->plugin, idx); } diff --git a/muse/muse/vst.h b/muse/muse/vst.h index 51eade15..0b84293c 100644 --- a/muse/muse/vst.h +++ b/muse/muse/vst.h @@ -71,7 +71,7 @@ class VstSynthIF : public SynthIF virtual const char* getPatchName(int, int, MType, bool) { return ""; } virtual void populatePatchPopup(QPopupMenu*, int, MType, bool) {}; virtual void write(int level, Xml& xml) const; - virtual float getParameter(unsigned long idx); + virtual float getParameter(unsigned long idx) const; virtual void setParameter(unsigned long idx, float value); virtual int getControllerInfo(int, const char**, int*, int*, int*, int*) { return 0; } }; diff --git a/muse/muse/widgets/canvas.cpp b/muse/muse/widgets/canvas.cpp index 14275746..edaeb501 100644 --- a/muse/muse/widgets/canvas.cpp +++ b/muse/muse/widgets/canvas.cpp @@ -8,6 +8,7 @@ #include <stdio.h> #include "canvas.h" +#include <qapplication.h> #include <qpainter.h> #include <qpopupmenu.h> #include <qcursor.h> @@ -635,179 +636,200 @@ void Canvas::viewMousePressEvent(QMouseEvent* event) } void Canvas::scrollTimerDone() +{ + //printf("Canvas::scrollTimerDone drag:%d doScroll:%d\n", drag, doScroll); + + if (drag != DRAG_OFF && doScroll) { - if (drag != DRAG_OFF && doScroll){ - bool doHMove = false; - bool doVMove = false; - int hoff = rmapx(xOffset())+mapx(xorg)-1; - int curxpos; - switch(hscrollDir) - { - case HSCROLL_RIGHT: - hoff += scrollSpeed; - switch(drag) - { - case DRAG_NEW: - case DRAG_RESIZE: - case DRAGX_MOVE: - case DRAGX_COPY: - case DRAGX_CLONE: - case DRAGY_MOVE: - case DRAGY_COPY: - case DRAGY_CLONE: - case DRAG_MOVE: - case DRAG_COPY: - case DRAG_CLONE: - emit horizontalScrollNoLimit(hoff); - canScrollLeft = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); - doHMove = true; - break; - default: - if(canScrollRight) - { - curxpos = xpos; - emit horizontalScroll(hoff); - if(xpos <= curxpos) - { - canScrollRight = false; - } - else - { - canScrollLeft = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); - doHMove = true; - } - } - else + //printf("Canvas::scrollTimerDone drag != DRAG_OFF && doScroll\n"); + + bool doHMove = false; + bool doVMove = false; + int hoff = rmapx(xOffset())+mapx(xorg)-1; + int curxpos; + switch(hscrollDir) + { + case HSCROLL_RIGHT: + hoff += scrollSpeed; + switch(drag) + { + case DRAG_NEW: + case DRAG_RESIZE: + case DRAGX_MOVE: + case DRAGX_COPY: + case DRAGX_CLONE: + case DRAGY_MOVE: + case DRAGY_COPY: + case DRAGY_CLONE: + case DRAG_MOVE: + case DRAG_COPY: + case DRAG_CLONE: + emit horizontalScrollNoLimit(hoff); + canScrollLeft = true; + ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); + doHMove = true; + break; + default: + if(canScrollRight) + { + curxpos = xpos; + emit horizontalScroll(hoff); + if(xpos <= curxpos) { + canScrollRight = false; } - break; - } - break; - case HSCROLL_LEFT: - if(canScrollLeft) - { - curxpos = xpos; - hoff -= scrollSpeed; - emit horizontalScroll(hoff); - if(xpos >= curxpos) - { - canScrollLeft = false; - } + else + { + canScrollLeft = true; + ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) + scrollSpeed)); + doHMove = true; + } + } else - { - canScrollRight = true; - ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) - scrollSpeed)); - doHMove = true; + { } - } - else + break; + } + break; + case HSCROLL_LEFT: + if(canScrollLeft) + { + curxpos = xpos; + hoff -= scrollSpeed; + emit horizontalScroll(hoff); + if(xpos >= curxpos) { + canScrollLeft = false; } - break; - default: - break; - } - int voff = rmapy(yOffset())+mapy(yorg); - int curypos; - switch(vscrollDir) - { - case VSCROLL_DOWN: - if(canScrollDown) - { - curypos = ypos; - voff += scrollSpeed; - emit verticalScroll(voff); - if(ypos <= curypos) - { - canScrollDown = false; - } - else - { - canScrollUp = true; - ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) + scrollSpeed)); - doVMove = true; - } - } else + { + canScrollRight = true; + ev_pos.setX(rmapxDev(rmapx(ev_pos.x()) - scrollSpeed)); + doHMove = true; + } + } + else + { + } + break; + default: + break; + } + int voff = rmapy(yOffset())+mapy(yorg); + int curypos; + switch(vscrollDir) + { + case VSCROLL_DOWN: + if(canScrollDown) + { + curypos = ypos; + voff += scrollSpeed; + emit verticalScroll(voff); + if(ypos <= curypos) { + canScrollDown = false; } - break; - case VSCROLL_UP: - if(canScrollUp) - { - curypos = ypos; - voff -= scrollSpeed; - emit verticalScroll(voff); - if(ypos >= curypos) - { - canScrollUp = false; - } - else - { - canScrollDown = true; - ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) - scrollSpeed)); - doVMove = true; - } - } else + { + canScrollUp = true; + ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) + scrollSpeed)); + doVMove = true; + } + } + else + { + } + break; + case VSCROLL_UP: + if(canScrollUp) + { + curypos = ypos; + voff -= scrollSpeed; + emit verticalScroll(voff); + if(ypos >= curypos) { + canScrollUp = false; } - break; - default: - break; - } - - if(!doHMove && !doVMove) - { - delete scrollTimer; - scrollTimer=NULL; - doScroll = false; - return; - } - QPoint dist = ev_pos - start; - switch(drag) - { - case DRAG_MOVE: - case DRAG_COPY: - case DRAG_CLONE: - moveItems(ev_pos, 0, false); - break; - case DRAGX_MOVE: - case DRAGX_COPY: - case DRAGX_CLONE: - moveItems(ev_pos, 1, false); - break; - case DRAGY_MOVE: - case DRAGY_COPY: - case DRAGY_CLONE: - moveItems(ev_pos, 2, false); - break; - case DRAG_LASSO: - lasso = QRect(start.x(), start.y(), dist.x(), dist.y()); - redraw(); - break; - case DRAG_NEW: - case DRAG_RESIZE: - if (dist.x()) { - if (dist.x() < 1) - curItem->setWidth(1); - else - curItem->setWidth(dist.x()); - redraw(); - } - break; - default: - break; - } - scrollTimer->start( 40, TRUE ); // X ms single-shot timer + else + { + canScrollDown = true; + ev_pos.setY(rmapyDev(rmapy(ev_pos.y()) - scrollSpeed)); + doVMove = true; + } + } + else + { + } + break; + default: + break; } - else { + + //printf("Canvas::scrollTimerDone doHMove:%d doVMove:%d\n", doHMove, doVMove); + + if(!doHMove && !doVMove) + { + delete scrollTimer; + scrollTimer=NULL; + doScroll = false; + return; + } + QPoint dist = ev_pos - start; + switch(drag) + { + case DRAG_MOVE: + case DRAG_COPY: + case DRAG_CLONE: + moveItems(ev_pos, 0, false); + break; + case DRAGX_MOVE: + case DRAGX_COPY: + case DRAGX_CLONE: + moveItems(ev_pos, 1, false); + break; + case DRAGY_MOVE: + case DRAGY_COPY: + case DRAGY_CLONE: + moveItems(ev_pos, 2, false); + break; + case DRAG_LASSO: + lasso = QRect(start.x(), start.y(), dist.x(), dist.y()); + redraw(); + break; + case DRAG_NEW: + case DRAG_RESIZE: + if (dist.x()) { + if (dist.x() < 1) + curItem->setWidth(1); + else + curItem->setWidth(dist.x()); + redraw(); + } + break; + default: + break; + } + //printf("Canvas::scrollTimerDone starting scrollTimer: Currently active?%d\n", scrollTimer->isActive()); + + // p3.3.43 Make sure to yield to other events (for up to 3 seconds), otherwise other events + // take a long time to reach us, causing scrolling to take a painfully long time to stop. + // FIXME: Didn't help at all. + //qApp->processEvents(); + // No, try up to 100 ms for each yield. + //qApp->processEvents(100); + // + //scrollTimer->start( 40, TRUE ); // X ms single-shot timer + // OK, changing the timeout from 40 to 80 helped. + scrollTimer->start( 80, TRUE ); // X ms single-shot timer + } + else + { + //printf("Canvas::scrollTimerDone !(drag != DRAG_OFF && doScroll) deleting scrollTimer\n"); + delete scrollTimer; scrollTimer=NULL; - } } +} //--------------------------------------------------------- @@ -1089,6 +1111,8 @@ void Canvas::viewMouseReleaseEvent(QMouseEvent* event) case DRAG_DELETE: break; } + //printf("Canvas::viewMouseReleaseEvent setting drag to DRAG_OFF\n"); + drag = DRAG_OFF; if (redrawFlag) redraw(); diff --git a/muse/muse/widgets/mtscale.cpp b/muse/muse/widgets/mtscale.cpp index 9554238d..b5f8282a 100644 --- a/muse/muse/widgets/mtscale.cpp +++ b/muse/muse/widgets/mtscale.cpp @@ -96,7 +96,6 @@ void MTScale::setPos(int idx, unsigned val, bool) int w = 18; if (tval < 0) { // tval<0 occurs whenever the window is scrolled left, so I switched to signed int (ml) - // Added by Tim. p3.3.6 //printf("MTScale::setPos - idx:%d val:%d tval:%d opos:%d w:%d h:%d\n", idx, val, tval, opos, width(), height()); redraw(QRect(0,0,width(),height())); @@ -111,7 +110,6 @@ void MTScale::setPos(int idx, unsigned val, bool) w += tval - opos; x += opos; } - // Added by Tim. p3.3.6 //printf("MTScale::setPos idx:%d val:%d tval:%d opos:%d x:%d w:%d h:%d\n", idx, val, tval, opos, x, w, height()); redraw(QRect(x, 0, w, height())); @@ -174,7 +172,9 @@ void MTScale::viewMouseMoveEvent(QMouseEvent* event) Marker *alreadyExists = song->getMarkerAt(x); if (!alreadyExists) { song->addMarker(QString(""), x, false); - emit addMarker(x); + // Removed p3.3.43 + // Song::addMarker() already emits a 'markerChanged'. + //emit addMarker(x); } } else if (i== 2 && (event->state() & Qt::ShiftButton )) { // If shift +RMB we remove a marker @@ -270,7 +270,6 @@ void MTScale::pdraw(QPainter& p, const QRect& r) else x2 = xp+200; - // Added by Tim. p3.3.6 //printf("MTScale::pdraw marker %s xp:%d y:%d h:%d r.x:%d r.w:%d\n", m->second.name().latin1(), xp, height(), y, r.x(), r.width()); // Must be reasonable about very low negative x values! With long songs > 15min diff --git a/muse/muse/widgets/mtscale.h b/muse/muse/widgets/mtscale.h index 82785cc7..cd3629ae 100644 --- a/muse/muse/widgets/mtscale.h +++ b/muse/muse/widgets/mtscale.h @@ -37,7 +37,7 @@ class MTScale : public View { signals: void timeChanged(unsigned); - void addMarker(int); + //void addMarker(int); public slots: void setPos(int, unsigned, bool); diff --git a/muse/muse/widgets/posedit.cpp b/muse/muse/widgets/posedit.cpp index 1582f584..61accda1 100644 --- a/muse/muse/widgets/posedit.cpp +++ b/muse/muse/widgets/posedit.cpp @@ -485,6 +485,7 @@ void PosEdit::setValue(const Pos& time) else time.mbt(&(sec[0].val), &(sec[1].val), &(sec[2].val)); changed = false; + updateButtons(); ed->repaint(ed->rect(), false); } @@ -843,6 +844,8 @@ void PosEdit::updateButtons() bool upEnabled = isEnabled() && (pos() < maxValue()); bool downEnabled = isEnabled() && (pos() > minValue()); + //printf("PosEdit::updateButtons smpte:%d upEnabled:%d downEnabled:%d\n", smpte(), upEnabled, downEnabled); + controls->setUpEnabled(upEnabled); controls->setDownEnabled(downEnabled); } @@ -854,3 +857,12 @@ void PosEdit::enterPressed() { emit returnPressed(); } + +//--------------------------------------------------------- +// setEnabled +//--------------------------------------------------------- +void PosEdit::setEnabled(bool v) +{ + QWidget::setEnabled(v); + updateButtons(); +} diff --git a/muse/muse/widgets/posedit.h b/muse/muse/widgets/posedit.h index 9913b6b0..79b78253 100644 --- a/muse/muse/widgets/posedit.h +++ b/muse/muse/widgets/posedit.h @@ -74,6 +74,8 @@ class PosEdit : public QWidget virtual void setValue(const Pos& time); void setValue(int t); void setValue(const QString& s); + // Added p3.3.43 + virtual void setEnabled(bool); public: PosEdit(QWidget*, const char* = 0); diff --git a/muse/muse/widgets/sigedit.cpp b/muse/muse/widgets/sigedit.cpp index 7daade6d..28d6b76a 100644 --- a/muse/muse/widgets/sigedit.cpp +++ b/muse/muse/widgets/sigedit.cpp @@ -21,6 +21,29 @@ extern int mtcType; +bool Sig::isValid() const +{ + if((z < 1) || (z > 63)) + return false; + + switch(n) + { + case 1: + case 2: + case 3: + case 4: + case 8: + case 16: + case 32: + case 64: + case 128: + return true; + default: + return false; + } +} + + //--------------------------------------------------------- // NumberSection //--------------------------------------------------------- @@ -287,6 +310,9 @@ bool SigEditor::eventFilter(QObject *o, QEvent *e) return true; } int num = txt[0].digitValue(); + + //printf("SigEditor::eventFilter num:%d\n", num); + if (num != -1) { cw->addNumber(focusSec, num); return true; @@ -581,9 +607,13 @@ bool SigEdit::outOfRange(int secNo, int val) const case 32: case 64: case 128: - return true; - default: + // Changed p3.3.43 + //return true; return false; + default: + // Changed p3.3.43 + //return false; + return true; } } @@ -602,18 +632,32 @@ void SigEdit::addNumber(int secNo, int num) QString txt = sectionText(secNo); + //printf("SigEdit::addNumber secNo:%d num:%d voff:%d txt:%s\n", secNo, num, voff, txt.latin1()); + if (txt.length() == sec[secNo].len) { + //printf("SigEdit::addNumber txt.length() == sec[secNo].len (%d)\n", sec[secNo].len); + if (!outOfRange(secNo, num - voff)) { + //printf("SigEdit::addNumber accepted\n"); + accepted = true; sec[secNo].val = num - voff; } } else { + //printf("SigEdit::addNumber txt.length() != sec[secNo].len (%d)\n", sec[secNo].len); + txt += QString::number(num); int temp = txt.toInt() - voff; if (outOfRange(secNo, temp)) + { + //printf("SigEdit::addNumber not accepted secNo:%d txt:%s temp:%d\n", secNo, txt.latin1(), temp); + txt = sectionText(secNo); + } else { + //printf("SigEdit::addNumber accepted\n"); + accepted = true; sec[secNo].val = temp; } diff --git a/muse/muse/widgets/sigedit.h b/muse/muse/widgets/sigedit.h index 98dfc7f5..fa3f6132 100644 --- a/muse/muse/widgets/sigedit.h +++ b/muse/muse/widgets/sigedit.h @@ -19,6 +19,7 @@ struct Sig { int n; public: Sig(int _z, int _n) : z(_z), n(_n) {} + bool isValid() const; }; #include "section.h" diff --git a/muse/muse/widgets/view.cpp b/muse/muse/widgets/view.cpp index 68256186..bd857072 100644 --- a/muse/muse/widgets/view.cpp +++ b/muse/muse/widgets/view.cpp @@ -73,9 +73,7 @@ void View::setXPos(int x) if (pm.isNull()) return; if (!pmValid) { - // Added by Tim. p3.3.6 //printf("View::setXPos !pmValid x:%d width:%d delta:%d\n", x, width(), delta); - redraw(); return; } @@ -100,7 +98,6 @@ void View::setXPos(int x) r |= olr; r |= olr1; - // Added by Tim. p3.3.6 //printf("View::setXPos x:%d w:%d delta:%d r.x:%d r.w:%d\n", x, w, delta, r.x(), r.width()); paint(r); @@ -118,7 +115,6 @@ void View::setYPos(int y) if (pm.isNull()) return; if (!pmValid) { - // Added by Tim. p3.3.6 //printf("View::setYPos !pmValid y:%d height:%d delta:%d\n", y, height(), delta); redraw(); @@ -135,7 +131,30 @@ void View::setYPos(int y) } else { // shift down bitBlt(&pm, 0, delta, &pm, 0, 0, w, h-delta, CopyROP, true); - r = QRect(0, 0, w, delta); + + // NOTE: June 2 2010: On my machine with an old NV V8200 + prop drivers (curr 96.43.11), + // this is a problem. There is severe graphical corruption in some of the view-based windows. + // Not just here but several other windows (ex. ladspa browser). + // I believe (?) I saw other QT3 apps exhibit this problem, too. QT4 apps don't do it. + // Neither does it happen when xorg drivers used. + // + // However, there is one type of MusE corruption which ALL drivers seem to show, and that is + // the arranger 'grey' non-part-based tracks (Input, Output, Group etc.). + // It is also observed on another machine with an ATI card and a different linux distro. + // This change also fixes that problem, although the fact that xorg drivers show the problem + // had long made me believe that it was our drawing technique, not particularly this line. + // Meaning that perhaps this line is not the right way to fix that problem. + // + // On the other hand the two problems may be related, and only one shows with xorg drivers... + // Ultimately it could just be my NV card, as a request for similar experience in mail list + // returned all negative. + // + // FIXME: This change cures it for me, but we shouldn't leave this in - shouldn't need to do this... + // + //r = QRect(0, 0, w, delta); + // Changed p3.3.43 + r = QRect(0, 0, w, h); + } QRect olr = overlayRect(); QRect olr1(olr); @@ -163,9 +182,7 @@ void View::resizeEvent(QResizeEvent* ev) void View::paintEvent(QPaintEvent* ev) { - // Added by Tim. p3.3.6 //printf("View::paintEvent pmValid:%d x:%d width:%d y:%d height:%d\n", pmValid, ev->rect().x(), ev->rect().width(), ev->rect().y(), ev->rect().height()); - if (!pmValid) paint(ev->rect()); bitBlt(this, ev->rect().topLeft(), &pm, ev->rect(), CopyROP, true); @@ -178,9 +195,7 @@ void View::paintEvent(QPaintEvent* ev) void View::redraw() { QRect r(0, 0, pm.width(), pm.height()); - // Added by Tim. p3.3.6 //printf("View::redraw() r.x:%d r.w:%d\n", r.x(), r.width()); - paint(r); update(); } @@ -191,9 +206,7 @@ void View::redraw() void View::redraw(const QRect& r) { - // Added by Tim. p3.3.6 //printf("View::redraw(QRect& r) r.x:%d r.w:%d\n", r.x(), r.width()); - paint(r); update(r); } @@ -219,9 +232,7 @@ void View::paint(const QRect& r) p.drawTiledPixmap(rr, bgPixmap, QPoint(xpos + rmapx(xorg) + rr.x(), ypos + rmapy(yorg) + rr.y())); p.setClipRegion(rr); - // Added by Tim. p3.3.6 //printf("View::paint r.x:%d w:%d\n", rr.x(), rr.width()); - pdraw(p, rr); // draw into pixmap p.resetXForm(); |