Skip to content

Commit

Permalink
Merge pull request #3344 from daschuer/stuck_hotcue
Browse files Browse the repository at this point in the history
Avoid hotcue buttons from being stucked in the pressed state
  • Loading branch information
uklotzde authored Nov 28, 2020
2 parents 8697917 + 0aac197 commit 097df28
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 25 deletions.
54 changes: 30 additions & 24 deletions src/engine/controls/cuecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,8 +769,13 @@ void CueControl::hotcueGotoAndStop(HotcueControl* pControl, double value) {
if (pCue) {
double position = pCue->getPosition();
if (position != Cue::kNoPosition) {
m_pPlay->set(0.0);
seekExact(position);
if (!m_iCurrentlyPreviewingHotcues && !m_bPreviewing) {
m_pPlay->set(0.0);
seekExact(position);
} else {
// this becomes a play latch command if we are previewing
m_pPlay->set(0.0);
}
}
}
}
Expand Down Expand Up @@ -861,7 +866,7 @@ void CueControl::hotcueActivatePreview(HotcueControl* pControl, double value) {
CuePointer pCue(pControl->getCue());

if (value > 0) {
if (pCue && pCue->getPosition() != Cue::kNoPosition) {
if (pCue && pCue->getPosition() != Cue::kNoPosition && !pControl->isPreviewing()) {
m_iCurrentlyPreviewingHotcues++;
double position = pCue->getPosition();
m_bypassCueSetByPlay = true;
Expand Down Expand Up @@ -1026,23 +1031,26 @@ void CueControl::cueGotoAndStop(double value) {
return;
}

QMutexLocker lock(&m_mutex);
m_pPlay->set(0.0);
double cuePoint = m_pCuePoint->get();

// Need to unlock before emitting any signals to prevent deadlock.
lock.unlock();

seekExact(cuePoint);
if (!m_iCurrentlyPreviewingHotcues && !m_bPreviewing) {
m_pPlay->set(0.0);
double position = m_pCuePoint->get();
seekExact(position);
} else {
// this becomes a play latch command if we are previewing
m_pPlay->set(0.0);
}
}

void CueControl::cuePreview(double value) {
//qDebug() << "CueControl::cuePreview" << value;
QMutexLocker lock(&m_mutex);

if (value > 0) {
m_bPreviewing = true;
m_bypassCueSetByPlay = true;
m_pPlay->set(1.0);
if (!m_bPreviewing) {
m_bPreviewing = true;
m_bypassCueSetByPlay = true;
m_pPlay->set(1.0);
}
} else if (m_bPreviewing) {
m_bPreviewing = false;
if (m_iCurrentlyPreviewingHotcues) {
Expand Down Expand Up @@ -1071,7 +1079,10 @@ void CueControl::cueCDJ(double value) {
TrackAt trackAt = getTrackAt();

if (value > 0) {
if (m_iCurrentlyPreviewingHotcues) {
if (m_bPreviewing) {
// already previewing, do nothing
return;
} else if (m_iCurrentlyPreviewingHotcues) {
// we are already previewing by hotcues
// just jump to cue point and continue previewing
m_bPreviewing = true;
Expand All @@ -1095,9 +1106,6 @@ void CueControl::cueCDJ(double value) {
} else {
// Pause not at cue point and not at end position
cueSet(value);
// Just in case.
m_bPreviewing = false;
m_pPlay->set(0.0);

// If quantize is enabled, jump to the cue point since it's not
// necessarily where we currently are
Expand Down Expand Up @@ -1138,7 +1146,10 @@ void CueControl::cueDenon(double value) {
TrackAt trackAt = getTrackAt();

if (value > 0) {
if (m_iCurrentlyPreviewingHotcues) {
if (m_bPreviewing) {
// already previewing, do nothing
return;
} else if (m_iCurrentlyPreviewingHotcues) {
// we are already previewing by hotcues
// just jump to cue point and continue previewing
m_bPreviewing = true;
Expand All @@ -1149,13 +1160,8 @@ void CueControl::cueDenon(double value) {
m_bPreviewing = true;
m_pPlay->set(1.0);
} else {
// Just in case.
m_bPreviewing = false;
m_pPlay->set(0.0);

// Need to unlock before emitting any signals to prevent deadlock.
lock.unlock();

seekAbs(m_pCuePoint->get());
}
} else if (m_bPreviewing) {
Expand Down
6 changes: 5 additions & 1 deletion src/skin/tooltips.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,16 +468,19 @@ void Tooltips::addStandardTooltips() {

QString whilePlaying = tr("(while playing)");
QString whileStopped = tr("(while stopped)");
QString whilePreviewing = tr("(while previewing)");
QString cueSet = tr("Places a cue point at the current position on the waveform.");
QString cueWhilePlaying = tr("Stops track at cue point, OR go to cue point and play after release (CUP mode).");
QString cueWhileStopped = tr("Set cue point (Pioneer/Mixxx/Numark mode), set cue point and play after release (CUP mode) "
"OR preview from it (Denon mode).");
QString cueHint = tr("Hint: Change the default cue mode in Preferences -> Interface.");
QString latchingPlay = tr("Is latching the playing state.");

// Currently used for decks
add("play_cue_set")
<< tr("Play/Pause")
<< QString("%1: %2").arg(leftClick, tr("Plays or pauses the track."))
<< QString("%1 %2: %3").arg(leftClick, whilePreviewing, latchingPlay)
<< QString("%1: %2").arg(rightClick, cueSet);

// Currently used for minimal decks
Expand All @@ -494,7 +497,8 @@ void Tooltips::addStandardTooltips() {
<< QString("%1 %2: %3").arg(leftClick, whileStopped, cueWhileStopped)
<< cueHint
<< quantizeSnap
<< QString("%1: %2").arg(rightClick, tr("Seeks the track to the cue point and stops."));
<< QString("%1: %2").arg(rightClick, tr("Seeks the track to the cue point and stops."))
<< QString("%1 %2: %3").arg(rightClick, whilePreviewing, latchingPlay);
add("cue_gotoandplay_cue_default")
<< tr("Play")
<< QString("%1: %2").arg(leftClick, tr("Plays track from the cue point."))
Expand Down
15 changes: 15 additions & 0 deletions src/widget/whotcuebutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ void WHotcueButton::setup(const QDomNode& node, const SkinContext& context) {
void WHotcueButton::mousePressEvent(QMouseEvent* e) {
const bool rightClick = e->button() == Qt::RightButton;
if (rightClick) {
if (isPressed()) {
// Discard right clicks when already left clicked.
// Otherwise the pop up menu receives the release event and the
// button stucks in the pressed stage.
return;
}
if (readDisplayValue() == 1) {
// hot cue is set
TrackPointer pTrack = PlayerInfo::instance().getTrackInfo(m_group);
Expand Down Expand Up @@ -116,6 +122,15 @@ void WHotcueButton::mousePressEvent(QMouseEvent* e) {
WPushButton::mousePressEvent(e);
}

void WHotcueButton::mouseReleaseEvent(QMouseEvent* e) {
const bool rightClick = e->button() == Qt::RightButton;
if (rightClick) {
// Don't handle stray release events
return;
}
WPushButton::mouseReleaseEvent(e);
}

ConfigKey WHotcueButton::createConfigKey(const QString& name) {
ConfigKey key;
key.group = m_group;
Expand Down
1 change: 1 addition & 0 deletions src/widget/whotcuebutton.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class WHotcueButton : public WPushButton {

protected:
void mousePressEvent(QMouseEvent* e) override;
void mouseReleaseEvent(QMouseEvent* e) override;
void restyleAndRepaint() override;

private slots:
Expand Down
14 changes: 14 additions & 0 deletions src/widget/wpushbutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,20 @@ bool WPushButton::event(QEvent* e) {
m_bHovered = true;
restyleAndRepaint();
} else if (e->type() == QEvent::Leave) {
if (m_bPressed) {
// A Leave event is send instead of a mouseReleaseEvent()
// fake it to get not stucked in pressed state
QMouseEvent mouseEvent = QMouseEvent(
QEvent::MouseButtonRelease,
QPointF(),
QPointF(),
QPointF(),
Qt::LeftButton,
Qt::NoButton,
0,
Qt::MouseEventSynthesizedByApplication);
mouseReleaseEvent(&mouseEvent);
}
m_bHovered = false;
restyleAndRepaint();
}
Expand Down

0 comments on commit 097df28

Please sign in to comment.