Compare commits

...

9 Commits

Author SHA1 Message Date
WarmUpTill
9bedbf6fb8 Display warning if plugin could not be loaded 2023-04-11 03:55:30 -07:00
WarmUpTill
853150e458 Resize MacroPropertiesDialog to fit contents 2023-04-11 03:55:30 -07:00
WarmUpTill
1ddd48e008 Improve dock handling when changing scene collections
Note that the positions of the docks will still not be restored
perfectly when changing scene collections.
To my understanding this would somehow have to be handled by the
QMainWindow which is controlled by OBS.

This might have to be revisited at a later date.
2023-04-11 03:55:30 -07:00
WarmUpTill
17d24d642e Add more error handling for reordering macros 2023-04-11 03:55:30 -07:00
WarmUpTill
87a46684cd Remove "Studio mode" backwards compatabilty fallback
This should remove the frequent logs of complaining about a name
conflict between different action types.
2023-04-11 03:55:30 -07:00
WarmUpTill
e4c5193945 CI: Use git tag as version identifier in packaging step 2023-04-11 03:55:30 -07:00
WarmUpTill
2e969bf6dd Fix video condition's pattern match mode not loading correctly 2023-04-11 03:55:30 -07:00
WarmUpTill
6db26d9f7b Fix crash when using OCR check of video condition 2023-04-11 03:55:30 -07:00
WarmUpTill
4f02c9ec36 Ask for confirmation even if only a single macro is being deleted 2023-04-06 00:36:07 -07:00
19 changed files with 262 additions and 69 deletions

View File

@@ -170,11 +170,17 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
local product_name
local product_version
local git_tag="$(git describe --tags)"
read -r product_name product_version <<< \
"$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
log_info "Using git tag as version identifier '${git_tag}'"
product_version="${git_tag}"
} else {
log_info "Using buildspec.json version identifier '${product_version}'"
}
case ${host_os} {
macos)

View File

