]> git.sesse.net Git - kdenlive/commitdiff
Made AbstractAudioScope and AbstractGfxScope inherit from AbstractScope; Done for...
authorSimon A. Eugster <simon.eu@gmail.com>
Fri, 3 Dec 2010 17:10:22 +0000 (17:10 +0000)
committerSimon A. Eugster <simon.eu@gmail.com>
Fri, 3 Dec 2010 17:10:22 +0000 (17:10 +0000)
svn path=/trunk/kdenlive/; revision=5129

18 files changed:
src/CMakeLists.txt
src/abstractgfxscopewidget.cpp [new file with mode: 0644]
src/abstractgfxscopewidget.h [new file with mode: 0644]
src/abstractscopewidget.cpp
src/abstractscopewidget.h
src/audioscopes/abstractaudioscopewidget.cpp
src/audioscopes/abstractaudioscopewidget.h
src/audioscopes/audiospectrum.cpp
src/audioscopes/audiospectrum.h
src/histogram.cpp
src/histogram.h
src/mainwindow.cpp
src/rgbparade.cpp
src/rgbparade.h
src/vectorscope.cpp
src/vectorscope.h
src/waveform.cpp
src/waveform.h

index 38c7a0efefab27582dda5bb56cfa9eb3db27428d..80fbab923cded2202f7abba4388fe2bd1fb2c8c0 100644 (file)
@@ -220,6 +220,7 @@ set(kdenlive_SRCS
   tracksconfigdialog.cpp
   configtrackscommand.cpp
   abstractscopewidget.cpp
+  abstractgfxscopewidget.cpp
   audioscopes/abstractaudioscopewidget.cpp
   audioscopes/audiospectrum.cpp
   rebuildgroupcommand.cpp
diff --git a/src/abstractgfxscopewidget.cpp b/src/abstractgfxscopewidget.cpp
new file mode 100644 (file)
index 0000000..48020ee
--- /dev/null
@@ -0,0 +1,459 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#include "qtconcurrentrun.h"
+
+#include "abstractgfxscopewidget.h"
+#include "renderer.h"
+#include "monitor.h"
+
+#include <QFuture>
+#include <QColor>
+#include <QMenu>
+#include <QMouseEvent>
+#include <QPainter>
+
+const int REALTIME_FPS = 30;
+
+const QColor light(250, 238, 226, 255);
+const QColor dark(40,  40,  39, 255);
+const QColor dark2(25,  25,  23, 255);
+
+const QPen AbstractGfxScopeWidget::penThick(QBrush(QColor(250, 250, 250)),     2, Qt::SolidLine);
+const QPen AbstractGfxScopeWidget::penThin(QBrush(QColor(250, 250, 250)),     1, Qt::SolidLine);
+const QPen AbstractGfxScopeWidget::penLight(QBrush(QColor(200, 200, 250, 150)), 1, Qt::SolidLine);
+const QPen AbstractGfxScopeWidget::penLightDots(QBrush(QColor(200, 200, 250, 150)), 1, Qt::DotLine);
+const QPen AbstractGfxScopeWidget::penDark(QBrush(QColor(0, 0, 20, 250)),      1, Qt::SolidLine);
+const QPen AbstractGfxScopeWidget::penDarkDots(QBrush(QColor(0, 0, 20, 250)),      1, Qt::DotLine);
+
+AbstractGfxScopeWidget::AbstractGfxScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse, QWidget *parent) :
+        QWidget(parent),
+        m_projMonitor(projMonitor),
+        m_clipMonitor(clipMonitor),
+        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_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);
+    m_menu->setPalette(m_scopePalette);
+    m_menu->addAction(m_aAutoRefresh);
+    m_menu->addAction(m_aRealtime);
+
+    this->setContextMenuPolicy(Qt::CustomContextMenu);
+
+    m_activeRender = (m_clipMonitor->isActive()) ? m_clipMonitor->render : m_projMonitor->render;
+
+    bool b = true;
+    b &= connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint)));
+
+    //b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated()));
+    b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage)));
+
+    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);
+}
+
+AbstractGfxScopeWidget::~AbstractGfxScopeWidget()
+{
+    writeConfig();
+
+    delete m_menu;
+    delete m_aAutoRefresh;
+    delete m_aRealtime;
+}
+
+void AbstractGfxScopeWidget::init()
+{
+    m_widgetName = widgetName();
+    readConfig();
+}
+
+void AbstractGfxScopeWidget::readConfig()
+{
+    KSharedConfigPtr config = KGlobal::config();
+    KConfigGroup scopeConfig(config, configName());
+    m_aAutoRefresh->setChecked(scopeConfig.readEntry("autoRefresh", true));
+    m_aRealtime->setChecked(scopeConfig.readEntry("realtime", false));
+    scopeConfig.sync();
+}
+
+void AbstractGfxScopeWidget::writeConfig()
+{
+    KSharedConfigPtr config = KGlobal::config();
+    KConfigGroup scopeConfig(config, configName());
+    scopeConfig.writeEntry("autoRefresh", m_aAutoRefresh->isChecked());
+    scopeConfig.writeEntry("realtime", m_aRealtime->isChecked());
+    scopeConfig.sync();
+}
+
+QString AbstractGfxScopeWidget::configName()
+{
+    return "Scope_" + m_widgetName;
+}
+
+void AbstractGfxScopeWidget::prodHUDThread()
+{
+    if (this->visibleRegion().isEmpty()) {
+//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating HUD.";
+    } else {
+        if (m_semaphoreHUD.tryAcquire(1)) {
+            Q_ASSERT(!m_threadHUD.isRunning());
+
+            m_newHUDFrames.fetchAndStoreRelaxed(0);
+            m_newHUDUpdates.fetchAndStoreRelaxed(0);
+            m_threadHUD = QtConcurrent::run(this, &AbstractGfxScopeWidget::renderHUD, m_accelFactorHUD);
+//            qDebug() << "HUD thread started in " << m_widgetName;
+
+        } else {
+//            qDebug() << "HUD semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadHUD.isRunning();
+        }
+    }
+}
+
+void AbstractGfxScopeWidget::prodScopeThread()
+{
+    // Only start a new thread if the scope is actually visible
+    // and not hidden by another widget on the stack and if user want the scope to update.
+    if (this->visibleRegion().isEmpty() || (!m_aAutoRefresh->isChecked() && !m_requestForcedUpdate)) {
+//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating scope.";
+    } else {
+        // Try to acquire the semaphore. This must only succeed if m_threadScope is not running
+        // anymore. Therefore the semaphore must NOT be released before m_threadScope ends.
+        // If acquiring the semaphore fails, the thread is still running.
+        if (m_semaphoreScope.tryAcquire(1)) {
+            Q_ASSERT(!m_threadScope.isRunning());
+
+            m_newScopeFrames.fetchAndStoreRelaxed(0);
+            m_newScopeUpdates.fetchAndStoreRelaxed(0);
+
+            Q_ASSERT(m_accelFactorScope > 0);
+
+            // See http://doc.qt.nokia.com/latest/qtconcurrentrun.html#run about
+            // running member functions in a thread
+            m_threadScope = QtConcurrent::run(this, &AbstractGfxScopeWidget::renderScope, m_accelFactorScope, m_scopeImage);
+            m_requestForcedUpdate = false;
+
+//            qDebug() << "Scope thread started in " << m_widgetName;
+
+        } else {
+//            qDebug() << "Scope semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadScope.isRunning();
+        }
+    }
+}
+void AbstractGfxScopeWidget::prodBackgroundThread()
+{
+    if (this->visibleRegion().isEmpty()) {
+//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating background.";
+    } else {
+        if (m_semaphoreBackground.tryAcquire(1)) {
+            Q_ASSERT(!m_threadBackground.isRunning());
+
+            m_newBackgroundFrames.fetchAndStoreRelaxed(0);
+            m_newBackgroundUpdates.fetchAndStoreRelaxed(0);
+            m_threadBackground = QtConcurrent::run(this, &AbstractGfxScopeWidget::renderBackground, m_accelFactorBackground);
+//            qDebug() << "Background thread started in " << m_widgetName;
+
+        } else {
+//            qDebug() << "Background semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadBackground.isRunning();
+        }
+    }
+}
+
+void AbstractGfxScopeWidget::forceUpdate(bool doUpdate)
+{
+//    qDebug() << "Force update called in " << widgetName() << ". Arg: " << doUpdate;
+    if (!doUpdate) {
+        return;
+    }
+    m_requestForcedUpdate = true;
+    m_newHUDUpdates.fetchAndAddRelaxed(1);
+    m_newScopeUpdates.fetchAndAddRelaxed(1);
+    m_newBackgroundUpdates.fetchAndAddRelaxed(1);
+    prodHUDThread();
+    prodScopeThread();
+    prodBackgroundThread();
+}
+void AbstractGfxScopeWidget::forceUpdateHUD()
+{
+    m_newHUDUpdates.fetchAndAddRelaxed(1);
+    prodHUDThread();
+
+}
+void AbstractGfxScopeWidget::forceUpdateScope()
+{
+    m_newScopeUpdates.fetchAndAddRelaxed(1);
+    m_requestForcedUpdate = true;
+    prodScopeThread();
+
+}
+void AbstractGfxScopeWidget::forceUpdateBackground()
+{
+    m_newBackgroundUpdates.fetchAndAddRelaxed(1);
+    prodBackgroundThread();
+
+}
+
+
+///// Events /////
+
+void AbstractGfxScopeWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+    if (!m_aAutoRefresh->isChecked()) {
+        m_requestForcedUpdate = true;
+        m_activeRender->sendFrameUpdate();
+    }
+    prodHUDThread();
+    prodScopeThread();
+    prodBackgroundThread();
+    QWidget::mouseReleaseEvent(event);
+}
+
+void AbstractGfxScopeWidget::resizeEvent(QResizeEvent *event)
+{
+    // Update the dimension of the available rect for painting
+    m_scopeRect = scopeRect();
+    forceUpdate();
+
+    QWidget::resizeEvent(event);
+}
+
+void AbstractGfxScopeWidget::showEvent(QShowEvent *event)
+{
+    QWidget::showEvent(event);
+    m_scopeRect = scopeRect();
+}
+
+void AbstractGfxScopeWidget::paintEvent(QPaintEvent *)
+{
+    QPainter davinci(this);
+    davinci.drawImage(m_scopeRect.topLeft(), m_imgBackground);
+    davinci.drawImage(m_scopeRect.topLeft(), m_imgScope);
+    davinci.drawImage(m_scopeRect.topLeft(), m_imgHUD);
+}
+
+void AbstractGfxScopeWidget::mouseMoveEvent(QMouseEvent *event)
+{
+    m_mousePos = event->pos();
+    m_mouseWithinWidget = true;
+    emit signalMousePositionChanged();
+}
+void AbstractGfxScopeWidget::leaveEvent(QEvent *)
+{
+    m_mouseWithinWidget = false;
+    emit signalMousePositionChanged();
+}
+
+void AbstractGfxScopeWidget::customContextMenuRequested(const QPoint &pos)
+{
+    m_menu->exec(this->mapToGlobal(pos));
+}
+
+uint AbstractGfxScopeWidget::calculateAccelFactorHUD(uint oldMseconds, uint)
+{
+    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
+}
+uint AbstractGfxScopeWidget::calculateAccelFactorScope(uint oldMseconds, uint)
+{
+    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
+}
+uint AbstractGfxScopeWidget::calculateAccelFactorBackground(uint oldMseconds, uint)
+{
+    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
+}
+
+
+///// Slots /////
+
+void AbstractGfxScopeWidget::slotHUDRenderingFinished(uint mseconds, uint oldFactor)
+{
+//    qDebug() << "HUD rendering has finished, waiting for termination in " << m_widgetName;
+    m_threadHUD.waitForFinished();
+    m_imgHUD = m_threadHUD.result();
+
+    m_semaphoreHUD.release(1);
+    this->update();
+
+    int accel;
+    if (m_aRealtime->isChecked()) {
+        accel = calculateAccelFactorHUD(mseconds, oldFactor);
+        if (m_accelFactorHUD < 1) {
+            accel = 1;
+        }
+        m_accelFactorHUD = accel;
+    }
+
+    if ((m_newHUDFrames > 0 && m_aAutoRefresh->isChecked()) || m_newHUDUpdates > 0) {
+//        qDebug() << "Trying to start a new HUD thread for " << m_widgetName
+//                << ". New frames/updates: " << m_newHUDFrames << "/" << m_newHUDUpdates;
+        prodHUDThread();;
+    }
+}
+
+void AbstractGfxScopeWidget::slotScopeRenderingFinished(uint mseconds, uint oldFactor)
+{
+    // The signal can be received before the thread has really finished. So we
+    // need to wait until it has really finished before starting a new thread.
+//    qDebug() << "Scope rendering has finished, waiting for termination in " << m_widgetName;
+    m_threadScope.waitForFinished();
+    m_imgScope = m_threadScope.result();
+
+    // The scope thread has finished. Now we can release the semaphore, allowing a new thread.
+    // See prodScopeThread where the semaphore is acquired again.
+    m_semaphoreScope.release(1);
+    this->update();
+
+    // Calculate the acceleration factor hint to get «realtime» updates.
+    int accel;
+    if (m_aRealtime->isChecked()) {
+        accel = calculateAccelFactorScope(mseconds, oldFactor);
+        if (accel < 1) {
+            // If mseconds happens to be 0.
+            accel = 1;
+        }
+        // Don't directly calculate with m_accelFactorScope as we are dealing with concurrency.
+        // If m_accelFactorScope is set to 0 at the wrong moment, who knows what might happen
+        // then :) Therefore use a local variable.
+        m_accelFactorScope = accel;
+    }
+
+    if ((m_newScopeFrames > 0 && m_aAutoRefresh->isChecked()) || m_newScopeUpdates > 0) {
+//        qDebug() << "Trying to start a new scope thread for " << m_widgetName
+//                << ". New frames/updates: " << m_newScopeFrames << "/" << m_newScopeUpdates;
+        prodScopeThread();
+    }
+}
+
+void AbstractGfxScopeWidget::slotBackgroundRenderingFinished(uint mseconds, uint oldFactor)
+{
+//    qDebug() << "Background rendering has finished, waiting for termination in " << m_widgetName;
+    m_threadBackground.waitForFinished();
+    m_imgBackground = m_threadBackground.result();
+
+    m_semaphoreBackground.release(1);
+    this->update();
+
+    int accel;
+    if (m_aRealtime->isChecked()) {
+        accel = calculateAccelFactorBackground(mseconds, oldFactor);
+        if (m_accelFactorBackground < 1) {
+            accel = 1;
+        }
+        m_accelFactorBackground = accel;
+    }
+
+    if ((m_newBackgroundFrames > 0 && m_aAutoRefresh->isChecked()) || m_newBackgroundUpdates > 0) {
+//        qDebug() << "Trying to start a new background thread for " << m_widgetName
+//                << ". New frames/updates: " << m_newBackgroundFrames << "/" << m_newBackgroundUpdates;
+        prodBackgroundThread();;
+    }
+}
+
+void AbstractGfxScopeWidget::slotActiveMonitorChanged(bool isClipMonitor)
+{
+//    qDebug() << "Active monitor has changed in " << m_widgetName << ". Is the clip monitor active now? " << isClipMonitor;
+
+    bool b = m_activeRender->disconnect(this);
+    Q_ASSERT(b);
+
+    m_activeRender = (isClipMonitor) ? m_clipMonitor->render : m_projMonitor->render;
+
+    //b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated()));
+    b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage)));
+    Q_ASSERT(b);
+
+    // Update the scope for the new monitor.
+    prodHUDThread();
+    prodScopeThread();
+    prodBackgroundThread();
+}
+
+void AbstractGfxScopeWidget::slotRenderZoneUpdated()
+{
+    m_newHUDFrames.fetchAndAddRelaxed(1);
+    m_newScopeFrames.fetchAndAddRelaxed(1);
+    m_newBackgroundFrames.fetchAndAddRelaxed(1);
+
+//    qDebug() << "Monitor incoming. New frames total HUD/Scope/Background: " << m_newHUDFrames
+//            << "/" << m_newScopeFrames << "/" << m_newBackgroundFrames;
+
+    if (this->visibleRegion().isEmpty()) {
+//        qDebug() << "Scope of widget " << m_widgetName << " is not at the top, not rendering.";
+    } else {
+        if (m_aAutoRefresh->isChecked()) {
+            prodHUDThread();
+            prodScopeThread();
+            prodBackgroundThread();
+        }
+    }
+}
+
+void AbstractGfxScopeWidget::slotRenderZoneUpdated(QImage frame)
+{
+    m_scopeImage = frame;
+    slotRenderZoneUpdated();
+}
+
+void AbstractGfxScopeWidget::slotResetRealtimeFactor(bool realtimeChecked)
+{
+    if (!realtimeChecked) {
+        m_accelFactorHUD = 1;
+        m_accelFactorScope = 1;
+        m_accelFactorBackground = 1;
+    }
+}
+
+bool AbstractGfxScopeWidget::autoRefreshEnabled()
+{
+    return m_aAutoRefresh->isChecked();
+}
+
+void AbstractGfxScopeWidget::slotAutoRefreshToggled(bool autoRefresh)
+{
+    if (isVisible()) emit requestAutoRefresh(autoRefresh);
+    // TODO only if depends on input
+    if (autoRefresh) {
+        //forceUpdate();
+        m_requestForcedUpdate = true;
+        m_activeRender->sendFrameUpdate();
+    }
+}
diff --git a/src/abstractgfxscopewidget.h b/src/abstractgfxscopewidget.h
new file mode 100644 (file)
index 0000000..05219ab
--- /dev/null
@@ -0,0 +1,272 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+/**
+  This abstract widget is a proof that abstract things sometimes *are* useful.
+
+  The widget expects three layers which
+  * Will be painted on top of each other on each update
+  * Are rendered in a separate thread so that the UI is not blocked
+  * Are rendered only if necessary (e.g., if a layer does not depend
+    on input images, it will not be re-rendered for incoming frames)
+
+  The layer order is as follows:
+     _____________________
+    /                     \
+   /      HUD Layer        \
+  /                         \
+  ---------------------------
+     _____________________
+    /                     \
+   /     Scope Layer       \
+  /                         \
+  ---------------------------
+     _____________________
+    /                     \
+   /   Background Layer    \
+  /                         \
+  ---------------------------
+
+  Colors of Scope Widgets are defined in here (and thus don't need to be
+  re-defined in the implementation of the widget's .ui file).
+
+  The custom context menu already contains entries, like for enabling auto-
+  refresh. It can certainly be extended in the implementation of the widget.
+
+  Note: Widgets deriving from this class should connect slotActiveMonitorChanged
+  to the appropriate signal.
+
+  If you intend to write an own widget inheriting from this one, please read
+  the comments on the unimplemented methods carefully. They are not only here
+  for optical amusement, but also contain important information.
+ */
+
+#ifndef ABSTRACTGFXSCOPEWIDGET_H
+#define ABSTRACTGFXSCOPEWIDGET_H
+
+
+#include <QtCore>
+#include <QWidget>
+
+class QMenu;
+
+class Monitor;
+class Render;
+
+class AbstractGfxScopeWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    AbstractGfxScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse = false, QWidget *parent = 0);
+    virtual ~AbstractGfxScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
+    QPalette m_scopePalette;
+
+    /** Initializes widget settings (reads configuration).
+      Has to be called in the implementing object. */
+    void init();
+
+    /** Does this scope have auto-refresh enabled */
+    bool autoRefreshEnabled();
+
+    ///// Unimplemented /////
+
+    virtual QString widgetName() const = 0;
+
+    ///// Variables /////
+    static const QPen penThick;
+    static const QPen penThin;
+    static const QPen penLight;
+    static const QPen penLightDots;
+    static const QPen penDark;
+    static const QPen penDarkDots;
+
+protected:
+    ///// Variables /////
+
+    Monitor *m_projMonitor;
+    Monitor *m_clipMonitor;
+    Render *m_activeRender;
+
+
+    /** The context menu. Feel free to add new entries in your implementation. */
+    QMenu *m_menu;
+
+    /** Enables auto refreshing of the scope.
+        This is when a new frame is shown on the active monitor.
+        Resize events always force a recalculation. */
+    QAction *m_aAutoRefresh;
+
+    /** Realtime rendering. Should be disabled if it is not supported.
+        Use the accelerationFactor variable passed to the render functions as a hint of
+        how many times faster the scope should be calculated. */
+    QAction *m_aRealtime;
+
+    /** The mouse position; Updated when the mouse enters the widget
+        AND mouse tracking has been enabled. */
+    QPoint m_mousePos;
+    /** Knows whether the mouse currently lies within the widget or not.
+        Can e.g. be used for drawing a HUD only when the mouse is in the widget. */
+    bool m_mouseWithinWidget;
+
+    /** Offset from the widget's borders */
+    const uchar offset;
+
+    /** The rect on the widget we're painting in.
+        Can be used by the implementing widget, e.g. in the render methods.
+        Is updated when necessary (size changes). */
+    QRect m_scopeRect;
+
+    /** Images storing the calculated layers. Will be used on repaint events. */
+    QImage m_imgHUD;
+    QImage m_imgScope;
+    QImage m_imgBackground;
+
+    /** The acceleration factors can be accessed also by other renderer tasks,
+        e.g. to display the scope's acceleration factor in the HUD renderer. */
+    int m_accelFactorHUD;
+    int m_accelFactorScope;
+    int m_accelFactorBackground;
+
+    /** Reads the widget's configuration.
+        Can be extended in the implementing subclass (make sure to run readConfig as well). */
+    virtual void readConfig();
+    /** Writes the widget configuration.
+        Implementing widgets have to implement an own method and run it in their destructor. */
+    void writeConfig();
+    /** Identifier for the widget's configuration. */
+    QString configName();
+
+
+    ///// Unimplemented Methods /////
+
+    /** Where on the widget we can paint in.
+        May also update other variables that depend on the widget's size.  */
+    virtual QRect scopeRect() = 0;
+
+    /** @brief HUD renderer. Must emit signalHUDRenderingFinished(). @see renderScope */
+    virtual QImage renderHUD(uint accelerationFactor) = 0;
+    /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
+        when calculation has finished, to allow multi-threading.
+        accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
+    virtual QImage renderScope(uint accelerationFactor, const QImage) = 0;
+    /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
+    virtual QImage renderBackground(uint accelerationFactor) = 0;
+
+    /** Must return true if the HUD layer depends on the input monitor.
+        If it does not, then it does not need to be re-calculated when
+        a new frame from the monitor is incoming. */
+    virtual bool isHUDDependingOnInput() const = 0;
+    /** @see isHUDDependingOnInput() */
+    virtual bool isScopeDependingOnInput() const = 0;
+    /** @see isHUDDependingOnInput() */
+    virtual bool isBackgroundDependingOnInput() const = 0;
+
+    ///// Can be reimplemented /////
+    /** Calculates the acceleration factor to be used by the render thread.
+        This method can be refined in the subclass if required. */
+    virtual uint calculateAccelFactorHUD(uint oldMseconds, uint oldFactor);
+    virtual uint calculateAccelFactorScope(uint oldMseconds, uint oldFactor);
+    virtual uint calculateAccelFactorBackground(uint oldMseconds, uint oldFactor);
+
+    ///// Reimplemented /////
+
+    void mouseMoveEvent(QMouseEvent *);
+    void leaveEvent(QEvent *);
+    void mouseReleaseEvent(QMouseEvent *);
+    void paintEvent(QPaintEvent *);
+    void resizeEvent(QResizeEvent *);
+    void showEvent(QShowEvent *); // Called when the widget is activated via the Menu entry
+    //    void raise(); // Called only when  manually calling the event -> useless
+
+
+protected slots:
+    /** Forces an update of all layers. */
+    void forceUpdate(bool doUpdate = true);
+    void forceUpdateHUD();
+    void forceUpdateScope();
+    void forceUpdateBackground();
+    void slotAutoRefreshToggled(bool);
+
+signals:
+    /** mseconds represent the time taken for the calculation,
+        accelerationFactor is the acceleration factor that has been used for this calculation. */
+    void signalHUDRenderingFinished(uint mseconds, uint accelerationFactor);
+    void signalScopeRenderingFinished(uint mseconds, uint accelerationFactor);
+    void signalBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
+
+    /** For the mouse position itself see m_mousePos.
+        To check whether the mouse has leaved the widget, see m_mouseWithinWidget. */
+    void signalMousePositionChanged();
+
+    /** Do we need the renderer to send its frames to us? */
+    void requestAutoRefresh(bool);
+
+private:
+
+    /** Counts the number of frames that have been rendered in the active monitor.
+      The frame number will be reset when the calculation starts for the current frame. */
+    QAtomicInt m_newHUDFrames;
+    QAtomicInt m_newScopeFrames;
+    QAtomicInt m_newBackgroundFrames;
+
+    /** Counts the number of updates that, unlike new frames, force a recalculation
+      of the scope, like for example a resize event. */
+    QAtomicInt m_newHUDUpdates;
+    QAtomicInt m_newScopeUpdates;
+    QAtomicInt m_newBackgroundUpdates;
+
+    /** The semaphores ensure that the QFutures for the HUD/Scope/Background threads cannot
+      be assigned a new thread while it is still running. (Could cause deadlocks and other
+      nasty things known from parallelism.) */
+    QSemaphore m_semaphoreHUD;
+    QSemaphore m_semaphoreScope;
+    QSemaphore m_semaphoreBackground;
+
+    QFuture<QImage> m_threadHUD;
+    QFuture<QImage> m_threadScope;
+    QFuture<QImage> m_threadBackground;
+
+    bool initialDimensionUpdateDone;
+    bool m_requestForcedUpdate;
+
+    QImage m_scopeImage;
+
+    QString m_widgetName;
+
+    void prodHUDThread();
+    void prodScopeThread();
+    void prodBackgroundThread();
+
+public slots:
+    /** @brief Must be called when the active monitor has shown a new frame.
+      This slot must be connected in the implementing class, it is *not*
+      done in this abstract class. */
+    void slotActiveMonitorChanged(bool isClipMonitor);
+
+private slots:
+    void customContextMenuRequested(const QPoint &pos);
+    /** To be called when a new frame has been received.
+      The scope then decides whether and when it wants to recalculate the scope, depending
+      on whether it is currently visible and whether a calculation thread is already running. */
+    void slotRenderZoneUpdated();
+    void slotRenderZoneUpdated(QImage);
+    /** The following slots are called when rendering of a component has finished. They e.g. update
+      the widget and decide whether to immediately restart the calculation thread. */
+    void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor);
+    void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor);
+    void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
+
+    /** Resets the acceleration factors to 1 when realtime rendering is disabled. */
+    void slotResetRealtimeFactor(bool realtimeChecked);
+
+};
+
+#endif // ABSTRACTGFXSCOPEWIDGET_H
index 7109704c8f4ffc2f84bbfecbf4e3ca8801233453..c72e584f554eb6a1b81db9b54054f37626b3a113 100644 (file)
@@ -170,7 +170,7 @@ void AbstractScopeWidget::prodScopeThread()
 
             // See http://doc.qt.nokia.com/latest/qtconcurrentrun.html#run about
             // running member functions in a thread
