From 86029e8e0eb5e89867a65c15c0bf0d03eadab111 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Tue, 15 Jun 2021 15:59:24 +0200 Subject: [PATCH] Add macro condition "Hotkey" --- CMakeLists.txt | 2 + data/locale/en-US.ini | 4 + src/headers/macro-condition-hotkey.hpp | 54 +++++++++++ src/macro-condition-hotkey.cpp | 124 +++++++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 src/headers/macro-condition-hotkey.hpp create mode 100644 src/macro-condition-hotkey.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 661e5148..36917a05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-condition-macro.hpp src/headers/macro-condition-file.hpp src/headers/macro-condition-filter.hpp + src/headers/macro-condition-hotkey.hpp src/headers/macro-condition-idle.hpp src/headers/macro-condition-media.hpp src/headers/macro-condition-plugin-state.hpp @@ -176,6 +177,7 @@ set(advanced-scene-switcher_SOURCES src/macro-condition-macro.cpp src/macro-condition-file.cpp src/macro-condition-filter.cpp + src/macro-condition-hotkey.cpp src/macro-condition-idle.cpp src/macro-condition-media.cpp src/macro-condition-plugin-state.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index db4f90a8..128f4da3 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -168,6 +168,10 @@ AdvSceneSwitcher.condition.sceneOrder.type.below="Is below" 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.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="Name: {{name}}" ; Macro Actions AdvSceneSwitcher.action.switchScene="Switch scene" diff --git a/src/headers/macro-condition-hotkey.hpp b/src/headers/macro-condition-hotkey.hpp new file mode 100644 index 00000000..1cb0ffb9 --- /dev/null +++ b/src/headers/macro-condition-hotkey.hpp @@ -0,0 +1,54 @@ +#pragma once +#include "macro.hpp" +#include +#include + +class MacroConditionHotkey : public MacroCondition { +public: + MacroConditionHotkey(); + ~MacroConditionHotkey(); + bool CheckCondition(); + bool Save(obs_data_t *obj); + bool Load(obs_data_t *obj); + std::string GetId() { return id; }; + static std::shared_ptr Create() + { + return std::make_shared(); + } + void SetPressed() { _pressed = true; } + + std::string _name; + obs_hotkey_id _hotkeyID = OBS_INVALID_HOTKEY_ID; + +private: + bool _pressed = false; + static bool _registered; + static const std::string id; +}; + +class MacroConditionHotkeyEdit : public QWidget { + Q_OBJECT + +public: + MacroConditionHotkeyEdit( + QWidget *parent, + std::shared_ptr cond = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr cond) + { + return new MacroConditionHotkeyEdit( + parent, + std::dynamic_pointer_cast(cond)); + } + +private slots: + void NameChanged(); + +protected: + QLineEdit *_name; + std::shared_ptr _entryData; + +private: + bool _loading = true; +}; diff --git a/src/macro-condition-hotkey.cpp b/src/macro-condition-hotkey.cpp new file mode 100644 index 00000000..bca33973 --- /dev/null +++ b/src/macro-condition-hotkey.cpp @@ -0,0 +1,124 @@ +#include "headers/macro-condition-edit.hpp" +#include "headers/macro-condition-hotkey.hpp" +#include "headers/utility.hpp" +#include "headers/advanced-scene-switcher.hpp" + +const std::string MacroConditionHotkey::id = "hotkey"; + +bool MacroConditionHotkey::_registered = MacroConditionFactory::Register( + MacroConditionHotkey::id, + {MacroConditionHotkey::Create, MacroConditionHotkeyEdit::Create, + "AdvSceneSwitcher.condition.hotkey", false}); + +static void hotkeyCB(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, + bool pressed) +{ + UNUSED_PARAMETER(id); + UNUSED_PARAMETER(data); + UNUSED_PARAMETER(hotkey); + if (pressed) { + auto c = static_cast(data); + c->SetPressed(); + } +} + +static uint32_t count = 1; + +MacroConditionHotkey::MacroConditionHotkey() +{ + if (_hotkeyID != OBS_INVALID_HOTKEY_ID) { + obs_hotkey_unregister(_hotkeyID); + } + + std::string hotkeyName = + "macro_condition_hotkey_" + std::to_string(count); + + _name = obs_module_text("AdvSceneSwitcher.condition.hotkey.name") + + std::string(" ") + std::to_string(count); + _hotkeyID = obs_hotkey_register_frontend(hotkeyName.c_str(), + _name.c_str(), hotkeyCB, this); + count++; +} + +MacroConditionHotkey::~MacroConditionHotkey() +{ + obs_hotkey_unregister(_hotkeyID); +} + +bool MacroConditionHotkey::CheckCondition() +{ + if (_pressed) { + _pressed = false; + return true; + } + return false; +} + +bool MacroConditionHotkey::Save(obs_data_t *obj) +{ + MacroCondition::Save(obj); + obs_data_set_string(obj, "desc", _name.c_str()); + obs_data_array_t *pauseHotkey = obs_hotkey_save(_hotkeyID); + obs_data_set_array(obj, "keyBind", pauseHotkey); + obs_data_array_release(pauseHotkey); + return true; +} + +bool MacroConditionHotkey::Load(obs_data_t *obj) +{ + MacroCondition::Load(obj); + _name = obs_data_get_string(obj, "desc"); + obs_data_array_t *pauseHotkey = obs_data_get_array(obj, "keyBind"); + obs_hotkey_load(_hotkeyID, pauseHotkey); + obs_data_array_release(pauseHotkey); + obs_hotkey_set_description(_hotkeyID, _name.c_str()); + return true; +} + +MacroConditionHotkeyEdit::MacroConditionHotkeyEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _name = new QLineEdit(); + QLabel *hint = new QLabel( + obs_module_text("AdvSceneSwitcher.condition.hotkey.tip")); + QWidget::connect(_name, SIGNAL(editingFinished()), this, + SLOT(NameChanged())); + + QHBoxLayout *switchLayout = new QHBoxLayout; + std::unordered_map widgetPlaceholders = { + {"{{name}}", _name}, + }; + placeWidgets(obs_module_text("AdvSceneSwitcher.condition.hotkey.entry"), + switchLayout, widgetPlaceholders); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout(switchLayout); + mainLayout->addWidget(hint); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroConditionHotkeyEdit::NameChanged() +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_name = _name->text().toStdString(); + obs_hotkey_set_description(_entryData->_hotkeyID, + _entryData->_name.c_str()); +} + +void MacroConditionHotkeyEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _name->setText(QString::fromStdString(_entryData->_name)); +}