@@ -128,9 +128,18 @@ Usage: %B${functrace[1]%:*}%b <option> [<options>]
local product_name
local product_version
local git_tag="$(git describe --tags)"
read -r product_name product_version <<< \
"$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
if [[ "${git_tag}" =~ '^([0-9]+\.){0,2}(\*|[0-9]+)$' ]] {
log_info "Using git tag as version identifier '${git_tag}'"
product_version="${git_tag}"
} else {
log_info "Using buildspec.json version identifier '${product_version}'"
}
if [[ ${host_os} == 'macos' ]] {
autoload -Uz check_packages read_codesign read_codesign_installer read_codesign_pass

View File

@@ -30,6 +30,8 @@ AdvSceneSwitcher.generalTab.generalBehavior.verboseLogging="Enable verbose loggi
AdvSceneSwitcher.generalTab.generalBehavior.saveWindowGeo="Save window position and size"
AdvSceneSwitcher.generalTab.generalBehavior.showTrayNotifications="Show system tray notifications"
AdvSceneSwitcher.generalTab.generalBehavior.disableUIHints="Disable UI hints"
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure="Display warning if plugins cannot be loaded"
AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage="<html><body>Loading of the following plugin libraries was unsuccessful, which could result in some Advanced Scene Switcher functions not being available:%1Check the OBS logs for details.<br>This message can be disabled on the General tab.</body></html>"
AdvSceneSwitcher.generalTab.generalBehavior.hideLegacyTabs="Hide tabs which can be represented via macros"
AdvSceneSwitcher.generalTab.matchBehavior="Match behavior"
AdvSceneSwitcher.generalTab.priority="Priority"
@@ -83,6 +85,7 @@ AdvSceneSwitcher.macroTab.defaultGroupName="Group %1"
AdvSceneSwitcher.macroTab.exists="Macro name exists already"
AdvSceneSwitcher.macroTab.groupDeleteConfirm="Are you sure you want to delete \"%1\" and all its elements?"
AdvSceneSwitcher.macroTab.deleteMultipleMacrosConfirmation="Are you sure you want to delete %1 macros?"
AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation="Are you sure you want to delete \"%1\"?"
AdvSceneSwitcher.macroTab.contextMenuAdd="Add"
AdvSceneSwitcher.macroTab.copy="Duplicate Macro"
AdvSceneSwitcher.macroTab.group="Group Selected Macros"

View File

@@ -256,6 +256,30 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_26">
<item>
<widget class="QCheckBox" name="warnPluginLoadFailure">
<property name="text">
<string>AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailure</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

@@ -43,9 +43,7 @@ AdvSceneSwitcher::AdvSceneSwitcher(QWidget *parent)
{
switcher->settingsWindowOpened = true;
ui->setupUi(this);
std::lock_guard<std::mutex> lock(switcher->m);
switcher->Prune();
loadUI();
}
@@ -58,26 +56,51 @@ AdvSceneSwitcher::~AdvSceneSwitcher()
}
}
bool translationAvailable()
static bool translationAvailable()
{
return !!strcmp(obs_module_text("AdvSceneSwitcher.pluginName"),
"AdvSceneSwitcher.pluginName");
}
static void DisplayMissingDependencyWarning()
{
if (!switcher->warnPluginLoadFailure ||
switcher->loadFailureLibs.isEmpty()) {
return;
}
QString failedLibsString = "<ul>";
for (const auto &lib : switcher->loadFailureLibs) {
failedLibsString += "<li>" + lib + "</li>";
}
failedLibsString += "</ul>";
QString warning(obs_module_text(
"AdvSceneSwitcher.generalTab.generalBehavior.warnPluginLoadFailureMessage"));
DisplayMessage(warning.arg(failedLibsString));
}
static void DisplayMissingDataDirWarning()
{
if (translationAvailable()) {
return;
}
QString msg = "Failed to find plug-in's 'data' directory.\n"
"Please check installation instructions!\n\n"
"Data most likely expected at:\n\n";
#ifdef _WIN32
msg += QString::fromStdString(
(std::filesystem::current_path().string()));
msg += "/";
#endif
msg += obs_get_module_data_path(obs_current_module());
DisplayMessage(msg);
}
void AdvSceneSwitcher::loadUI()
{
if (!translationAvailable()) {
QString msg = "Failed to find plug-in's 'data' directory.\n"
"Please check installation instructions!\n\n"
"Data most likely expected at:\n\n";
#ifdef _WIN32
msg += QString::fromStdString(
(std::filesystem::current_path().string()));
msg += "/";
#endif
msg += obs_get_module_data_path(obs_current_module());
(void)DisplayMessage(msg);
}
DisplayMissingDataDirWarning();
DisplayMissingDependencyWarning();
setupGeneralTab();
setupTitleTab();
@@ -687,6 +710,7 @@ void LoadPlugins()
blog(LOG_WARNING, "failed to load \"%s\": %s",
file.toStdString().c_str(),
lib->errorString().toStdString().c_str());
switcher->loadFailureLibs << file;
}
}
}

View File

@@ -202,6 +202,7 @@ public slots:
void on_saveWindowGeo_stateChanged(int state);
void on_showTrayNotifications_stateChanged(int state);
void on_uiHintsDisable_stateChanged(int state);
void on_warnPluginLoadFailure_stateChanged(int state);
void on_hideLegacyTabs_stateChanged(int state);
void on_exportSettings_clicked();

View File