-            m_threadScope = QtConcurrent::run(this, &AbstractScopeWidget::renderScope, m_accelFactorScope, m_scopeImage);
+            m_threadScope = QtConcurrent::run(this, &AbstractScopeWidget::renderScope, m_accelFactorScope);
             m_requestForcedUpdate = false;
 
 //            qDebug() << "Scope thread started in " << m_widgetName;
index 0d5a597bdc5663966c6002bc35e7d1a6fdb81e51..9e28432af11938ffd625f231678ee403b10636dc 100644 (file)
@@ -155,7 +155,7 @@ protected:
     /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
         when calculation has finished, to allow multi-threading.
         accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
-    virtual QImage renderScope(uint accelerationFactor, const QImage) = 0;
+    virtual QImage renderScope(uint accelerationFactor) = 0;
     /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
     virtual QImage renderBackground(uint accelerationFactor) = 0;
 
@@ -250,7 +250,7 @@ public slots:
       done in this abstract class. */
     void slotActiveMonitorChanged(bool isClipMonitor);
 
-private slots:
+protected slots:
     void customContextMenuRequested(const QPoint &pos);
     /** To be called when a new frame has been received.
       The scope then decides whether and when it wants to recalculate the scope, depending
index 2a9f1b2306f5293571651bdb99b2bb472c5821e3..52f91b9a1b29ce910f00f9c476ecc080fd1bb657 100644 (file)
 #include <QMouseEvent>
 #include <QPainter>
 
-const int REALTIME_FPS = 30;
-
-const QColor light(250, 238, 226, 255);
-const QColor dark(40,  40,  39, 255);
-const QColor dark2(25,  25,  23, 255);
-
-const QPen AbstractAudioScopeWidget::penThick(QBrush(QColor(250, 250, 250)),     2, Qt::SolidLine);
-const QPen AbstractAudioScopeWidget::penThin(QBrush(QColor(250, 250, 250)),     1, Qt::SolidLine);
-const QPen AbstractAudioScopeWidget::penLight(QBrush(QColor(200, 200, 250, 150)), 1, Qt::SolidLine);
-const QPen AbstractAudioScopeWidget::penDark(QBrush(QColor(0, 0, 20, 250)),      1, Qt::SolidLine);
-
 AbstractAudioScopeWidget::AbstractAudioScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse, QWidget *parent) :
-        QWidget(parent),
-        m_projMonitor(projMonitor),
-        m_clipMonitor(clipMonitor),
-        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_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);
-    m_menu->setPalette(m_scopePalette);
-    m_menu->addAction(m_aAutoRefresh);
-    m_menu->addAction(m_aRealtime);
-
-    this->setContextMenuPolicy(Qt::CustomContextMenu);
-
-    m_activeRender = (m_clipMonitor->isActive()) ? m_clipMonitor->render : m_projMonitor->render;
-
-    bool b = true;
-    b &= connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint)));
-
-    //b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated()));
-//    b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage)));
-
-    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);
-}
-
-AbstractAudioScopeWidget::~AbstractAudioScopeWidget()
-{
-    writeConfig();
-
-    delete m_menu;
-    delete m_aAutoRefresh;
-    delete m_aRealtime;
-}
-
-void AbstractAudioScopeWidget::init()
-{
-    m_widgetName = widgetName();
-    readConfig();
-}
-
-void AbstractAudioScopeWidget::readConfig()
-{
-    KSharedConfigPtr config = KGlobal::config();
-    KConfigGroup scopeConfig(config, configName());
-    m_aAutoRefresh->setChecked(scopeConfig.readEntry("autoRefresh", true));
-    m_aRealtime->setChecked(scopeConfig.readEntry("realtime", false));
-    scopeConfig.sync();
-}
-
-void AbstractAudioScopeWidget::writeConfig()
-{
-    KSharedConfigPtr config = KGlobal::config();
-    KConfigGroup scopeConfig(config, configName());
-    scopeConfig.writeEntry("autoRefresh", m_aAutoRefresh->isChecked());
-    scopeConfig.writeEntry("realtime", m_aRealtime->isChecked());
-    scopeConfig.sync();
-}
-
-QString AbstractAudioScopeWidget::configName()
-{
-    return "Scope_" + m_widgetName;
-}
-
-void AbstractAudioScopeWidget::prodHUDThread()
-{
-    if (this->visibleRegion().isEmpty()) {
-//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating HUD.";
-    } else {
-        if (m_semaphoreHUD.tryAcquire(1)) {
-            Q_ASSERT(!m_threadHUD.isRunning());
-
-            m_newHUDFrames.fetchAndStoreRelaxed(0);
-            m_newHUDUpdates.fetchAndStoreRelaxed(0);
-            m_threadHUD = QtConcurrent::run(this, &AbstractAudioScopeWidget::renderHUD, m_accelFactorHUD);
-//            qDebug() << "HUD thread started in " << m_widgetName;
-
-        } else {
-//            qDebug() << "HUD semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadHUD.isRunning();
-        }
-    }
-}
-
-void AbstractAudioScopeWidget::prodScopeThread()
-{
-    // Only start a new thread if the scope is actually visible
-    // and not hidden by another widget on the stack and if user want the scope to update.
-    if (this->visibleRegion().isEmpty() || (!m_aAutoRefresh->isChecked() && !m_requestForcedUpdate)) {
-//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating scope.";
-    } else {
-        // Try to acquire the semaphore. This must only succeed if m_threadScope is not running
-        // anymore. Therefore the semaphore must NOT be released before m_threadScope ends.
-        // If acquiring the semaphore fails, the thread is still running.
-        if (m_semaphoreScope.tryAcquire(1)) {
-            Q_ASSERT(!m_threadScope.isRunning());
-
-            m_newScopeFrames.fetchAndStoreRelaxed(0);
-            m_newScopeUpdates.fetchAndStoreRelaxed(0);
-
-            Q_ASSERT(m_accelFactorScope > 0);
-
-            // See http://doc.qt.nokia.com/latest/qtconcurrentrun.html#run about
-            // running member functions in a thread
-            m_threadScope = QtConcurrent::run(this, &AbstractAudioScopeWidget::renderScope,
-                                              m_accelFactorScope, m_audioFrame, m_freq, m_nChannels, m_nSamples);
-            m_requestForcedUpdate = false;
-
-//            qDebug() << "Scope thread started in " << m_widgetName;
-
-        } else {
-//            qDebug() << "Scope semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadScope.isRunning();
-        }
-    }
-}
-void AbstractAudioScopeWidget::prodBackgroundThread()
-{
-    if (this->visibleRegion().isEmpty()) {
-//        qDebug() << "Scope " << m_widgetName << " is not visible. Not calculating background.";
-    } else {
-        if (m_semaphoreBackground.tryAcquire(1)) {
-            Q_ASSERT(!m_threadBackground.isRunning());
-
-            m_newBackgroundFrames.fetchAndStoreRelaxed(0);
-            m_newBackgroundUpdates.fetchAndStoreRelaxed(0);
-            m_threadBackground = QtConcurrent::run(this, &AbstractAudioScopeWidget::renderBackground, m_accelFactorBackground);
-//            qDebug() << "Background thread started in " << m_widgetName;
-
-        } else {
-//            qDebug() << "Background semaphore locked, not prodding in " << m_widgetName << ". Thread running: " << m_threadBackground.isRunning();
-        }
-    }
-}
-
-void AbstractAudioScopeWidget::forceUpdate(bool doUpdate)
-{
-//    qDebug() << "Force update called in " << widgetName() << ". Arg: " << doUpdate;
-    if (!doUpdate) {
-        return;
-    }
-    m_requestForcedUpdate = true;
-    m_newHUDUpdates.fetchAndAddRelaxed(1);
-    m_newScopeUpdates.fetchAndAddRelaxed(1);
-    m_newBackgroundUpdates.fetchAndAddRelaxed(1);
-    prodHUDThread();
-    prodScopeThread();
-    prodBackgroundThread();
-}
-void AbstractAudioScopeWidget::forceUpdateHUD()
-{
-    m_newHUDUpdates.fetchAndAddRelaxed(1);
-    prodHUDThread();
-
-}
-void AbstractAudioScopeWidget::forceUpdateScope()
-{
-    m_newScopeUpdates.fetchAndAddRelaxed(1);
-    m_requestForcedUpdate = true;
-    prodScopeThread();
-
-}
-void AbstractAudioScopeWidget::forceUpdateBackground()
-{
-    m_newBackgroundUpdates.fetchAndAddRelaxed(1);
-    prodBackgroundThread();
-
-}
-
-
-///// Events /////
-
-void AbstractAudioScopeWidget::mouseReleaseEvent(QMouseEvent *event)
-{
-    if (!m_aAutoRefresh->isChecked()) {
-        m_requestForcedUpdate = true;
-        m_activeRender->sendFrameUpdate();
-    }
-    prodHUDThread();
-    prodScopeThread();
-    prodBackgroundThread();
-    QWidget::mouseReleaseEvent(event);
-}
-
-void AbstractAudioScopeWidget::resizeEvent(QResizeEvent *event)
-{
-    // Update the dimension of the available rect for painting
-    m_scopeRect = scopeRect();
-    forceUpdate();
-
-    QWidget::resizeEvent(event);
-}
-
-void AbstractAudioScopeWidget::showEvent(QShowEvent *event)
-{
-    QWidget::showEvent(event);
-    m_scopeRect = scopeRect();
-}
-
-void AbstractAudioScopeWidget::paintEvent(QPaintEvent *)
-{
-    QPainter davinci(this);
-    davinci.drawImage(m_scopeRect.topLeft(), m_imgBackground);
-    davinci.drawImage(m_scopeRect.topLeft(), m_imgScope);
-    davinci.drawImage(m_scopeRect.topLeft(), m_imgHUD);
-}
-
-void AbstractAudioScopeWidget::mouseMoveEvent(QMouseEvent *event)
-{
-    m_mousePos = event->pos();
-    m_mouseWithinWidget = true;
-    emit signalMousePositionChanged();
-}
-void AbstractAudioScopeWidget::leaveEvent(QEvent *)
+        AbstractScopeWidget(projMonitor, clipMonitor, trackMouse, parent)
 {
-    m_mouseWithinWidget = false;
-    emit signalMousePositionChanged();
-}
-
-void AbstractAudioScopeWidget::customContextMenuRequested(const QPoint &pos)
-{
-    m_menu->exec(this->mapToGlobal(pos));
-}
-
-uint AbstractAudioScopeWidget::calculateAccelFactorHUD(uint oldMseconds, uint)
-{
-    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
-}
-uint AbstractAudioScopeWidget::calculateAccelFactorScope(uint oldMseconds, uint)
-{
-    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
-}
-uint AbstractAudioScopeWidget::calculateAccelFactorBackground(uint oldMseconds, uint)
-{
-    return ceil((float)oldMseconds*REALTIME_FPS / 1000);
-}
-
-
-///// Slots /////
-
-void AbstractAudioScopeWidget::slotHUDRenderingFinished(uint mseconds, uint oldFactor)
-{
-//    qDebug() << "HUD rendering has finished, waiting for termination in " << m_widgetName;
-    m_threadHUD.waitForFinished();
-    m_imgHUD = m_threadHUD.result();
-
-    m_semaphoreHUD.release(1);
-    this->update();
-
-    int accel;
-    if (m_aRealtime->isChecked()) {
-        accel = calculateAccelFactorHUD(mseconds, oldFactor);
-        if (m_accelFactorHUD < 1) {
-            accel = 1;
-        }
-        m_accelFactorHUD = accel;
-    }
-
-    if ((m_newHUDFrames > 0 && m_aAutoRefresh->isChecked()) || m_newHUDUpdates > 0) {
-//        qDebug() << "Trying to start a new HUD thread for " << m_widgetName
-//                << ". New frames/updates: " << m_newHUDFrames << "/" << m_newHUDUpdates;
-        prodHUDThread();;
-    }
-}
-
-void AbstractAudioScopeWidget::slotScopeRenderingFinished(uint mseconds, uint oldFactor)
-{
-    // The signal can be received before the thread has really finished. So we
-    // need to wait until it has really finished before starting a new thread.
-//    qDebug() << "Scope rendering has finished, waiting for termination in " << m_widgetName;
-    m_threadScope.waitForFinished();
-    m_imgScope = m_threadScope.result();
-
-    // The scope thread has finished. Now we can release the semaphore, allowing a new thread.
-    // See prodScopeThread where the semaphore is acquired again.
-    m_semaphoreScope.release(1);
-    this->update();
-
-    // Calculate the acceleration factor hint to get «realtime» updates.
-    int accel;
-    if (m_aRealtime->isChecked()) {
-        accel = calculateAccelFactorScope(mseconds, oldFactor);
-        if (accel < 1) {
-            // If mseconds happens to be 0.
-            accel = 1;
-        }
-        // Don't directly calculate with m_accelFactorScope as we are dealing with concurrency.
-        // If m_accelFactorScope is set to 0 at the wrong moment, who knows what might happen
-        // then :) Therefore use a local variable.
-        m_accelFactorScope = accel;
-    }
-
-    if ((m_newScopeFrames > 0 && m_aAutoRefresh->isChecked()) || m_newScopeUpdates > 0) {
-//        qDebug() << "Trying to start a new scope thread for " << m_widgetName
-//                << ". New frames/updates: " << m_newScopeFrames << "/" << m_newScopeUpdates;
-        prodScopeThread();
-    }
-}
-
-void AbstractAudioScopeWidget::slotBackgroundRenderingFinished(uint mseconds, uint oldFactor)
-{
-//    qDebug() << "Background rendering has finished, waiting for termination in " << m_widgetName;
-    m_threadBackground.waitForFinished();
-    m_imgBackground = m_threadBackground.result();
-
-    m_semaphoreBackground.release(1);
-    this->update();
-
-    int accel;
-    if (m_aRealtime->isChecked()) {
-        accel = calculateAccelFactorBackground(mseconds, oldFactor);
-        if (m_accelFactorBackground < 1) {
-            accel = 1;
-        }
-        m_accelFactorBackground = accel;
-    }
-
-    if ((m_newBackgroundFrames > 0 && m_aAutoRefresh->isChecked()) || m_newBackgroundUpdates > 0) {
-//        qDebug() << "Trying to start a new background thread for " << m_widgetName
-//                << ". New frames/updates: " << m_newBackgroundFrames << "/" << m_newBackgroundUpdates;
-        prodBackgroundThread();;
-    }
-}
-
-//void AbstractAudioScopeWidget::slotActiveMonitorChanged(bool isClipMonitor)
-//{
-////    qDebug() << "Active monitor has changed in " << m_widgetName << ". Is the clip monitor active now? " << isClipMonitor;
-
-//    bool b = m_activeRender->disconnect(this);
-//    Q_ASSERT(b);
-
-//    m_activeRender = (isClipMonitor) ? m_clipMonitor->render : m_projMonitor->render;
-
-//    //b &= connect(m_activeRender, SIGNAL(rendererPosition(int)), this, SLOT(slotRenderZoneUpdated()));
-//    b &= connect(m_activeRender, SIGNAL(frameUpdated(QImage)), this, SLOT(slotRenderZoneUpdated(QImage)));
-//    Q_ASSERT(b);
-
-//    // Update the scope for the new monitor.
-//    prodHUDThread();
-//    prodScopeThread();
-//    prodBackgroundThread();
-//}
-
-void AbstractAudioScopeWidget::slotRenderZoneUpdated()
-{
-    m_newHUDFrames.fetchAndAddRelaxed(1);
-    m_newScopeFrames.fetchAndAddRelaxed(1);
-    m_newBackgroundFrames.fetchAndAddRelaxed(1);
-
-//    qDebug() << "Audio incoming. New frames total HUD/Scope/Background: " << m_newHUDFrames
-//            << "/" << m_newScopeFrames << "/" << m_newBackgroundFrames;
-
-    if (this->visibleRegion().isEmpty()) {
-//        qDebug() << "Scope of widget " << m_widgetName << " is not at the top, not rendering.";
-    } else {
-        if (m_aAutoRefresh->isChecked()) {
-            prodHUDThread();
-            prodScopeThread();
-            prodBackgroundThread();
-        }
-    }
 }
 
 void AbstractAudioScopeWidget::slotReceiveAudio(const QVector<int16_t>& sampleData, int freq, int num_channels, int num_samples)
 {
-    //qDebug() << "Received audio. Size is " << (int) sampleData.size() << ".";
-    if (sampleData.size() > 0) {
-        //qDebug() << "Received: " << sampleData.data()[0] << ", " << sampleData.data()[1] << ", " << sampleData.data()[2];
-    }
     m_audioFrame = sampleData;
     m_freq = freq;
     m_nChannels = num_channels;
     m_nSamples = num_samples;
-    slotRenderZoneUpdated();
+    AbstractScopeWidget::slotRenderZoneUpdated();
     //TODO
 }
 
-void AbstractAudioScopeWidget::slotResetRealtimeFactor(bool realtimeChecked)
-{
-    if (!realtimeChecked) {
-        m_accelFactorHUD = 1;
-        m_accelFactorScope = 1;
-        m_accelFactorBackground = 1;
-    }
-}
-
-bool AbstractAudioScopeWidget::autoRefreshEnabled()
-{
-    return m_aAutoRefresh->isChecked();
-}
+AbstractAudioScopeWidget::~AbstractAudioScopeWidget() {}
 
-void AbstractAudioScopeWidget::slotAutoRefreshToggled(bool autoRefresh)
+QImage AbstractAudioScopeWidget::renderScope(uint accelerationFactor)
 {
-    if (isVisible()) emit requestAutoRefresh(autoRefresh);
-    // TODO only if depends on input
-    if (autoRefresh) {
-        //forceUpdate();
-        m_requestForcedUpdate = true;
-        m_activeRender->sendFrameUpdate();
-    }
+    return renderAudioScope(accelerationFactor, m_audioFrame, m_freq, m_nChannels, m_nSamples);
 }
index 3bc6beadb5e8c7ae1d60b8ba2f2914d27fce3aa6..e519e2a4398a6c2465bd82e53b3ce8a0229896f7 100644 (file)
 #include <QtCore>
 #include <QWidget>
 
+#include "abstractscopewidget.h"
+
 class QMenu;
 
 class Monitor;
 class Render;
 
-class AbstractAudioScopeWidget : public QWidget
+class AbstractAudioScopeWidget : public AbstractScopeWidget
 {
     Q_OBJECT
 public:
     AbstractAudioScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse = false, QWidget *parent = 0);
-    virtual ~AbstractAudioScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
-    QPalette m_scopePalette;
-
-    /** Initializes widget settings (reads configuration).
-      Has to be called in the implementing object. */
-    void init();
-
-    /** Does this scope have auto-refresh enabled */
-    bool autoRefreshEnabled();
-
-    ///// Unimplemented /////
-
-    virtual QString widgetName() const = 0;
-
-    ///// Variables /////
-    static const QPen penThick;
-    static const QPen penThin;
-    static const QPen penLight;
-    static const QPen penDark;
+    virtual ~AbstractAudioScopeWidget();
 
 protected:
