summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2020-05-16 21:38:09 +0200
committerGitHub <noreply@github.com>2020-05-16 21:38:09 +0200
commita440c5a32954d4dacaa91e479141f442103b7434 (patch)
treecc08d34e1002294497f985990a0855e1a3b418a6
parent472d443cb56c2e7d1791ac9a3ec8cab03ffd10ad (diff)
parent3deebd91f84e8baba004f571b7d75884e232ae19 (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.cpp17
-rw-r--r--src/waveform/renderers/waveformmark.h3
-rw-r--r--src/waveform/renderers/waveformrendermark.cpp41
-rw-r--r--src/waveform/renderers/waveformwidgetrenderer.cpp17
-rw-r--r--src/waveform/renderers/waveformwidgetrenderer.h9
-rw-r--r--src/waveform/waveformmarklabel.h4
-rw-r--r--src/widget/wcuemenupopup.cpp5
-rw-r--r--src/widget/wcuemenupopup.h8
-rw-r--r--src/widget/woverview.cpp37
-rw-r--r--src/widget/woverview.h1
-rw-r--r--src/widget/wwaveformviewer.cpp112
-rw-r--r--src/widget/wwaveformviewer.h18
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