@@ -172,6 +172,15 @@ void AdvSceneSwitcher::on_uiHintsDisable_stateChanged(int state)
switcher->disableHints = state;
}
void AdvSceneSwitcher::on_warnPluginLoadFailure_stateChanged(int state)
{
if (loading) {
return;
}
switcher->warnPluginLoadFailure = state;
}
bool isLegacyTab(const QString &name)
{
return name == obs_module_text(
@@ -617,6 +626,7 @@ void SwitcherData::saveGeneralSettings(obs_data_t *obj)
obs_data_set_bool(obj, "showSystemTrayNotifications",
showSystemTrayNotifications);
obs_data_set_bool(obj, "disableHints", disableHints);
obs_data_set_bool(obj, "warnPluginLoadFailure", warnPluginLoadFailure);
obs_data_set_bool(obj, "hideLegacyTabs", hideLegacyTabs);
obs_data_set_int(obj, "priority0", functionNamesByPriority[0]);
@@ -673,6 +683,8 @@ void SwitcherData::loadGeneralSettings(obs_data_t *obj)
showSystemTrayNotifications =
obs_data_get_bool(obj, "showSystemTrayNotifications");
disableHints = obs_data_get_bool(obj, "disableHints");
obs_data_set_default_bool(obj, "warnPluginLoadFailure", true);
warnPluginLoadFailure = obs_data_get_bool(obj, "warnPluginLoadFailure");
obs_data_set_default_bool(obj, "hideLegacyTabs", true);
hideLegacyTabs = obs_data_get_bool(obj, "hideLegacyTabs");
@@ -971,6 +983,7 @@ void AdvSceneSwitcher::setupGeneralTab()
ui->showTrayNotifications->setChecked(
switcher->showSystemTrayNotifications);
ui->uiHintsDisable->setChecked(switcher->disableHints);
ui->warnPluginLoadFailure->setChecked(switcher->warnPluginLoadFailure);
ui->hideLegacyTabs->setChecked(switcher->hideLegacyTabs);
for (int p : switcher->functionNamesByPriority) {

View File

@@ -9,16 +9,6 @@ bool MacroActionSudioMode::_registered = MacroActionFactory::Register(
{MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
"AdvSceneSwitcher.action.studioMode"});
// TODO: Remove in future version (backwards compatibility)
static const std::string idOld1 = "scene_swap";
static const std::string idOld2 = "preview_scene";
static bool oldRegisterd1 = MacroActionFactory::Register(
idOld1, {MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
"AdvSceneSwitcher.action.studioMode"});
static bool oldRegisterd2 = MacroActionFactory::Register(
idOld2, {MacroActionSudioMode::Create, MacroActionSudioModeEdit::Create,
"AdvSceneSwitcher.action.studioMode"});
const static std::map<StudioModeAction, std::string> actionTypes = {
{StudioModeAction::SWAP_SCENE,
"AdvSceneSwitcher.action.studioMode.type.swap"},
@@ -98,10 +88,6 @@ bool MacroActionSudioMode::Load(obs_data_t *obj)
_action =
static_cast<StudioModeAction>(obs_data_get_int(obj, "action"));
_scene.Load(obj);
// TODO: Remove in future version (backwards compatibility)
if (obs_data_get_string(obj, "id") == idOld2) {
_action = StudioModeAction::SET_SCENE;
}
return true;
}

View File

@@ -44,6 +44,9 @@ MacroDock::MacroDock(Macro *m, QWidget *parent)
wrapper->setFrameShadow(QFrame::Sunken);
wrapper->setLayout(layout);
setWidget(wrapper);
setFloating(true);
hide();
}
void MacroDock::SetName(const QString &name)

View File

@@ -1,7 +1,6 @@
#include "macro-properties.hpp"
#include <QVBoxLayout>
#include <QGroupBox>
#include <QDialogButtonBox>
#include <obs-module.h>
@@ -52,8 +51,6 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
setModal(true);
setWindowModality(Qt::WindowModality::WindowModal);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setMinimumWidth(500);
setMinimumHeight(300);
auto highlightOptions = new QGroupBox(
obs_module_text("AdvSceneSwitcher.macroTab.highlightSettings"));
@@ -70,13 +67,13 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
hotkeyLayout->addWidget(_currentMacroRegisterHotkeys);
hotkeyOptions->setLayout(hotkeyLayout);
auto dockOptions = new QGroupBox(
_dockOptions = new QGroupBox(
obs_module_text("AdvSceneSwitcher.macroTab.dockSettings"));
QVBoxLayout *dockLayout = new QVBoxLayout;
dockLayout->addWidget(_currentMacroRegisterDock);
dockLayout->addWidget(_currentMacroDockAddRunButton);
dockLayout->addWidget(_currentMacroDockAddPauseButton);
dockOptions->setLayout(dockLayout);
_dockOptions->setLayout(dockLayout);
QDialogButtonBox *buttonbox = new QDialogButtonBox(
QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
@@ -90,7 +87,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(highlightOptions);
layout->addWidget(hotkeyOptions);
layout->addWidget(dockOptions);
layout->addWidget(_dockOptions);
layout->addWidget(buttonbox);
setLayout(layout);
@@ -100,7 +97,7 @@ MacroPropertiesDialog::MacroPropertiesDialog(QWidget *parent,
_newMacroRegisterHotkeys->setChecked(prop._newMacroRegisterHotkeys);
if (!macro || macro->IsGroup()) {
hotkeyOptions->hide();
dockOptions->hide();
_dockOptions->hide();
return;
}
_currentMacroRegisterHotkeys->setChecked(macro->PauseHotkeysEnabled());
@@ -117,6 +114,10 @@ void MacroPropertiesDialog::DockEnableChanged(int enabled)
{
_currentMacroDockAddRunButton->setVisible(enabled);
_currentMacroDockAddPauseButton->setVisible(enabled);
_dockOptions->adjustSize();
_dockOptions->updateGeometry();
adjustSize();
updateGeometry();
}
bool MacroPropertiesDialog::AskForSettings(QWidget *parent,

View File

@@ -4,6 +4,7 @@
#include <QWidget>
#include <QDialog>
#include <QCheckBox>
#include <QGroupBox>
#include <obs-data.h>
class MacroProperties {
@@ -39,4 +40,5 @@ private:
QCheckBox *_currentMacroRegisterDock;
QCheckBox *_currentMacroDockAddRunButton;
QCheckBox *_currentMacroDockAddPauseButton;
QGroupBox *_dockOptions;
};

View File

@@ -125,6 +125,13 @@ void AdvSceneSwitcher::on_macroRemove_clicked()
}
if (macros.size() == 1) {
QString deleteWarning = obs_module_text(
"AdvSceneSwitcher.macroTab.deleteSingleMacroConfirmation");
if (!DisplayMessage(deleteWarning.arg(QString::fromStdString(
macros.at(0)->Name())),
true)) {
return;
}
RemoveMacro(macros.at(0));
return;
}

View File

@@ -245,7 +245,7 @@ MacroIndexToModelIndex(int realIdx,
inCollapsedGroup = false;
continue;
}
const auto &m = macros[i];
const auto &m = macros.at(i);
inCollapsedGroup = m->IsGroup() && m->IsCollapsed();
groupSize = m->GroupSize();
modelIdx++;
@@ -256,15 +256,24 @@ MacroIndexToModelIndex(int realIdx,
void MacroTreeModel::MoveItemBefore(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &before)
{
if (item == before) {
if (!item || !before || item == before) {
return;
}
auto modelFromEndIdx = GetItemModelIndex(item);
auto modelFromIdx = modelFromEndIdx;
auto modelTo = GetItemModelIndex(before);
auto macroFrom = GetItemMacroIndex(item);
auto macroTo = GetItemMacroIndex(before);
int modelFromIdx = 0, modelFromEndIdx = 0, modelTo = 0, macroFrom = 0,
macroTo = 0;
try {
modelFromEndIdx = GetItemModelIndex(item);
modelFromIdx = modelFromEndIdx;
modelTo = GetItemModelIndex(before);
macroFrom = GetItemMacroIndex(item);
macroTo = GetItemMacroIndex(before);
} catch (const std::out_of_range &) {
blog(LOG_WARNING,
"error while trying to move item \"%s\" before \"%s\"",
item->Name().c_str(), before->Name().c_str());
return;
}
if (before->IsSubitem()) {
modelTo -= before->IsCollapsed() ? 0 : before->GroupSize();
@@ -300,15 +309,24 @@ void MacroTreeModel::MoveItemBefore(const std::shared_ptr<Macro> &item,
void MacroTreeModel::MoveItemAfter(const std::shared_ptr<Macro> &item,
const std::shared_ptr<Macro> &after)
{
if (item == after) {
if (!item || !after || item == after) {
return;
}
auto modelFromIdx = GetItemModelIndex(item);
auto modelFromEndIdx = modelFromIdx;
auto modelTo = GetItemModelIndex(after);
auto macroFrom = GetItemMacroIndex(item);
auto macroTo = GetItemMacroIndex(after);
int modelFromIdx = 0, modelFromEndIdx = 0, modelTo = 0, macroFrom = 0,
macroTo = 0;
try {
modelFromIdx = GetItemModelIndex(item);
modelFromEndIdx = modelFromIdx;
modelTo = GetItemModelIndex(after);
macroFrom = GetItemMacroIndex(item);
macroTo = GetItemMacroIndex(after);
} catch (const std::out_of_range &) {
blog(LOG_WARNING,
"error while trying to move item \"%s\" after \"%s\"",
item->Name().c_str(), after->Name().c_str());
return;
}
if (after->IsGroup()) {
modelTo += after->IsCollapsed() ? 0 : after->GroupSize();

View File

@@ -267,6 +267,11 @@ void Macro::SetOnChangeHighlight()
_onChangeTriggered = true;
}
bool Macro::DockIsVisible() const
{
return _dock && _dockAction && _dock->isVisible();
}
void Macro::SetPaused(bool pause)
{
if (_paused && !pause) {
@@ -341,13 +346,7 @@ 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, "dockHasRunButton", _dockHasRunButton);
obs_data_set_bool(obj, "dockHasPauseButton", _dockHasPauseButton);
SaveDockSettings(obj);
obs_data_set_bool(obj, "registerHotkeys", _registerHotkeys);
obs_data_array_t *pauseHotkey = obs_hotkey_save(_pauseHotkey);
@@ -438,9 +437,7 @@ bool Macro::Load(obs_data_t *obj)
return true;
}
_dockHasRunButton = obs_data_get_bool(obj, "dockHasRunButton");
_dockHasPauseButton = obs_data_get_bool(obj, "dockHasPauseButton");
EnableDock(obs_data_get_bool(obj, "registerDock"));
LoadDockSettings(obj);
obs_data_set_default_bool(obj, "registerHotkeys", true);
_registerHotkeys = obs_data_get_bool(obj, "registerHotkeys");
@@ -583,22 +580,103 @@ bool Macro::PauseHotkeysEnabled()
return _registerHotkeys;
}
void Macro::SaveDockSettings(obs_data_t *obj) const
{
auto dockSettings = obs_data_create();
obs_data_set_bool(dockSettings, "register", _registerDock);
// The object name is used to restore the position of the dock
if (_registerDock) {
SetDockWidgetName();
}
obs_data_set_bool(dockSettings, "hasRunButton", _dockHasRunButton);
obs_data_set_bool(dockSettings, "hasPauseButton", _dockHasPauseButton);
if (_dock) {
auto window = static_cast<QMainWindow *>(
obs_frontend_get_main_window());
obs_data_set_bool(dockSettings, "isFloating",
_dock->isFloating());
obs_data_set_bool(dockSettings, "isVisible", DockIsVisible());
obs_data_set_int(dockSettings, "area",
window->dockWidgetArea(_dock));
obs_data_set_string(
dockSettings, "geometry",
_dock->saveGeometry().toBase64().constData());
}
obs_data_set_obj(obj, "dockSettings", dockSettings);
obs_data_release(dockSettings);
}
void Macro::LoadDockSettings(obs_data_t *obj)
{
auto dockSettings = obs_data_get_obj(obj, "dockSettings");
if (!dockSettings) {
// TODO: Remove this fallback
_dockHasRunButton = obs_data_get_bool(obj, "dockHasRunButton");
_dockHasPauseButton =
obs_data_get_bool(obj, "dockHasPauseButton");
EnableDock(obs_data_get_bool(obj, "registerDock"));
return;
}
const bool dockEnabled = obs_data_get_bool(dockSettings, "register");
_dockIsVisible = obs_data_get_bool(dockSettings, "isVisible");
if (dockEnabled) {
_dockHasRunButton =
obs_data_get_bool(dockSettings, "hasRunButton");
_dockHasPauseButton =
obs_data_get_bool(dockSettings, "hasPauseButton");
_dockIsFloating = obs_data_get_bool(dockSettings, "isFloating");
_dockArea = static_cast<Qt::DockWidgetArea>(
obs_data_get_int(dockSettings, "area"));
auto geometryStr =
obs_data_get_string(dockSettings, "geometry");
if (geometryStr && strlen(geometryStr)) {
_dockGeo =
QByteArray::fromBase64(QByteArray(geometryStr));
}
}
EnableDock(dockEnabled);
obs_data_release(dockSettings);
}
void Macro::EnableDock(bool value)
{
if (_registerDock == value) {
return;
}
// Reset dock regardless
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();
// Unregister dock
if (_registerDock) {
_dockIsFloating = true;
_dockGeo = QByteArray();
_registerDock = value;
return;
}
// Create new dock widget
auto window =
static_cast<QMainWindow *>(obs_frontend_get_main_window());
_dock = new MacroDock(this, window);
SetDockWidgetName(); // Used by OBS to restore position
// Register new dock
_dockAction = static_cast<QAction *>(obs_frontend_add_dock(_dock));
// Note that OBSBasic::OBSInit() has precedence over the visibility and
// geometry set here.
// The function calls here are only intended to attempt to restore the
// dock status when switching scene collections.
_dock->setVisible(_dockIsVisible);
if (window->dockWidgetArea(_dock) != _dockArea) {
window->addDockWidget(_dockArea, _dock);
}
if (_dock->isFloating() != _dockIsFloating) {
_dock->setFloating(_dockIsFloating);
}
_dock->restoreGeometry(_dockGeo);
_registerDock = value;
}

View File

@@ -4,6 +4,7 @@
#include "macro-ref.hpp"
#include <QString>
#include <QByteArray>
#include <string>
#include <deque>
#include <memory>
@@ -96,7 +97,10 @@ private:
void RunActions(bool &ret, bool ignorePause);
void RunActions(bool ignorePause);
void SetOnChangeHighlight();
bool DockIsVisible() const;
void SetDockWidgetName() const;
void SaveDockSettings(obs_data_t *obj) const;
void LoadDockSettings(obs_data_t *obj);
void RemoveDock();
std::string _name = "";
@@ -125,6 +129,10 @@ private:
bool _registerDock = false;
bool _dockHasRunButton = true;
bool _dockHasPauseButton = true;
bool _dockIsFloating = true;
bool _dockIsVisible = false;
Qt::DockWidgetArea _dockArea;
QByteArray _dockGeo;
MacroDock *_dock = nullptr;
QAction *_dockAction = nullptr;

View File

@@ -147,6 +147,10 @@ cv::Mat preprocessForOCR(const QImage &image, const QColor &color)
std::string runOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
const QColor &color)
{
if (image.isNull()) {
return "";
}
#ifdef OCR_SUPPORT
auto mat = preprocessForOCR(image, color);
ocr->SetImage(mat.data, mat.cols, mat.rows, 1, mat.step);

View File

@@ -32,7 +32,7 @@ bool PatternMatchParameters::Load(obs_data_t *obj)
}
useAlphaAsMask = obs_data_get_bool(data, "useAlphaAsMask");
// TODO: Remove this fallback in a future version
if (!obs_data_has_user_value(obj, "matchMode")) {
if (!obs_data_has_user_value(data, "matchMode")) {
matchMode = cv::TM_CCORR_NORMED;
} else {
matchMode = static_cast<cv::TemplateMatchModes>(

View File

@@ -146,6 +146,9 @@ StatusDock::StatusDock(QWidget *parent) : OBSDock(parent)
wrapper->setFrameShadow(QFrame::Sunken);
wrapper->setLayout(layout);
setWidget(wrapper);
setFloating(true);
hide();
}
void SetupDock()

View File

@@ -106,6 +106,9 @@ struct SwitcherData {
int interval = default_interval;
QStringList loadFailureLibs;
bool warnPluginLoadFailure = true;
obs_source_t *waitScene = nullptr;
OBSWeakSource currentScene = nullptr;
OBSWeakSource previousScene = nullptr;