-    ///// Variables /////
-
-    Monitor *m_projMonitor;
-    Monitor *m_clipMonitor;
-    Render *m_activeRender;
-
-
-    /** The context menu. Feel free to add new entries in your implementation. */
-    QMenu *m_menu;
-
-    /** Enables auto refreshing of the scope.
-        This is when a new frame is shown on the active monitor.
-        Resize events always force a recalculation. */
-    QAction *m_aAutoRefresh;
-
-    /** Realtime rendering. Should be disabled if it is not supported.
-        Use the accelerationFactor variable passed to the render functions as a hint of
-        how many times faster the scope should be calculated. */
-    QAction *m_aRealtime;
-
-    /** The mouse position; Updated when the mouse enters the widget
-        AND mouse tracking has been enabled. */
-    QPoint m_mousePos;
-    /** Knows whether the mouse currently lies within the widget or not.
-        Can e.g. be used for drawing a HUD only when the mouse is in the widget. */
-    bool m_mouseWithinWidget;
-
-    /** Offset from the widget's borders */
-    const uchar offset;
-
-    /** The rect on the widget we're painting in.
-        Can be used by the implementing widget, e.g. in the render methods.
-        Is updated when necessary (size changes). */
-    QRect m_scopeRect;
-
-    /** Images storing the calculated layers. Will be used on repaint events. */
-    QImage m_imgHUD;
-    QImage m_imgScope;
-    QImage m_imgBackground;
-
-    /** The acceleration factors can be accessed also by other renderer tasks,
-        e.g. to display the scope's acceleration factor in the HUD renderer. */
-    int m_accelFactorHUD;
-    int m_accelFactorScope;
-    int m_accelFactorBackground;
-
-    /** Reads the widget's configuration.
-        Can be extended in the implementing subclass (make sure to run readConfig as well). */
-    virtual void readConfig();
-    /** Writes the widget configuration.
-        Implementing widgets have to implement an own method and run it in their destructor. */
-    void writeConfig();
-    /** Identifier for the widget's configuration. */
-    QString configName();
-
+    virtual QImage renderScope(uint accelerationFactor);
 
     ///// Unimplemented Methods /////
