Add option to highlight recently executed macros on the Macro tab

This commit is contained in:
WarmUpTill 2022-01-30 22:17:41 +01:00 committed by WarmUpTill
parent dc698e426d
commit 1e7726bcfc
8 changed files with 135 additions and 60 deletions

View File

@ -32,6 +32,7 @@ AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system t
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
AdvSceneSwitcher.generalTab.generalBehavior.verticalMacroControls="Use permanent vertical controls on Macro tab"
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
AdvSceneSwitcher.generalTab.generalBehavior.highlightExecutedMacros="Highlight recently executed macros"
AdvSceneSwitcher.generalTab.priority="Priority"
AdvSceneSwitcher.generalTab.priority.description="Switching methods priority (Highest priority is at the top)"
AdvSceneSwitcher.generalTab.priority.threadPriority="Use thread priority"

View File

@ -349,6 +349,30 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_26">
<item>
<widget class="QCheckBox" name="highlightExecutedMacros">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.highlightExecutedMacros</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_19">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_24">
<item>

View File

@ -202,6 +202,15 @@ void AdvSceneSwitcher::on_useVerticalMacroControls_stateChanged(int state)
setupMacroTab();
}
void AdvSceneSwitcher::on_highlightExecutedMacros_stateChanged(int state)
{
if (loading) {
return;
}
switcher->highlightExecutedMacros = state;
}
bool isLegacyTab(const QString &name)
{
return name == obs_module_text(
@ -565,6 +574,8 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
obs_data_set_bool(obj, "disableHints", disableHints);
obs_data_set_bool(obj, "useVerticalMacroControls",
useVerticalMacroControls);
obs_data_set_bool(obj, "highlightExecutedMacros",
highlightExecutedMacros);
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
@ -641,6 +652,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
disableHints = obs_data_get_bool(obj, "disableHints");
useVerticalMacroControls =
obs_data_get_bool(obj, "useVerticalMacroControls");
highlightExecutedMacros =
obs_data_get_bool(obj, "highlightExecutedMacros");
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
obs_data_set_default_int(obj, "priority0", default_priority_0);
@ -857,6 +870,8 @@ void AdvSceneSwitcher::setupGeneralTab()
ui->uiHintsDisable->setChecked(switcher->disableHints);
ui->useVerticalMacroControls->setChecked(
switcher->useVerticalMacroControls);
ui->highlightExecutedMacros->setChecked(
switcher->highlightExecutedMacros);
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
for (int p : switcher->functionNamesByPriority) {

View File

@ -117,7 +117,6 @@ public slots:
void on_runMacroInParallel_stateChanged(int value);
void on_runMacroOnChange_stateChanged(int value);
void on_macros_currentRowChanged(int idx);
void on_macros_itemChanged(QListWidgetItem *);
void on_conditionAdd_clicked();
void on_conditionRemove_clicked();
void on_actionAdd_clicked();
@ -140,6 +139,7 @@ public slots:
void RemoveMacroCondition(int idx);
void MoveMacroConditionUp(int idx);
void MoveMacroConditionDown(int idx);
void HighlightMatchedMacros();
void on_screenRegionSwitches_currentRowChanged(int idx);
void on_showFrame_clicked();
@ -171,6 +171,7 @@ public slots:
void on_showTrayNotifications_stateChanged(int state);
void on_uiHintsDisable_stateChanged(int state);
void on_useVerticalMacroControls_stateChanged(int state);
void on_highlightExecutedMacros_stateChanged(int state);
void on_hideLegacyTabs_stateChanged(int state);
void on_exportSettings_clicked();

View File

@ -106,6 +106,9 @@ public:
// Helper function for plugin state condition regarding scene change
bool SwitchesScene();
// UI helpers for the macro tab
bool WasExecutedRecently();
private:
void SetupHotkeys();
void ClearHotkeys();
@ -127,6 +130,8 @@ private:
obs_hotkey_id _unpauseHotkey = OBS_INVALID_HOTKEY_ID;
obs_hotkey_id _togglePauseHotkey = OBS_INVALID_HOTKEY_ID;
bool _wasExecutedRecently = false;
bool _die = false;
bool _stop = false;
bool _done = true;

View File

@ -88,6 +88,7 @@ struct SwitcherData {
bool disableHints = false;
bool useVerticalMacroControls = false;
bool hideLegacyTabs = false;
bool highlightExecutedMacros = false;
bool showSystemTrayNotifications = false;
bool showFrame = false;
bool transitionOverrideOverride = false;

View File

@ -1,4 +1,5 @@
#include "headers/macro.hpp"
#include "headers/macro-list-entry-widget.hpp"
#include "headers/macro-action-edit.hpp"
#include "headers/macro-condition-edit.hpp"
#include "headers/advanced-scene-switcher.hpp"
@ -8,6 +9,7 @@
#include <QColor>
#include <QMenu>
static QTimer highlightMatchTimer;
static QMetaObject::Connection addPulse;
bool macroNameExists(std::string name)
@ -52,6 +54,17 @@ bool AdvSceneSwitcher::addNewMacro(std::string &name)
return true;
}
QListWidgetItem *AddNewMacroListEntry(QListWidget *list,
std::shared_ptr<Macro> &macro)
{
QListWidgetItem *item = new QListWidgetItem(list);
item->setData(Qt::UserRole, QString::fromStdString(macro->Name()));
auto listEntry = new MacroListEntryWidget(macro, list);
item->setSizeHint(listEntry->minimumSizeHint());
list->setItemWidget(item, listEntry);
return item;
}
void AdvSceneSwitcher::on_macroAdd_clicked()
{
std::string name;
@ -60,10 +73,7 @@ void AdvSceneSwitcher::on_macroAdd_clicked()
}
QString text = QString::fromStdString(name);
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
item->setData(Qt::UserRole, text);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Checked);
auto item = AddNewMacroListEntry(ui->macros, switcher->macros.back());
ui->macros->setCurrentItem(item);
ui->macroAdd->disconnect(addPulse);
@ -102,34 +112,44 @@ void AdvSceneSwitcher::on_macroRemove_clicked()
void AdvSceneSwitcher::on_macroUp_clicked()
{
std::lock_guard<std::mutex> lock(switcher->m);
int index = ui->macros->currentRow();
if (index != -1 && index != 0) {
ui->macros->insertItem(index - 1, ui->macros->takeItem(index));
ui->macros->setCurrentRow(index - 1);
if (!listMoveUp(ui->macros)) {
return;
}
iter_swap(switcher->macros.begin() + index,
switcher->macros.begin() + index - 1);
int index = ui->macros->currentRow() + 1;
auto *entry1 = static_cast<MacroListEntryWidget *>(
ui->macros->itemWidget(ui->macros->item(index)));
auto *entry2 = static_cast<MacroListEntryWidget *>(
ui->macros->itemWidget(ui->macros->item(index - 1)));
entry1->SetMacro(*(switcher->macros.begin() + index - 1));
entry2->SetMacro(*(switcher->macros.begin() + index));
iter_swap(switcher->macros.begin() + index,
switcher->macros.begin() + index - 1);
for (auto &m : switcher->macros) {
m->ResolveMacroRef();
}
for (auto &m : switcher->macros) {
m->ResolveMacroRef();
}
}
void AdvSceneSwitcher::on_macroDown_clicked()
{
std::lock_guard<std::mutex> lock(switcher->m);
int index = ui->macros->currentRow();
if (index != -1 && index != ui->macros->count() - 1) {
ui->macros->insertItem(index + 1, ui->macros->takeItem(index));
ui->macros->setCurrentRow(index + 1);
if (!listMoveDown(ui->macros)) {
return;
}
iter_swap(switcher->macros.begin() + index,
switcher->macros.begin() + index + 1);
int index = ui->macros->currentRow() - 1;
auto *entry1 = static_cast<MacroListEntryWidget *>(
ui->macros->itemWidget(ui->macros->item(index)));
auto *entry2 = static_cast<MacroListEntryWidget *>(
ui->macros->itemWidget(ui->macros->item(index + 1)));
entry1->SetMacro(*(switcher->macros.begin() + index + 1));
entry2->SetMacro(*(switcher->macros.begin() + index));
iter_swap(switcher->macros.begin() + index,
switcher->macros.begin() + index + 1);
for (auto &m : switcher->macros) {
m->ResolveMacroRef();
}
for (auto &m : switcher->macros) {
m->ResolveMacroRef();
}
}
@ -160,11 +180,10 @@ void AdvSceneSwitcher::on_macroName_editingFinished()
if (nameValid) {
macro->SetName(newName.toUtf8().constData());
QListWidgetItem *item = ui->macros->currentItem();
// Don't trigger itemChanged()
// pause state remains as is
ui->macros->blockSignals(true);
item->setText(newName);
ui->macros->blockSignals(false);
item->setData(Qt::UserRole, newName);
auto listEntry = static_cast<MacroListEntryWidget *>(
ui->macros->itemWidget(item));
listEntry->SetName(newName);
} else {
ui->macroName->setText(oldName);
}
@ -313,7 +332,7 @@ Macro *AdvSceneSwitcher::getSelectedMacro()
return nullptr;
}
QString name = item->text();
QString name = item->data(Qt::UserRole).toString();
return GetMacroByQString(name);
}
@ -329,7 +348,7 @@ void AdvSceneSwitcher::on_macros_currentRowChanged(int idx)
}
QListWidgetItem *item = ui->macros->item(idx);
QString macroName = item->text();
QString macroName = item->data(Qt::UserRole).toString();
auto macro = GetMacroByQString(macroName);
if (macro) {
@ -337,36 +356,12 @@ void AdvSceneSwitcher::on_macros_currentRowChanged(int idx)
}
}
void AdvSceneSwitcher::on_macros_itemChanged(QListWidgetItem *item)
{
if (loading) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
QString name = item->text();
auto m = GetMacroByQString(name);
if (m) {
m->SetPaused(item->checkState() != Qt::Checked);
}
}
void AdvSceneSwitcher::setupMacroTab()
{
const QSignalBlocker signalBlocker(ui->macros);
ui->macros->clear();
for (auto &m : switcher->macros) {
QString text = QString::fromStdString(m->Name());
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
item->setData(Qt::UserRole, text);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
if (m->Paused()) {
item->setCheckState(Qt::Unchecked);
} else {
item->setCheckState(Qt::Checked);
}
AddNewMacroListEntry(ui->macros, m);
}
if (switcher->macros.size() == 0) {
@ -392,6 +387,11 @@ void AdvSceneSwitcher::setupMacroTab()
ui->macroPriorityWarning->setVisible(
switcher->functionNamesByPriority[0] != macro_func);
highlightMatchTimer.setInterval(1000);
connect(&highlightMatchTimer, &QTimer::timeout, this,
&AdvSceneSwitcher::HighlightMatchedMacros);
highlightMatchTimer.start();
}
void AdvSceneSwitcher::ShowMacroContextMenu(const QPoint &pos)
@ -442,11 +442,7 @@ void AdvSceneSwitcher::CopyMacro()
switcher->macros.back()->SetName(name);
obs_data_release(data);
QString text = QString::fromStdString(name);
QListWidgetItem *item = new QListWidgetItem(text, ui->macros);
item->setData(Qt::UserRole, text);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(Qt::Checked);
auto item = AddNewMacroListEntry(ui->macros, switcher->macros.back());
ui->macros->setCurrentItem(item);
}
@ -521,3 +517,25 @@ void AdvSceneSwitcher::MinimizeConditions()
sizes[1] = sum - conditionsHeight;
ui->macroSplitter->setSizes(sizes);
}
void AdvSceneSwitcher::HighlightMatchedMacros()
{
if (loading || !(switcher && switcher->highlightExecutedMacros)) {
return;
}
for (int idx = 0; idx < (int)switcher->macros.size(); idx++) {
if (switcher->macros[idx]->WasExecutedRecently()) {
auto item = ui->macros->item(idx);
if (!item) {
continue;
}
auto widget = ui->macros->itemWidget(item);
if (!widget) {
continue;
}
PulseWidget(widget, Qt::green, QColor(0, 0, 0, 0),
true);
}
}
}

View File

@ -133,6 +133,7 @@ bool Macro::PerformAction(bool forceParallel, bool ignorePause)
} else {
RunActions(ret, ignorePause);
}
_wasExecutedRecently = true;
return ret;
}
@ -382,6 +383,15 @@ bool Macro::SwitchesScene()
return false;
}
bool Macro::WasExecutedRecently()
{
if (_wasExecutedRecently) {
_wasExecutedRecently = false;
return true;
}
return false;
}
static void pauseCB(void *data, obs_hotkey_id, obs_hotkey_t *, bool pressed)
{
if (pressed) {