Beispiel #1
0
void RGBMatrix_Test::previewMaps()
{
    RGBMatrix mtx(m_doc);
    QVERIFY(mtx.algorithm() != NULL);
    QCOMPARE(mtx.algorithm()->name(), QString("Stripes"));

    int steps = mtx.stepsCount();
    QCOMPARE(steps, 0);

    RGBMap map = mtx.previewMap(0);
    QCOMPARE(map.size(), 0); // No fixture group

    mtx.setFixtureGroup(0);
    steps = mtx.stepsCount();
    QCOMPARE(steps, 5);

    map = mtx.previewMap(0);
    QCOMPARE(map.size(), 5);

    for (int z = 0; z < steps; z++)
    {
        map = mtx.previewMap(z);
        for (int y = 0; y < 5; y++)
        {
            for (int x = 0; x < 5; x++)
            {
                if (x == z)
                    QCOMPARE(map[y][x], QColor(Qt::black).rgb());
                else
                    QCOMPARE(map[y][x], uint(0));
            }
        }
    }
}
Beispiel #2
0
void RGBText_Test::verticalScroll()
{
    RGBText text(m_doc);
    text.setText("QLC");
    text.setAnimationStyle(RGBText::Vertical);

    QFontMetrics fm(text.font());
    QCOMPARE(text.rgbMapStepCount(QSize()), fm.ascent() * 3); // Q, L, C

    // Since fonts and their rendering differs from installation to installation,
    // these tests are here only to check that nothing crashes. The end result is
    // more or less OS, platform, HW and SW dependent and testing individual pixels
    // would thus be rather pointless.
    for (int i = 0; i < fm.ascent() * 3; i++)
    {
        RGBMap map = text.rgbMap(QSize(10, 10), QRgb(0xFFFFFFFF), i);
        QCOMPARE(map.size(), 10);
        for (int y = 0; y < 10; y++)
            QCOMPARE(map[y].size(), 10);
    }

    // Invalid step
    RGBMap map = text.rgbMap(QSize(10, 10), QRgb(0xFFFFFFFF), fm.ascent() * 4);
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
    {
        QCOMPARE(map[i].size(), 10);
        for (int j = 0; j < 10; j++)
        {
            QCOMPARE(map[i][j], QRgb(0));
        }
    }
}
Beispiel #3
0
void RGBText_Test::horizontalScroll()
{
    RGBText text(m_doc);
    text.setText("QLC");
    text.setAnimationStyle(RGBText::Horizontal);

    QFontMetrics fm(text.font());
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
    QCOMPARE(text.rgbMapStepCount(QSize()), fm.width("QLC"));
#else
    QCOMPARE(text.rgbMapStepCount(QSize()), fm.horizontalAdvance("QLC"));
#endif

    // Since fonts and their rendering differs from installation to installation,
    // these tests are here only to check that nothing crashes. The end result is
    // more or less OS, platform, HW and SW dependent and testing individual pixels
    // would thus be rather pointless.
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
    for (int i = 0; i < fm.width("QLC"); i++)
#else
    for (int i = 0; i < fm.horizontalAdvance("QLC"); i++)
#endif
    {
        RGBMap map = text.rgbMap(QSize(10, 10), QRgb(0xFFFFFFFF), i);
        QCOMPARE(map.size(), 10);
        for (int y = 0; y < 10; y++)
            QCOMPARE(map[y].size(), 10);
    }

    // Invalid step
#if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
    RGBMap map = text.rgbMap(QSize(10, 10), QRgb(0xFFFFFFFF), fm.width("QLC"));
#else
    RGBMap map = text.rgbMap(QSize(10, 10), QRgb(0xFFFFFFFF), fm.horizontalAdvance("QLC"));
#endif
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
    {
        QCOMPARE(map[i].size(), 10);
        for (int j = 0; j < 10; j++)
        {
            QCOMPARE(map[i][j], QRgb(0));
        }
    }
}
Beispiel #4
0
void RGBText_Test::staticLetters()
{
    RGBText text(m_doc);
    text.setText("QLC");
    text.setAnimationStyle(RGBText::StaticLetters);
    QCOMPARE(text.rgbMapStepCount(QSize()), 3); // Q, L, C

    QRgb color(0xFFFFFFFF);

    // Since fonts and their rendering differs from installation to installation,
    // these tests are here only to check that nothing crashes. The end result is
    // more or less OS, platform, HW and SW dependent and testing individual pixels
    // would thus be rather pointless.
    RGBMap map = text.rgbMap(QSize(10, 10), color, 0);
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
        QCOMPARE(map[i].size(), 10);

    map = text.rgbMap(QSize(10, 10), color, 1);
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
        QCOMPARE(map[i].size(), 10);

    map = text.rgbMap(QSize(10, 10), color, 2);
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
        QCOMPARE(map[i].size(), 10);

    // Invalid step
    map = text.rgbMap(QSize(10, 10), color, 3);
    QCOMPARE(map.size(), 10);
    for (int i = 0; i < 10; i++)
    {
        QCOMPARE(map[i].size(), 10);
        for (int j = 0; j < 10; j++)
        {
            QCOMPARE(map[i][j], QColor(Qt::black).rgb());
        }
    }
}
Beispiel #5
0
void RGBMatrixEditor::slotPreviewTimeout()
{
    RGBItem* shape = NULL;

    if (m_matrix->duration() <= 0)
        return;

    m_previewIterator += MasterTimer::tick();
    if (m_previewIterator >= m_matrix->duration())
    {
        //qDebug() << "previewTimeout. Step:" << m_previewStep;
        if (m_matrix->runOrder() == RGBMatrix::PingPong)
        {
            if (m_previewDirection == Function::Forward && (m_previewStep + 1) == m_previewMaps.size())
                m_previewDirection = Function::Backward;
            else if (m_previewDirection == Function::Backward && (m_previewStep - 1) < 0)
                m_previewDirection = Function::Forward;
        }

        if (m_previewDirection == Function::Forward)
        {
            m_previewStep++;
            if (m_previewStep >= m_previewMaps.size())
            {
                m_previewStep = 0;
                m_matrix->setStepColor(m_matrix->startColor());
            }
            else
                m_matrix->updateStepColor(m_previewDirection);
        }
        else
        {
            m_previewStep--;
            if (m_previewStep < 0)
            {
                m_previewStep = m_previewMaps.size() - 1;
                if (m_matrix->endColor().isValid())
                    m_matrix->setStepColor(m_matrix->endColor());
                else
                    m_matrix->setStepColor(m_matrix->startColor());
            }
            else
                m_matrix->updateStepColor(m_previewDirection);
        }
        m_previewMaps = m_matrix->previewMaps();
        m_previewIterator = 0;
    }

    RGBMap map;
    if (m_previewStep >= 0 && m_previewStep < m_previewMaps.size())
        map = m_previewMaps[m_previewStep];

    for (int y = 0; y < map.size(); y++)
    {
        for (int x = 0; x < map[y].size(); x++)
        {
            QLCPoint pt(x, y);
            if (m_previewHash.contains(pt) == true)
            {
                shape = static_cast<RGBItem*>(m_previewHash[pt]);
                if (shape->color() != QColor(map[y][x]).rgb())
                    shape->setColor(map[y][x]);

                if (shape->color() == QColor(Qt::black).rgb())
                    shape->draw(m_matrix->fadeOutSpeed());
                else
                    shape->draw(m_matrix->fadeInSpeed());
            }
        }
    }
}
Beispiel #6
0
bool RGBMatrixEditor::createPreviewItems()
{
    m_previewHash.clear();
    m_scene->clear();

    FixtureGroup* grp = m_doc->fixtureGroup(m_matrix->fixtureGroup());
    if (grp == NULL)
    {
        QGraphicsTextItem* text = new QGraphicsTextItem(tr("No fixture group to control"));
        text->setDefaultTextColor(Qt::white);
        m_scene->addItem(text);
        return false;
    }

    m_previewDirection = m_matrix->direction();

    if (m_previewDirection == Function::Forward)
    {
        m_matrix->setStepColor(m_matrix->startColor());
    }
    else
    {
        if (m_matrix->endColor().isValid())
            m_matrix->setStepColor(m_matrix->endColor());
        else
            m_matrix->setStepColor(m_matrix->startColor());
    }

    m_matrix->calculateColorDelta();
    m_previewMaps = m_matrix->previewMaps();

    if ((m_previewDirection == Function::Forward) || m_previewMaps.isEmpty())
    {
        m_previewStep = 0;
    }
    else
    {
        m_previewStep = m_previewMaps.size() - 1;
    }

    RGBMap map;
    if (m_previewStep < m_previewMaps.size())
        map = m_previewMaps[m_previewStep];

    if (map.isEmpty())
        return false;

    for (int x = 0; x < grp->size().width(); x++)
    {
        for (int y = 0; y < grp->size().height(); y++)
        {
            QLCPoint pt(x, y);

            if (grp->headHash().contains(pt) == true)
            {
                RGBItem* item = new RGBItem;
                item->setRect(x * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
                              y * RECT_SIZE + RECT_PADDING + ITEM_PADDING,
                              ITEM_SIZE - (2 * ITEM_PADDING),
                              ITEM_SIZE - (2 * ITEM_PADDING));
                item->setColor(map[y][x]);
                item->draw(0);
                m_scene->addItem(item);
                m_previewHash[pt] = item;
            }
        }
    }
    return true;
}
Beispiel #7
0
void RGBMatrix::updateMapChannels(const RGBMap& map, const FixtureGroup* grp)
{
    quint32 mdAssigned = QLCChannel::invalid();
    quint32 mdFxi = Fixture::invalidId();

    uint fadeTime = 0;
    if (overrideFadeInSpeed() == defaultSpeed())
        fadeTime = fadeInSpeed();
    else
        fadeTime = overrideFadeInSpeed();

    // Create/modify fade channels for ALL pixels in the color map.
    for (int y = 0; y < map.size(); y++)
    {
        for (int x = 0; x < map[y].size(); x++)
        {
            QLCPoint pt(x, y);
            GroupHead grpHead(grp->head(pt));
            Fixture* fxi = doc()->fixture(grpHead.fxi);
            if (fxi == NULL)
                continue;

            if (grpHead.fxi != mdFxi)
            {
                mdAssigned = QLCChannel::invalid();
                mdFxi = grpHead.fxi;
            }

            QLCFixtureHead head = fxi->head(grpHead.head);

            QVector <quint32> rgb = head.rgbChannels();
            QVector <quint32> cmy = head.cmyChannels();
            if (rgb.size() == 3)
            {
                // RGB color mixing
                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);

                fc.setChannel(rgb.at(0));
                fc.setTarget(qRed(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(rgb.at(1));
                fc.setTarget(qGreen(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(rgb.at(2));
                fc.setTarget(qBlue(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }
            else if (cmy.size() == 3)
            {
                // CMY color mixing
                QColor col(map[y][x]);

                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);

                fc.setChannel(cmy.at(0));
                fc.setTarget(col.cyan());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(cmy.at(1));
                fc.setTarget(col.magenta());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(cmy.at(2));
                fc.setTarget(col.yellow());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }

            if (m_dimmerControl &&
                head.masterIntensityChannel() != QLCChannel::invalid())
            {
                //qDebug() << "RGBMatrix: found dimmer at" << head.masterIntensityChannel();
                // Simple intensity (dimmer) channel
                QColor col(map[y][x]);
                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);
                fc.setChannel(head.masterIntensityChannel());
                if (col.value() == 0 && mdAssigned != head.masterIntensityChannel())
                    fc.setTarget(0);
                else
                {
                    fc.setTarget(255);
                    if (mdAssigned == QLCChannel::invalid())
                        mdAssigned = head.masterIntensityChannel();
                }
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }
        }
    }
}
Beispiel #8
0
void RGBMatrixEditor::slotPreviewTimeout()
{
    if (m_matrix == NULL || m_group == NULL || m_matrix->duration() <= 0)
        return;

    RGBMap map;

    m_previewIterator += MasterTimer::tick();

    if (m_previewIterator >= m_matrix->duration())
    {
        int stepsCount = m_matrix->stepsCount();
        //qDebug() << "previewTimeout. Step:" << m_previewStep;
        if (m_matrix->runOrder() == RGBMatrix::PingPong)
        {
            if (m_previewDirection == Function::Forward && (m_previewStep + 1) == stepsCount)
                m_previewDirection = Function::Backward;
            else if (m_previewDirection == Function::Backward && (m_previewStep - 1) < 0)
                m_previewDirection = Function::Forward;
        }

        if (m_previewDirection == Function::Forward)
        {
            m_previewStep++;
            if (m_previewStep >= stepsCount)
            {
                m_previewStep = 0;
                m_matrix->setStepColor(m_matrix->startColor());
            }
            else
                m_matrix->updateStepColor(m_previewStep);
        }
        else
        {
            m_previewStep--;
            if (m_previewStep < 0)
            {
                m_previewStep = stepsCount - 1;
                if (m_matrix->endColor().isValid())
                    m_matrix->setStepColor(m_matrix->endColor());
                else
                    m_matrix->setStepColor(m_matrix->startColor());
            }
            else
                m_matrix->updateStepColor(m_previewStep);
        }
        map = m_matrix->previewMap(m_previewStep);
        m_previewIterator = 0;
/*
        for (int y = 0; y < map.size(); y++)
        {
            for (int x = 0; x < map[y].size(); x++)
            {
                QLCPoint pt(x, y);
                if (m_group->head(pt).isValid())
                {
                    if (shape->color() != QColor(map[y][x]).rgb())
                        shape->setColor(map[y][x]);

                    if (shape->color() == QColor(Qt::black).rgb())
                        shape->draw(m_matrix->fadeOutSpeed());
                    else
                        shape->draw(m_matrix->fadeInSpeed());
                }
            }
        }
*/
        if (m_previewData.isEmpty() || map.isEmpty())
            return;

        QHashIterator<QLCPoint, GroupHead> it(m_group->headHash());
        while(it.hasNext())
        {
            it.next();

            QLCPoint pt(it.key());
            //GroupHead head(it.value());
            int ptIdx = pt.x() + (pt.y() * m_group->size().width());
            if (ptIdx < m_previewData.size())
                m_previewData[ptIdx] = QVariant(QColor(map[pt.y()][pt.x()]));
        }

        //qDebug() << "Preview data changed !";
        emit previewDataChanged(m_previewData);
    }
}
Beispiel #9
0
void RGBMatrix::updateMapChannels(const RGBMap& map, const FixtureGroup* grp)
{
    uint fadeTime = (overrideFadeInSpeed() == defaultSpeed()) ? fadeInSpeed() : overrideFadeInSpeed();

    // Create/modify fade channels for ALL pixels in the color map.
    for (int y = 0; y < map.size(); y++)
    {
        for (int x = 0; x < map[y].size(); x++)
        {
            QLCPoint pt(x, y);
            GroupHead grpHead(grp->head(pt));
            Fixture* fxi = doc()->fixture(grpHead.fxi);
            if (fxi == NULL)
                continue;

            QLCFixtureHead head = fxi->head(grpHead.head);

            QVector <quint32> rgb = head.rgbChannels();
            QVector <quint32> cmy = head.cmyChannels();

            quint32 masterDim = fxi->masterIntensityChannel();
            quint32 headDim = head.channelNumber(QLCChannel::Intensity, QLCChannel::MSB);

            // Collect all dimmers that affect current head:
            // They are the master dimmer (affects whole fixture)
            // and per-head dimmer.
            //
            // If there are no RGB or CMY channels, the least important* dimmer channel
            // is used to create grayscale image.
            //
            // The rest of the dimmer channels are set to full if dimmer control is
            // enabled and target color is > 0 (see
            // http://www.qlcplus.org/forum/viewtopic.php?f=29&t=11090)
            //
            // Note: If there is only one head, and only one dimmer channel,
            // make it a master dimmer in fixture definition.
            //
            // *least important - per head dimmer if present,
            // otherwise per fixture dimmer if present
            QVector <quint32> dim;
            if (masterDim != QLCChannel::invalid())
                dim << masterDim;

            if (headDim != QLCChannel::invalid())
                dim << headDim;

            uint col = map[y][x];

            if (rgb.size() == 3)
            {
                // RGB color mixing
                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(0));
                    fc.setTarget(qRed(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(1));
                    fc.setTarget(qGreen(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(2));
                    fc.setTarget(qBlue(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
            else if (cmy.size() == 3)
            {
                // CMY color mixing
                QColor cmyCol(col);

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(0));
                    fc.setTarget(cmyCol.cyan());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(1));
                    fc.setTarget(cmyCol.magenta());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(2));
                    fc.setTarget(cmyCol.yellow());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
            else if (!dim.empty())
            {
                // Set dimmer to value of the color (e.g. for PARs)
                FadeChannel fc(doc(), grpHead.fxi, dim.last());
                // the weights are taken from
                // https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601
                fc.setTarget(0.299 * qRed(col) + 0.587 * qGreen(col) + 0.114 * qBlue(col));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
                dim.pop_back();
            }

            if (m_dimmerControl)
            {
                // Set the rest of the dimmer channels to full on
                foreach(quint32 ch, dim)
                {
                    FadeChannel fc(doc(), grpHead.fxi, ch);
                    fc.setTarget(col == 0 ? 0 : 255);
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
        }
    }