diff options
author | Uwe Klotz <uklotz@mixxx.org> | 2020-05-16 21:38:09 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-16 21:38:09 +0200 |
commit | a440c5a32954d4dacaa91e479141f442103b7434 (patch) | |
tree | cc08d34e1002294497f985990a0855e1a3b418a6 | |
parent | 472d443cb56c2e7d1791ac9a3ec8cab03ffd10ad (diff) | |
parent | 3deebd91f84e8baba004f571b7d75884e232ae19 (diff) |
Merge pull request #2783 from hacksdump/scrolling-waveform-cue-context-menu
Cue context menu for scrolling waveform
-rw-r--r-- | src/waveform/renderers/waveformmark.cpp | 17 | ||||
-rw-r--r-- | src/waveform/renderers/waveformmark.h | 3 | ||||
-rw-r--r-- | src/waveform/renderers/waveformrendermark.cpp | 41 | ||||
-rw-r--r-- | src/waveform/renderers/waveformwidgetrenderer.cpp | 17 | ||||
-rw-r--r-- | src/waveform/renderers/waveformwidgetrenderer.h | 9 | ||||
-rw-r--r-- | src/waveform/waveformmarklabel.h | 4 | ||||
-rw-r--r-- | src/widget/wcuemenupopup.cpp | 5 | ||||
-rw-r--r-- | src/widget/wcuemenupopup.h | 8 | ||||
-rw-r--r-- | src/widget/woverview.cpp | 37 | ||||
-rw-r--r-- | src/widget/woverview.h | 1 | ||||
-rw-r--r-- | src/widget/wwaveformviewer.cpp | 112 | ||||
-rw-r--r-- | src/widget/wwaveformviewer.h | 18 |
12 files changed, 201 insertions, 71 deletions
diff --git a/src/waveform/renderers/waveformmark.cpp b/src/waveform/renderers/waveformmark.cpp index 5d8e7d1164..b9449d24b4 100644 --- a/src/waveform/renderers/waveformmark.cpp +++ b/src/waveform/renderers/waveformmark.cpp @@ -99,7 +99,24 @@ WaveformMark::WaveformMark(const QString& group, } void WaveformMark::setBaseColor(QColor baseColor) { + m_image = QImage(); m_fillColor = baseColor; m_borderColor = Color::chooseContrastColor(baseColor); m_labelColor = Color::chooseColorByBrightness(baseColor, QColor(255,255,255,255), QColor(0,0,0,255)); }; + +bool WaveformMark::contains(QPoint point, Qt::Orientation orientation) const { + // Without some padding, the user would only have a single pixel width that + // would count as hovering over the WaveformMark. + float lineHoverPadding = 5.0; + int position; + if (orientation == Qt::Horizontal) { + position = point.x(); + } else { + position = point.y(); + } + bool lineHovered = m_linePosition >= position - lineHoverPadding && + m_linePosition <= position + lineHoverPadding; + + return m_label.area().contains(point) || lineHovered; +} diff --git a/src/waveform/renderers/waveformmark.h b/src/waveform/renderers/waveformmark.h index caf652adaa..abb0da8286 100644 --- a/src/waveform/renderers/waveformmark.h +++ b/src/waveform/renderers/waveformmark.h @@ -66,6 +66,9 @@ class WaveformMark { return m_labelColor; } + // Check if a point (in image co-ordinates) lies on drawn image. + bool contains(QPoint point, Qt::Orientation orientation) const; + QColor m_textColor; QString m_text; Qt::Alignment m_align; diff --git a/src/waveform/renderers/waveformrendermark.cpp b/src/waveform/renderers/waveformrendermark.cpp index 2a51726d4c..5e9356fae7 100644 --- a/src/waveform/renderers/waveformrendermark.cpp +++ b/src/waveform/renderers/waveformrendermark.cpp @@ -31,7 +31,8 @@ void WaveformRenderMark::setup(const QDomNode& node, const SkinContext& context) void WaveformRenderMark::draw(QPainter* painter, QPaintEvent* /*event*/) { PainterScope PainterScope(painter); - + // Maps mark objects to their positions in the widget. + QMap<WaveformMarkPointer, int> marksOnScreen; /* //DEBUG for (int i = 0; i < m_markPoints.size(); i++) { @@ -60,32 +61,37 @@ void WaveformRenderMark::draw(QPainter* painter, QPaintEvent* /*event*/) { if (samplePosition != -1.0) { double currentMarkPoint = m_waveformRenderer->transformSamplePositionInRendererWorld(samplePosition); - if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { // NOTE: vRince I guess image width is odd to display the center on the exact line ! // external image should respect that ... const int markHalfWidth = pMark->m_image.width() / 2.0 / m_waveformRenderer->getDevicePixelRatio(); - // Check if the current point need to be displayed + // Check if the current point needs to be displayed. if (currentMarkPoint > -markHalfWidth && currentMarkPoint < m_waveformRenderer->getWidth() + markHalfWidth) { - painter->drawImage(QPoint(currentMarkPoint - markHalfWidth, 0), pMark->m_image); + int drawOffset = currentMarkPoint - markHalfWidth; + painter->drawImage(QPoint(drawOffset, 0), pMark->m_image); + marksOnScreen[pMark] = drawOffset; } } else { const int markHalfHeight = pMark->m_image.height() / 2.0; - - if (currentMarkPoint > -markHalfHeight && currentMarkPoint < m_waveformRenderer->getHeight() + markHalfHeight) { - painter->drawImage(QPoint(0,currentMarkPoint - markHalfHeight), pMark->m_image); + if (currentMarkPoint > -markHalfHeight && + currentMarkPoint < m_waveformRenderer->getHeight() + + markHalfHeight) { + int drawOffset = currentMarkPoint - markHalfHeight; + painter->drawImage(QPoint(0, drawOffset), pMark->m_image); + marksOnScreen[pMark] = drawOffset; } } } } + m_waveformRenderer->setMarkPositions(marksOnScreen); } void WaveformRenderMark::onResize() { // Delete all marks' images. New images will be created on next paint. - for (const auto& pMark: m_marks) { - pMark->m_image = QImage(); + for (const auto& pMark : m_marks) { + pMark->m_image = QImage(); } } @@ -104,12 +110,12 @@ void WaveformRenderMark::onSetTrack() { void WaveformRenderMark::slotCuesUpdated() { TrackPointer trackInfo = m_waveformRenderer->getTrackInfo(); - if (!trackInfo){ + if (!trackInfo) { return; } QList<CuePointer> loadedCues = trackInfo->getCuePoints(); - for (const CuePointer pCue: loadedCues) { + for (const CuePointer pCue : loadedCues) { int hotCue = pCue->getHotCue(); if (hotCue == Cue::kNoHotCue) { continue; @@ -125,7 +131,8 @@ void WaveformRenderMark::slotCuesUpdated() { QString newLabel = pCue->getLabel(); QColor newColor = mixxx::RgbColor::toQColor(pCue->getColor()); if (pMark->m_text.isNull() || newLabel != pMark->m_text || - !pMark->fillColor().isValid() || newColor != pMark->fillColor()) { + !pMark->fillColor().isValid() || + newColor != pMark->fillColor()) { pMark->m_text = newLabel; pMark->setBaseColor(newColor); generateMarkImage(pMark); @@ -142,7 +149,8 @@ void WaveformRenderMark::generateMarkImage(WaveformMarkPointer pMark) { // If loading the image didn't fail, then we're done. Otherwise fall // through and render a label. if (!image.isNull()) { - pMark->m_image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); + pMark->m_image = + image.convertToFormat(QImage::Format_ARGB32_Premultiplied); //WImageStore::correctImageColors(&pMark->m_image); return; } @@ -200,7 +208,8 @@ void WaveformRenderMark::generateMarkImage(WaveformMarkPointer pMark) { pMark->m_image = QImage(width * m_waveformRenderer->getDevicePixelRatio(), height * m_waveformRenderer->getDevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); - pMark->m_image.setDevicePixelRatio(m_waveformRenderer->getDevicePixelRatio()); + pMark->m_image.setDevicePixelRatio( + m_waveformRenderer->getDevicePixelRatio()); Qt::Alignment markAlignH = pMark->m_align & Qt::AlignHorizontal_Mask; Qt::Alignment markAlignV = pMark->m_align & Qt::AlignVertical_Mask; @@ -217,6 +226,8 @@ void WaveformRenderMark::generateMarkImage(WaveformMarkPointer pMark) { labelRect.moveBottom(height - 1); } + pMark->m_label.setAreaRect(labelRect); + // Fill with transparent pixels pMark->m_image.fill(QColor(0, 0, 0, 0).rgba()); @@ -228,6 +239,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMarkPointer pMark) { // Draw marker lines if (m_waveformRenderer->getOrientation() == Qt::Horizontal) { int middle = width / 2; + pMark->m_linePosition = middle; if (markAlignH == Qt::AlignHCenter) { if (labelRect.top() > 0) { painter.setPen(pMark->fillColor()); @@ -256,6 +268,7 @@ void WaveformRenderMark::generateMarkImage(WaveformMarkPointer pMark) { } } else { // Vertical int middle = height / 2; + pMark->m_linePosition = middle; if (markAlignV == Qt::AlignVCenter) { if (labelRect.left() > 0) { painter.setPen(pMark->fillColor()); diff --git a/src/waveform/renderers/waveformwidgetrenderer.cpp b/src/waveform/renderers/waveformwidgetrenderer.cpp index 8c37c2d2cd..bd181fdf0f 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.cpp +++ b/src/waveform/renderers/waveformwidgetrenderer.cpp @@ -288,3 +288,20 @@ void WaveformWidgetRenderer::setTrack(TrackPointer track) { m_rendererStack[i]->onSetTrack(); } } + +WaveformMarkPointer WaveformWidgetRenderer::getCueMarkAtPoint(QPoint point) const { + for (const auto& pMark : m_markPositions.keys()) { + int markImagePositionInWidgetSpace = m_markPositions[pMark]; + QPoint pointInImageSpace; + if (getOrientation() == Qt::Horizontal) { + pointInImageSpace = QPoint(point.x() - markImagePositionInWidgetSpace, point.y()); + } else { + DEBUG_ASSERT(getOrientation() == Qt::Vertical); + pointInImageSpace = QPoint(point.x(), point.y() - markImagePositionInWidgetSpace); + } + if (pMark->contains(pointInImageSpace, getOrientation())) { + return pMark; + } + } + return nullptr; +} diff --git a/src/waveform/renderers/waveformwidgetrenderer.h b/src/waveform/renderers/waveformwidgetrenderer.h index 9cab36f6c8..6e7ef4b042 100644 --- a/src/waveform/renderers/waveformwidgetrenderer.h +++ b/src/waveform/renderers/waveformwidgetrenderer.h @@ -8,9 +8,10 @@ #include "track/track.h" #include "util/class.h" +#include "util/performancetimer.h" +#include "waveform/renderers/waveformmark.h" #include "waveform/renderers/waveformrendererabstract.h" #include "waveform/renderers/waveformsignalcolors.h" -#include "util/performancetimer.h" //#define WAVEFORMWIDGETRENDERER_DEBUG @@ -39,6 +40,8 @@ class WaveformWidgetRenderer { inline const char* getGroup() const { return m_group;} const TrackPointer getTrackInfo() const { return m_pTrack;} + /// Get cue mark at a point on the waveform widget. + WaveformMarkPointer getCueMarkAtPoint(QPoint point) const; double getFirstDisplayedPosition() const { return m_firstDisplayedPosition;} double getLastDisplayedPosition() const { return m_lastDisplayedPosition;} @@ -93,6 +96,9 @@ class WaveformWidgetRenderer { } void setTrack(TrackPointer track); + void setMarkPositions(QMap<WaveformMarkPointer, int> markPositions) { + m_markPositions = markPositions; + } double getPlayMarkerPosition() { return m_playMarkerPosition; @@ -151,6 +157,7 @@ class WaveformWidgetRenderer { private: DISALLOW_COPY_AND_ASSIGN(WaveformWidgetRenderer); friend class WaveformWidgetFactory; + QMap<WaveformMarkPointer, int> m_markPositions; }; #endif // WAVEFORMWIDGETRENDERER_H diff --git a/src/waveform/waveformmarklabel.h b/src/waveform/waveformmarklabel.h index 02ff40ca79..e3a588a49b 100644 --- a/src/waveform/waveformmarklabel.h +++ b/src/waveform/waveformmarklabel.h @@ -27,6 +27,10 @@ class WaveformMarkLabel { return m_areaRect; }; + void setAreaRect(QRectF areaRect) { + m_areaRect = areaRect; + } + bool intersects(const QRectF& other) const { return m_areaRect.intersects(other); } diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp index 66bd49d378..6b270f5559 100644 --- a/src/widget/wcuemenupopup.cpp +++ b/src/widget/wcuemenupopup.cpp @@ -132,3 +132,8 @@ void WCueMenuPopup::slotDeleteCue() { m_pTrack->removeCue(m_pCue); hide(); } + +void WCueMenuPopup::closeEvent(QCloseEvent* event) { + emit aboutToHide(); + QWidget::closeEvent(event); +} diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h index 7e1743590d..d04e825f6f 100644 --- a/src/widget/wcuemenupopup.h +++ b/src/widget/wcuemenupopup.h @@ -37,11 +37,6 @@ class WCueMenuPopup : public QWidget { show(); } - void hide() { - emit aboutToHide(); - QWidget::hide(); - } - void show() { setColorPalette(m_colorPaletteSettings.getHotcueColorPalette()); m_pEditLabel->setFocus(); @@ -68,4 +63,7 @@ class WCueMenuPopup : public QWidget { QLineEdit* m_pEditLabel; WColorPicker* m_pColorPicker; QPushButton* m_pDeleteCue; + + protected: + void closeEvent(QCloseEvent* event) override; }; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index daa64d937f..a2c6b0bdc5 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -62,7 +62,6 @@ WOverview::WOverview( m_iPickupPos(0), m_iPlayPos(0), m_pHoveredMark(nullptr), - m_bHotcueMenuShowing(false), m_bTimeRulerActive(false), m_orientation(Qt::Horizontal), m_iLabelFontSize(10), @@ -309,8 +308,10 @@ void WOverview::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) //qDebug() << this << "WOverview::slotLoadingTrack" << pNewTrack.get() << pOldTrack.get(); DEBUG_ASSERT(m_pCurrentTrack == pOldTrack); if (m_pCurrentTrack != nullptr) { - disconnect(m_pCurrentTrack.get(), SIGNAL(waveformSummaryUpdated()), - this, SLOT(slotWaveformSummaryUpdated())); + disconnect(m_pCurrentTrack.get(), + &Track::waveformSummaryUpdated, + this, + &WOverview::slotWaveformSummaryUpdated); } m_waveformSourceImage = QImage(); @@ -325,11 +326,12 @@ void WOverview::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) m_pCurrentTrack = pNewTrack; m_pWaveform = pNewTrack->getWaveformSummary(); - connect(pNewTrack.get(), SIGNAL(waveformSummaryUpdated()), - this, SLOT(slotWaveformSummaryUpdated())); + connect(pNewTrack.get(), + &Track::waveformSummaryUpdated, + this, + &WOverview::slotWaveformSummaryUpdated); slotWaveformSummaryUpdated(); - connect(pNewTrack.get(), SIGNAL(cuesUpdated()), - this, SLOT(receiveCuesUpdated())); + connect(pNewTrack.get(), &Track::cuesUpdated, this, &WOverview::receiveCuesUpdated); } else { m_pCurrentTrack.reset(); m_pWaveform.clear(); @@ -441,9 +443,7 @@ void WOverview::mouseMoveEvent(QMouseEvent* e) { } m_pHoveredMark.clear(); - // Without some padding, the user would only have a single pixel width that - // would count as hovering over the WaveformMark. - float lineHoverPadding = 5.0; + // Non-hotcue marks (intro/outro cues, main cue, loop in/out) are sorted // before hotcues in m_marksToRender so if there is a hotcue in the same // location, the hotcue gets rendered on top. When right clicking, the @@ -452,16 +452,7 @@ void WOverview::mouseMoveEvent(QMouseEvent* e) { // reverse and the loop breaks as soon as m_pHoveredMark is set. for (int i = m_marksToRender.size() - 1; i >= 0; --i) { WaveformMarkPointer pMark = m_marksToRender.at(i); - int hoveredPosition; - if (m_orientation == Qt::Horizontal) { - hoveredPosition = e->x(); - } else { - hoveredPosition = e->y(); - } - bool lineHovered = - pMark->m_linePosition >= hoveredPosition - lineHoverPadding && pMark->m_linePosition <= hoveredPosition + lineHoverPadding; - - if (pMark->m_label.area().contains(e->pos()) || lineHovered) { + if (pMark->contains(e->pos(), m_orientation)) { m_pHoveredMark = pMark; break; } @@ -539,28 +530,24 @@ void WOverview::mousePressEvent(QMouseEvent* e) { } if (pHoveredCue != nullptr) { m_pCueMenuPopup->setTrackAndCue(m_pCurrentTrack, pHoveredCue); - QPoint cueMenuTopLeft = mixxx::widgethelper::mapPopupToScreen( windowHandle()->screen()->size(), e->globalPos(), m_pCueMenuPopup->size()); m_pCueMenuPopup->popup(cueMenuTopLeft); - - m_bHotcueMenuShowing = true; } } } } void WOverview::slotCueMenuPopupAboutToHide() { - m_bHotcueMenuShowing = false; m_pHoveredMark.clear(); update(); } void WOverview::leaveEvent(QEvent* pEvent) { Q_UNUSED(pEvent); - if (!m_bHotcueMenuShowing) { + if (!m_pCueMenuPopup->isVisible()) { m_pHoveredMark.clear(); } m_bLeftClickDragging = false; diff --git a/src/widget/woverview.h b/src/widget/woverview.h index b3b695cf58..626c65e895 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -156,7 +156,6 @@ class WOverview : public WWidget, public TrackDropTarget { int m_iPlayPos; WaveformMarkPointer m_pHoveredMark; - bool m_bHotcueMenuShowing; bool m_bTimeRulerActive; QPointF m_timeRulerPos; WaveformMarkLabel m_timeRulerPositionLabel; diff --git a/src/widget/wwaveformviewer.cpp b/src/widget/wwaveformviewer.cpp index d64448103e..e475a9fb4c 100644 --- a/src/widget/wwaveformviewer.cpp +++ b/src/widget/wwaveformviewer.cpp @@ -1,31 +1,33 @@ +#include "widget/wwaveformviewer.h" -#include <QtDebug> #include <QDomNode> -#include <QEvent> #include <QDragEnterEvent> -#include <QUrl> -#include <QPainter> +#include <QEvent> #include <QMimeData> +#include <QPainter> +#include <QUrl> +#include <QtDebug> #include "control/controlobject.h" #include "control/controlproxy.h" #include "track/track.h" -#include "waveform/widgets/waveformwidgetabstract.h" -#include "widget/wwaveformviewer.h" -#include "waveform/waveformwidgetfactory.h" #include "util/dnd.h" #include "util/math.h" +#include "util/widgethelper.h" +#include "waveform/waveformwidgetfactory.h" +#include "waveform/widgets/waveformwidgetabstract.h" -WWaveformViewer::WWaveformViewer(const char *group, UserSettingsPointer pConfig, QWidget * parent) +WWaveformViewer::WWaveformViewer(const char* group, UserSettingsPointer pConfig, QWidget* parent) : WWidget(parent), m_pGroup(group), m_pConfig(pConfig), m_zoomZoneWidth(20), m_bScratching(false), m_bBending(false), + m_pCueMenuPopup(make_parented<WCueMenuPopup>(pConfig, this)), m_waveformWidget(nullptr) { + setMouseTracking(true); setAcceptDrops(true); - m_pZoom = new ControlProxy(group, "waveform_zoom", this); m_pZoom->connectValueChanged(this, &WWaveformViewer::onZoomChange); @@ -35,6 +37,7 @@ WWaveformViewer::WWaveformViewer(const char *group, UserSettingsPointer pConfig, group, "scratch_position", this); m_pWheel = new ControlProxy( group, "wheel", this); + m_pPlayEnabled = new ControlProxy(group, "play", this); setAttribute(Qt::WA_OpaquePaintEvent); } @@ -77,18 +80,33 @@ void WWaveformViewer::mousePressEvent(QMouseEvent* event) { m_pScratchPosition->set(targetPosition); m_pScratchPositionEnable->slotSet(1.0); } else if (event->button() == Qt::RightButton) { - // If we are scratching then disable and reset because the two shouldn't - // be used at once. - if (m_bScratching) { - m_pScratchPositionEnable->slotSet(0.0); - m_bScratching = false; + const auto currentTrack = m_waveformWidget->getTrackInfo(); + if (!isPlaying() && m_pHoveredMark) { + auto cueAtClickPos = getCuePointerFromCueMark(m_pHoveredMark); + if (cueAtClickPos) { + m_pCueMenuPopup->setTrackAndCue(currentTrack, cueAtClickPos); + QPoint cueMenuTopLeft = mixxx::widgethelper::mapPopupToScreen( + windowHandle()->screen()->size(), + event->globalPos(), + m_pCueMenuPopup->size()); + m_pCueMenuPopup->popup(cueMenuTopLeft); + } + } else { + // If we are scratching then disable and reset because the two shouldn't + // be used at once. + if (m_bScratching) { + m_pScratchPositionEnable->slotSet(0.0); + m_bScratching = false; + } + m_pWheel->setParameter(0.5); + m_bBending = true; } - m_pWheel->setParameter(0.5); - m_bBending = true; } - // Set the cursor to a hand while the mouse is down. - setCursor(Qt::ClosedHandCursor); + // Set the cursor to a hand while the mouse is down (when cue menu is not open). + if (!m_pCueMenuPopup->isVisible()) { + setCursor(Qt::ClosedHandCursor); + } } void WWaveformViewer::mouseMoveEvent(QMouseEvent* event) { @@ -120,6 +138,24 @@ void WWaveformViewer::mouseMoveEvent(QMouseEvent* event) { // clamp to [0.0, 1.0] v = math_clamp(v, 0.0, 1.0); m_pWheel->setParameter(v); + } else if (!isPlaying()) { + WaveformMarkPointer pMark; + pMark = m_waveformWidget->getCueMarkAtPoint(event->pos()); + if (pMark && getCuePointerFromCueMark(pMark)) { + if (!m_pHoveredMark) { + m_pHoveredMark = pMark; + highlightMark(pMark); + } else if (pMark != m_pHoveredMark) { + unhighlightMark(m_pHoveredMark); + m_pHoveredMark = pMark; + highlightMark(pMark); + } + } else { + if (m_pHoveredMark) { + unhighlightMark(m_pHoveredMark); + m_pHoveredMark = nullptr; + } + } } } @@ -156,6 +192,13 @@ void WWaveformViewer::dropEvent(QDropEvent* event) { DragAndDropHelper::handleTrackDropEvent(event, *this, m_pGroup, m_pConfig); } +void WWaveformViewer::leaveEvent(QEvent*) { + if (m_pHoveredMark) { + unhighlightMark(m_pHoveredMark); + m_pHoveredMark = nullptr; + } +} + void WWaveformViewer::slotTrackLoaded(TrackPointer track) { if (m_waveformWidget) { m_waveformWidget->setTrack(track); @@ -208,13 +251,38 @@ void WWaveformViewer::setPlayMarkerPosition(double position) { void WWaveformViewer::setWaveformWidget(WaveformWidgetAbstract* waveformWidget) { if (m_waveformWidget) { QWidget* pWidget = m_waveformWidget->getWidget(); - disconnect(pWidget, SIGNAL(destroyed()), - this, SLOT(slotWidgetDead())); + disconnect(pWidget, &QWidget::destroyed, this, &WWaveformViewer::slotWidgetDead); } m_waveformWidget = waveformWidget; if (m_waveformWidget) { QWidget* pWidget = m_waveformWidget->getWidget(); - connect(pWidget, SIGNAL(destroyed()), - this, SLOT(slotWidgetDead())); + connect(pWidget, &QWidget::destroyed, this, &WWaveformViewer::slotWidgetDead); + m_waveformWidget->getWidget()->setMouseTracking(true); } } + +CuePointer WWaveformViewer::getCuePointerFromCueMark(WaveformMarkPointer pMark) const { + if (pMark && pMark->getHotCue() != Cue::kNoHotCue) { + QList<CuePointer> cueList = m_waveformWidget->getTrackInfo()->getCuePoints(); + for (const auto& pCue : cueList) { + if (pCue->getHotCue() == pMark->getHotCue()) { + return pCue; + } + } + } + return CuePointer(); +} + +void WWaveformViewer::highlightMark(WaveformMarkPointer pMark) { + QColor highlightColor = Color::chooseContrastColor(pMark->fillColor()); + pMark->setBaseColor(highlightColor); +} + +void WWaveformViewer::unhighlightMark(WaveformMarkPointer pMark) { + QColor originalColor = mixxx::RgbColor::toQColor(getCuePointerFromCueMark(pMark)->getColor()); + pMark->setBaseColor(originalColor); +} + +bool WWaveformViewer::isPlaying() const { + return m_pPlayEnabled->get(); +} diff --git a/src/widget/wwaveformviewer.h b/src/widget/wwaveformviewer.h index bc9ffe1b7d..c0733ad1ab 100644 --- a/src/widget/wwaveformviewer.h +++ b/src/widget/wwaveformviewer.h @@ -8,10 +8,13 @@ #include <QList> #include <QMutex> +#include "skin/skincontext.h" #include "track/track.h" +#include "util/parented_ptr.h" +#include "waveform/renderers/waveformmark.h" #include "widget/trackdroptarget.h" +#include "widget/wcuemenupopup.h" #include "widget/wwidget.h" -#include "skin/skincontext.h" class ControlProxy; class WaveformWidgetAbstract; @@ -32,8 +35,9 @@ class WWaveformViewer : public WWidget, public TrackDropTarget { void mousePressEvent(QMouseEvent * /*unused*/) override; void mouseMoveEvent(QMouseEvent * /*unused*/) override; void mouseReleaseEvent(QMouseEvent * /*unused*/) override; + void leaveEvent(QEvent* /*unused*/) override; -signals: + signals: void trackDropped(QString filename, QString group) override; void cloneDeck(QString source_group, QString target_group) override; @@ -51,7 +55,7 @@ private slots: m_waveformWidget = nullptr; } -private: + private: void setWaveformWidget(WaveformWidgetAbstract* waveformWidget); WaveformWidgetAbstract* getWaveformWidget() { return m_waveformWidget; @@ -69,13 +73,21 @@ private: ControlProxy* m_pScratchPositionEnable; ControlProxy* m_pScratchPosition; ControlProxy* m_pWheel; + ControlProxy* m_pPlayEnabled; bool m_bScratching; bool m_bBending; QPoint m_mouseAnchor; + parented_ptr<WCueMenuPopup> m_pCueMenuPopup; + WaveformMarkPointer m_pHoveredMark; WaveformWidgetAbstract* m_waveformWidget; friend class WaveformWidgetFactory; + + CuePointer getCuePointerFromCueMark(WaveformMarkPointer pMark) const; + void highlightMark(WaveformMarkPointer pMark); + void unhighlightMark(WaveformMarkPointer pMark); + bool isPlaying() const; }; #endif |