diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp index a2fa4b61cd25..5910cf51a1d2 100644 --- a/src/engine/controls/cuecontrol.cpp +++ b/src/engine/controls/cuecontrol.cpp @@ -103,7 +103,6 @@ CueControl::CueControl(const QString& group, m_trackMutex(QT_RECURSIVE_MUTEX_INIT) { // To silence a compiler warning about CUE_MODE_PIONEER. Q_UNUSED(CUE_MODE_PIONEER); - createControls(); m_pTrackSamples = ControlObject::getControl(ConfigKey(group, "track_samples")); @@ -126,168 +125,75 @@ CueControl::CueControl(const QString& group, m_pCueSet = new ControlPushButton(ConfigKey(group, "cue_set")); m_pCueSet->setButtonMode(ControlPushButton::TRIGGER); - connect(m_pCueSet, &ControlObject::valueChanged, - this, &CueControl::cueSet, - Qt::DirectConnection); - m_pCueClear = new ControlPushButton(ConfigKey(group, "cue_clear")); m_pCueClear->setButtonMode(ControlPushButton::TRIGGER); - connect(m_pCueClear, &ControlObject::valueChanged, - this, &CueControl::cueClear, - Qt::DirectConnection); - m_pCueGoto = new ControlPushButton(ConfigKey(group, "cue_goto")); - connect(m_pCueGoto, &ControlObject::valueChanged, - this, &CueControl::cueGoto, - Qt::DirectConnection); - m_pCueGotoAndPlay = new ControlPushButton(ConfigKey(group, "cue_gotoandplay")); - connect(m_pCueGotoAndPlay, &ControlObject::valueChanged, - this, &CueControl::cueGotoAndPlay, - Qt::DirectConnection); - m_pCuePlay = new ControlPushButton(ConfigKey(group, "cue_play")); - connect(m_pCuePlay, &ControlObject::valueChanged, - this, &CueControl::cuePlay, - Qt::DirectConnection); - m_pCueGotoAndStop = new ControlPushButton(ConfigKey(group, "cue_gotoandstop")); - connect(m_pCueGotoAndStop, &ControlObject::valueChanged, - this, &CueControl::cueGotoAndStop, - Qt::DirectConnection); - m_pCuePreview = new ControlPushButton(ConfigKey(group, "cue_preview")); - connect(m_pCuePreview, &ControlObject::valueChanged, - this, &CueControl::cuePreview, - Qt::DirectConnection); - m_pCueCDJ = new ControlPushButton(ConfigKey(group, "cue_cdj")); - connect(m_pCueCDJ, &ControlObject::valueChanged, - this, &CueControl::cueCDJ, - Qt::DirectConnection); - m_pCueDefault = new ControlPushButton(ConfigKey(group, "cue_default")); - connect(m_pCueDefault, &ControlObject::valueChanged, - this, &CueControl::cueDefault, - Qt::DirectConnection); - m_pPlayStutter = new ControlPushButton(ConfigKey(group, "play_stutter")); - connect(m_pPlayStutter, &ControlObject::valueChanged, - this, &CueControl::playStutter, - Qt::DirectConnection); - - m_pCueIndicator = new ControlIndicator(ConfigKey(group, "cue_indicator")); - m_pPlayIndicator = new ControlIndicator(ConfigKey(group, "play_indicator")); m_pPlayLatched = new ControlObject(ConfigKey(group, "play_latched")); m_pPlayLatched->setReadOnly(); + m_pCueIndicator = new ControlIndicator(ConfigKey(group, "cue_indicator")); + m_pPlayIndicator = new ControlIndicator(ConfigKey(group, "play_indicator")); + m_pIntroStartPosition = new ControlObject(ConfigKey(group, "intro_start_position")); m_pIntroStartPosition->set(Cue::kNoPosition); - m_pIntroStartEnabled = new ControlObject(ConfigKey(group, "intro_start_enabled")); m_pIntroStartEnabled->setReadOnly(); - m_pIntroStartSet = new ControlPushButton(ConfigKey(group, "intro_start_set")); - connect(m_pIntroStartSet, &ControlObject::valueChanged, - this, &CueControl::introStartSet, - Qt::DirectConnection); - m_pIntroStartClear = new ControlPushButton(ConfigKey(group, "intro_start_clear")); - connect(m_pIntroStartClear, &ControlObject::valueChanged, - this, &CueControl::introStartClear, - Qt::DirectConnection); - m_pIntroStartActivate = new ControlPushButton(ConfigKey(group, "intro_start_activate")); - connect(m_pIntroStartActivate, &ControlObject::valueChanged, - this, &CueControl::introStartActivate, - Qt::DirectConnection); - m_pIntroEndPosition = new ControlObject(ConfigKey(group, "intro_end_position")); m_pIntroEndPosition->set(Cue::kNoPosition); - m_pIntroEndEnabled = new ControlObject(ConfigKey(group, "intro_end_enabled")); m_pIntroEndEnabled->setReadOnly(); - m_pIntroEndSet = new ControlPushButton(ConfigKey(group, "intro_end_set")); - connect(m_pIntroEndSet, &ControlObject::valueChanged, - this, &CueControl::introEndSet, - Qt::DirectConnection); - m_pIntroEndClear = new ControlPushButton(ConfigKey(group, "intro_end_clear")); - connect(m_pIntroEndClear, &ControlObject::valueChanged, - this, &CueControl::introEndClear, - Qt::DirectConnection); - m_pIntroEndActivate = new ControlPushButton(ConfigKey(group, "intro_end_activate")); - connect(m_pIntroEndActivate, &ControlObject::valueChanged, - this, &CueControl::introEndActivate, - Qt::DirectConnection); m_pOutroStartPosition = new ControlObject(ConfigKey(group, "outro_start_position")); m_pOutroStartPosition->set(Cue::kNoPosition); - m_pOutroStartEnabled = new ControlObject(ConfigKey(group, "outro_start_enabled")); m_pOutroStartEnabled->setReadOnly(); - m_pOutroStartSet = new ControlPushButton(ConfigKey(group, "outro_start_set")); - connect(m_pOutroStartSet, &ControlObject::valueChanged, - this, &CueControl::outroStartSet, - Qt::DirectConnection); - m_pOutroStartClear = new ControlPushButton(ConfigKey(group, "outro_start_clear")); - connect(m_pOutroStartClear, &ControlObject::valueChanged, - this, &CueControl::outroStartClear, - Qt::DirectConnection); - m_pOutroStartActivate = new ControlPushButton(ConfigKey(group, "outro_start_activate")); - connect(m_pOutroStartActivate, &ControlObject::valueChanged, - this, &CueControl::outroStartActivate, - Qt::DirectConnection); - m_pOutroEndPosition = new ControlObject(ConfigKey(group, "outro_end_position")); m_pOutroEndPosition->set(Cue::kNoPosition); - m_pOutroEndEnabled = new ControlObject(ConfigKey(group, "outro_end_enabled")); m_pOutroEndEnabled->setReadOnly(); - m_pOutroEndSet = new ControlPushButton(ConfigKey(group, "outro_end_set")); - connect(m_pOutroEndSet, &ControlObject::valueChanged, - this, &CueControl::outroEndSet, - Qt::DirectConnection); - m_pOutroEndClear = new ControlPushButton(ConfigKey(group, "outro_end_clear")); - connect(m_pOutroEndClear, &ControlObject::valueChanged, - this, &CueControl::outroEndClear, - Qt::DirectConnection); - m_pOutroEndActivate = new ControlPushButton(ConfigKey(group, "outro_end_activate")); - connect(m_pOutroEndActivate, &ControlObject::valueChanged, - this, &CueControl::outroEndActivate, - Qt::DirectConnection); m_pVinylControlEnabled = new ControlProxy(group, "vinylcontrol_enabled"); m_pVinylControlMode = new ControlProxy(group, "vinylcontrol_mode"); m_pHotcueFocus = new ControlObject(ConfigKey(group, "hotcue_focus")); setHotcueFocusIndex(Cue::kNoHotCue); - m_pHotcueFocusColorPrev = new ControlObject(ConfigKey(group, "hotcue_focus_color_prev")); - connect(m_pHotcueFocusColorPrev, - &ControlObject::valueChanged, - this, - &CueControl::hotcueFocusColorPrev, - Qt::DirectConnection); - m_pHotcueFocusColorNext = new ControlObject(ConfigKey(group, "hotcue_focus_color_next")); - connect(m_pHotcueFocusColorNext, - &ControlObject::valueChanged, - this, - &CueControl::hotcueFocusColorNext, - Qt::DirectConnection); + + // Create hotcue controls + for (int i = 0; i < m_iNumHotCues; ++i) { + HotcueControl* pControl = new HotcueControl(group, i); + m_hotcueControls.append(pControl); + } + + m_pPassthrough = new ControlProxy(group, "passthrough"); + m_pPassthrough->connectValueChanged( + this, &CueControl::passthroughChanged, Qt::DirectConnection); + + connectControls(); } CueControl::~CueControl() { @@ -331,13 +237,138 @@ CueControl::~CueControl() { delete m_pHotcueFocus; delete m_pHotcueFocusColorPrev; delete m_pHotcueFocusColorNext; + delete m_pPassthrough; qDeleteAll(m_hotcueControls); } -void CueControl::createControls() { - for (int i = 0; i < m_iNumHotCues; ++i) { - HotcueControl* pControl = new HotcueControl(getGroup(), i); +void CueControl::connectControls() { + // Cue controls + connect(m_pCueSet, + &ControlObject::valueChanged, + this, + &CueControl::cueSet, + Qt::DirectConnection); + connect(m_pCueClear, + &ControlObject::valueChanged, + this, + &CueControl::cueClear, + Qt::DirectConnection); + connect(m_pCueGoto, + &ControlObject::valueChanged, + this, + &CueControl::cueGoto, + Qt::DirectConnection); + connect(m_pCueGotoAndPlay, + &ControlObject::valueChanged, + this, + &CueControl::cueGotoAndPlay, + Qt::DirectConnection); + connect(m_pCuePlay, + &ControlObject::valueChanged, + this, + &CueControl::cuePlay, + Qt::DirectConnection); + connect(m_pCueGotoAndStop, + &ControlObject::valueChanged, + this, + &CueControl::cueGotoAndStop, + Qt::DirectConnection); + connect(m_pCuePreview, + &ControlObject::valueChanged, + this, + &CueControl::cuePreview, + Qt::DirectConnection); + connect(m_pCueCDJ, + &ControlObject::valueChanged, + this, + &CueControl::cueCDJ, + Qt::DirectConnection); + connect(m_pCueDefault, + &ControlObject::valueChanged, + this, + &CueControl::cueDefault, + Qt::DirectConnection); + connect(m_pPlayStutter, + &ControlObject::valueChanged, + this, + &CueControl::playStutter, + Qt::DirectConnection); + + connect(m_pIntroStartSet, + &ControlObject::valueChanged, + this, + &CueControl::introStartSet, + Qt::DirectConnection); + connect(m_pIntroStartClear, + &ControlObject::valueChanged, + this, + &CueControl::introStartClear, + Qt::DirectConnection); + connect(m_pIntroStartActivate, + &ControlObject::valueChanged, + this, + &CueControl::introStartActivate, + Qt::DirectConnection); + connect(m_pIntroEndSet, + &ControlObject::valueChanged, + this, + &CueControl::introEndSet, + Qt::DirectConnection); + connect(m_pIntroEndClear, + &ControlObject::valueChanged, + this, + &CueControl::introEndClear, + Qt::DirectConnection); + connect(m_pIntroEndActivate, + &ControlObject::valueChanged, + this, + &CueControl::introEndActivate, + Qt::DirectConnection); + connect(m_pOutroStartSet, + &ControlObject::valueChanged, + this, + &CueControl::outroStartSet, + Qt::DirectConnection); + connect(m_pOutroStartClear, + &ControlObject::valueChanged, + this, + &CueControl::outroStartClear, + Qt::DirectConnection); + connect(m_pOutroStartActivate, + &ControlObject::valueChanged, + this, + &CueControl::outroStartActivate, + Qt::DirectConnection); + connect(m_pOutroEndSet, + &ControlObject::valueChanged, + this, + &CueControl::outroEndSet, + Qt::DirectConnection); + connect(m_pOutroEndClear, + &ControlObject::valueChanged, + this, + &CueControl::outroEndClear, + Qt::DirectConnection); + connect(m_pOutroEndActivate, + &ControlObject::valueChanged, + this, + &CueControl::outroEndActivate, + Qt::DirectConnection); + + connect(m_pHotcueFocusColorPrev, + &ControlObject::valueChanged, + this, + &CueControl::hotcueFocusColorPrev, + Qt::DirectConnection); + connect(m_pHotcueFocusColorNext, + &ControlObject::valueChanged, + this, + &CueControl::hotcueFocusColorNext, + Qt::DirectConnection); + + // Hotcue controls + for (const auto& pControl : qAsConst(m_hotcueControls)) { connect(pControl, &HotcueControl::hotcuePositionChanged, this, &CueControl::hotcuePositionChanged, Qt::DirectConnection); @@ -391,8 +422,55 @@ void CueControl::createControls() { this, &CueControl::hotcueClear, Qt::DirectConnection); + } +} - m_hotcueControls.append(pControl); +void CueControl::disconnectControls() { + disconnect(m_pCueSet, nullptr, this, nullptr); + disconnect(m_pCueClear, nullptr, this, nullptr); + disconnect(m_pCueGoto, nullptr, this, nullptr); + disconnect(m_pCueGotoAndPlay, nullptr, this, nullptr); + disconnect(m_pCuePlay, nullptr, this, nullptr); + disconnect(m_pCueGotoAndStop, nullptr, this, nullptr); + disconnect(m_pCuePreview, nullptr, this, nullptr); + disconnect(m_pCueCDJ, nullptr, this, nullptr); + disconnect(m_pCueDefault, nullptr, this, nullptr); + disconnect(m_pPlayStutter, nullptr, this, nullptr); + + disconnect(m_pIntroStartSet, nullptr, this, nullptr); + disconnect(m_pIntroStartClear, nullptr, this, nullptr); + disconnect(m_pIntroStartActivate, nullptr, this, nullptr); + disconnect(m_pIntroEndSet, nullptr, this, nullptr); + disconnect(m_pIntroEndClear, nullptr, this, nullptr); + disconnect(m_pIntroEndActivate, nullptr, this, nullptr); + + disconnect(m_pOutroStartSet, nullptr, this, nullptr); + disconnect(m_pOutroStartClear, nullptr, this, nullptr); + disconnect(m_pOutroStartActivate, nullptr, this, nullptr); + disconnect(m_pOutroEndSet, nullptr, this, nullptr); + disconnect(m_pOutroEndClear, nullptr, this, nullptr); + disconnect(m_pOutroEndActivate, nullptr, this, nullptr); + + disconnect(m_pHotcueFocusColorPrev, nullptr, this, nullptr); + disconnect(m_pHotcueFocusColorNext, nullptr, this, nullptr); + + for (const auto& pControl : qAsConst(m_hotcueControls)) { + disconnect(pControl, nullptr, this, nullptr); + } +} + +void CueControl::passthroughChanged(double enabled) { + qDebug() << " ."; + qDebug() << " CC passthroughChanged" << enabled; + qDebug() << " ."; + if (enabled != 0) { + // If passthrough was enabled seeking and playing is prohibited, and the + // waveform and overview are blocked. + // Disconnect all cue controls to prevent cue changes without UI feedback. + disconnectControls(); + } else { + // Reconnect all controls when deck returns to regular mode. + connectControls(); } } diff --git a/src/engine/controls/cuecontrol.h b/src/engine/controls/cuecontrol.h index 09c2ce637f60..6206de046dc9 100644 --- a/src/engine/controls/cuecontrol.h +++ b/src/engine/controls/cuecontrol.h @@ -65,7 +65,7 @@ class HotcueControl : public QObject { Set = 1, /// Hotcue is currently active (this only applies to Saved Loop cues /// while their loop is enabled). This status can be used by skins or - /// controller mappings to highlight a the cue control that has saved the current loop, + /// controller mappings to highlight the cue control that has saved the current loop, /// because resizing or moving the loop will make persistent changes to /// the cue. Active = 2, @@ -232,6 +232,8 @@ class CueControl : public EngineControl { void hotcueFocusColorNext(double v); void hotcueFocusColorPrev(double v); + void passthroughChanged(double v); + void cueSet(double v); void cueClear(double v); void cueGoto(double v); @@ -268,7 +270,8 @@ class CueControl : public EngineControl { }; // These methods are not thread safe, only call them when the lock is held. - void createControls(); + void connectControls(); + void disconnectControls(); void attachCue(const CuePointer& pCue, HotcueControl* pControl); void detachCue(HotcueControl* pControl); void setCurrentSavedLoopControlAndActivate(HotcueControl* pControl); @@ -346,6 +349,8 @@ class CueControl : public EngineControl { ControlObject* m_pHotcueFocusColorNext; ControlObject* m_pHotcueFocusColorPrev; + ControlProxy* m_pPassthrough; + QAtomicPointer m_pCurrentSavedLoopControl; // Tells us which controls map to which hotcue