From b76dad557818a35f47621e669f6dc087e476b63a Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Sat, 20 May 2023 12:54:35 -0400 Subject: Create option for control objects to be issued repeatedly if a keyboard key is held. Fixes https://github.com/mixxxdj/mixxx/issues/11569 Applies to: * beats_adjust_faster, beats_adjust_slower * beats_translate_earlier, beats_translate_later * beat_next, beat_prev * beatjump_size_halve, beatjump_size_double * beatjump_forward, beatjump_backward * loop_halve, loop_double * beatjump_X_foward, beatjump_X_backward * rate_perm_down, rate_perm_down_small, rate_perm_up, rate_perm_up_small --- src/control/control.cpp | 6 ++++-- src/control/control.h | 11 +++++++++++ src/control/controlobject.h | 10 ++++++++++ src/controllers/keyboard/keyboardeventfilter.cpp | 13 +++---------- src/controllers/keyboard/keyboardeventfilter.h | 15 ++++++++++++++- src/engine/controls/bpmcontrol.cpp | 4 ++++ src/engine/controls/loopingcontrol.cpp | 10 ++++++++++ src/engine/controls/ratecontrol.cpp | 4 ++++ 8 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/control/control.cpp b/src/control/control.cpp index ce902b34b6..0af9f8d5d7 100644 --- a/src/control/control.cpp +++ b/src/control/control.cpp @@ -37,7 +37,8 @@ ControlDoublePrivate::ControlDoublePrivate() m_trackFlags(Stat::COUNT | Stat::SUM | Stat::AVERAGE | Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), // default CO is read only - m_confirmRequired(true) { + m_confirmRequired(true), + m_kbd_repeatable(false) { m_value.setValue(0.0); } @@ -56,7 +57,8 @@ ControlDoublePrivate::ControlDoublePrivate( m_trackType(Stat::UNSPECIFIED), m_trackFlags(Stat::COUNT | Stat::SUM | Stat::AVERAGE | Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), - m_confirmRequired(false) { + m_confirmRequired(false), + m_kbd_repeatable(false) { initialize(defaultValue); } diff --git a/src/control/control.h b/src/control/control.h index 69c6b6e10d..9af659c282 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -80,6 +80,14 @@ class ControlDoublePrivate : public QObject { m_description = description; } + void setKbdRepeatable(bool enable) { + m_kbd_repeatable = enable; + } + + bool getKbdRepeatable() const { + return m_kbd_repeatable; + } + // Sets the control value. void set(double value, QObject* pSender); // directly sets the control value. Must be used from and only from the @@ -198,6 +206,9 @@ class ControlDoublePrivate : public QObject { // User-visible, i18n description for what the control does. QString m_description; + // If true, this control will be issued repeatedly if the keyboard key is held. + bool m_kbd_repeatable; + // The control value. ControlValueAtomic m_value; // The default control value. diff --git a/src/control/controlobject.h b/src/control/controlobject.h index 0f511183be..d36b2add69 100644 --- a/src/control/controlobject.h +++ b/src/control/controlobject.h @@ -53,6 +53,16 @@ class ControlObject : public QObject { } } + void setKbdRepeatable(bool enable) { + if (m_pControl) { + m_pControl->setKbdRepeatable(enable); + } + } + + bool getKbdRepeatable() const { + return m_pControl ? m_pControl->getKbdRepeatable() : false; + } + // Return the key of the object inline ConfigKey getKey() const { return m_key; diff --git a/src/controllers/keyboard/keyboardeventfilter.cpp b/src/controllers/keyboard/keyboardeventfilter.cpp index 19dc4e947f..31fac4688c 100644 --- a/src/controllers/keyboard/keyboardeventfilter.cpp +++ b/src/controllers/keyboard/keyboardeventfilter.cpp @@ -5,7 +5,6 @@ #include #include -#include "control/controlobject.h" #include "moc_keyboardeventfilter.cpp" #include "util/cmdlineargs.h" @@ -37,15 +36,9 @@ bool KeyboardEventFilter::eventFilter(QObject*, QEvent* e) { #else int keyId = ke->nativeScanCode(); #endif - //qDebug() << "KeyPress event =" << ke->key() << "KeyId =" << keyId; - // Run through list of active keys to see if the pressed key is already active - // Just for returning true if we are consuming this key event - - foreach (const KeyDownInformation& keyDownInfo, m_qActiveKeyList) { - if (keyDownInfo.keyId == keyId) { - return true; - } + if (shouldSkipHeldKey(keyId)) { + return true; } QKeySequence ks = getKeySeq(ke); @@ -77,7 +70,7 @@ bool KeyboardEventFilter::eventFilter(QObject*, QEvent* e) { } return result; } - } else if (e->type()==QEvent::KeyRelease) { + } else if (e->type() == QEvent::KeyRelease) { QKeyEvent* ke = (QKeyEvent*)e; #ifdef __APPLE__ diff --git a/src/controllers/keyboard/keyboardeventfilter.h b/src/controllers/keyboard/keyboardeventfilter.h index b557a4a8c5..7eb5b7dedb 100644 --- a/src/controllers/keyboard/keyboardeventfilter.h +++ b/src/controllers/keyboard/keyboardeventfilter.h @@ -1,10 +1,11 @@ #pragma once -#include #include #include #include +#include +#include "control/controlobject.h" #include "preferences/configobject.h" class ControlObject; @@ -39,6 +40,18 @@ class KeyboardEventFilter : public QObject { // Returns a valid QString with modifier keys from a QKeyEvent QKeySequence getKeySeq(QKeyEvent *e); + + // Run through list of active keys to see if the pressed key is already active + // and is not a control that repeats when held. + bool shouldSkipHeldKey(int keyId) { + foreach (const KeyDownInformation& keyDownInfo, m_qActiveKeyList) { + if (keyDownInfo.keyId == keyId && !keyDownInfo.pControl->getKbdRepeatable()) { + return true; + } + } + return false; + } + // List containing keys which is currently pressed QList m_qActiveKeyList; // Pointer to keyboard config object diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index 608fb17468..2491c67d75 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -73,18 +73,22 @@ BpmControl::BpmControl(const QString& group, m_pLocalBpm = new ControlObject(ConfigKey(group, "local_bpm")); m_pAdjustBeatsFaster = new ControlPushButton(ConfigKey(group, "beats_adjust_faster"), false); + m_pAdjustBeatsFaster->setKbdRepeatable(true); connect(m_pAdjustBeatsFaster, &ControlObject::valueChanged, this, &BpmControl::slotAdjustBeatsFaster, Qt::DirectConnection); m_pAdjustBeatsSlower = new ControlPushButton(ConfigKey(group, "beats_adjust_slower"), false); + m_pAdjustBeatsSlower->setKbdRepeatable(true); connect(m_pAdjustBeatsSlower, &ControlObject::valueChanged, this, &BpmControl::slotAdjustBeatsSlower, Qt::DirectConnection); m_pTranslateBeatsEarlier = new ControlPushButton(ConfigKey(group, "beats_translate_earlier"), false); + m_pTranslateBeatsEarlier->setKbdRepeatable(true); connect(m_pTranslateBeatsEarlier, &ControlObject::valueChanged, this, &BpmControl::slotTranslateBeatsEarlier, Qt::DirectConnection); m_pTranslateBeatsLater = new ControlPushButton(ConfigKey(group, "beats_translate_later"), false); + m_pTranslateBeatsLater->setKbdRepeatable(true); connect(m_pTranslateBeatsLater, &ControlObject::valueChanged, this, &BpmControl::slotTranslateBeatsLater, Qt::DirectConnection); diff --git a/src/engine/controls/loopingcontrol.cpp b/src/engine/controls/loopingcontrol.cpp index 695d2dca2c..4015076143 100644 --- a/src/engine/controls/loopingcontrol.cpp +++ b/src/engine/controls/loopingcontrol.cpp @@ -125,7 +125,9 @@ LoopingControl::LoopingControl(const QString& group, m_pQuantizeEnabled = ControlObject::getControl(ConfigKey(group, "quantize")); m_pNextBeat = ControlObject::getControl(ConfigKey(group, "beat_next")); + m_pNextBeat->setKbdRepeatable(true); m_pPreviousBeat = ControlObject::getControl(ConfigKey(group, "beat_prev")); + m_pPreviousBeat->setKbdRepeatable(true); m_pClosestBeat = ControlObject::getControl(ConfigKey(group, "beat_closest")); m_pTrackSamples = ControlObject::getControl(ConfigKey(group, "track_samples")); m_pSlipEnabled = ControlObject::getControl(ConfigKey(group, "slip_enabled")); @@ -180,20 +182,24 @@ LoopingControl::LoopingControl(const QString& group, Qt::DirectConnection); m_pCOBeatJumpSizeHalve = new ControlPushButton(ConfigKey(group, "beatjump_size_halve")); + m_pCOBeatJumpSizeHalve->setKbdRepeatable(true); connect(m_pCOBeatJumpSizeHalve, &ControlObject::valueChanged, this, &LoopingControl::slotBeatJumpSizeHalve); m_pCOBeatJumpSizeDouble = new ControlPushButton(ConfigKey(group, "beatjump_size_double")); + m_pCOBeatJumpSizeDouble->setKbdRepeatable(true); connect(m_pCOBeatJumpSizeDouble, &ControlObject::valueChanged, this, &LoopingControl::slotBeatJumpSizeDouble); m_pCOBeatJumpForward = new ControlPushButton(ConfigKey(group, "beatjump_forward")); + m_pCOBeatJumpForward->setKbdRepeatable(true); connect(m_pCOBeatJumpForward, &ControlObject::valueChanged, this, &LoopingControl::slotBeatJumpForward); m_pCOBeatJumpBackward = new ControlPushButton(ConfigKey(group, "beatjump_backward")); + m_pCOBeatJumpBackward->setKbdRepeatable(true); connect(m_pCOBeatJumpBackward, &ControlObject::valueChanged, this, &LoopingControl::slotBeatJumpBackward); @@ -225,9 +231,11 @@ LoopingControl::LoopingControl(const QString& group, connect(m_pCOLoopScale, &ControlObject::valueChanged, this, &LoopingControl::slotLoopScale); m_pLoopHalveButton = new ControlPushButton(ConfigKey(group, "loop_halve")); + m_pLoopHalveButton->setKbdRepeatable(true); connect(m_pLoopHalveButton, &ControlObject::valueChanged, this, &LoopingControl::slotLoopHalve); m_pLoopDoubleButton = new ControlPushButton(ConfigKey(group, "loop_double")); + m_pLoopDoubleButton->setKbdRepeatable(true); connect(m_pLoopDoubleButton, &ControlObject::valueChanged, this, &LoopingControl::slotLoopDouble); @@ -1719,11 +1727,13 @@ BeatJumpControl::BeatJumpControl(const QString& group, double size) : m_dBeatJumpSize(size) { m_pJumpForward = new ControlPushButton( keyForControl(group, "beatjump_%1_forward", size)); + m_pJumpForward->setKbdRepeatable(true); connect(m_pJumpForward, &ControlObject::valueChanged, this, &BeatJumpControl::slotJumpForward, Qt::DirectConnection); m_pJumpBackward = new ControlPushButton( keyForControl(group, "beatjump_%1_backward", size)); + m_pJumpBackward->setKbdRepeatable(true); connect(m_pJumpBackward, &ControlObject::valueChanged, this, &BeatJumpControl::slotJumpBackward, Qt::DirectConnection); diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp index dc0c3babd9..9e3de90cb6 100644 --- a/src/engine/controls/ratecontrol.cpp +++ b/src/engine/controls/ratecontrol.cpp @@ -104,24 +104,28 @@ RateControl::RateControl(const QString& group, connect(m_pButtonRatePermDown, &ControlObject::valueChanged, this, &RateControl::slotControlRatePermDown, Qt::DirectConnection); + m_pButtonRatePermDown->setKbdRepeatable(true); m_pButtonRatePermDownSmall = new ControlPushButton(ConfigKey(group,"rate_perm_down_small")); connect(m_pButtonRatePermDownSmall, &ControlObject::valueChanged, this, &RateControl::slotControlRatePermDownSmall, Qt::DirectConnection); + m_pButtonRatePermDownSmall->setKbdRepeatable(true); m_pButtonRatePermUp = new ControlPushButton(ConfigKey(group,"rate_perm_up")); connect(m_pButtonRatePermUp, &ControlObject::valueChanged, this, &RateControl::slotControlRatePermUp, Qt::DirectConnection); + m_pButtonRatePermUp->setKbdRepeatable(true); m_pButtonRatePermUpSmall = new ControlPushButton(ConfigKey(group,"rate_perm_up_small")); connect(m_pButtonRatePermUpSmall, &ControlObject::valueChanged, this, &RateControl::slotControlRatePermUpSmall, Qt::DirectConnection); + m_pButtonRatePermUpSmall->setKbdRepeatable(true); // Temporary rate-change buttons m_pButtonRateTempDown = -- cgit v1.2.3 From 0e3dfa9a0ec799cbcef003fb066c805ccc14d800 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Sat, 20 May 2023 15:36:11 -0400 Subject: Update src/controllers/keyboard/keyboardeventfilter.h use std::any_of instead of old foreach Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- src/controllers/keyboard/keyboardeventfilter.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/controllers/keyboard/keyboardeventfilter.h b/src/controllers/keyboard/keyboardeventfilter.h index 7eb5b7dedb..f9b6a99dbc 100644 --- a/src/controllers/keyboard/keyboardeventfilter.h +++ b/src/controllers/keyboard/keyboardeventfilter.h @@ -44,12 +44,12 @@ class KeyboardEventFilter : public QObject { // Run through list of active keys to see if the pressed key is already active // and is not a control that repeats when held. bool shouldSkipHeldKey(int keyId) { - foreach (const KeyDownInformation& keyDownInfo, m_qActiveKeyList) { - if (keyDownInfo.keyId == keyId && !keyDownInfo.pControl->getKbdRepeatable()) { - return true; - } - } - return false; + return std::any_of( + m_qActiveKeyList.cbegin(), + m_qActiveKeyList.cend(), + [&](const KeyDownInformation& keyDownInfo) { + return keyDownInfo.keyId == keyId && !keyDownInfo.pControl->getKbdRepeatable(); + }); } // List containing keys which is currently pressed -- cgit v1.2.3 From d7a780f41b6c51b18d87d95038b84d507df7b404 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Sun, 21 May 2023 14:44:32 -0400 Subject: keyboard repeat: also apply to potmeter controls --- src/control/controlpotmeter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/control/controlpotmeter.cpp b/src/control/controlpotmeter.cpp index 966f788295..0af92ef560 100644 --- a/src/control/controlpotmeter.cpp +++ b/src/control/controlpotmeter.cpp @@ -67,6 +67,7 @@ PotmeterControls::PotmeterControls(const ConfigKey& key) ControlPushButton* controlUp = new ControlPushButton( ConfigKey(key.group, QString(key.item) + "_up")); + controlUp->setKbdRepeatable(true); controlUp->setParent(this); connect(controlUp, &ControlPushButton::valueChanged, @@ -75,6 +76,7 @@ PotmeterControls::PotmeterControls(const ConfigKey& key) ControlPushButton* controlDown = new ControlPushButton( ConfigKey(key.group, QString(key.item) + "_down")); + controlDown->setKbdRepeatable(true); controlDown->setParent(this); connect(controlDown, &ControlPushButton::valueChanged, @@ -83,6 +85,7 @@ PotmeterControls::PotmeterControls(const ConfigKey& key) ControlPushButton* controlUpSmall = new ControlPushButton( ConfigKey(key.group, QString(key.item) + "_up_small")); + controlUpSmall->setKbdRepeatable(true); controlUpSmall->setParent(this); connect(controlUpSmall, &ControlPushButton::valueChanged, @@ -91,6 +94,7 @@ PotmeterControls::PotmeterControls(const ConfigKey& key) ControlPushButton* controlDownSmall = new ControlPushButton( ConfigKey(key.group, QString(key.item) + "_down_small")); + controlDownSmall->setKbdRepeatable(true); controlDownSmall->setParent(this); connect(controlDownSmall, &ControlPushButton::valueChanged, -- cgit v1.2.3 From ddb4436666338f7937e4a8a7f500089db6639d40 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Tue, 23 May 2023 12:33:26 -0400 Subject: Keyboard Repeat: use camelCase var --- src/control/control.cpp | 4 ++-- src/control/control.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/control/control.cpp b/src/control/control.cpp index 0af9f8d5d7..e44ac4f42c 100644 --- a/src/control/control.cpp +++ b/src/control/control.cpp @@ -38,7 +38,7 @@ ControlDoublePrivate::ControlDoublePrivate() Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), // default CO is read only m_confirmRequired(true), - m_kbd_repeatable(false) { + m_kbdRepeatable(false) { m_value.setValue(0.0); } @@ -58,7 +58,7 @@ ControlDoublePrivate::ControlDoublePrivate( m_trackFlags(Stat::COUNT | Stat::SUM | Stat::AVERAGE | Stat::SAMPLE_VARIANCE | Stat::MIN | Stat::MAX), m_confirmRequired(false), - m_kbd_repeatable(false) { + m_kbdRepeatable(false) { initialize(defaultValue); } diff --git a/src/control/control.h b/src/control/control.h index 9af659c282..a33c4648f1 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -81,11 +81,11 @@ class ControlDoublePrivate : public QObject { } void setKbdRepeatable(bool enable) { - m_kbd_repeatable = enable; + m_kbdRepeatable = enable; } bool getKbdRepeatable() const { - return m_kbd_repeatable; + return m_kbdRepeatable; } // Sets the control value. @@ -207,7 +207,7 @@ class ControlDoublePrivate : public QObject { QString m_description; // If true, this control will be issued repeatedly if the keyboard key is held. - bool m_kbd_repeatable; + bool m_kbdRepeatable; // The control value. ControlValueAtomic m_value; -- cgit v1.2.3