mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add Stream Deck condition type
The Stream Deck plugin to enable communication with the Advanced Scene Switcher can be found here: https://github.com/WarmUpTill/advanced-scene-switcher-streamdeck-plugin
This commit is contained in:
parent
b60235d964
commit
faa65facfe
|
|
@ -745,6 +745,15 @@ AdvSceneSwitcher.condition.usb.vendorName="Vendor Name:"
|
|||
AdvSceneSwitcher.condition.usb.productName="Product Name:"
|
||||
AdvSceneSwitcher.condition.usb.serialNumber="Serial Number:"
|
||||
AdvSceneSwitcher.condition.noDevicesFoundWarning="No USB devices detected!\nThe plugin might not have the required permissions to check for USB devices."
|
||||
AdvSceneSwitcher.condition.streamDeck="Stream Deck"
|
||||
AdvSceneSwitcher.condition.streamDeck.checkKeyState="Check key state"
|
||||
AdvSceneSwitcher.condition.streamDeck.keyState.pressed="Pressed"
|
||||
AdvSceneSwitcher.condition.streamDeck.keyState.released="Released"
|
||||
AdvSceneSwitcher.condition.streamDeck.checkKeyPosition="Check key position"
|
||||
AdvSceneSwitcher.condition.streamDeck.checkData="Check data field"
|
||||
AdvSceneSwitcher.condition.streamDeck.startListen="Start listening"
|
||||
AdvSceneSwitcher.condition.streamDeck.stopListen="Stop listening"
|
||||
AdvSceneSwitcher.condition.streamDeck.pluginDownload="<html><head/><body><p>The Stream Deck plugin can be found <a href=\"https://github.com/WarmUpTill/advanced-scene-switcher-streamdeck-plugin/releases\"><span style=\" text-decoration: underline; color:#268bd2;\">here on GitHub</span></a>.</p></body></html>"
|
||||
|
||||
# Macro Actions
|
||||
AdvSceneSwitcher.action.unknown="Unknown action"
|
||||
|
|
@ -1881,6 +1890,13 @@ AdvSceneSwitcher.tempVar.media.vlc.disc_number="Disc number (VLC)"
|
|||
AdvSceneSwitcher.tempVar.media.vlc.disc_total="Disc total (VLC)"
|
||||
AdvSceneSwitcher.tempVar.media.vlc.metadata.description="This property is exposed by the VLC Source type.\nNot all of these might be applicable to every file.\nIn case the metadata is not available an empty string will be returned."
|
||||
|
||||
AdvSceneSwitcher.tempVar.streamDeck.keyPressed="Key pressed"
|
||||
AdvSceneSwitcher.tempVar.streamDeck.keyPressed.description="Will return \"0\" when the key is pressed, and \"1\" otherwise."
|
||||
AdvSceneSwitcher.tempVar.streamDeck.row="Key row"
|
||||
AdvSceneSwitcher.tempVar.streamDeck.column="Key column"
|
||||
AdvSceneSwitcher.tempVar.streamDeck.data="Data"
|
||||
AdvSceneSwitcher.tempVar.streamDeck.data.description="The value of the \"Data\" field configured in the action on the Stream Deck side."
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ install_advss_plugin_dependency(...)
|
|||
|
||||
add_plugin(midi)
|
||||
add_plugin(openvr)
|
||||
add_plugin(stream-deck)
|
||||
add_plugin(twitch)
|
||||
add_plugin(usb)
|
||||
add_plugin(video)
|
||||
|
|
|
|||
12
plugins/stream-deck/CMakeLists.txt
Normal file
12
plugins/stream-deck/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
project(advanced-scene-switcher-stream-deck)
|
||||
|
||||
add_library(${PROJECT_NAME} MODULE)
|
||||
|
||||
get_target_property(ADVSS_SOURCE_DIR advanced-scene-switcher-lib SOURCE_DIR)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE macro-condition-stream-deck.cpp
|
||||
macro-condition-stream-deck.hpp)
|
||||
setup_advss_plugin(${PROJECT_NAME})
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||
install_advss_plugin(${PROJECT_NAME})
|
||||
403
plugins/stream-deck/macro-condition-stream-deck.cpp
Normal file
403
plugins/stream-deck/macro-condition-stream-deck.cpp
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
#include "macro-condition-stream-deck.hpp"
|
||||
#include "layout-helpers.hpp"
|
||||
#include "websocket-api.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
const std::string MacroConditionStreamdeck::id = "streamdeck";
|
||||
|
||||
bool MacroConditionStreamdeck::_registered = MacroConditionFactory::Register(
|
||||
MacroConditionStreamdeck::id,
|
||||
{MacroConditionStreamdeck::Create, MacroConditionStreamdeckEdit::Create,
|
||||
"AdvSceneSwitcher.condition.streamDeck"});
|
||||
|
||||
constexpr char streamDeckMessage[] = "StreamDeckKeyEvent";
|
||||
|
||||
static StreamDeckMessageDispatcher messageDispatcher;
|
||||
|
||||
static bool setup();
|
||||
static bool setupDone = setup();
|
||||
static void receiveStreamDeckMessage(obs_data_t *request_data, obs_data_t *);
|
||||
|
||||
bool setup()
|
||||
{
|
||||
RegisterWebsocketRequest(streamDeckMessage, receiveStreamDeckMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void printParseError(obs_data_t *data)
|
||||
{
|
||||
blog(LOG_INFO, "received unexpected stream deck message: %s",
|
||||
obs_data_get_json(data) ? obs_data_get_json(data) : "''");
|
||||
}
|
||||
|
||||
void receiveStreamDeckMessage(obs_data_t *request_data, obs_data_t *)
|
||||
{
|
||||
StreamDeckMessage message;
|
||||
OBSDataAutoRelease data = obs_data_get_obj(request_data, "data");
|
||||
if (!data) {
|
||||
printParseError(request_data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!obs_data_has_user_value(data, "isKeyDownEvent")) {
|
||||
printParseError(request_data);
|
||||
return;
|
||||
}
|
||||
message.keyDown = obs_data_get_bool(data, "isKeyDownEvent");
|
||||
|
||||
OBSDataAutoRelease coordinates = obs_data_get_obj(data, "coordinates");
|
||||
if (!coordinates) {
|
||||
printParseError(request_data);
|
||||
return;
|
||||
}
|
||||
|
||||
message.row = obs_data_get_int(coordinates, "row");
|
||||
message.column = obs_data_get_int(coordinates, "column");
|
||||
|
||||
OBSDataAutoRelease settings = obs_data_get_obj(data, "settings");
|
||||
if (!settings) {
|
||||
printParseError(request_data);
|
||||
return;
|
||||
}
|
||||
message.data = obs_data_get_string(settings, "data");
|
||||
|
||||
messageDispatcher.DispatchMessage(message);
|
||||
}
|
||||
|
||||
StreamDeckMessageBuffer RegisterForStreamDeckMessages()
|
||||
{
|
||||
return messageDispatcher.RegisterClient();
|
||||
}
|
||||
|
||||
MacroConditionStreamdeck::MacroConditionStreamdeck(Macro *m)
|
||||
: MacroCondition(m, true)
|
||||
{
|
||||
_messageBuffer = RegisterForStreamDeckMessages();
|
||||
}
|
||||
|
||||
bool MacroConditionStreamdeck::MessageMatches(const StreamDeckMessage &message)
|
||||
{
|
||||
const bool keyStateMatches = !_pattern.checkKeyState ||
|
||||
((message.keyDown && _pattern.keyDown) ||
|
||||
(!message.keyDown && !message.keyDown));
|
||||
const bool positionMatches = !_pattern.checkPosition ||
|
||||
(message.row == _pattern.row &&
|
||||
message.column == _pattern.column);
|
||||
const bool dataMatches =
|
||||
!_pattern.checkData ||
|
||||
(_pattern.regex.Enabled()
|
||||
? _pattern.regex.Matches(message.data, _pattern.data)
|
||||
: message.data == std::string(_pattern.data));
|
||||
return keyStateMatches && positionMatches && dataMatches;
|
||||
}
|
||||
|
||||
bool MacroConditionStreamdeck::CheckCondition()
|
||||
{
|
||||
while (!_messageBuffer->Empty()) {
|
||||
auto message = _messageBuffer->ConsumeMessage();
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!message->keyDown) {
|
||||
_lastMatchingKeyIsStillPressed = false;
|
||||
}
|
||||
|
||||
if (MessageMatches(*message)) {
|
||||
_lastMatchingKeyIsStillPressed = message->keyDown;
|
||||
SetTempVarValues(*message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lastMatchingKeyIsStillPressed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MacroConditionStreamdeck::Save(obs_data_t *obj) const
|
||||
{
|
||||
MacroCondition::Save(obj);
|
||||
_pattern.Save(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacroConditionStreamdeck::Load(obs_data_t *obj)
|
||||
{
|
||||
MacroCondition::Load(obj);
|
||||
_pattern.Load(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeck::StreamDeckMessagePattern::Save(
|
||||
obs_data_t *obj) const
|
||||
{
|
||||
OBSDataAutoRelease dataObj = obs_data_create();
|
||||
obs_data_set_bool(dataObj, "checkKeyState", checkKeyState);
|
||||
obs_data_set_bool(dataObj, "keyDown", keyDown);
|
||||
obs_data_set_bool(dataObj, "checkPosition", checkPosition);
|
||||
row.Save(dataObj, "row");
|
||||
column.Save(dataObj, "column");
|
||||
obs_data_set_bool(dataObj, "checkData", checkData);
|
||||
data.Save(dataObj, "data");
|
||||
regex.Save(dataObj);
|
||||
obs_data_set_obj(obj, "pattern", dataObj);
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeck::StreamDeckMessagePattern::Load(obs_data_t *obj)
|
||||
{
|
||||
OBSDataAutoRelease dataObj = obs_data_get_obj(obj, "pattern");
|
||||
checkKeyState = obs_data_get_bool(dataObj, "checkKeyState");
|
||||
keyDown = obs_data_get_bool(dataObj, "keyDown");
|
||||
checkPosition = obs_data_get_bool(dataObj, "checkPosition");
|
||||
row.Load(dataObj, "row");
|
||||
column.Load(dataObj, "column");
|
||||
checkData = obs_data_get_bool(dataObj, "checkData");
|
||||
data.Load(dataObj, "data");
|
||||
regex.Load(dataObj);
|
||||
obs_data_set_obj(obj, "pattern", dataObj);
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeck::SetTempVarValues(const StreamDeckMessage &message)
|
||||
{
|
||||
SetTempVarValue("keyPressed", std::to_string(message.keyDown));
|
||||
SetTempVarValue("row", std::to_string(message.row));
|
||||
SetTempVarValue("column", std::to_string(message.column));
|
||||
SetTempVarValue("data", message.data);
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeck::SetupTempVars()
|
||||
{
|
||||
AddTempvar(
|
||||
"keyPressed",
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.streamDeck.keyPressed"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.streamDeck.keyPressed.description"));
|
||||
AddTempvar("row",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.streamDeck.row"));
|
||||
AddTempvar(
|
||||
"column",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.streamDeck.column"));
|
||||
AddTempvar(
|
||||
"data",
|
||||
obs_module_text("AdvSceneSwitcher.tempVar.streamDeck.data"),
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.tempVar.streamDeck.data.description"));
|
||||
}
|
||||
|
||||
MacroConditionStreamdeckEdit::MacroConditionStreamdeckEdit(
|
||||
QWidget *parent, std::shared_ptr<MacroConditionStreamdeck> entryData)
|
||||
: QWidget(parent),
|
||||
_checkKeyState(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.checkKeyState"))),
|
||||
_keyState(new QComboBox(this)),
|
||||
_checkPosition(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.checkKeyPosition"))),
|
||||
_row(new VariableSpinBox(this)),
|
||||
_column(new VariableSpinBox(this)),
|
||||
_checkData(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.checkData"))),
|
||||
_data(new VariableTextEdit(this)),
|
||||
_regex(new RegexConfigWidget(this)),
|
||||
_listen(new QPushButton(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.startListen"),
|
||||
this))
|
||||
{
|
||||
_keyState->addItem(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.keyState.pressed"),
|
||||
true);
|
||||
_keyState->addItem(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.keyState.released"),
|
||||
false);
|
||||
|
||||
connect(_checkKeyState, &QCheckBox::stateChanged, this,
|
||||
&MacroConditionStreamdeckEdit::CheckKeyStateChanged);
|
||||
connect(_keyState, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &MacroConditionStreamdeckEdit::KeyStateChanged);
|
||||
connect(_checkPosition, &QCheckBox::stateChanged, this,
|
||||
&MacroConditionStreamdeckEdit::CheckPositionChanged);
|
||||
connect(_row,
|
||||
static_cast<void (VariableSpinBox::*)(const IntVariable &)>(
|
||||
&VariableSpinBox::NumberVariableChanged),
|
||||
this, &MacroConditionStreamdeckEdit::RowChanged);
|
||||
connect(_column,
|
||||
static_cast<void (VariableSpinBox::*)(const IntVariable &)>(
|
||||
&VariableSpinBox::NumberVariableChanged),
|
||||
this, &MacroConditionStreamdeckEdit::ColumnChanged);
|
||||
connect(_checkData, &QCheckBox::stateChanged, this,
|
||||
&MacroConditionStreamdeckEdit::CheckDataChanged);
|
||||
connect(_regex, &RegexConfigWidget::RegexConfigChanged, this,
|
||||
&MacroConditionStreamdeckEdit::RegexChanged);
|
||||
connect(_data, &VariableTextEdit::textChanged, this,
|
||||
&MacroConditionStreamdeckEdit::DataChanged);
|
||||
connect(_listen, &QPushButton::clicked, this,
|
||||
&MacroConditionStreamdeckEdit::ListenClicked);
|
||||
|
||||
auto keyStateLayout = new QHBoxLayout();
|
||||
keyStateLayout->addWidget(_checkKeyState);
|
||||
keyStateLayout->addWidget(_keyState);
|
||||
keyStateLayout->addStretch();
|
||||
|
||||
auto positionLayout = new QHBoxLayout();
|
||||
positionLayout->addWidget(_row);
|
||||
positionLayout->addWidget(_column);
|
||||
|
||||
auto dataLayout = new QHBoxLayout();
|
||||
dataLayout->addWidget(_checkData);
|
||||
dataLayout->addWidget(_regex);
|
||||
dataLayout->addStretch();
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
layout->addLayout(keyStateLayout);
|
||||
layout->addWidget(_checkPosition);
|
||||
layout->addLayout(positionLayout);
|
||||
layout->addLayout(dataLayout);
|
||||
layout->addWidget(_data);
|
||||
layout->addWidget(_listen);
|
||||
layout->addWidget(new QLabel(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.pluginDownload")));
|
||||
setLayout(layout);
|
||||
|
||||
_entryData = entryData;
|
||||
UpdateEntryData();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::UpdateEntryData()
|
||||
{
|
||||
if (!_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
_checkKeyState->setChecked(_entryData->_pattern.checkKeyState);
|
||||
_keyState->setCurrentIndex(
|
||||
_keyState->findData(_entryData->_pattern.keyDown));
|
||||
_checkPosition->setChecked(_entryData->_pattern.checkPosition);
|
||||
_row->SetValue(_entryData->_pattern.row);
|
||||
_column->SetValue(_entryData->_pattern.column);
|
||||
_checkData->setChecked(_entryData->_pattern.checkData);
|
||||
_data->setPlainText(_entryData->_pattern.data);
|
||||
_regex->SetRegexConfig(_entryData->_pattern.regex);
|
||||
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::CheckKeyStateChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.checkKeyState = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::KeyStateChanged(int index)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.keyDown = _keyState->itemData(index).toBool();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::CheckPositionChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.checkPosition = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::RowChanged(const IntVariable &value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.row = value;
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::ColumnChanged(const IntVariable &value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.column = value;
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::CheckDataChanged(int state)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.checkData = state;
|
||||
SetWidgetVisibility();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::RegexChanged(const RegexConfig ®ex)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.regex = regex;
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::DataChanged()
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_pattern.data = _data->toPlainText().toStdString();
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::ListenClicked()
|
||||
{
|
||||
_isListening = !_isListening;
|
||||
|
||||
_keyState->setDisabled(_isListening);
|
||||
_row->setDisabled(_isListening);
|
||||
_column->setDisabled(_isListening);
|
||||
_data->setDisabled(_isListening);
|
||||
_regex->setDisabled(_isListening);
|
||||
|
||||
if (_isListening) {
|
||||
_messageBuffer = RegisterForStreamDeckMessages();
|
||||
_listen->setText(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.stopListen"));
|
||||
} else {
|
||||
_updateListenSettings.stop();
|
||||
_messageBuffer.reset();
|
||||
_listen->setText(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.streamDeck.startListen"));
|
||||
return;
|
||||
}
|
||||
|
||||
connect(&_updateListenSettings, &QTimer::timeout, this, [this]() {
|
||||
if (_messageBuffer->Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StreamDeckMessage lastMessageInBuffer;
|
||||
while (!_messageBuffer->Empty()) {
|
||||
auto message = _messageBuffer->ConsumeMessage();
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
lastMessageInBuffer = *message;
|
||||
}
|
||||
|
||||
_keyState->setCurrentIndex(
|
||||
_keyState->findData(lastMessageInBuffer.keyDown));
|
||||
_row->SetFixedValue(lastMessageInBuffer.row);
|
||||
_column->SetFixedValue(lastMessageInBuffer.column);
|
||||
_data->setPlainText(lastMessageInBuffer.data);
|
||||
});
|
||||
|
||||
_updateListenSettings.start(300);
|
||||
}
|
||||
|
||||
void MacroConditionStreamdeckEdit::SetWidgetVisibility()
|
||||
{
|
||||
_keyState->setVisible(_checkKeyState->isChecked());
|
||||
_row->setVisible(_checkPosition->isChecked());
|
||||
_column->setVisible(_checkPosition->isChecked());
|
||||
_data->setVisible(_checkData->isChecked());
|
||||
_regex->setVisible(_checkData->isChecked());
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
116
plugins/stream-deck/macro-condition-stream-deck.hpp
Normal file
116
plugins/stream-deck/macro-condition-stream-deck.hpp
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#pragma once
|
||||
#include "macro-condition-edit.hpp"
|
||||
#include "message-buffer.hpp"
|
||||
#include "message-dispatcher.hpp"
|
||||
#include "regex-config.hpp"
|
||||
#include "variable-spinbox.hpp"
|
||||
#include "variable-text-edit.hpp"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
namespace advss {
|
||||
|
||||
struct StreamDeckMessage {
|
||||
bool keyDown = true;
|
||||
int row = 0;
|
||||
int column = 0;
|
||||
std::string data = "";
|
||||
};
|
||||
|
||||
using StreamDeckMessageBuffer =
|
||||
std::shared_ptr<MessageBuffer<StreamDeckMessage>>;
|
||||
using StreamDeckMessageDispatcher = MessageDispatcher<StreamDeckMessage>;
|
||||
[[nodiscard]] StreamDeckMessageBuffer RegisterForStreamDeckMessages();
|
||||
|
||||
class MacroConditionStreamdeck : public MacroCondition {
|
||||
public:
|
||||
MacroConditionStreamdeck(Macro *m);
|
||||
bool CheckCondition();
|
||||
bool Save(obs_data_t *obj) const;
|
||||
bool Load(obs_data_t *obj);
|
||||
std::string GetId() const { return id; };
|
||||
static std::shared_ptr<MacroCondition> Create(Macro *m)
|
||||
{
|
||||
return std::make_shared<MacroConditionStreamdeck>(m);
|
||||
}
|
||||
|
||||
struct StreamDeckMessagePattern {
|
||||
void Save(obs_data_t *) const;
|
||||
void Load(obs_data_t *);
|
||||
|
||||
bool checkKeyState = true;
|
||||
bool keyDown = true;
|
||||
bool checkPosition = true;
|
||||
IntVariable row;
|
||||
IntVariable column;
|
||||
bool checkData = true;
|
||||
StringVariable data;
|
||||
RegexConfig regex;
|
||||
};
|
||||
StreamDeckMessagePattern _pattern;
|
||||
|
||||
private:
|
||||
void SetTempVarValues(const StreamDeckMessage &);
|
||||
void SetupTempVars();
|
||||
bool MessageMatches(const StreamDeckMessage &);
|
||||
|
||||
// Keep track of the key state so that the condition can still evaluate
|
||||
// to true while the key is held down.
|
||||
bool _lastMatchingKeyIsStillPressed = false;
|
||||
|
||||
StreamDeckMessageBuffer _messageBuffer;
|
||||
|
||||
static bool _registered;
|
||||
static const std::string id;
|
||||
};
|
||||
|
||||
class MacroConditionStreamdeckEdit : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MacroConditionStreamdeckEdit(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<MacroConditionStreamdeck> cond = nullptr);
|
||||
void UpdateEntryData();
|
||||
static QWidget *Create(QWidget *parent,
|
||||
std::shared_ptr<MacroCondition> cond)
|
||||
{
|
||||
return new MacroConditionStreamdeckEdit(
|
||||
parent,
|
||||
std::dynamic_pointer_cast<MacroConditionStreamdeck>(
|
||||
cond));
|
||||
}
|
||||
|
||||
private slots:
|
||||
void CheckKeyStateChanged(int);
|
||||
void KeyStateChanged(int);
|
||||
void CheckPositionChanged(int);
|
||||
void RowChanged(const IntVariable &);
|
||||
void ColumnChanged(const IntVariable &);
|
||||
void CheckDataChanged(int);
|
||||
void RegexChanged(const RegexConfig &);
|
||||
void DataChanged();
|
||||
void ListenClicked();
|
||||
|
||||
private:
|
||||
void SetWidgetVisibility();
|
||||
|
||||
QCheckBox *_checkKeyState;
|
||||
QComboBox *_keyState;
|
||||
QCheckBox *_checkPosition;
|
||||
VariableSpinBox *_row;
|
||||
VariableSpinBox *_column;
|
||||
QCheckBox *_checkData;
|
||||
VariableTextEdit *_data;
|
||||
RegexConfigWidget *_regex;
|
||||
QPushButton *_listen;
|
||||
|
||||
bool _isListening = false;
|
||||
StreamDeckMessageBuffer _messageBuffer;
|
||||
QTimer _updateListenSettings;
|
||||
|
||||
std::shared_ptr<MacroConditionStreamdeck> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
Loading…
Reference in New Issue
Block a user