Add option to create docks of macros

These docks allow to control the pause state and manual execution of the
macro actions
This commit is contained in:
WarmUpTill 2023-03-23 21:26:36 +01:00 committed by WarmUpTill
parent 9044ae4ade
commit 6f2c53d14e
8 changed files with 208 additions and 4 deletions

View File

@ -221,6 +221,8 @@ target_sources(
src/macro-core/macro-condition-window.hpp
src/macro-core/macro-condition.cpp
src/macro-core/macro-condition.hpp
src/macro-core/macro-dock.cpp
src/macro-core/macro-dock.hpp
src/macro-core/macro-properties.cpp
src/macro-core/macro-properties.hpp
src/macro-core/macro-ref.cpp

View File

@ -95,11 +95,17 @@ AdvSceneSwitcher.macroTab.maximize="Maximize"
AdvSceneSwitcher.macroTab.minimize="Minimize"
AdvSceneSwitcher.macroTab.highlightSettings="Visual settings"
AdvSceneSwitcher.macroTab.hotkeySettings="Hotkey settings"
AdvSceneSwitcher.macroTab.dockSettings="Dock settings"
AdvSceneSwitcher.macroTab.highlightExecutedMacros="Highlight recently executed macros"
AdvSceneSwitcher.macroTab.highlightTrueConditions="Highlight conditions of currently selected macro that evaluated to true recently"
AdvSceneSwitcher.macroTab.highlightPerformedActions="Highlight recently performed actions of currently selected macro"
AdvSceneSwitcher.macroTab.newMacroRegisterHotkey="Register hotkeys to control the pause state of new macros"
AdvSceneSwitcher.macroTab.currentDisableHotkeys="Register hotkeys to control the pause state of selected macro"
AdvSceneSwitcher.macroTab.currentRegisterDock="Register dock widget to control the pause state of selected macro or run it manually"
AdvSceneSwitcher.macroDock.pause="Pause"
AdvSceneSwitcher.macroDock.unpause="Unpause"
AdvSceneSwitcher.macroDock.run="Run"
; Macro List
AdvSceneSwitcher.macroList.deleted="deleted"

View File

@ -0,0 +1,86 @@
#include "macro-dock.hpp"
#include "macro.hpp"
#include "utility.hpp"
#include <QLayout>
#include <obs-module.h>
MacroDock::MacroDock(Macro *m, QWidget *parent)
: OBSDock(parent),
_run(new QPushButton(
obs_module_text("AdvSceneSwitcher.macroDock.run"))),
_pauseToggle(new QPushButton()),
_macro(m)
{
if (_macro) {
setWindowTitle(QString::fromStdString(_macro->Name()));
} else {
setWindowTitle("<deleted macro>");
}
setFeatures(DockWidgetClosable | DockWidgetMovable |
DockWidgetFloatable);
QWidget::connect(_run, SIGNAL(clicked()), this, SLOT(RunClicked()));
QWidget::connect(_pauseToggle, SIGNAL(clicked()), this,
SLOT(PauseToggleClicked()));
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(_run);
layout->addWidget(_pauseToggle);
QWidget::connect(&_timer, SIGNAL(timeout()), this,
SLOT(UpdatePauseText()));
_timer.start(1000);
UpdatePauseText();
// QFrame wrapper is necessary to avoid dock being partially
// transparent
QFrame *wrapper = new QFrame;
wrapper->setFrameShape(QFrame::StyledPanel);
wrapper->setFrameShadow(QFrame::Sunken);
wrapper->setLayout(layout);
setWidget(wrapper);
}
void MacroDock::SetName(const QString &name)
{
setWindowTitle(name);
}
void MacroDock::RunClicked()
{
if (!_macro) {
return;
}
auto ret = _macro->PerformActions();
if (!ret) {
QString err =
obs_module_text("AdvSceneSwitcher.macroTab.runFail");
DisplayMessage(err.arg(QString::fromStdString(_macro->Name())));
}
}
void MacroDock::PauseToggleClicked()
{
if (!_macro) {
return;
}
_macro->SetPaused(!_macro->Paused());
UpdatePauseText();
}
void MacroDock::UpdatePauseText()
{
if (!_macro) {
return;
}
_pauseToggle->setText(
_macro->Paused()
? obs_module_text("AdvSceneSwitcher.macroDock.unpause")
: obs_module_text("AdvSceneSwitcher.macroDock.pause"));
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "obs-dock.hpp"
#include <QPushButton>
#include <QTimer>
#include <memory>
class Macro;
class MacroDock : public OBSDock {
Q_OBJECT
public:
MacroDock(Macro *, QWidget *parent);
void SetName(const QString &);
private slots:
void RunClicked();
void PauseToggleClicked();
void UpdatePauseText();
private:
QPushButton *_run;
QPushButton *_pauseToggle;
QTimer _timer;
Macro *_macro;
};

View File

@ -41,7 +41,9 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
_newMacroRegisterHotkeys(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.macroTab.newMacroRegisterHotkey"))),
_currentMacroRegisterHotkeys(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.macroTab.currentDisableHotkeys")))
"AdvSceneSwitcher.macroTab.currentDisableHotkeys"))),
_currentMacroRegisterDock(new QCheckBox(obs_module_text(
"AdvSceneSwitcher.macroTab.currentRegisterDock")))
{
setModal(true);
setWindowModality(Qt::WindowModality::WindowModal);
@ -64,6 +66,12 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
hotkeyLayout->addWidget(_currentMacroRegisterHotkeys);
hotkeyOptions->setLayout(hotkeyLayout);
auto dockOptions = new QGroupBox(
obs_module_text("AdvSceneSwitcher.macroTab.dockSettings"));
QVBoxLayout *dockLayout = new QVBoxLayout;
dockLayout->addWidget(_currentMacroRegisterDock);
dockOptions->setLayout(dockLayout);
QDialogButtonBox *buttonbox = new QDialogButtonBox(
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
buttonbox->setCenterButtons(true);
@ -73,6 +81,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(highlightOptions);
layout->addWidget(hotkeyOptions);
layout->addWidget(dockOptions);
layout->addWidget(buttonbox);
setLayout(layout);
@ -83,8 +92,10 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
if (macro && !macro->IsGroup()) {
_currentMacroRegisterHotkeys->setChecked(
macro->PauseHotkeysEnabled());
_currentMacroRegisterDock->setChecked(macro->DockEnabled());
} else {
hotkeyOptions->hide();
dockOptions->hide();
}
}
@ -102,9 +113,12 @@ bool MacroPropertiesDialog::AskForSettings(QWidget *parent,
userInput._highlightActions = dialog._actions->isChecked();
userInput._newMacroRegisterHotkeys =
dialog._newMacroRegisterHotkeys->isChecked();
if (macro) {
macro->EnablePauseHotkeys(
dialog._currentMacroRegisterHotkeys->isChecked());
if (!macro) {
return true;
}
macro->EnablePauseHotkeys(
dialog._currentMacroRegisterHotkeys->isChecked());
macro->EnableDock(dialog._currentMacroRegisterDock->isChecked());
return true;
}

View File

@ -34,4 +34,5 @@ private:
QCheckBox *_newMacroRegisterHotkeys;
// Current macro specific settings
QCheckBox *_currentMacroRegisterHotkeys;
QCheckBox *_currentMacroRegisterDock;
};

View File

@ -1,6 +1,7 @@
#include "macro.hpp"
#include "macro-action-edit.hpp"
#include "macro-condition-edit.hpp"
#include "macro-dock.hpp"
#include "macro-action-scene-switch.hpp"
#include "advanced-scene-switcher.hpp"
#include "hotkey.hpp"
@ -9,6 +10,7 @@
#undef max
#include <chrono>
#include <unordered_map>
#include <QMainWindow>
constexpr int perfLogThreshold = 300;
@ -26,6 +28,7 @@ Macro::~Macro()
_die = true;
Stop();
ClearHotkeys();
RemoveDock();
}
std::shared_ptr<Macro>
@ -227,6 +230,7 @@ void Macro::SetName(const std::string &name)
{
_name = name;
SetHotkeysDesc();
SetDockWidgetName();
}
void Macro::ResetTimers()
@ -337,6 +341,12 @@ bool Macro::Save(obs_data_t *obj) const
return true;
}
obs_data_set_bool(obj, "registerDock", _registerDock);
// The object name is used to restore the position of the dock
if (_registerDock) {
SetDockWidgetName();
}
obs_data_set_bool(obj, "registerHotkeys", _registerHotkeys);
obs_data_array_t *pauseHotkey = obs_hotkey_save(_pauseHotkey);
obs_data_set_array(obj, "pauseHotkey", pauseHotkey);
@ -426,6 +436,8 @@ bool Macro::Load(obs_data_t *obj)
return true;
}
EnableDock(obs_data_get_bool(obj, "registerDock"));
obs_data_set_default_bool(obj, "registerHotkeys", true);
_registerHotkeys = obs_data_get_bool(obj, "registerHotkeys");
if (_registerHotkeys) {
@ -567,6 +579,51 @@ bool Macro::PauseHotkeysEnabled()
return _registerHotkeys;
}
void Macro::EnableDock(bool value)
{
if (_registerDock == value) {
return;
}
RemoveDock();
if (!_registerDock) {
_dock = new MacroDock(this,
static_cast<QMainWindow *>(
obs_frontend_get_main_window()));
_dockAction =
static_cast<QAction *>(obs_frontend_add_dock(_dock));
SetDockWidgetName();
}
_registerDock = value;
}
void Macro::RemoveDock()
{
if (_dock) {
_dock->close();
_dock->deleteLater();
_dockAction->deleteLater();
_dock = nullptr;
_dockAction = nullptr;
}
}
void Macro::SetDockWidgetName() const
{
if (!_dock) {
return;
}
// Set prefix to avoid dock name conflict
_dock->setObjectName("ADVSS-" + QString::fromStdString(_name));
_dock->SetName(QString::fromStdString(_name));
if (!_dockAction) {
return;
}
_dockAction->setText(QString::fromStdString(_name));
}
static void pauseCB(void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed)
{
if (pressed) {

View File

@ -14,6 +14,8 @@
constexpr auto macro_func = 10;
class MacroDock;
class Macro {
public:
Macro(const std::string &name = "", const bool addHotkey = false);
@ -78,6 +80,9 @@ public:
void EnablePauseHotkeys(bool);
bool PauseHotkeysEnabled();
void EnableDock(bool);
bool DockEnabled() { return _registerDock; }
void ResetTimers();
private:
@ -87,6 +92,8 @@ private:
void RunActions(bool &ret, bool ignorePause);
void RunActions(bool ignorePause);
void SetOnChangeHighlight();
void SetDockWidgetName() const;
void RemoveDock();
std::string _name = "";
std::deque<std::shared_ptr<MacroCondition>> _conditions;
@ -111,6 +118,9 @@ private:
bool _isCollapsed = false;
bool _wasExecutedRecently = false;
bool _onChangeTriggered = false;
bool _registerDock = false;
MacroDock *_dock = nullptr;
QAction *_dockAction = nullptr;
std::chrono::high_resolution_clock::time_point _lastCheckTime{};