diff --git a/src/control/control.cpp b/src/control/control.cpp index c45708f0bbd..b7a9ac1f0f0 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_kbdRepeatable(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_kbdRepeatable(false) { initialize(defaultValue); } diff --git a/src/control/control.h b/src/control/control.h index 69c6b6e10de..a33c4648f1f 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_kbdRepeatable = enable; + } + + bool getKbdRepeatable() const { + return m_kbdRepeatable; + } + // 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_kbdRepeatable; + // The control value. ControlValueAtomic m_value; // The default control value. diff --git a/src/control/controlobject.h b/src/control/controlobject.h index a543b5ca48e..49d927a8172 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; + } + void addAlias(const ConfigKey& aliasKey) const { ControlDoublePrivate::insertAlias(aliasKey, m_key); } diff --git a/src/control/controlpotmeter.cpp b/src/control/controlpotmeter.cpp index 145d17613b8..e0c5631a674 100644 --- a/src/control/controlpotmeter.cpp +++ b/src/control/controlpotmeter.cpp @@ -91,6 +91,11 @@ PotmeterControls::PotmeterControls(const ConfigKey& key) &ControlPushButton::valueChanged, this, &PotmeterControls::decSmallValue); + m_controlUp.setKbdRepeatable(true); + m_controlUpSmall.setKbdRepeatable(true); + m_controlDown.setKbdRepeatable(true); + m_controlDownSmall.setKbdRepeatable(true); + connect(&m_controlSetDefault, &ControlPushButton::valueChanged, this, diff --git a/src/controllers/keyboard/keyboardeventfilter.cpp b/src/controllers/keyboard/keyboardeventfilter.cpp index c69b872414e..3a33f76f609 100644 --- a/src/controllers/keyboard/keyboardeventfilter.cpp +++ b/src/controllers/keyboard/keyboardeventfilter.cpp @@ -4,7 +4,6 @@ #include #include -#include "control/controlobject.h" #include "moc_keyboardeventfilter.cpp" #include "util/cmdlineargs.h" @@ -36,15 +35,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); @@ -76,7 +69,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 5f49fd34dcd..4e35cc75d3d 100644 --- a/src/controllers/keyboard/keyboardeventfilter.h +++ b/src/controllers/keyboard/keyboardeventfilter.h @@ -1,8 +1,9 @@ #pragma once -#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) { + 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 QList m_qActiveKeyList; // Pointer to keyboard config object diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp index 9219af09304..6c9759a17e6 100644 --- a/src/engine/controls/bpmcontrol.cpp +++ b/src/engine/controls/bpmcontrol.cpp @@ -68,18 +68,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 a4b558d84c1..507fce85ff9 100644 --- a/src/engine/controls/loopingcontrol.cpp +++ b/src/engine/controls/loopingcontrol.cpp @@ -176,20 +176,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); @@ -221,9 +225,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); @@ -1790,11 +1796,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 bf76da8841c..455e84d15a3 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 =