Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overview: abort play pos dragging if cursor is relased outside the valid area #13741

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions res/images/cross_circle_red.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions res/mixxx.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
<RCC version="1.0">
<qresource prefix="/">
<file>../LICENSE</file>
<!-- for track dnd cursor -->
<file>images/library/ic_library_drag_and_drop.svg</file>
<!-- for drag abort cursor in overveiw waveform -->
<file>images/cross_circle_red.svg</file>
<!-- open/closed lock icons for BPM button -->
<file>images/library/ic_library_locked.svg</file>
<file>images/library/ic_library_unlocked.svg</file>
Expand Down
92 changes: 65 additions & 27 deletions src/widget/woverview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
#include "widget/controlwidgetconnection.h"
#include "wskincolor.h"

namespace {
// Horizontal and vertical margin around the widget where we accept play pos dragging.
constexpr int kDragOutsideLimitX = 100;
constexpr int kDragOutsideLimitY = 50;
} // anonymous namespace

WOverview::WOverview(
const QString& group,
PlayerManager* pPlayerManager,
Expand All @@ -50,6 +56,8 @@ WOverview::WOverview(
m_iPlayPos(0),
m_bTimeRulerActive(false),
m_orientation(Qt::Horizontal),
m_dragMarginH(kDragOutsideLimitX),
m_dragMarginV(kDragOutsideLimitY),
m_iLabelFontSize(10),
m_a(1.0),
m_b(0.0),
Expand Down Expand Up @@ -115,6 +123,12 @@ WOverview::WOverview(
this, &WOverview::onTrackAnalyzerProgress);

connect(m_pCueMenuPopup.get(), &WCueMenuPopup::aboutToHide, this, &WOverview::slotCueMenuPopupAboutToHide);

// Style the cursor we show when the cursor leaves the valid
// play pos dragging area.
QPixmap abortPixmap(32, 32);
abortPixmap.load(":/images/cross_circle_red.svg");
m_dragAbortCursor = QCursor(abortPixmap);
}

void WOverview::setup(const QDomNode& node, const SkinContext& context) {
Expand Down Expand Up @@ -226,6 +240,8 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) {
QString orientationString = context.selectString(node, "Orientation").toLower();
if (orientationString == "vertical") {
m_orientation = Qt::Vertical;
m_dragMarginH = kDragOutsideLimitY;
m_dragMarginV = kDragOutsideLimitX;
} else {
m_orientation = Qt::Horizontal;
}
Expand Down Expand Up @@ -417,11 +433,17 @@ void WOverview::onRateRatioChange(double v) {
void WOverview::onPassthroughChange(double v) {
m_bPassthroughEnabled = static_cast<bool>(v);

if (!m_bPassthroughEnabled) {
if (m_bPassthroughEnabled) {
// Abort play position dragging
m_bLeftClickDragging = false;
m_bTimeRulerActive = false;
m_iPickupPos = m_iPlayPos;
unsetCursor();
} else {
slotWaveformSummaryUpdated();
}

// Always call this to trigger a repaint even if not track is loaded
// Always call this to trigger a repaint even if no track is loaded
update();
}

Expand Down Expand Up @@ -487,18 +509,27 @@ void WOverview::receiveCuesUpdated() {

void WOverview::mouseMoveEvent(QMouseEvent* e) {
if (m_bLeftClickDragging) {
if (isPosInAllowedPosDragZone(e->pos())) {
m_bTimeRulerActive = true;
m_timeRulerPos = e->pos();
unsetCursor();
} else {
// Remove the time ruler to indicate dragging position is invalid,
// don't abort dragging!
m_iPickupPos = m_iPlayPos;
m_bTimeRulerActive = false;

setCursor(m_dragAbortCursor);
// Remember to restore cursor everywhere where we cancel dragging.
// Update immediately.
update();
return;
}

if (m_orientation == Qt::Horizontal) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_iPickupPos = math_clamp(static_cast<int>(e->position().x()), 0, width() - 1);
#else
m_iPickupPos = math_clamp(e->x(), 0, width() - 1);
#endif
m_iPickupPos = math_clamp(e->pos().x(), 0, width() - 1);
} else {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_iPickupPos = math_clamp(static_cast<int>(e->position().y()), 0, height() - 1);
#else
m_iPickupPos = math_clamp(e->y(), 0, height() - 1);
#endif
m_iPickupPos = math_clamp(e->pos().y(), 0, height() - 1);
}
}

Expand All @@ -515,24 +546,36 @@ void WOverview::mouseMoveEvent(QMouseEvent* e) {

m_pHoveredMark = m_marks.findHoveredMark(e->pos(), m_orientation);

//qDebug() << "WOverview::mouseMoveEvent" << e->pos() << m_iPos;
// qDebug() << "WOverview::mouseMoveEvent" << e->pos();
update();
}

void WOverview::mouseReleaseEvent(QMouseEvent* e) {
mouseMoveEvent(e);
if (m_bPassthroughEnabled) {
m_bLeftClickDragging = false;
// We may be dragging, and we may be outside the valid dragging area.
// If so, we've set the 'invalid drag' cursor. Restore the cursor now.
unsetCursor();
return;
}
//qDebug() << "WOverview::mouseReleaseEvent" << e->pos() << m_iPos << ">>" << dValue;

if (e->button() == Qt::LeftButton) {
if (m_bLeftClickDragging) {
m_iPlayPos = m_iPickupPos;
double dValue = positionToValue(m_iPickupPos);
setControlParameterUp(dValue);
m_bLeftClickDragging = false;
unsetCursor();
if (isPosInAllowedPosDragZone(e->pos())) {
m_iPlayPos = m_iPickupPos;
double dValue = positionToValue(m_iPickupPos);
setControlParameterUp(dValue);
m_bLeftClickDragging = false;
} else {
// Abort dragging if we are way outside the widget.
m_iPickupPos = m_iPlayPos;
m_bLeftClickDragging = false;
m_bTimeRulerActive = false;
return;
}
}
m_bTimeRulerActive = false;
} else if (e->button() == Qt::RightButton) {
Expand All @@ -547,6 +590,7 @@ void WOverview::mousePressEvent(QMouseEvent* e) {
mouseMoveEvent(e);
if (m_bPassthroughEnabled) {
m_bLeftClickDragging = false;
unsetCursor();
return;
}
double trackSamples = getTrackSamples();
Expand All @@ -555,17 +599,9 @@ void WOverview::mousePressEvent(QMouseEvent* e) {
}
if (e->button() == Qt::LeftButton) {
if (m_orientation == Qt::Horizontal) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_iPickupPos = math_clamp(static_cast<int>(e->position().x()), 0, width() - 1);
#else
m_iPickupPos = math_clamp(e->x(), 0, width() - 1);
#endif
m_iPickupPos = math_clamp(e->pos().x(), 0, width() - 1);
} else {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
m_iPickupPos = math_clamp(static_cast<int>(e->position().y()), 0, height() - 1);
#else
m_iPickupPos = math_clamp(e->y(), 0, height() - 1);
#endif
m_iPickupPos = math_clamp(e->pos().y(), 0, height() - 1);
}

if (m_pHoveredMark != nullptr) {
Expand All @@ -584,6 +620,7 @@ void WOverview::mousePressEvent(QMouseEvent* e) {
m_iPickupPos = m_iPlayPos;
m_bLeftClickDragging = false;
m_bTimeRulerActive = false;
unsetCursor();
} else if (m_pHoveredMark == nullptr) {
m_bTimeRulerActive = true;
m_timeRulerPos = e->pos();
Expand Down Expand Up @@ -673,6 +710,7 @@ void WOverview::paintEvent(QPaintEvent* pEvent) {
if (m_bPassthroughEnabled) {
drawPassthroughOverlay(&painter);
m_pPassthroughLabel->show();
unsetCursor();
} else {
m_pPassthroughLabel->hide();
}
Expand Down
13 changes: 12 additions & 1 deletion src/widget/woverview.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ class WOverview : public WWidget, public TrackDropTarget {
return m_orientation == Qt::Horizontal ? height() : width();
}

inline bool isPosInAllowedPosDragZone(const QPoint pos) {
const QRect dragZone = rect().marginsAdded(QMargins(
m_dragMarginH,
m_dragMarginV,
m_dragMarginH,
m_dragMarginV));
return dragZone.contains(pos);
}

ConstWaveformPointer getWaveform() const {
return m_pWaveform;
}
Expand Down Expand Up @@ -164,6 +173,8 @@ class WOverview : public WWidget, public TrackDropTarget {
int m_iPlayPos;
bool m_bTimeRulerActive;
Qt::Orientation m_orientation;
int m_dragMarginH;
int m_dragMarginV;
int m_iLabelFontSize;

// Coefficient value-position linear transposition
Expand Down Expand Up @@ -211,10 +222,10 @@ class WOverview : public WWidget, public TrackDropTarget {
QColor m_lowColor;
int m_dimBrightThreshold;
parented_ptr<QLabel> m_pPassthroughLabel;
QCursor m_dragAbortCursor;

WaveformMarkSet m_marks;
std::vector<WaveformMarkRange> m_markRanges;
WaveformMarkLabel m_cuePositionLabel;
WaveformMarkLabel m_cueTimeDistanceLabel;

};
Loading