-
-    /** Where on the widget we can paint in.
-        May also update other variables that depend on the widget's size.  */
-    virtual QRect scopeRect() = 0;
-
-    /** @brief HUD renderer. Must emit signalHUDRenderingFinished(). @see renderScope */
-    virtual QImage renderHUD(uint accelerationFactor) = 0;
     /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
         when calculation has finished, to allow multi-threading.
         accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
-    virtual QImage renderScope(uint accelerationFactor,
+    virtual QImage renderAudioScope(uint accelerationFactor,
                                const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples) = 0;
-    /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
-    virtual QImage renderBackground(uint accelerationFactor) = 0;
-
-    /** Must return true if the HUD layer depends on the input monitor.
-        If it does not, then it does not need to be re-calculated when
-        a new frame from the monitor is incoming. */
-    virtual bool isHUDDependingOnInput() const = 0;
-    /** @see isHUDDependingOnInput() */
-    virtual bool isScopeDependingOnInput() const = 0;
-    /** @see isHUDDependingOnInput() */
-    virtual bool isBackgroundDependingOnInput() const = 0;
-
-    ///// Can be reimplemented /////
-    /** Calculates the acceleration factor to be used by the render thread.
-        This method can be refined in the subclass if required. */
-    virtual uint calculateAccelFactorHUD(uint oldMseconds, uint oldFactor);
-    virtual uint calculateAccelFactorScope(uint oldMseconds, uint oldFactor);
-    virtual uint calculateAccelFactorBackground(uint oldMseconds, uint oldFactor);
-
-    ///// Reimplemented /////
-
-    void mouseMoveEvent(QMouseEvent *);
-    void leaveEvent(QEvent *);
-    void mouseReleaseEvent(QMouseEvent *);
-    void paintEvent(QPaintEvent *);
-    void resizeEvent(QResizeEvent *);
-    void showEvent(QShowEvent *); // Called when the widget is activated via the Menu entry
-    //    void raise(); // Called only when  manually calling the event -> useless
-
-
-protected slots:
-    /** Forces an update of all layers. */
-    void forceUpdate(bool doUpdate = true);
-    void forceUpdateHUD();
-    void forceUpdateScope();
-    void forceUpdateBackground();
-    void slotAutoRefreshToggled(bool);
-
-signals:
-    /** mseconds represent the time taken for the calculation,
-        accelerationFactor is the acceleration factor that has been used. */
-    void signalHUDRenderingFinished(uint mseconds, uint accelerationFactor);
-    void signalScopeRenderingFinished(uint mseconds, uint accelerationFactor);
-    void signalBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
-
-    /** For the mouse position itself see m_mousePos.
-        To check whether the mouse has leaved the widget, see m_mouseWithinWidget. */
-    void signalMousePositionChanged();
-
-    /** Do we need the renderer to send its frames to us? */
-    void requestAutoRefresh(bool);
 
 private:
-
-    /** Counts the number of frames that have been rendered in the active monitor.
-      The frame number will be reset when the calculation starts for the current frame. */
-    QAtomicInt m_newHUDFrames;
-    QAtomicInt m_newScopeFrames;
-    QAtomicInt m_newBackgroundFrames;
-
-    /** Counts the number of updates that, unlike new frames, force a recalculation
-      of the scope, like for example a resize event. */
-    QAtomicInt m_newHUDUpdates;
-    QAtomicInt m_newScopeUpdates;
-    QAtomicInt m_newBackgroundUpdates;
-
-    /** The semaphores ensure that the QFutures for the HUD/Scope/Background threads cannot
-      be assigned a new thread while it is still running. (Could cause deadlocks and other
-      nasty things known from parallelism.) */
-    QSemaphore m_semaphoreHUD;
-    QSemaphore m_semaphoreScope;
-    QSemaphore m_semaphoreBackground;
-
-    QFuture<QImage> m_threadHUD;
-    QFuture<QImage> m_threadScope;
-    QFuture<QImage> m_threadBackground;
-
-    bool initialDimensionUpdateDone;
-    bool m_requestForcedUpdate;
-
-//    QImage m_scopeImage;
-    QVector<int16_t> m_audioFrame; //NEW
+    QVector<int16_t> m_audioFrame;
     int m_freq;
     int m_nChannels;
     int m_nSamples;
 
-    QString m_widgetName;
-
-    void prodHUDThread();
-    void prodScopeThread();
-    void prodBackgroundThread();
-
-public slots:
-    /** @brief Must be called when the active monitor has shown a new frame.
-      This slot must be connected in the implementing class, it is *not*
-      done in this abstract class. */
-//    void slotActiveMonitorChanged(bool isClipMonitor);
-
 private slots:
-    void customContextMenuRequested(const QPoint &pos);
-    /** To be called when a new frame has been received.
-      The scope then decides whether and when it wants to recalculate the scope, depending
-      on whether it is currently visible and whether a calculation thread is already running. */
-    void slotRenderZoneUpdated();
-//    void slotRenderZoneUpdated(QImage);//OLD
     void slotReceiveAudio(const QVector<int16_t>& sampleData, int freq, int num_channels, int num_samples); // NEW, TODO comment
-    /** The following slots are called when rendering of a component has finished. They e.g. update
-      the widget and decide whether to immediately restart the calculation thread. */
-    void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor);
-    void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor);
-    void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
-
-    /** Resets the acceleration factors to 1 when realtime rendering is disabled. */
-    void slotResetRealtimeFactor(bool realtimeChecked);
 
 };
 
