diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index 8733e552..baf8be67 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -287,8 +287,8 @@ AdvSceneSwitcher.condition.sceneOrder.entry="Auf{{scenes}}{{sources}}{{condition AdvSceneSwitcher.condition.hotkey="Hotkey" AdvSceneSwitcher.condition.hotkey.name="Makro-Trigger-Hotkey" AdvSceneSwitcher.condition.hotkey.tip="Hinweis: Die Tastenkombinationen für diesen Hotkey können in den OBS-Einstellungen konfiguriert werden" -AdvSceneSwitcher.condition.hotkey.entry.line1="Hotkey ist gedrückt" -AdvSceneSwitcher.condition.hotkey.entry.line2="Name: {{name}}" +AdvSceneSwitcher.condition.hotkey.entry.keyState="Hotkey ist{{keyState}}" +AdvSceneSwitcher.condition.hotkey.entry.name="Name:{{name}}" AdvSceneSwitcher.condition.replay="Replay Buffer" AdvSceneSwitcher.condition.replay.state.stopped="Replay Buffer gestoppt" AdvSceneSwitcher.condition.replay.state.started="Replay Buffer gestartet" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index ff5e5443..0c1164cc 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -482,10 +482,12 @@ AdvSceneSwitcher.condition.sceneOrder.type.position="Is at position" AdvSceneSwitcher.condition.sceneOrder.positionInfo="The position value starts at the bottom with 0 and increases by one for each scene item including the ones in scene groups" AdvSceneSwitcher.condition.sceneOrder.entry="On{{scenes}}{{sources}}{{conditions}}{{sources2}}{{position}}" AdvSceneSwitcher.condition.hotkey="Hotkey" +AdvSceneSwitcher.condition.hotkey.pressed="pressed" +AdvSceneSwitcher.condition.hotkey.released="released" AdvSceneSwitcher.condition.hotkey.name="Macro trigger hotkey" AdvSceneSwitcher.condition.hotkey.tip="Note: You can configure the keybindings for this hotkey in the OBS settings window" -AdvSceneSwitcher.condition.hotkey.entry.line1="Hotkey is pressed" -AdvSceneSwitcher.condition.hotkey.entry.line2="Name:{{name}}" +AdvSceneSwitcher.condition.hotkey.entry.keyState="Hotkey is{{keyState}}" +AdvSceneSwitcher.condition.hotkey.entry.name="Name:{{name}}" AdvSceneSwitcher.condition.replay="Replay buffer" AdvSceneSwitcher.condition.replay.state.stopped="Replay buffer stopped" AdvSceneSwitcher.condition.replay.state.started="Replay buffer started" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index d16fdb79..fd60f033 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -238,8 +238,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="En{{scenes}}{{sources}}{{conditions AdvSceneSwitcher.condition.hotkey="Tecla de acceso rápido" AdvSceneSwitcher.condition.hotkey.name="Tecla de acceso directo de activación de macro" AdvSceneSwitcher.condition.hotkey.tip="Nota: puede configurar las combinaciones de teclas para esta tecla de acceso rápido en la ventana de configuración de OBS" -AdvSceneSwitcher.condition.hotkey.entry.line1="Se presiona la tecla de acceso rápido" -AdvSceneSwitcher.condition.hotkey.entry.line2="Nombre: {{name}}" +AdvSceneSwitcher.condition.hotkey.entry.name="Nombre:{{name}}" AdvSceneSwitcher.condition.replay="Búfer de reproducción" AdvSceneSwitcher.condition.replay.state.stopped="Búfer de reproducción detenido" AdvSceneSwitcher.condition.replay.state.started="Búfer de reproducción iniciado" diff --git a/data/locale/fr-FR.ini b/data/locale/fr-FR.ini index df2b4e8a..ce30e3b5 100644 --- a/data/locale/fr-FR.ini +++ b/data/locale/fr-FR.ini @@ -351,8 +351,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="Sur{{scenes}}{{sources}}{{condition AdvSceneSwitcher.condition.hotkey="Raccourci clavier" AdvSceneSwitcher.condition.hotkey.name="Raccourci clavier de déclenchement de macro" AdvSceneSwitcher.condition.hotkey.tip="Remarque : Vous pouvez configurer les raccourcis clavier pour ce raccourci dans la fenêtre de paramètres d'OBS" -AdvSceneSwitcher.condition.hotkey.entry.line1="Raccourci clavier est enfoncé" -AdvSceneSwitcher.condition.hotkey.entry.line2="Nom :{{name}}" +AdvSceneSwitcher.condition.hotkey.entry.name="Nom:{{name}}" AdvSceneSwitcher.condition.replay="Tampon de répétition" AdvSceneSwitcher.condition.replay.state.stopped="Tampon de répétition arrêté" AdvSceneSwitcher.condition.replay.state.started="Tampon de répétition démarré" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index 56f8bdaf..4fa4fa1e 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -332,8 +332,7 @@ AdvSceneSwitcher.condition.sceneOrder.entry="在 {{scenes}} {{sources}} {{condit AdvSceneSwitcher.condition.hotkey="热键" AdvSceneSwitcher.condition.hotkey.name="宏触发热键" AdvSceneSwitcher.condition.hotkey.tip="注意:您可以在OBS设置窗口中为此热键配置按键绑定" -AdvSceneSwitcher.condition.hotkey.entry.line1="热键被按下" -AdvSceneSwitcher.condition.hotkey.entry.line2="名称: {{name}}" +AdvSceneSwitcher.condition.hotkey.entry.name="名称:{{name}}" AdvSceneSwitcher.condition.replay="回放缓存" AdvSceneSwitcher.condition.replay.state.stopped="回放缓存已停止" AdvSceneSwitcher.condition.replay.state.started="回放缓存已启动" diff --git a/plugins/base/macro-condition-hotkey.cpp b/plugins/base/macro-condition-hotkey.cpp index b145a85e..26cd03f2 100644 --- a/plugins/base/macro-condition-hotkey.cpp +++ b/plugins/base/macro-condition-hotkey.cpp @@ -23,13 +23,17 @@ MacroConditionHotkey::MacroConditionHotkey(Macro *m) : MacroCondition(m) bool MacroConditionHotkey::CheckCondition() { - const bool hotkeyIsCurrentlyPressed = _hotkey->GetPressed(); - const bool hotkeyWasPressedSinceLastCheck = _hotkey->GetLastPressed() > - _lastCheck; + const bool keyStateCurrentlyMatches = + _checkPressed ? _hotkey->GetPressed() : !_hotkey->GetPressed(); + const auto lastKeyStateMatch = _checkPressed + ? _hotkey->GetLastPressed() + : _hotkey->GetLastReleased(); + const bool hotkeySateChangedSinceLastCheck = lastKeyStateMatch > + _lastCheck; const bool macroWasPausedSinceLastCheck = MacroWasPausedSince(GetMacro(), _lastCheck); - bool ret = hotkeyIsCurrentlyPressed || - (hotkeyWasPressedSinceLastCheck && + bool ret = keyStateCurrentlyMatches || + (hotkeySateChangedSinceLastCheck && !macroWasPausedSinceLastCheck); _lastCheck = std::chrono::high_resolution_clock::now(); return ret; @@ -39,6 +43,7 @@ bool MacroConditionHotkey::Save(obs_data_t *obj) const { MacroCondition::Save(obj); _hotkey->Save(obj); + obs_data_set_bool(obj, "checkPressed", _checkPressed); return true; } @@ -52,34 +57,47 @@ bool MacroConditionHotkey::Load(obs_data_t *obj) "hotkey name conflict for \"%s\" - using previous key bind", description); } + if (obs_data_has_user_value(obj, "checkPressed")) { + _checkPressed = obs_data_get_bool(obj, "checkPressed"); + } else { // TODO: Remove fallback at some point in the future + _checkPressed = true; + } return true; } MacroConditionHotkeyEdit::MacroConditionHotkeyEdit( QWidget *parent, std::shared_ptr entryData) - : QWidget(parent) + : QWidget(parent), + _name(new QLineEdit()), + _keyState(new QComboBox()) { - _name = new QLineEdit(); - QLabel *line1 = new QLabel(obs_module_text( - "AdvSceneSwitcher.condition.hotkey.entry.line1")); - QLabel *hint = new QLabel( - obs_module_text("AdvSceneSwitcher.condition.hotkey.tip")); + _keyState->addItems( + QStringList() + << obs_module_text("AdvSceneSwitcher.condition.hotkey.pressed") + << obs_module_text( + "AdvSceneSwitcher.condition.hotkey.released")); QWidget::connect(_name, SIGNAL(editingFinished()), this, SLOT(NameChanged())); + QWidget::connect(_keyState, SIGNAL(currentIndexChanged(int)), this, + SLOT(KeyStateChanged(int))); - QHBoxLayout *switchLayout = new QHBoxLayout; - std::unordered_map widgetPlaceholders = { - {"{{name}}", _name}, - }; - PlaceWidgets(obs_module_text( - "AdvSceneSwitcher.condition.hotkey.entry.line2"), - switchLayout, widgetPlaceholders); + auto keyStateLayout = new QHBoxLayout; + PlaceWidgets( + obs_module_text( + "AdvSceneSwitcher.condition.hotkey.entry.keyState"), + keyStateLayout, {{"{{keyState}}", _keyState}}); - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(line1); - mainLayout->addLayout(switchLayout); - mainLayout->addWidget(hint); + auto nameLayout = new QHBoxLayout; + PlaceWidgets( + obs_module_text("AdvSceneSwitcher.condition.hotkey.entry.name"), + nameLayout, {{"{{name}}", _name}}); + + auto mainLayout = new QVBoxLayout; + mainLayout->addLayout(keyStateLayout); + mainLayout->addLayout(nameLayout); + mainLayout->addWidget(new QLabel( + obs_module_text("AdvSceneSwitcher.condition.hotkey.tip"))); setLayout(mainLayout); _entryData = entryData; @@ -116,6 +134,17 @@ void MacroConditionHotkeyEdit::UpdateEntryData() _name->setText( QString::fromStdString(_entryData->_hotkey->GetDescription())); + _keyState->setCurrentIndex(_entryData->_checkPressed ? 0 : 1); +} + +void MacroConditionHotkeyEdit::KeyStateChanged(int index) +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_checkPressed = index == 0; } } // namespace advss diff --git a/plugins/base/macro-condition-hotkey.hpp b/plugins/base/macro-condition-hotkey.hpp index 7f817248..f31164f6 100644 --- a/plugins/base/macro-condition-hotkey.hpp +++ b/plugins/base/macro-condition-hotkey.hpp @@ -20,6 +20,7 @@ public: } std::shared_ptr _hotkey; + bool _checkPressed = true; private: std::chrono::high_resolution_clock::time_point _lastCheck{}; @@ -46,12 +47,12 @@ public: private slots: void NameChanged(); - -protected: - QLineEdit *_name; - std::shared_ptr _entryData; + void KeyStateChanged(int); private: + QLineEdit *_name; + QComboBox *_keyState; + std::shared_ptr _entryData; bool _loading = true; }; diff --git a/plugins/base/utils/hotkey-helpers.cpp b/plugins/base/utils/hotkey-helpers.cpp index 41874196..5563d0c6 100644 --- a/plugins/base/utils/hotkey-helpers.cpp +++ b/plugins/base/utils/hotkey-helpers.cpp @@ -116,6 +116,9 @@ void Hotkey::Callback(void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed) if (pressed) { hotkey->_lastPressed = std::chrono::high_resolution_clock::now(); + } else { + hotkey->_lastReleased = + std::chrono::high_resolution_clock::now(); } hotkey->_pressed = pressed; } diff --git a/plugins/base/utils/hotkey-helpers.hpp b/plugins/base/utils/hotkey-helpers.hpp index efbbded2..cd55df21 100644 --- a/plugins/base/utils/hotkey-helpers.hpp +++ b/plugins/base/utils/hotkey-helpers.hpp @@ -27,6 +27,7 @@ public: bool GetPressed() const { return _pressed; } auto GetLastPressed() const { return _lastPressed; } + auto GetLastReleased() const { return _lastReleased; } std::string GetDescription() const { return _description; } bool UpdateDescription(const std::string &); @@ -43,6 +44,7 @@ private: obs_hotkey_id _hotkeyID = OBS_INVALID_HOTKEY_ID; bool _pressed = false; std::chrono::high_resolution_clock::time_point _lastPressed{}; + std::chrono::high_resolution_clock::time_point _lastReleased{}; // When set will not attempt to share settings with existing hotkey bool _ignoreExistingHotkeys = false; };