From 5b12468a468ef9b2cae1d1711bf18d55fb7fa86f Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Fri, 14 May 2021 18:08:46 +0200 Subject: [PATCH] Add macro condition process --- CMakeLists.txt | 2 + data/locale/en-US.ini | 2 + src/headers/macro-condition-process.hpp | 52 +++++++++++ src/macro-condition-process.cpp | 110 ++++++++++++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 src/headers/macro-condition-process.hpp create mode 100644 src/macro-condition-process.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ee2ac31..71a1ec6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-condition-file.hpp src/headers/macro-condition-media.hpp src/headers/macro-condition-plugin-state.hpp + src/headers/macro-condition-process.hpp src/headers/macro-condition-recording.hpp src/headers/macro-condition-region.hpp src/headers/macro-condition-scene.hpp @@ -147,6 +148,7 @@ set(advanced-scene-switcher_SOURCES src/macro-condition-file.cpp src/macro-condition-media.cpp src/macro-condition-plugin-state.cpp + src/macro-condition-process.cpp src/macro-condition-recording.cpp src/macro-condition-region.cpp src/macro-condition-scene.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 03b103f3..aaa6ebf3 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -115,6 +115,8 @@ AdvSceneSwitcher.condition.record.state.start="Recording running" AdvSceneSwitcher.condition.record.state.pause="Recording paused" AdvSceneSwitcher.condition.record.state.stop="Recording stopped" AdvSceneSwitcher.condition.record.entry="{{recordState}} for {{duration}}" +AdvSceneSwitcher.condition.process="Process" +AdvSceneSwitcher.condition.process.entry="{{processes}} is running {{focused}} and is focused" AdvSceneSwitcher.condition.pluginState="Plugin state" AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval" AdvSceneSwitcher.condition.pluginState.entry="{{condition}}" diff --git a/src/headers/macro-condition-process.hpp b/src/headers/macro-condition-process.hpp new file mode 100644 index 00000000..a934cc68 --- /dev/null +++ b/src/headers/macro-condition-process.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "macro.hpp" +#include +#include + +class MacroConditionProcess : public MacroCondition { +public: + bool CheckCondition(); + bool Save(obs_data_t *obj); + bool Load(obs_data_t *obj); + int GetId() { return id; }; + static std::shared_ptr Create() + { + return std::make_shared(); + } + + std::string _process; + bool _focus = true; + +private: + static bool _registered; + static const int id; +}; + +class MacroConditionProcessEdit : public QWidget { + Q_OBJECT + +public: + MacroConditionProcessEdit( + QWidget *parent, + std::shared_ptr cond = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr cond) + { + return new MacroConditionProcessEdit( + parent, + std::dynamic_pointer_cast(cond)); + } + +private slots: + void ProcessChanged(const QString &text); + void FocusChanged(int state); + +protected: + QComboBox *_processSelection; + QCheckBox *_focused; + std::shared_ptr _entryData; + +private: + bool _loading = true; +}; diff --git a/src/macro-condition-process.cpp b/src/macro-condition-process.cpp new file mode 100644 index 00000000..992ef67a --- /dev/null +++ b/src/macro-condition-process.cpp @@ -0,0 +1,110 @@ +#include "headers/macro-condition-edit.hpp" +#include "headers/macro-condition-process.hpp" +#include "headers/utility.hpp" +#include "headers/advanced-scene-switcher.hpp" + +#include + +const int MacroConditionProcess::id = 9; + +bool MacroConditionProcess::_registered = MacroConditionFactory::Register( + MacroConditionProcess::id, + {MacroConditionProcess::Create, MacroConditionProcessEdit::Create, + "AdvSceneSwitcher.condition.process"}); + +bool MacroConditionProcess::CheckCondition() +{ + std::string title; + QStringList runningProcesses; + + QString proc = QString::fromStdString(_process); + + GetCurrentWindowTitle(title); + GetProcessList(runningProcesses); + + bool equals = runningProcesses.contains(proc); + bool matches = runningProcesses.indexOf(QRegularExpression(proc)) != -1; + bool focus = !_focus || isInFocus(proc); + + return (equals || matches) && focus; +} + +bool MacroConditionProcess::Save(obs_data_t *obj) +{ + MacroCondition::Save(obj); + obs_data_set_string(obj, "process", _process.c_str()); + obs_data_set_bool(obj, "focus", _focus); + return true; +} + +bool MacroConditionProcess::Load(obs_data_t *obj) +{ + MacroCondition::Load(obj); + _process = obs_data_get_string(obj, "process"); + _focus = obs_data_get_bool(obj, "focus"); + return true; +} + +MacroConditionProcessEdit::MacroConditionProcessEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _processSelection = new QComboBox(); + _processSelection->setEditable(true); + _processSelection->setMaxVisibleItems(20); + + _focused = new QCheckBox(); + + QWidget::connect(_processSelection, + SIGNAL(currentTextChanged(const QString &)), this, + SLOT(ProcessChanged(const QString &))); + QWidget::connect(_focused, SIGNAL(stateChanged(int)), this, + SLOT(FocusChanged(int))); + + AdvSceneSwitcher::populateProcessSelection(_processSelection); + + std::unordered_map widgetPlaceholders = { + {"{{processes}}", _processSelection}, + {"{{focused}}", _focused}, + }; + + QHBoxLayout *mainLayout = new QHBoxLayout; + placeWidgets( + obs_module_text("AdvSceneSwitcher.condition.process.entry"), + mainLayout, widgetPlaceholders); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroConditionProcessEdit::ProcessChanged(const QString &text) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_process = text.toStdString(); +} + +void MacroConditionProcessEdit::FocusChanged(int state) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_focus = state; +} + +void MacroConditionProcessEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _processSelection->setCurrentText(_entryData->_process.c_str()); + _focused->setChecked(_entryData->_focus); +}