예제 #1
0
AbstractScopeWidget::AbstractScopeWidget(bool trackMouse, QWidget *parent) :
        QWidget(parent)
        , m_mousePos(0, 0)
        , m_mouseWithinWidget(false)
        , offset(5)
        , m_accelFactorHUD(1)
        , m_accelFactorScope(1)
        , m_accelFactorBackground(1)
        , m_semaphoreHUD(1)
        , m_semaphoreScope(1)
        , m_semaphoreBackground(1)
        , initialDimensionUpdateDone(false)
        , m_requestForcedUpdate(false)
        , m_rescaleMinDist(4)
        , m_rescaleVerticalThreshold(2.0f)
        , m_rescaleActive(false)
	, m_rescalePropertiesLocked(false)
	, m_rescaleFirstRescaleDone(true)
	, m_rescaleDirection(North)

{
    m_scopePalette = QPalette();
    m_scopePalette.setBrush(QPalette::Window, QBrush(dark2));
    m_scopePalette.setBrush(QPalette::Base, QBrush(dark));
    m_scopePalette.setBrush(QPalette::Button, QBrush(dark));
    m_scopePalette.setBrush(QPalette::Text, QBrush(light));
    m_scopePalette.setBrush(QPalette::WindowText, QBrush(light));
    m_scopePalette.setBrush(QPalette::ButtonText, QBrush(light));
    this->setPalette(m_scopePalette);
    this->setAutoFillBackground(true);

    m_aAutoRefresh = new QAction(i18n("Auto Refresh"), this);
    m_aAutoRefresh->setCheckable(true);
    m_aRealtime = new QAction(i18n("Realtime (with precision loss)"), this);
    m_aRealtime->setCheckable(true);

    m_menu = new QMenu(this);
    // Disabled dark palette on menus since it breaks up with some themes: kdenlive issue #2950
    //m_menu->setPalette(m_scopePalette);
    m_menu->addAction(m_aAutoRefresh);
    m_menu->addAction(m_aRealtime);

    this->setContextMenuPolicy(Qt::CustomContextMenu);

    bool b = true;
    b &= connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint)));

    b &= connect(this, SIGNAL(signalHUDRenderingFinished(uint, uint)), this, SLOT(slotHUDRenderingFinished(uint, uint)));
    b &= connect(this, SIGNAL(signalScopeRenderingFinished(uint, uint)), this, SLOT(slotScopeRenderingFinished(uint, uint)));
    b &= connect(this, SIGNAL(signalBackgroundRenderingFinished(uint, uint)), this, SLOT(slotBackgroundRenderingFinished(uint, uint)));
    b &= connect(m_aRealtime, SIGNAL(toggled(bool)), this, SLOT(slotResetRealtimeFactor(bool)));
    b &= connect(m_aAutoRefresh, SIGNAL(toggled(bool)), this, SLOT(slotAutoRefreshToggled(bool)));
    Q_ASSERT(b);

    // Enable mouse tracking if desired.
    // Causes the mouseMoved signal to be emitted when the mouse moves inside the
    // widget, even when no mouse button is pressed.
    this->setMouseTracking(trackMouse);
}
예제 #2
0
QImage AudioSpectrum::renderHUD(uint)
{
    QTime start = QTime::currentTime();

    if (m_innerScopeRect.height() > 0 && m_innerScopeRect.width() > 0) { // May be below 0 if widget is too small

        // Minimum distance between two lines
        const uint minDistY = 30;
        const uint minDistX = 40;
        const uint textDistX = 10;
        const uint textDistY = 25;
        const uint topDist = m_innerScopeRect.top() - m_scopeRect.top();
        const uint leftDist = m_innerScopeRect.left() - m_scopeRect.left();
        const uint dbDiff = ceil((float)minDistY/m_innerScopeRect.height() * (m_dBmax-m_dBmin));
        const int mouseX = m_mousePos.x() - m_innerScopeRect.left();
        const int mouseY = m_mousePos.y() - m_innerScopeRect.top();


        QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
        hud.fill(qRgba(0,0,0,0));

        QPainter davinci(&hud);
        davinci.setPen(AbstractScopeWidget::penLight);

        int y;
        for (int db = -dbDiff; db > m_dBmin; db -= dbDiff) {
            y = topDist + m_innerScopeRect.height() * ((float)db)/(m_dBmin - m_dBmax);
            if (y-topDist > m_innerScopeRect.height()-minDistY+10) {
                // Abort here, there is still a line left for min dB to paint which needs some room.
                break;
            }
            davinci.drawLine(leftDist, y, leftDist + m_innerScopeRect.width()-1, y);
            davinci.drawText(leftDist + m_innerScopeRect.width() + textDistX, y + 6, i18n("%1 dB", m_dBmax + db));
        }
        davinci.drawLine(leftDist, topDist, leftDist + m_innerScopeRect.width()-1, topDist);
        davinci.drawText(leftDist + m_innerScopeRect.width() + textDistX, topDist+6, i18n("%1 dB", m_dBmax));
        davinci.drawLine(leftDist, topDist+m_innerScopeRect.height()-1, leftDist + m_innerScopeRect.width()-1, topDist+m_innerScopeRect.height()-1);
        davinci.drawText(leftDist + m_innerScopeRect.width() + textDistX, topDist+m_innerScopeRect.height()+6, i18n("%1 dB", m_dBmin));

        const uint hzDiff = ceil( ((float)minDistX)/m_innerScopeRect.width() * m_freqMax / 1000 ) * 1000;
        int x = 0;
        const int rightBorder = leftDist + m_innerScopeRect.width()-1;
        y = topDist + m_innerScopeRect.height() + textDistY;
        for (int hz = 0; x <= rightBorder; hz += hzDiff) {
            davinci.setPen(AbstractScopeWidget::penLighter);
            x = leftDist + m_innerScopeRect.width() * ((float)hz)/m_freqMax;

            if (x <= rightBorder) {
                davinci.drawLine(x, topDist, x, topDist + m_innerScopeRect.height()+6);
            }
            if (hz < m_freqMax && x+textDistY < leftDist + m_innerScopeRect.width()) {
                davinci.drawText(x-4, y, QVariant(hz/1000).toString());
            } else {
                x = leftDist + m_innerScopeRect.width();
                davinci.drawLine(x, topDist, x, topDist + m_innerScopeRect.height()+6);
                davinci.drawText(x-10, y, i18n("%1 kHz", QString("%1").arg((double)m_freqMax/1000, 0, 'f', 1)));
            }

            if (hz > 0) {
                // Draw finer lines between the main lines
                davinci.setPen(AbstractScopeWidget::penLightDots);
                for (uint dHz = 3; dHz > 0; dHz--) {
                    x = leftDist + m_innerScopeRect.width() * ((float)hz - dHz * hzDiff/4.0f)/m_freqMax;
                    if (x > rightBorder) {
                        break;
                    }
                    davinci.drawLine(x, topDist, x, topDist + m_innerScopeRect.height()-1);
                }
            }
        }

        if (m_aTrackMouse->isChecked() && m_mouseWithinWidget && mouseX < m_innerScopeRect.width()-1) {
            davinci.setPen(AbstractScopeWidget::penThin);

            x = leftDist + mouseX;

            float db = 0;
            float freq = ((float) mouseX)/(m_innerScopeRect.width()-1) * m_freqMax;
            bool drawDb = false;

            m_lastFFTLock.acquire();
            // We need to test whether the mouse is inside the widget
            // because the position could already have changed in the meantime (-> crash)
            if (m_lastFFT.size() > 0 && mouseX >= 0 && mouseX < m_innerScopeRect.width()) {
                uint right = ((float) m_freqMax)/(m_freq/2) * (m_lastFFT.size() - 1);
                QVector<float> dbMap = FFTTools::interpolatePeakPreserving(m_lastFFT, m_innerScopeRect.width(), 0, right, -120);

                db = dbMap[mouseX];
                y = topDist + m_innerScopeRect.height()-1 - (dbMap[mouseX] - m_dBmin) / (m_dBmax-m_dBmin) * (m_innerScopeRect.height()-1);

                if (y < (int)topDist + m_innerScopeRect.height()-1) {
                    drawDb = true;
                    davinci.drawLine(x, y, leftDist + m_innerScopeRect.width()-1, y);
                }
            } else {
                y = topDist + mouseY;
            }
            m_lastFFTLock.release();

            if (y > (int)topDist + mouseY) {
                y = topDist+ mouseY;
            }
            davinci.drawLine(x, y, x, topDist + m_innerScopeRect.height()-1);

            if (drawDb) {
                QPoint dist(20, -20);
                QRect rect(
                            leftDist + mouseX + dist.x(),
                            topDist + mouseY + dist.y(),
                            100,
                            40
                            );
                if (rect.right() > (int)leftDist + m_innerScopeRect.width()-1) {
                    // Mirror the rectangle at the y axis to keep it inside the widget
                    rect = QRect(
                                rect.topLeft() - QPoint(rect.width() + 2*dist.x(), 0),
                                rect.size());
                }

                QRect textRect(
                            rect.topLeft() + QPoint(12, 4),
                            rect.size()
                            );

                davinci.fillRect(rect, AbstractScopeWidget::penBackground.brush());
                davinci.setPen(AbstractScopeWidget::penLighter);
                davinci.drawRect(rect);
                davinci.drawText(textRect, QString(
                                     i18n("%1 dB", QString("%1").arg(db, 0, 'f', 2))
                                     + '\n'
                                     + i18n("%1 kHz", QString("%1").arg(freq/1000, 0, 'f', 2))));
            }

        }

        emit signalHUDRenderingFinished(start.elapsed(), 1);
        return hud;

    } else {
#ifdef DEBUG_AUDIOSPEC
        qDebug() << "Widget is too small for painting inside. Size of inner scope rect is "
                 << m_innerScopeRect.width() << "x" << m_innerScopeRect.height() <<".";
#endif
        emit signalHUDRenderingFinished(0, 1);
        return QImage();
    }

}
예제 #3
0
QImage Waveform::renderHUD(uint)
{
    QImage hud(m_scopeRect.size(), QImage::Format_ARGB32);
    hud.fill(qRgba(0,0,0,0));

    QPainter davinci(&hud);
    davinci.setPen(penLight);

    QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(KdenliveSettings::current_profile());
//    qDebug() << values.value("width");

    const int rightX = scopeRect().width()-m_textWidth.width()+3;
    const int x = m_mousePos.x() - scopeRect().x();
    const int y = m_mousePos.y() - scopeRect().y();

    if (scopeRect().height() > 0 && m_mouseWithinWidget) {
        int val = 255*(1-(float)y/scopeRect().height());

        if (val >= 0 && val <= 255) {
            // Draw a horizontal line through the current mouse position
            // and show the value of the waveform there
            davinci.drawLine(0, y, scopeRect().size().width()-m_textWidth.width(), y);

            // Make the value stick to the line unless it is at the top/bottom of the scope
            int valY = y+5;
            const int top = 30;
            const int bottom = 20;
            if (valY < top) {
                valY = top;
            } else if (valY > scopeRect().height()-bottom) {
                valY = scopeRect().height()-bottom;
            }
            davinci.drawText(rightX, valY, QVariant(val).toString());
        }

        if (scopeRect().width() > 0) {
            // Draw a vertical line and the x position of the source clip
            bool ok;
            const int profileWidth = values.value("width").toInt(&ok);

            if (ok) {
                const int clipX = (float)x/(scopeRect().width()-m_textWidth.width()-1)*(profileWidth-1);

                if (clipX >= 0 && clipX <= profileWidth) {
                    int valX = x-15;
                    if (valX < 0) { valX = 0; }
                    if (valX > scopeRect().width()-55-m_textWidth.width()) { valX = scopeRect().width()-55-m_textWidth.width(); }

                    davinci.drawLine(x, y, x, scopeRect().height()-m_paddingBottom);
                    davinci.drawText(valX, scopeRect().height()-5, QVariant(clipX).toString() + " px");
                }
            }
        }

    }
    davinci.drawText(rightX, scopeRect().height()-m_paddingBottom, "0");
    davinci.drawText(rightX, 10, "255");

    emit signalHUDRenderingFinished(0, 1);
    return hud;
}
예제 #4
0
QImage Histogram::renderHUD(uint)
{
    emit signalHUDRenderingFinished(0, 1);
    return QImage();
}