index 9833b3f21b2a1287cdd98772c4fce3407e3ba680..b45bb9c896fe35d94bfc9e60db7c1f00431b74f1 100644 (file)
@@ -1,3 +1,13 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
 #include "audiospectrum.h"
 #include "tools/kiss_fftr.h"
 
@@ -47,7 +57,7 @@ AudioSpectrum::AudioSpectrum(Monitor *projMonitor, Monitor *clipMonitor, QWidget
     b &= connect(ui->windowSize, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateCfg()));
     Q_ASSERT(b);
 
-    init();
+    AbstractScopeWidget::init();
 }
 AudioSpectrum::~AudioSpectrum()
 {
@@ -59,10 +69,10 @@ AudioSpectrum::~AudioSpectrum()
 
 void AudioSpectrum::readConfig()
 {
-    AbstractAudioScopeWidget::readConfig();
+    AbstractScopeWidget::readConfig();
 
     KSharedConfigPtr config = KGlobal::config();
-    KConfigGroup scopeConfig(config, configName());
+    KConfigGroup scopeConfig(config, AbstractScopeWidget::configName());
     QString scale = scopeConfig.readEntry("scale");
     if (scale == "lin") {
         m_aLin->setChecked(true);
@@ -75,7 +85,7 @@ void AudioSpectrum::readConfig()
 void AudioSpectrum::writeConfig()
 {
     KSharedConfigPtr config = KGlobal::config();
-    KConfigGroup scopeConfig(config, configName());
+    KConfigGroup scopeConfig(config, AbstractScopeWidget::configName());
     QString scale;
     if (m_aLin->isChecked()) {
         scale = "lin";
@@ -94,7 +104,7 @@ bool AudioSpectrum::isScopeDependingOnInput() const { return true; }
 bool AudioSpectrum::isHUDDependingOnInput() const { return false; }
 
 QImage AudioSpectrum::renderBackground(uint) { return QImage(); }
-QImage AudioSpectrum::renderScope(uint, const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples)
+QImage AudioSpectrum::renderAudioScope(uint, const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples)
 {
     if (audioFrame.size() > 63) {
         m_freqMax = freq / 2;
@@ -152,7 +162,6 @@ QImage AudioSpectrum::renderScope(uint, const QVector<int16_t> audioFrame, const
                 val = pow(pow(fabs(freqData[i].r),2) + pow(fabs(freqData[i].i),2), .5);
             }
             freqSpectrum[i] = val;
-    //        qDebug() << val;
         }
 
 
@@ -248,11 +257,9 @@ QImage AudioSpectrum::renderHUD(uint)
     }
 
 
-    qDebug() << "max freq: " << m_freqMax;
     const uint hzDiff = ceil( ((float)minDistX)/rect.width() * m_freqMax / 1000 ) * 1000;
-    qDebug() << hzDiff;
     int x;
-    for (int hz = hzDiff; hz < m_freqMax; hz += hzDiff) {
+    for (uint hz = hzDiff; hz < m_freqMax; hz += hzDiff) {
         x = rect.width() * ((float)hz)/m_freqMax;
         davinci.drawLine(x, 0, x, rect.height()+4);
         davinci.drawText(x-4, rect.height() + 20, QVariant(hz/1000).toString());
index 51f6e62cee29a3a3fd5ff4e7453a27a24e41bd1f..205d120257b733780f4cd826d6c7736bf46074ad 100644 (file)
@@ -1,3 +1,13 @@
+/***************************************************************************
+ *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
 #ifndef AUDIOSPECTRUM_H
 #define AUDIOSPECTRUM_H
 
@@ -23,7 +33,7 @@ protected:
     ///// Implemented methods /////
     QRect scopeRect();
     QImage renderHUD(uint accelerationFactor);
-    QImage renderScope(uint accelerationFactor, const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples);
+    QImage renderAudioScope(uint accelerationFactor, const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples);
     QImage renderBackground(uint accelerationFactor);
     bool isHUDDependingOnInput() const;
     bool isScopeDependingOnInput() const;
index a5d1fc42af1e6772f01a8df986ca60c3b66dd4d8..4065b163346e9f211182fc6313fc7173c4d12cc5 100644 (file)
@@ -15,7 +15,7 @@
 #include "renderer.h"
 
 Histogram::Histogram(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
-    AbstractScopeWidget(projMonitor, clipMonitor, false, parent)
+    AbstractGfxScopeWidget(projMonitor, clipMonitor, false, parent)
 {
     ui = new Ui::Histogram_UI();
     ui->setupUi(this);
@@ -65,7 +65,7 @@ Histogram::~Histogram()
 
 void Histogram::readConfig()
 {
-    AbstractScopeWidget::readConfig();
+    AbstractGfxScopeWidget::readConfig();
 
     KSharedConfigPtr config = KGlobal::config();
     KConfigGroup scopeConfig(config, configName());
index af066a539395811589914c72809cf8c2a8f8af28..7796899e49c08c0ac8d772d6761b10f187c28b78 100644 (file)
 #ifndef HISTOGRAM_H
 #define HISTOGRAM_H
 
-#include "abstractscopewidget.h"
+#include "abstractgfxscopewidget.h"
 #include "ui_histogram_ui.h"
 
 class HistogramGenerator;
 
-class Histogram : public AbstractScopeWidget {
+class Histogram : public AbstractGfxScopeWidget {
     Q_OBJECT
 
 public:
index 48242bc4fbde8b0f5c1581d3f13df96706fe3e4c..dc40c9b5c8f4a8b478048519dd1553313651ad36 100644 (file)
@@ -3969,7 +3969,7 @@ void MainWindow::slotMonitorRequestRenderFrame(bool request)
         return;
     } else {
         for (int i = 0; i < m_scopesList.count(); i++) {
-            if (m_scopesList.at(i)->isVisible() && tabifiedDockWidgets(m_scopesList.at(i)).isEmpty() && static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled()) {
+            if (m_scopesList.at(i)->isVisible() && tabifiedDockWidgets(m_scopesList.at(i)).isEmpty() && static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled()) {
                 request = true;
                 break;
             }
@@ -3991,8 +3991,8 @@ void MainWindow::slotDoUpdateScopeFrameRequest()
     // Check scopes
     bool request = false;
     for (int i = 0; i < m_scopesList.count(); i++) {
-        if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled()) {
-            kDebug() << "SCOPE VISIBLE: " << static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->widgetName();
+        if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled()) {
+            kDebug() << "SCOPE VISIBLE: " << static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget())->widgetName();
             request = true;
             break;
         }
@@ -4012,8 +4012,8 @@ void MainWindow::slotUpdateColorScopes()
     bool request = false;
     for (int i = 0; i < m_scopesList.count(); i++) {
         // Check if we need the renderer to send a new frame for update
-        if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled())) request = true;
-        static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->slotActiveMonitorChanged(m_clipMonitor->isActive());
+        if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled())) request = true;
+        static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget())->slotActiveMonitorChanged(m_clipMonitor->isActive());
     }
     if (request) {
         if (m_clipMonitor->isActive()) m_clipMonitor->render->sendFrameUpdate();
@@ -4029,7 +4029,7 @@ void MainWindow::slotOpenStopmotion()
         for (int i = 0; i < m_scopesList.count(); i++) {
             // Check if we need the renderer to send a new frame for update
             /*if (!m_scopesList.at(i)->widget()->visibleRegion().isEmpty() && !(static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->autoRefreshEnabled())) request = true;*/
-            connect(m_stopmotion, SIGNAL(gotFrame(QImage)), static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget()), SLOT(slotRenderZoneUpdated(QImage)));
+            connect(m_stopmotion, SIGNAL(gotFrame(QImage)), static_cast<AbstractGfxScopeWidget *>(m_scopesList.at(i)->widget()), SLOT(slotRenderZoneUpdated(QImage)));
             //static_cast<AbstractScopeWidget *>(m_scopesList.at(i)->widget())->slotMonitorCapture();
         }
     }
index 40762aa7b49294fd07551db32f58c7963aefac82..0ea40eea7cec205385d6608f89793bcf74fad4d8 100644 (file)
@@ -17,7 +17,7 @@
 #include "rgbparadegenerator.h"
 
 RGBParade::RGBParade(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
-        AbstractScopeWidget(projMonitor, clipMonitor, true, parent)
+        AbstractGfxScopeWidget(projMonitor, clipMonitor, true, parent)
 {
     ui = new Ui::RGBParade_UI();
     ui->setupUi(this);
@@ -58,7 +58,7 @@ RGBParade::~RGBParade()
 
 void RGBParade::readConfig()
 {
-    AbstractScopeWidget::readConfig();
+    AbstractGfxScopeWidget::readConfig();
 
     KSharedConfigPtr config = KGlobal::config();
     KConfigGroup scopeConfig(config, configName());
index 1757f7074a0cff801054e0af4cf4f9941590c484..0fd42fe65a2d820181f07924f7f494547a026c70 100644 (file)
@@ -12,7 +12,7 @@
 #define RGBPARADE_H
 
 #include <QObject>
-#include "abstractscopewidget.h"
+#include "abstractgfxscopewidget.h"
 #include "ui_rgbparade_ui.h"
 
 class Monitor;
@@ -20,7 +20,7 @@ class QImage;
 class RGBParade_UI;
 class RGBParadeGenerator;
 
-class RGBParade : public AbstractScopeWidget
+class RGBParade : public AbstractGfxScopeWidget
 {
 public:
     RGBParade(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
index 860fd61cbfe3b165678acbb1accf14c8af6f82b1..729643e5abaad6e2f7d946c1ebc2ac5fc230100d 100644 (file)
@@ -43,7 +43,7 @@ const QPointF YPbPr_Yl(-.5, .081);
 
 
 Vectorscope::Vectorscope(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
-    AbstractScopeWidget(projMonitor, clipMonitor, true, parent),
+    AbstractGfxScopeWidget(projMonitor, clipMonitor, true, parent),
     m_gain(1)
 {
     ui = new Ui::Vectorscope_UI();
@@ -142,7 +142,7 @@ QString Vectorscope::widgetName() const { return QString("Vectorscope"); }
 
 void Vectorscope::readConfig()
 {
-    AbstractScopeWidget::readConfig();
+    AbstractGfxScopeWidget::readConfig();
 
     KSharedConfigPtr config = KGlobal::config();
     KConfigGroup scopeConfig(config, configName());
index d2798caef10f60687b0356fa93df95a8bcc68ef2..66c660194ca6a322f3481a7f2ee146a5e0452562 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <QtCore>
 #include "ui_vectorscope_ui.h"
-#include "abstractscopewidget.h"
+#include "abstractgfxscopewidget.h"
 
 class ColorPlaneExport;
 class ColorTools;
@@ -24,7 +24,7 @@ class VectorscopeGenerator;
 
 enum BACKGROUND_MODE { BG_NONE = 0, BG_YUV = 1, BG_CHROMA = 2, BG_YPbPr = 3 };
 
-class Vectorscope : public AbstractScopeWidget {
+class Vectorscope : public AbstractGfxScopeWidget {
     Q_OBJECT
 
 public:
index 5bd51f19d2d75f891a5944dd3cb0b99571d38173..27beee2e543f495f68885b6cee73a9c37326a96d 100644 (file)
@@ -26,7 +26,7 @@ const QSize Waveform::m_textWidth(35,0);
 const int Waveform::m_paddingBottom(20);
 
 Waveform::Waveform(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
-    AbstractScopeWidget(projMonitor, clipMonitor, true, parent)
+    AbstractGfxScopeWidget(projMonitor, clipMonitor, true, parent)
 {
     ui = new Ui::Waveform_UI();
     ui->setupUi(this);
@@ -71,7 +71,7 @@ Waveform::~Waveform()
 
 void Waveform::readConfig()
 {
-    AbstractScopeWidget::readConfig();
+    AbstractGfxScopeWidget::readConfig();
 
     KSharedConfigPtr config = KGlobal::config();
     KConfigGroup scopeConfig(config, configName());
index 5ece240f3995ca4ccc7d13f60ed19fc058262b0b..45fde952003bb5c90f16cbd7676e58137545c070 100644 (file)
 #ifndef WAVEFORM_H
 #define WAVEFORM_H
 
-#include "abstractscopewidget.h"
+#include "abstractgfxscopewidget.h"
 
 #include "ui_waveform_ui.h"
 
 class Waveform_UI;
 class WaveformGenerator;
 
-class Waveform : public AbstractScopeWidget {
+class Waveform : public AbstractGfxScopeWidget {
     Q_OBJECT
 
 public: