//============================================================================== void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const { out << "{<\n"; const int w = jmin (maxW, im.getWidth()); const int h = jmin (maxH, im.getHeight()); int charsOnLine = 0; const Image::BitmapData srcData (im, 0, 0, w, h); Colour pixel; for (int y = h; --y >= 0;) { for (int x = 0; x < w; ++x) { const uint8* pixelData = srcData.getPixelPointer (x, y); if (x >= sx && y >= sy) { if (im.isARGB()) { PixelARGB p (*(const PixelARGB*) pixelData); p.unpremultiply(); pixel = Colours::white.overlaidWith (Colour (p.getARGB())); } else if (im.isRGB()) { pixel = Colour (((const PixelRGB*) pixelData)->getARGB()); } else { pixel = Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixelData); } } else { pixel = Colours::transparentWhite; } const uint8 pixelValues[3] = { pixel.getRed(), pixel.getGreen(), pixel.getBlue() }; out << String::toHexString (pixelValues, 3, 0); charsOnLine += 3; if (charsOnLine > 100) { out << '\n'; charsOnLine = 0; } } } out << "\n>}\n"; }
XYZColour const XYZColour::from (Colour const& sRGB) { float r = sRGB.getRed () / 255.f; float g = sRGB.getGreen () / 255.f; float b = sRGB.getBlue () / 255.f; if (r > 0.04045f) r = 100.f * pow ((r + 0.055f) / 1.055f, 2.4f); else r = r / 12.92f; if (g > 0.04045f) g = 100.f * pow ((g + 0.055f) / 1.055f, 2.4f); else g = g / 12.92f; if (b > 0.04045f) b = 100.f * pow ((b + 0.055f) / 1.055f, 2.4f); else b = b / 12.92f; // D65 float x = r * 0.4124f + g * 0.3576f + b * 0.1805f; float y = r * 0.2126f + g * 0.7152f + b * 0.0722f; float z = r * 0.0193f + g * 0.1192f + b * 0.9505f; return XYZColour (x, y, z, sRGB.getAlpha() / 255.f); }
void ProcessorList::saveStateToXml(XmlElement* xml) { XmlElement* processorListState = xml->createNewChildElement("PROCESSORLIST"); for (int i = 0; i < 5; i++) { XmlElement* colorState = processorListState->createNewChildElement("COLOR"); int id; switch (i) { case 0: id = PROCESSOR_COLOR; break; case 1: id = SOURCE_COLOR; break; case 2: id = FILTER_COLOR; break; case 3: id = SINK_COLOR; break; case 4: id = UTILITY_COLOR; break; default: // do nothing ; } Colour c = findColour(id); colorState->setAttribute("ID", (int) id); colorState->setAttribute("R", (int) c.getRed()); colorState->setAttribute("G", (int) c.getGreen()); colorState->setAttribute("B", (int) c.getBlue()); } }
bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out) { using namespace jpeglibNamespace; using namespace JPEGHelpers; struct jpeg_compress_struct jpegCompStruct; jpeg_create_compress (&jpegCompStruct); struct jpeg_error_mgr jerr; setupSilentErrorHandler (jerr); jpegCompStruct.err = &jerr; JuceJpegDest dest; jpegCompStruct.dest = &dest; dest.output = &out; HeapBlock <char> tempBuffer (jpegBufferSize); dest.buffer = tempBuffer; dest.next_output_byte = (JOCTET*) dest.buffer; dest.free_in_buffer = jpegBufferSize; dest.init_destination = jpegWriteInit; dest.empty_output_buffer = jpegWriteFlush; dest.term_destination = jpegWriteTerminate; jpegCompStruct.image_width = (JDIMENSION) image.getWidth(); jpegCompStruct.image_height = (JDIMENSION) image.getHeight(); jpegCompStruct.input_components = 3; jpegCompStruct.in_color_space = JCS_RGB; jpegCompStruct.write_JFIF_header = 1; jpegCompStruct.X_density = 72; jpegCompStruct.Y_density = 72; jpeg_set_defaults (&jpegCompStruct); jpegCompStruct.dct_method = JDCT_FLOAT; jpegCompStruct.optimize_coding = 1; if (quality < 0.0f) quality = 0.85f; jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundToInt (quality * 100.0f)), TRUE); jpeg_start_compress (&jpegCompStruct, TRUE); const int strideBytes = (int) (jpegCompStruct.image_width * jpegCompStruct.input_components); JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct, JPOOL_IMAGE, (JDIMENSION) strideBytes, 1); const Image::BitmapData srcData (image, Image::BitmapData::readOnly); while (jpegCompStruct.next_scanline < jpegCompStruct.image_height) { uint8* dst = *buffer; if (srcData.pixelFormat == Image::RGB) { const uint8* src = srcData.getLinePointer ((int) jpegCompStruct.next_scanline); for (int i = srcData.width; --i >= 0;) { *dst++ = ((const PixelRGB*) src)->getRed(); *dst++ = ((const PixelRGB*) src)->getGreen(); *dst++ = ((const PixelRGB*) src)->getBlue(); src += srcData.pixelStride; } } else { for (int x = 0; x < srcData.width; ++x) { const Colour pixel (srcData.getPixelColour (x, (int) jpegCompStruct.next_scanline)); *dst++ = pixel.getRed(); *dst++ = pixel.getGreen(); *dst++ = pixel.getBlue(); } } jpeg_write_scanlines (&jpegCompStruct, buffer, 1); } jpeg_finish_compress (&jpegCompStruct); jpeg_destroy_compress (&jpegCompStruct); return 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 ControlEditorDialog::slotUpdate(bool added) { RG_DEBUG << "ControlEditorDialog::slotUpdate" << endl; MidiDevice *md = dynamic_cast<MidiDevice *>(m_studio->getDevice(m_device)); if (!md) return ; ControlList::const_iterator it = md->beginControllers(); ControlParameterItem *item; int i = 0; // Attempt to track last controller selected so we can reselect it int lastControllerId = -1; ControlParameterItem *lastItem = dynamic_cast<ControlParameterItem *>(m_treeWidget->currentItem()); if (lastItem) { lastControllerId = lastItem->getId(); } m_treeWidget->clear(); for (; it != md->endControllers(); ++it) { Composition &comp = m_doc->getComposition(); QString colour = strtoqstr(comp.getGeneralColourMap().getNameByIndex(it->getColourIndex())); if (colour == "") colour = tr("<default>"); QString position = QString("%1").arg(it->getIPBPosition()); if (position.toInt() == -1) position = tr("<not showing>"); QString value; value.sprintf("%d (0x%x)", it->getControllerValue(), it->getControllerValue()); if (it->getType() == PitchBend::EventType) { item = new ControlParameterItem( i++, m_treeWidget, QStringList() << strtoqstr(it->getName()) << strtoqstr(it->getType()) << QString("-") << strtoqstr(it->getDescription()) << QString("%1").arg(it->getMin()) << QString("%1").arg(it->getMax()) << QString("%1").arg(it->getDefault()) << colour << position ); } else { item = new ControlParameterItem( i++, m_treeWidget, QStringList() << strtoqstr(it->getName()) << strtoqstr(it->getType()) << value << strtoqstr(it->getDescription()) << QString("%1").arg(it->getMin()) << QString("%1").arg(it->getMax()) << QString("%1").arg(it->getDefault()) << colour << position ); } if (item->getId() == lastControllerId) { m_treeWidget->setCurrentItem(item); } // create and set a colour pixmap // QPixmap colourPixmap(16, 16); Colour c = comp.getGeneralColourMap().getColourByIndex(it->getColourIndex()); colourPixmap.fill(QColor(c.getRed(), c.getGreen(), c.getBlue())); item->setIcon(7, QIcon(colourPixmap)); m_treeWidget->addTopLevelItem(item); } if(m_treeWidget->topLevelItemCount() == 0) { QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget, QStringList(tr("<none>"))); m_treeWidget->addTopLevelItem(item); m_treeWidget->setSelectionMode(QAbstractItemView::NoSelection); } else { m_treeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); } // This logic is kind of frigged up, and may be too fragile. It assumes // that if you added an item, the last thing iterated through will be that // new item, so the value of the variable item will be the last thing // iterated through, and therefore the newest item you just added and want // to edit. // // I got substantially far along the way to making this quick and dirty hack // work before I thought it would be a lot cleaner to have the // AddControlParameterCommand itself launch the dialog and allow the user to // edit the parameters before ever adding it to the list at all. That would // be a lot cleaner, but it would also require going against the flow of how // this logic always worked, so it would require a lot more thought to // achieve the same end result that way. Instead, I just used this hack // overloaded slotUpdate() to tell it when a new controller was added, so we // could grab it here and launch the dialog on the generic blah we just added // to the list right before this slot got called with the optional bool set // true. // // (so much for verbose comments being helpful... I wrote that not too long // ago, and reading it now, I have NO fscking idea what I was talking about) // if (added) { RG_DEBUG << "ControlEditorDialog: detected new item entered; launching editor" << endl; m_treeWidget->setCurrentItem(item); slotEdit(item, 0); } }
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); } }
ControlParameterEditDialog::ControlParameterEditDialog( QWidget *parent, ControlParameter *control, RosegardenDocument *doc): QDialog(parent), m_doc(doc), m_control(control) { m_dialogControl = *control; // copy in the ControlParameter setModal(true); setWindowTitle(tr("Edit Controller")); QGridLayout *metagrid = new QGridLayout; setLayout(metagrid); QWidget *vbox = new QWidget(this); QVBoxLayout *vboxLayout = new QVBoxLayout; metagrid->addWidget(vbox, 0, 0); QGroupBox *frame = new QGroupBox(tr("Controller Properties"), vbox); vboxLayout->addWidget(frame); vbox->setLayout(vboxLayout); frame->setContentsMargins(10, 10, 10, 10); QGridLayout *layout = new QGridLayout(frame); layout->setSpacing(5); layout->addWidget(new QLabel(tr("Name:"), frame), 0, 0); m_nameEdit = new LineEdit(frame); layout->addWidget(m_nameEdit, 0, 1, 1, 2); layout->addWidget(new QLabel(tr("Type:"), frame), 1, 0); m_typeCombo = new QComboBox(frame); // spacing hack will stretch the whole grid layout, so combos don't get // scrunched up: m_typeCombo->setMinimumContentsLength(20); layout->addWidget(m_typeCombo, 1, 1, 1, 2); layout->addWidget(new QLabel(tr("Description:"), frame), 2, 0); m_description = new LineEdit(frame); layout->addWidget(m_description, 2, 1, 1, 2); // hex value alongside decimal value m_hexValue = new QLabel(frame); layout->addWidget(m_hexValue, 3, 1); layout->addWidget(new QLabel(tr("Controller number:"), frame), 3, 0); m_controllerBox = new QSpinBox(frame); layout->addWidget(m_controllerBox, 3, 2); layout->addWidget(new QLabel(tr("Minimum value:"), frame), 4, 0); m_minBox = new QSpinBox(frame); layout->addWidget(m_minBox, 4, 1, 1, 2); layout->addWidget(new QLabel(tr("Maximum value:"), frame), 5, 0); m_maxBox = new QSpinBox(frame); layout->addWidget(m_maxBox, 5, 1, 1, 2); layout->addWidget(new QLabel(tr("Default value:"), frame), 6, 0); m_defaultBox = new QSpinBox(frame); layout->addWidget(m_defaultBox, 6, 1, 1, 2); layout->addWidget(new QLabel(tr("Color:"), frame), 7, 0); m_colourCombo = new QComboBox(frame); layout->addWidget(m_colourCombo, 7, 1, 1, 2); layout->addWidget(new QLabel(tr("Instrument Parameter Box position:"), frame), 8, 0); m_ipbPosition = new QComboBox(frame); layout->addWidget(m_ipbPosition, 8, 1, 1, 2); frame->setLayout(layout); connect(m_nameEdit, SIGNAL(textChanged(const QString&)), SLOT(slotNameChanged(const QString&))); connect(m_typeCombo, SIGNAL(activated(int)), SLOT(slotTypeChanged(int))); connect(m_description, SIGNAL(textChanged(const QString&)), SLOT(slotDescriptionChanged(const QString &))); connect(m_controllerBox, SIGNAL(valueChanged(int)), SLOT(slotControllerChanged(int))); connect(m_minBox, SIGNAL(valueChanged(int)), SLOT(slotMinChanged(int))); connect(m_maxBox, SIGNAL(valueChanged(int)), SLOT(slotMaxChanged(int))); connect(m_defaultBox, SIGNAL(valueChanged(int)), SLOT(slotDefaultChanged(int))); connect(m_colourCombo, SIGNAL(activated(int)), SLOT(slotColourChanged(int))); connect(m_ipbPosition, SIGNAL(activated(int)), SLOT(slotIPBPositionChanged(int))); //m_nameEdit->selectAll(); //m_description->selectAll(); // set limits m_controllerBox->setMinimum(0); m_controllerBox->setMaximum(127); m_minBox->setMinimum(INT_MIN); m_minBox->setMaximum(INT_MAX); m_maxBox->setMinimum(INT_MIN); m_maxBox->setMaximum(INT_MAX); m_defaultBox->setMinimum(INT_MIN); m_defaultBox->setMaximum(INT_MAX); // populate combos m_typeCombo->addItem(strtoqstr(Controller::EventType)); m_typeCombo->addItem(strtoqstr(PitchBend::EventType)); /* m_typeCombo->addItem(strtoqstr(KeyPressure::EventType)); m_typeCombo->addItem(strtoqstr(ChannelPressure::EventType)); */ // Populate colour combo // // ColourMap &colourMap = m_doc->getComposition().getGeneralColourMap(); RCMap::const_iterator it; QPixmap colourPixmap(16, 16); for (it = colourMap.begin(); it != colourMap.end(); ++it) { Colour c = it->second.first; colourPixmap.fill(QColor(c.getRed(), c.getGreen(), c.getBlue())); m_colourCombo->addItem(colourPixmap, strtoqstr(it->second.second)); } // Populate IPB position combo // m_ipbPosition->addItem(tr("<not showing>")); // I couldn't find a constant for the maximum possible controller slots. // This seems to be it. It used to be 32. I upped it to 1024 because the // IPB is in a scrollable widget now, and that seems like a really // comfortable amount of headroom without being totally nuts like MAX_INT for (unsigned int i = 0; i < 1024; i++) m_ipbPosition->addItem(QString("%1").arg(i)); if (m_control->getType() == Controller::EventType) m_typeCombo->setCurrentIndex(0); else if (m_control->getType() == PitchBend::EventType) m_typeCombo->setCurrentIndex(1); /* else if (m_control->getType() == KeyPressure::EventType) m_typeCombo->setCurrentIndex(2); else if (m_control->getType() == ChannelPressure::EventType) m_typeCombo->setCurrentIndex(3); */ populate(); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); metagrid->addWidget(buttonBox, 1, 0); metagrid->setRowStretch(0, 10); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); }