ControlList GetExportableChildren(Gwen::Controls::Base* pRoot) { ControlList list; for (int i = 0; i < pRoot->NumChildren(); i++) { Gwen::Controls::Base* pBaseChild = pRoot->GetChild(i); if (!pBaseChild) continue; // // If we have a child is isn't exportable - maybe it has a // child that is // We will count it as one of our children. // if (!pBaseChild->UserData.Exists("ControlFactory")) { list.Add(GetExportableChildren(pBaseChild)); continue; } list.Add(pBaseChild); } return list; }
// Add controller CON at INDEX, shifting further controllers one // position forwards. // Used only by RemoveControlParameterCommand. void MidiDevice::addControlParameter(const ControlParameter &con, int index, bool propagateToInstruments) { ControlList controls; // if we're out of range just add the control if (index >= (int)m_controlList.size()) { addControlParameter(con, propagateToInstruments); return; } // Rebuild the ControlList entry by entry, placing CON at INDEX. // For entry INDEX we do two push_back's, for other entries we do // one. for (int i = 0; i < (int)m_controlList.size(); ++i) { if (index == i) { controls.push_back(con); // !!! This seems to do more than we need, since we // discard the original m_controlList. addControlParameter(con, propagateToInstruments); } controls.push_back(m_controlList[i]); } // Assign the ControlList we just made. m_controlList = controls; }
void Hierarchy::OnNodeSelected( Event::Info info ) { if ( !info.ControlCaller->UserData.Exists( "TargetControl" ) ) return; Controls::Base* ctrl = info.ControlCaller->UserData.Get<Controls::Base*>( "TargetControl" ); ControlList list; list.Add( ctrl ); m_pCanvas->SelectControls( list ); }
ControlList MidiDevice::getIPBControlParameters() const { ControlList retList; Rosegarden::MidiByte MIDI_CONTROLLER_VOLUME = 0x07; for (ControlList::const_iterator it = m_controlList.begin(); it != m_controlList.end(); ++it) { if (it->getIPBPosition() != -1 && it->getControllerValue() != MIDI_CONTROLLER_VOLUME) retList.push_back(*it); } return retList; }
void MidiDevice::replaceControlParameters(const ControlList &con) { // Clear down instrument controllers in preparation for replace. InstrumentList insList = getAllInstruments(); InstrumentList::iterator iIt = insList.begin(); for(; iIt != insList.end(); ++iIt) { (*iIt)->clearStaticControllers(); } // Clear the Device control list m_controlList.clear(); // Now add the controllers to the device, ControlList::const_iterator cIt = con.begin(); for(; cIt != con.end(); ++cIt) { addControlParameter(*cIt, true); } }
void MidiMixerWindow::setupTabs() { DeviceListConstIterator it; MidiDevice *dev = 0; InstrumentList instruments; InstrumentList::const_iterator iIt; int faderCount = 0, deviceCount = 1; if (m_tabFrame) delete m_tabFrame; // Setup m_tabFrame // QWidget *blackWidget = new QWidget(this); setCentralWidget(blackWidget); QVBoxLayout *centralLayout = new QVBoxLayout; blackWidget->setLayout(centralLayout); m_tabWidget = new QTabWidget; centralLayout->addWidget(m_tabWidget); connect(m_tabWidget, SIGNAL(currentChanged(QWidget *)), this, SLOT(slotCurrentTabChanged(QWidget *))); m_tabWidget->setTabPosition(QTabWidget::South); setWindowTitle(tr("MIDI Mixer")); setWindowIcon(IconLoader().loadPixmap("window-midimixer")); for (it = m_studio->begin(); it != m_studio->end(); ++it) { dev = dynamic_cast<MidiDevice*>(*it); if (dev) { // Get the control parameters that are on the IPB (and hence can // be shown here too). // ControlList controls = getIPBForMidiMixer(dev); instruments = dev->getPresentationInstruments(); // Don't add a frame for empty devices // if (!instruments.size()) continue; m_tabFrame = new QFrame(m_tabWidget); m_tabFrame->setContentsMargins(10, 10, 10, 10); // m_tabFrame->setContentsMargins(5, 5, 5, 5); ??? QGridLayout *mainLayout = new QGridLayout(m_tabFrame); // MIDI Mixer label QLabel *label = new QLabel("", m_tabFrame); mainLayout->addWidget(label, 0, 0, 0, 16, Qt::AlignCenter); // control labels for (size_t i = 0; i < controls.size(); ++i) { label = new QLabel(QObject::tr(controls[i].getName().c_str()), m_tabFrame); mainLayout->addWidget(label, i + 1, 0, Qt::AlignCenter); } // meter label // (obsolete abandoned code deleted here) // volume label label = new QLabel(tr("Volume"), m_tabFrame); mainLayout->addWidget(label, controls.size() + 2, 0, Qt::AlignCenter); // instrument label label = new QLabel(tr("Instrument"), m_tabFrame); label->setFixedWidth(80); //!!! this should come from metrics mainLayout->addWidget(label, controls.size() + 3, 0, Qt::AlignLeft); int posCount = 1; int firstInstrument = -1; for (iIt = instruments.begin(); iIt != instruments.end(); ++iIt) { // Add new fader struct // m_faders.push_back(new FaderStruct()); // Store the first ID // if (firstInstrument == -1) firstInstrument = (*iIt)->getId(); // Add the controls // for (size_t i = 0; i < controls.size(); ++i) { QColor knobColour = QColor(Qt::white); if (controls[i].getColourIndex() > 0) { Colour c = m_document->getComposition().getGeneralColourMap(). getColourByIndex(controls[i].getColourIndex()); knobColour = QColor(c.getRed(), c.getGreen(), c.getBlue()); } Rotary *controller = new Rotary(m_tabFrame, controls[i].getMin(), controls[i].getMax(), 1.0, 5.0, controls[i].getDefault(), 20, Rotary::NoTicks, false, controls[i].getDefault() == 64); //!!! hacky controller->setKnobColour(knobColour); connect(controller, SIGNAL(valueChanged(float)), this, SLOT(slotControllerChanged(float))); mainLayout->addWidget(controller, i + 1, posCount, Qt::AlignCenter); // Store the rotary // m_faders[faderCount]->m_controllerRotaries.push_back( std::pair<MidiByte, Rotary*> (controls[i].getControllerValue(), controller)); } // VU meter // MidiMixerVUMeter *meter = new MidiMixerVUMeter(m_tabFrame, VUMeter::FixedHeightVisiblePeakHold, 6, 30); mainLayout->addWidget(meter, controls.size() + 1, posCount, Qt::AlignCenter); m_faders[faderCount]->m_vuMeter = meter; // Volume fader // Fader *fader = new Fader(0, 127, 100, 20, 80, m_tabFrame); mainLayout->addWidget(fader, controls.size() + 2, posCount, Qt::AlignCenter); m_faders[faderCount]->m_volumeFader = fader; // Label // QLabel *idLabel = new QLabel(QString("%1"). arg((*iIt)->getId() - firstInstrument + 1), m_tabFrame); idLabel->setObjectName("idLabel"); mainLayout->addWidget(idLabel, controls.size() + 3, posCount, Qt::AlignCenter); // store id in struct m_faders[faderCount]->m_id = (*iIt)->getId(); // Connect them up // connect(fader, SIGNAL(faderChanged(float)), this, SLOT(slotFaderLevelChanged(float))); // Update all the faders and controllers // slotUpdateInstrument((*iIt)->getId()); // Increment counters // posCount++; faderCount++; } QString name = QString("%1 (%2)") .arg(QObject::tr(dev->getName().c_str())) .arg(deviceCount++); addTab(m_tabFrame, name); } } }
void MidiMixerWindow::sendControllerRefresh() { //!!! need to know if we have a current external controller device, // as this is expensive int tabIndex = m_tabWidget->currentIndex(); RG_DEBUG << "MidiMixerWindow::slotCurrentTabChanged: current is " << tabIndex << endl; if (tabIndex < 0) return ; int i = 0; for (DeviceList::const_iterator dit = m_studio->begin(); dit != m_studio->end(); ++dit) { MidiDevice *dev = dynamic_cast<MidiDevice*>(*dit); RG_DEBUG << "device is " << (*dit)->getId() << ", dev " << dev << endl; if (!dev) continue; if (i != tabIndex) { ++i; continue; } InstrumentList instruments = dev->getPresentationInstruments(); ControlList controls = getIPBForMidiMixer(dev); RG_DEBUG << "device has " << instruments.size() << " presentation instruments, " << dev->getAllInstruments().size() << " instruments " << endl; for (InstrumentList::const_iterator iIt = instruments.begin(); iIt != instruments.end(); ++iIt) { Instrument *instrument = *iIt; if (!instrument->hasFixedChannel()) { continue; } int channel = instrument->getNaturalChannel(); RG_DEBUG << "instrument is " << instrument->getId() << endl; for (ControlList::const_iterator cIt = controls.begin(); cIt != controls.end(); ++cIt) { int controller = (*cIt).getControllerValue(); int value; try { value = instrument->getControllerValue(controller); } catch (std::string s) { std::cerr << "Exception in MidiMixerWindow::currentChanged: " << s << " (controller " << controller << ", instrument " << instrument->getId() << ")" << std::endl; value = 0; } MappedEvent mE(instrument->getId(), MappedEvent::MidiController, controller, value); mE.setRecordedChannel(channel); mE.setRecordedDevice(Device::CONTROL_DEVICE); StudioControl::sendMappedEvent(mE); } MappedEvent mE(instrument->getId(), MappedEvent::MidiController, MIDI_CONTROLLER_VOLUME, instrument->getVolume()); mE.setRecordedChannel(channel); mE.setRecordedDevice(Device::CONTROL_DEVICE); RG_DEBUG << "sending controller mapped event for channel " << channel << ", volume " << instrument->getVolume() << endl; StudioControl::sendMappedEvent(mE); } break; } }
void MidiMixerWindow::slotControllerDeviceEventReceived(MappedEvent *e, const void *preferredCustomer) { if (preferredCustomer != this) return ; RG_DEBUG << "MidiMixerWindow::slotControllerDeviceEventReceived: this one's for me" << endl; raise(); // get channel number n from event // get nth instrument on current tab if (e->getType() != MappedEvent::MidiController) return ; unsigned int channel = e->getRecordedChannel(); MidiByte controller = e->getData1(); MidiByte value = e->getData2(); int tabIndex = m_tabWidget->currentIndex(); int i = 0; for (DeviceList::const_iterator it = m_studio->begin(); it != m_studio->end(); ++it) { MidiDevice *dev = dynamic_cast<MidiDevice*>(*it); if (!dev) continue; if (i != tabIndex) { ++i; continue; } InstrumentList instruments = dev->getPresentationInstruments(); for (InstrumentList::const_iterator iIt = instruments.begin(); iIt != instruments.end(); ++iIt) { Instrument *instrument = *iIt; if (instrument->getNaturalChannel() != channel) continue; ControlList cl = dev->getIPBControlParameters(); for (ControlList::const_iterator i = cl.begin(); i != cl.end(); ++i) { if ((*i).getControllerValue() == controller) { RG_DEBUG << "Setting controller " << controller << " for instrument " << instrument->getId() << " to " << value << endl; instrument->setControllerValue(controller, value); break; } } slotUpdateInstrument(instrument->getId()); emit instrumentParametersChanged(instrument->getId()); } break; } }
void MidiMixerWindow::slotUpdateInstrument(InstrumentId id) { //RG_DEBUG << "MidiMixerWindow::slotUpdateInstrument - id = " << id << endl; DeviceListConstIterator it; MidiDevice *dev = 0; InstrumentList instruments; InstrumentList::const_iterator iIt; int count = 0; blockSignals(true); for (it = m_studio->begin(); it != m_studio->end(); ++it) { dev = dynamic_cast<MidiDevice*>(*it); if (dev) { instruments = dev->getPresentationInstruments(); ControlList controls = getIPBForMidiMixer(dev); for (iIt = instruments.begin(); iIt != instruments.end(); ++iIt) { // Match and set // if ((*iIt)->getId() == id) { // Set Volume fader // m_faders[count]->m_volumeFader->blockSignals(true); MidiByte volumeValue; try { volumeValue = (*iIt)-> getControllerValue(MIDI_CONTROLLER_VOLUME); } catch (std::string s) { // This should never get called. volumeValue = (*iIt)->getVolume(); } m_faders[count]->m_volumeFader->setFader(float(volumeValue)); m_faders[count]->m_volumeFader->blockSignals(false); /* StaticControllers &staticControls = (*iIt)->getStaticControllers(); RG_DEBUG << "STATIC CONTROLS SIZE = " << staticControls.size() << endl; */ // Set all controllers for this Instrument // for (size_t i = 0; i < controls.size(); ++i) { float value = 0.0; m_faders[count]->m_controllerRotaries[i].second->blockSignals(true); // The ControllerValues might not yet be set on // the actual Instrument so don't always expect // to find one. There might be a hole here for // deleted Controllers to hang around on // Instruments.. // try { value = float((*iIt)->getControllerValue (controls[i].getControllerValue())); } catch (std::string s) { /* RG_DEBUG << "MidiMixerWindow::slotUpdateInstrument - " << "can't match controller " << int(controls[i]. getControllerValue()) << " - \"" << s << "\"" << endl; */ continue; } /* RG_DEBUG << "MidiMixerWindow::slotUpdateInstrument" << " - MATCHED " << int(controls[i].getControllerValue()) << endl; */ m_faders[count]->m_controllerRotaries[i]. second->setPosition(value); m_faders[count]->m_controllerRotaries[i].second->blockSignals(false); } } count++; } } } blockSignals(false); }
void MIDIInstrumentParameterPanel::setupControllers(MidiDevice *md) { RG_DEBUG << "setupControllers()"; if (!md) return; // To cut down on flicker, we avoid destroying and recreating // widgets as far as possible here. If a label already exists, // we just set its text; if a rotary exists, we only replace it // if we actually need a different one. Composition &comp = m_doc->getComposition(); ControlList list = md->getControlParameters(); // Sort by IPB position. std::sort(list.begin(), list.end(), ControlParameter::ControlPositionCmp()); int count = 0; RotaryInfoVector::iterator rotaryIter = m_rotaries.begin(); // For each controller for (ControlList::iterator it = list.begin(); it != list.end(); ++it) { if (it->getIPBPosition() == -1) continue; // Get the knob colour (even if it's default, because otherwise it turns // black instead of the default color from the map! it was here the // whole time, this simple!) // const Colour c = comp.getGeneralColourMap().getColourByIndex( it->getColourIndex()); const QColor knobColour = QColor(c.getRed(), c.getGreen(), c.getBlue()); Rotary *rotary = 0; // If the Rotary widgets have already been created, update them. if (rotaryIter != m_rotaries.end()) { // Update the controller number that is associated with the // existing rotary widget. rotaryIter->controller = it->getControllerValue(); // Update the properties of the existing rotary widget. rotary = rotaryIter->rotary; rotary->setMinimum(it->getMin()); rotary->setMaximum(it->getMax()); // If the default is 64, then this is most likely a "centered" // control which should show its distance from the 12 o'clock // position around the outside. rotary->setCentered((it->getDefault() == 64)); rotary->setKnobColour(knobColour); // Update the controller name. rotaryIter->label->setText(QObject::tr(it->getName().c_str())); // Next Rotary widget ++rotaryIter; } else { // Need to create the Rotary widget. // Create a horizontal box for the Rotary/Label pair. QWidget *hbox = new QWidget(m_rotaryFrame); QHBoxLayout *hboxLayout = new QHBoxLayout; hboxLayout->setSpacing(8); hboxLayout->setMargin(0); hbox->setLayout(hboxLayout); // Add a Rotary float pageStep = 5.0; if (it->getMax() - it->getMin() < 10) pageStep = 1.0; else if (it->getMax() - it->getMin() < 20) pageStep = 2.0; rotary = new Rotary(hbox, // parent it->getMin(), // minimum it->getMax(), // maximum 1.0, // step pageStep, // pageStep it->getDefault(), // initialPosition 20, // size Rotary::NoTicks, // ticks false, // snapToTicks (it->getDefault() == 64)); // centred, see setCentered() above rotary->setKnobColour(knobColour); hboxLayout->addWidget(rotary); // Add a label SqueezedLabel *label = new SqueezedLabel(QObject::tr(it->getName().c_str()), hbox); label->setFont(font()); hboxLayout->addWidget(label); RG_DEBUG << "setupControllers(): Adding new widget at " << (count / 2) << "," << (count % 2); // Add the compound (Rotary and Label) widget to the grid. m_rotaryGrid->addWidget(hbox, count / 2, (count % 2) * 2, Qt::AlignLeft); hbox->show(); // Add to the Rotary info list RotaryInfo ri; ri.rotary = rotary; ri.label = label; ri.controller = it->getControllerValue(); m_rotaries.push_back(ri); // Connect for changes to the Rotary by the user. connect(rotary, SIGNAL(valueChanged(float)), m_rotaryMapper, SLOT(map())); rotaryIter = m_rotaries.end(); } // Add signal mapping // m_rotaryMapper->setMapping(rotary, int(it->getControllerValue())); ++count; } // If there are more rotary widgets than this instrument needs, // delete them. if (rotaryIter != m_rotaries.end()) { for (RotaryInfoVector::iterator it = rotaryIter; it != m_rotaries.end(); ++it) { // ??? Instead of deleting and recreating, we could hide the // extras and bring them back when needed. delete it->rotary; delete it->label; } m_rotaries.resize(count); } }