From 062997dba4bf4cd216f3ab855995c16b275c655c Mon Sep 17 00:00:00 2001 From: "Simon A. Eugster" Date: Tue, 7 Dec 2010 20:42:25 +0000 Subject: [PATCH] * Moved movement detection to Abstract Scope widget * Auto-Refresh: virtual modifier removed from slot (did not connect due to dubious reasons here with the virtual modifier) * Code cleanup, unused functions removed svn path=/trunk/kdenlive/; revision=5150 --- src/abstractscopewidget.cpp | 117 ++++++++++++++++---- src/abstractscopewidget.h | 36 +++++- src/audioscopes/audiospectrum.cpp | 175 ++++++++---------------------- src/audioscopes/audiospectrum.h | 26 +---- src/audioscopes/spectrogram.cpp | 2 +- src/mainwindow.cpp | 14 ++- 6 files changed, 186 insertions(+), 184 deletions(-) diff --git a/src/abstractscopewidget.cpp b/src/abstractscopewidget.cpp index 86f1cb59..9c3bc416 100644 --- a/src/abstractscopewidget.cpp +++ b/src/abstractscopewidget.cpp @@ -40,6 +40,8 @@ const QPen AbstractScopeWidget::penLightDots(QBrush(QColor(200, 200, 250, 150)), const QPen AbstractScopeWidget::penDark(QBrush(QColor(0, 0, 20, 250)), 1, Qt::SolidLine); const QPen AbstractScopeWidget::penDarkDots(QBrush(QColor(0, 0, 20, 250)), 1, Qt::DotLine); +const QString AbstractScopeWidget::directions[] = {"North", "Northeast", "East", "Southeast"}; + AbstractScopeWidget::AbstractScopeWidget(bool trackMouse, QWidget *parent) : QWidget(parent), m_mousePos(0, 0), @@ -52,7 +54,9 @@ AbstractScopeWidget::AbstractScopeWidget(bool trackMouse, QWidget *parent) : m_semaphoreScope(1), m_semaphoreBackground(1), initialDimensionUpdateDone(false), - m_requestForcedUpdate(false) + m_requestForcedUpdate(false), + m_rescaleMinDist(4), + m_rescaleVerticalThreshold(2.0f) { m_scopePalette = QPalette(); @@ -222,7 +226,7 @@ void AbstractScopeWidget::prodBackgroundThread() void AbstractScopeWidget::forceUpdate(bool doUpdate) { #ifdef DEBUG_ASW - qDebug() << "Force update called in " << widgetName() << ". Arg: " << doUpdate; + qDebug() << "Forced update called in " << widgetName() << ". Arg: " << doUpdate; #endif if (!doUpdate) { @@ -259,16 +263,6 @@ void AbstractScopeWidget::forceUpdateBackground() ///// Events ///// -void AbstractScopeWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (!m_aAutoRefresh->isChecked()) { - m_requestForcedUpdate = true; - } - prodHUDThread(); - prodScopeThread(); - prodBackgroundThread(); - QWidget::mouseReleaseEvent(event); -} void AbstractScopeWidget::resizeEvent(QResizeEvent *event) { @@ -293,12 +287,88 @@ void AbstractScopeWidget::paintEvent(QPaintEvent *) davinci.drawImage(m_scopeRect.topLeft(), m_imgHUD); } +void AbstractScopeWidget::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + // Rescaling mode starts + m_rescaleActive = true; + m_rescalePropertiesLocked = false; + m_rescaleFirstRescaleDone = false; + m_rescaleStartPoint = event->pos(); + m_rescaleModifiers = event->modifiers(); + } +} +void AbstractScopeWidget::mouseReleaseEvent(QMouseEvent *event) +{ + m_rescaleActive = false; + m_rescalePropertiesLocked = false; + + if (!m_aAutoRefresh->isChecked()) { + m_requestForcedUpdate = true; + } + prodHUDThread(); + prodScopeThread(); + prodBackgroundThread(); + QWidget::mouseReleaseEvent(event); +} void AbstractScopeWidget::mouseMoveEvent(QMouseEvent *event) { m_mousePos = event->pos(); m_mouseWithinWidget = true; emit signalMousePositionChanged(); + + QPoint movement = event->pos()-m_rescaleStartPoint; + + if (m_rescaleActive) { + if (m_rescalePropertiesLocked) { + // Direction is known, now adjust parameters + + // Reset the starting point to make the next moveEvent relative to the current one + m_rescaleStartPoint = event->pos(); + + + if (!m_rescaleFirstRescaleDone) { + // We have just learned the desired direction; Normalize the movement to one pixel + // to avoid a jump by m_rescaleMinDist + + if (movement.x() != 0) { + movement.setX(movement.x() / abs(movement.x())); + } + if (movement.y() != 0) { + movement.setY(movement.y() / abs(movement.y())); + } + + m_rescaleFirstRescaleDone = true; + } + + handleMouseDrag(movement, m_rescaleDirection, m_rescaleModifiers); + + + + } else { + // Detect the movement direction here. + // This algorithm relies on the aspect ratio of dy/dx (size and signum). + if (movement.manhattanLength() > m_rescaleMinDist) { + float diff = ((float) movement.y())/movement.x(); + + if (abs(diff) > m_rescaleVerticalThreshold || movement.x() == 0) { + m_rescaleDirection = North; + } else if (abs(diff) < 1/m_rescaleVerticalThreshold) { + m_rescaleDirection = East; + } else if (diff < 0) { + m_rescaleDirection = Northeast; + } else { + m_rescaleDirection = Southeast; + } +#ifdef DEBUG_ASW + qDebug() << "Diff is " << diff << "; chose " << directions[m_rescaleDirection] << " as direction"; +#endif + m_rescalePropertiesLocked = true; + } + } + } } + void AbstractScopeWidget::leaveEvent(QEvent *) { m_mouseWithinWidget = false; @@ -328,7 +398,9 @@ uint AbstractScopeWidget::calculateAccelFactorBackground(uint oldMseconds, uint) void AbstractScopeWidget::slotHUDRenderingFinished(uint mseconds, uint oldFactor) { -// qDebug() << "HUD rendering has finished, waiting for termination in " << m_widgetName; +#ifdef DEBUG_ASW + qDebug() << "HUD rendering has finished in " << mseconds << " ms, waiting for termination in " << m_widgetName; +#endif m_threadHUD.waitForFinished(); m_imgHUD = m_threadHUD.result(); @@ -358,7 +430,7 @@ void AbstractScopeWidget::slotScopeRenderingFinished(uint mseconds, uint oldFact // 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. #ifdef DEBUG_ASW - qDebug() << "Scope rendering has finished, waiting for termination in " << m_widgetName; + qDebug() << "Scope rendering has finished in " << mseconds << " ms, waiting for termination in " << m_widgetName; #endif m_threadScope.waitForFinished(); m_imgScope = m_threadScope.result(); @@ -394,7 +466,7 @@ void AbstractScopeWidget::slotScopeRenderingFinished(uint mseconds, uint oldFact void AbstractScopeWidget::slotBackgroundRenderingFinished(uint mseconds, uint oldFactor) { #ifdef DEBUG_ASW - qDebug() << "Background rendering has finished, waiting for termination in " << m_widgetName; + qDebug() << "Background rendering has finished in " << mseconds << " ms, waiting for termination in " << m_widgetName; #endif m_threadBackground.waitForFinished(); m_imgBackground = m_threadBackground.result(); @@ -427,7 +499,7 @@ void AbstractScopeWidget::slotRenderZoneUpdated() m_newBackgroundFrames.fetchAndAddRelaxed(1); #ifdef DEBUG_ASW - qDebug() << "Monitor incoming. New frames total HUD/Scope/Background: " << m_newHUDFrames + qDebug() << "Monitor incoming at " << widgetName() << ". New frames total HUD/Scope/Background: " << m_newHUDFrames << "/" << m_newScopeFrames << "/" << m_newBackgroundFrames; #endif @@ -444,12 +516,6 @@ void AbstractScopeWidget::slotRenderZoneUpdated() } } -void AbstractScopeWidget::slotRenderZoneUpdated(QImage frame) -{ - m_scopeImage = frame; - slotRenderZoneUpdated(); -} - void AbstractScopeWidget::slotResetRealtimeFactor(bool realtimeChecked) { if (!realtimeChecked) { @@ -466,7 +532,12 @@ bool AbstractScopeWidget::autoRefreshEnabled() void AbstractScopeWidget::slotAutoRefreshToggled(bool autoRefresh) { +#ifdef DEBUG_ASW + qDebug() << "Auto-refresh switched to " << autoRefresh << " in " << widgetName() + << " (Visible: " << isVisible() << "/" << this->visibleRegion().isEmpty() << ")"; +#endif if (isVisible()) { + // Notify listeners whether we accept new frames now emit requestAutoRefresh(autoRefresh); } // TODO only if depends on input @@ -476,6 +547,8 @@ void AbstractScopeWidget::slotAutoRefreshToggled(bool autoRefresh) } } +void AbstractScopeWidget::handleMouseDrag(const QPoint, const RescaleDirection, const Qt::KeyboardModifiers) { } + #ifdef DEBUG_ASW #undef DEBUG_ASW diff --git a/src/abstractscopewidget.h b/src/abstractscopewidget.h index 030eafbb..c1a77118 100644 --- a/src/abstractscopewidget.h +++ b/src/abstractscopewidget.h @@ -60,13 +60,19 @@ class AbstractScopeWidget : public QWidget public: AbstractScopeWidget(bool trackMouse = false, QWidget *parent = 0); virtual ~AbstractScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks + + + enum RescaleDirection { North, Northeast, East, Southeast }; + + QPalette m_scopePalette; /** Initializes widget settings (reads configuration). Has to be called in the implementing object. */ virtual void init(); - /** Does this scope have auto-refresh enabled */ + /** Tell whether this scope has auto-refresh enabled. Required for determining whether + new data (e.g. an image frame) has to be delivered to this widget. */ bool autoRefreshEnabled(); ///// Unimplemented ///// @@ -81,6 +87,8 @@ public: static const QPen penDark; static const QPen penDarkDots; + static const QString directions[]; // Mainly for debug output + protected: ///// Variables ///// @@ -165,11 +173,17 @@ protected: virtual uint calculateAccelFactorScope(uint oldMseconds, uint oldFactor); virtual uint calculateAccelFactorBackground(uint oldMseconds, uint oldFactor); + /** The Abstract Scope will try to detect the movement direction when dragging on the widget with the mouse. + As soon as the direction is determined it will execute this method. Can be used e.g. for re-scaling content. + This is just a dummy function, re-implement to add functionality. */ + virtual void handleMouseDrag(const QPoint movement, const RescaleDirection rescaleDirection, const Qt::KeyboardModifiers rescaleModifiers); + ///// Reimplemented ///// - void mouseMoveEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); 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 @@ -182,7 +196,7 @@ protected slots: void forceUpdateHUD(); void forceUpdateScope(); void forceUpdateBackground(); - virtual void slotAutoRefreshToggled(bool); + void slotAutoRefreshToggled(bool); signals: /** mseconds represent the time taken for the calculation, @@ -234,13 +248,25 @@ private: void prodScopeThread(); void prodBackgroundThread(); + ///// Movement detection ///// + const int m_rescaleMinDist; + const float m_rescaleVerticalThreshold; + + bool m_rescaleActive; + bool m_rescalePropertiesLocked; + bool m_rescaleFirstRescaleDone; + short m_rescaleScale; + Qt::KeyboardModifiers m_rescaleModifiers; + RescaleDirection m_rescaleDirection; + QPoint m_rescaleStartPoint; + + 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 on whether it is currently visible and whether a calculation thread is already running. */ void slotRenderZoneUpdated(); - void slotRenderZoneUpdated(QImage);//TODO remove /** 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); diff --git a/src/audioscopes/audiospectrum.cpp b/src/audioscopes/audiospectrum.cpp index b4e3a6b9..bad169f2 100644 --- a/src/audioscopes/audiospectrum.cpp +++ b/src/audioscopes/audiospectrum.cpp @@ -32,16 +32,9 @@ bool fileWritten = false; #define MAX_FREQ_VALUE 96000 #define MIN_FREQ_VALUE 1000 -const QString AudioSpectrum::directions[] = {"North", "Northeast", "East", "Southeast"}; - AudioSpectrum::AudioSpectrum(QWidget *parent) : AbstractAudioScopeWidget(false, parent), - m_fftTools(), - m_rescaleMinDist(8), - m_rescaleVerticalThreshold(2.0f), - m_rescaleActive(false), - m_rescalePropertiesLocked(false), - m_rescaleScale(1) + m_fftTools() { ui = new Ui::AudioSpectrum_UI; ui->setupUi(this); @@ -355,149 +348,71 @@ void AudioSpectrum::slotResetMaxFreq() ///// EVENTS ///// -void AudioSpectrum::mouseMoveEvent(QMouseEvent *event) +void AudioSpectrum::handleMouseDrag(const QPoint movement, const RescaleDirection rescaleDirection, const Qt::KeyboardModifiers rescaleModifiers) { - QPoint movement = event->pos()-m_rescaleStartPoint; - - if (m_rescaleActive) { - if (m_rescalePropertiesLocked) { - // Direction is known, now adjust parameters - - // Reset the starting point to make the next moveEvent relative to the current one - m_rescaleStartPoint = event->pos(); - - - if (!m_rescaleFirstRescaleDone) { - // We have just learned the desired direction; Normalize the movement to one pixel - // to avoid a jump by m_rescaleMinDist - - if (movement.x() != 0) { - movement.setX(movement.x() / abs(movement.x())); - } - if (movement.y() != 0) { - movement.setY(movement.y() / abs(movement.y())); - } - - m_rescaleFirstRescaleDone = true; - } - - if (m_rescaleClockDirection == AudioSpectrum::North) { - // Nort-South direction: Adjust the dB scale + if (rescaleDirection == AudioSpectrum::North) { + // Nort-South direction: Adjust the dB scale - if ((m_rescaleModifiers & Qt::ShiftModifier) == 0) { + if ((rescaleModifiers & Qt::ShiftModifier) == 0) { - // By default adjust the min dB value - m_dBmin += movement.y(); + // By default adjust the min dB value + m_dBmin += movement.y(); - } else { + } else { - // Adjust max dB value if Shift is pressed. - m_dBmax += movement.y(); + // Adjust max dB value if Shift is pressed. + m_dBmax += movement.y(); - } + } - // Ensure the dB values lie in [-100, 0] (or rather [MIN_DB_VALUE, 0]) - // 0 is the upper bound, everything below -70 dB is most likely noise + // Ensure the dB values lie in [-100, 0] (or rather [MIN_DB_VALUE, 0]) + // 0 is the upper bound, everything below -70 dB is most likely noise + if (m_dBmax > 0) { + m_dBmax = 0; + } + if (m_dBmin < MIN_DB_VALUE) { + m_dBmin = MIN_DB_VALUE; + } + // Ensure there is at least 6 dB between the minimum and the maximum value; + // lower values hardly make sense + if (m_dBmax - m_dBmin < 6) { + if ((rescaleModifiers & Qt::ShiftModifier) == 0) { + // min was adjusted; Try to adjust the max value to maintain the + // minimum dB difference of 6 dB + m_dBmax = m_dBmin + 6; if (m_dBmax > 0) { m_dBmax = 0; + m_dBmin = -6; } + } else { + // max was adjusted, adjust min + m_dBmin = m_dBmax - 6; if (m_dBmin < MIN_DB_VALUE) { m_dBmin = MIN_DB_VALUE; + m_dBmax = MIN_DB_VALUE+6; } - // Ensure there is at least 6 dB between the minimum and the maximum value; - // lower values hardly make sense - if (m_dBmax - m_dBmin < 6) { - if ((m_rescaleModifiers & Qt::ShiftModifier) == 0) { - // min was adjusted; Try to adjust the max value to maintain the - // minimum dB difference of 6 dB - m_dBmax = m_dBmin + 6; - if (m_dBmax > 0) { - m_dBmax = 0; - m_dBmin = -6; - } - } else { - // max was adjusted, adjust min - m_dBmin = m_dBmax - 6; - if (m_dBmin < MIN_DB_VALUE) { - m_dBmin = MIN_DB_VALUE; - m_dBmax = MIN_DB_VALUE+6; - } - } - } - - forceUpdateHUD(); - forceUpdateScope(); - - } else if (m_rescaleClockDirection == AudioSpectrum::East) { - // East-West direction: Adjust the maximum frequency - m_freqMax -= 100*movement.x(); - if (m_freqMax < MIN_FREQ_VALUE) { - m_freqMax = MIN_FREQ_VALUE; - } - if (m_freqMax > MAX_FREQ_VALUE) { - m_freqMax = MAX_FREQ_VALUE; - } - m_customFreq = true; - - forceUpdateHUD(); - forceUpdateScope(); } + } + forceUpdateHUD(); + forceUpdateScope(); - } else { - // Detect the movement direction here. - // This algorithm relies on the aspect ratio of dy/dx (size and signum). - if (movement.manhattanLength() > m_rescaleMinDist) { - float diff = ((float) movement.y())/movement.x(); - - if (abs(diff) > m_rescaleVerticalThreshold || movement.x() == 0) { - m_rescaleClockDirection = AudioSpectrum::North; - } else if (abs(diff) < 1/m_rescaleVerticalThreshold) { - m_rescaleClockDirection = AudioSpectrum::East; - } else if (diff < 0) { - m_rescaleClockDirection = AudioSpectrum::Northeast; - } else { - m_rescaleClockDirection = AudioSpectrum::Southeast; - } -#ifdef DEBUG_AUDIOSPEC - qDebug() << "Diff is " << diff << "; chose " << directions[m_rescaleClockDirection] << " as direction"; -#endif - m_rescalePropertiesLocked = true; - } + } else if (rescaleDirection == AudioSpectrum::East) { + // East-West direction: Adjust the maximum frequency + m_freqMax -= 100*movement.x(); + if (m_freqMax < MIN_FREQ_VALUE) { + m_freqMax = MIN_FREQ_VALUE; } - } else { - AbstractAudioScopeWidget::mouseMoveEvent(event); - } -} - -void AudioSpectrum::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - // Rescaling mode starts - m_rescaleActive = true; - m_rescalePropertiesLocked = false; - m_rescaleFirstRescaleDone = false; - m_rescaleStartPoint = event->pos(); - m_rescaleModifiers = event->modifiers(); + if (m_freqMax > MAX_FREQ_VALUE) { + m_freqMax = MAX_FREQ_VALUE; + } + m_customFreq = true; - } else { - AbstractAudioScopeWidget::mousePressEvent(event); + forceUpdateHUD(); + forceUpdateScope(); } } -void AudioSpectrum::mouseReleaseEvent(QMouseEvent *event) -{ - m_rescaleActive = false; - m_rescalePropertiesLocked = false; - - AbstractAudioScopeWidget::mouseReleaseEvent(event); -} - -const QString AudioSpectrum::cfgSignature(const int size) -{ - return QString("s%1").arg(size); -} - #ifdef DEBUG_AUDIOSPEC #undef DEBUG_AUDIOSPEC diff --git a/src/audioscopes/audiospectrum.h b/src/audioscopes/audiospectrum.h index e3e2498e..b159f682 100644 --- a/src/audioscopes/audiospectrum.h +++ b/src/audioscopes/audiospectrum.h @@ -37,10 +37,6 @@ public: // Implemented virtual methods QString widgetName() const; - static const QString directions[]; // Mainly for debug output - enum RescaleDirection { North, Northeast, East, Southeast }; - enum RescaleDimension { Min_dB, Max_dB, Max_Hz }; - protected: ///// Implemented methods ///// @@ -54,9 +50,7 @@ protected: virtual void readConfig(); void writeConfig(); - void mouseMoveEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); + virtual void handleMouseDrag(const QPoint movement, const RescaleDirection rescaleDirection, const Qt::KeyboardModifiers rescaleModifiers); private: Ui::AudioSpectrum_UI *ui; @@ -80,24 +74,6 @@ private: bool m_customFreq; - /** Returns a signature for a kiss_fft configuration - used as a hash in the cache */ - static const QString cfgSignature(const int size); - - - ///// Movement detection ///// - const int m_rescaleMinDist; - const float m_rescaleVerticalThreshold; - - bool m_rescaleActive; - bool m_rescalePropertiesLocked; - bool m_rescaleFirstRescaleDone; - short m_rescaleScale; - Qt::KeyboardModifiers m_rescaleModifiers; - AudioSpectrum::RescaleDirection m_rescaleClockDirection; - QPoint m_rescaleStartPoint; - - private slots: void slotResetMaxFreq(); diff --git a/src/audioscopes/spectrogram.cpp b/src/audioscopes/spectrogram.cpp index b8d70f6f..b3eb46af 100644 --- a/src/audioscopes/spectrogram.cpp +++ b/src/audioscopes/spectrogram.cpp @@ -18,7 +18,7 @@ // Can be less as a pre-rendered image is kept in space. #define SPECTROGRAM_HISTORY_SIZE 1000 -#define DEBUG_SPECTROGRAM +//#define DEBUG_SPECTROGRAM #ifdef DEBUG_SPECTROGRAM #include #endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fe5a3dc9..238a0fbf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -112,6 +112,11 @@ #include +//#define DEBUG_MAINW +#ifdef DEBUG_MAINW +#include +#endif + static const char version[] = VERSION; static const int ID_TIMELINE_POS = 0; @@ -4003,6 +4008,9 @@ void MainWindow::slotMonitorRequestRenderFrame(bool request) } } } +#ifdef DEBUG_MAINW + qDebug() << "Any scope accepting new frames? " << request; +#endif if (!request) { m_projectMonitor->render->sendFrameForAnalysis = false; } @@ -4026,8 +4034,9 @@ void MainWindow::slotDoUpdateScopeFrameRequest() } } if (!request) { - if (!m_projectMonitor->effectSceneDisplayed()) + if (!m_projectMonitor->effectSceneDisplayed()) { m_projectMonitor->render->sendFrameForAnalysis = false; + } m_clipMonitor->render->sendFrameForAnalysis = false; } else { m_projectMonitor->render->sendFrameForAnalysis = true; @@ -4075,3 +4084,6 @@ void MainWindow::slotDeleteClip(const QString &id) #include "mainwindow.moc" +#ifdef DEBUG_MAINW +#undef DEBUG_MAINW +#endif -- 2.39.2