mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-07 00:56:00 -05:00
Compare commits
1 Commits
master
...
1.36.1-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc17f0c708 |
@@ -342,9 +342,7 @@ AdvSceneSwitcher.condition.audio.type.volume="Configured volume level"
|
|||||||
AdvSceneSwitcher.condition.audio.type.syncOffset="Sync offset"
|
AdvSceneSwitcher.condition.audio.type.syncOffset="Sync offset"
|
||||||
AdvSceneSwitcher.condition.audio.type.monitor="Audio monitoring"
|
AdvSceneSwitcher.condition.audio.type.monitor="Audio monitoring"
|
||||||
AdvSceneSwitcher.condition.audio.type.balance="Audio balance"
|
AdvSceneSwitcher.condition.audio.type.balance="Audio balance"
|
||||||
AdvSceneSwitcher.condition.audio.type.track="Audio track"
|
|
||||||
AdvSceneSwitcher.condition.audio.entry="{{checkType}}of{{audioSources}}is{{condition}}{{volume}}{{volumeDB}}{{percentDBToggle}}{{syncOffset}}{{monitorTypes}}"
|
AdvSceneSwitcher.condition.audio.entry="{{checkType}}of{{audioSources}}is{{condition}}{{volume}}{{volumeDB}}{{percentDBToggle}}{{syncOffset}}{{monitorTypes}}"
|
||||||
AdvSceneSwitcher.condition.audio.layout.track="{{audioSources}}is enabled on{{checkType}}{{track}}"
|
|
||||||
AdvSceneSwitcher.condition.cursor="Cursor"
|
AdvSceneSwitcher.condition.cursor="Cursor"
|
||||||
AdvSceneSwitcher.condition.cursor.type.region="is in region"
|
AdvSceneSwitcher.condition.cursor.type.region="is in region"
|
||||||
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
|
AdvSceneSwitcher.condition.cursor.type.moving="is moving"
|
||||||
@@ -2376,7 +2374,6 @@ AdvSceneSwitcher.tempVar.audio.muted="Source muted"
|
|||||||
AdvSceneSwitcher.tempVar.audio.sync_offset="Source audio sync offset"
|
AdvSceneSwitcher.tempVar.audio.sync_offset="Source audio sync offset"
|
||||||
AdvSceneSwitcher.tempVar.audio.monitor="Source audio monitor type"
|
AdvSceneSwitcher.tempVar.audio.monitor="Source audio monitor type"
|
||||||
AdvSceneSwitcher.tempVar.audio.balance="Source audio balance"
|
AdvSceneSwitcher.tempVar.audio.balance="Source audio balance"
|
||||||
AdvSceneSwitcher.tempVar.audio.trackEnabled="Audio track enabled"
|
|
||||||
|
|
||||||
AdvSceneSwitcher.tempVar.clipboard.mimeType.primary="Primary clipboard item MIME type"
|
AdvSceneSwitcher.tempVar.clipboard.mimeType.primary="Primary clipboard item MIME type"
|
||||||
AdvSceneSwitcher.tempVar.clipboard.mimeType.primary.description="Highest priority MIME type of the current item stored in clipboard, if available."
|
AdvSceneSwitcher.tempVar.clipboard.mimeType.primary.description="Highest priority MIME type of the current item stored in clipboard, if available."
|
||||||
@@ -3126,3 +3123,6 @@ AdvSceneSwitcher.sceneGroupTab.defaultname="Scene Group %1"
|
|||||||
AdvSceneSwitcher.sceneGroupTab.exists="Scene Group or Scene name exists already"
|
AdvSceneSwitcher.sceneGroupTab.exists="Scene Group or Scene name exists already"
|
||||||
AdvSceneSwitcher.sceneGroupTab.help="Scene Groups can be selected as a target just like a regular scene.\n\nAs the name suggests a scene group is a collection of multiple scenes.\nThe scene group will advance through the list of its assigned scenes depending on the configured settings, which can be found on the right side.\n\nYou can configure the scene group to advance to the next scene in the list:\nAfter a number of times the scene group is selected as a target.\nAfter a certain amount of time has passed.\nOr randomly.\n\nFor example, a scene group containing the scenes ...\nScene 1\nScene 2\nScene 3 \n... will activate \"Scene 1\" the first time it is selected as a target.\nThe second time it will activate \"Scene 2\".\nThe remaining times \"Scene 3\" will be activated.\n\nClick the highlighted plus symbol below to add a new scene group."
|
AdvSceneSwitcher.sceneGroupTab.help="Scene Groups can be selected as a target just like a regular scene.\n\nAs the name suggests a scene group is a collection of multiple scenes.\nThe scene group will advance through the list of its assigned scenes depending on the configured settings, which can be found on the right side.\n\nYou can configure the scene group to advance to the next scene in the list:\nAfter a number of times the scene group is selected as a target.\nAfter a certain amount of time has passed.\nOr randomly.\n\nFor example, a scene group containing the scenes ...\nScene 1\nScene 2\nScene 3 \n... will activate \"Scene 1\" the first time it is selected as a target.\nThe second time it will activate \"Scene 2\".\nThe remaining times \"Scene 3\" will be activated.\n\nClick the highlighted plus symbol below to add a new scene group."
|
||||||
AdvSceneSwitcher.sceneGroupTab.scenes.help="Select the scene group you want to modify on the left.\n\nSelect a scene to add to this scene group by selecting the scene above and clicking the plus symbol below.\n\nA scene can be added multiple times to the same scene group."
|
AdvSceneSwitcher.sceneGroupTab.scenes.help="Select the scene group you want to modify on the left.\n\nSelect a scene to add to this scene group by selecting the scene above and clicking the plus symbol below.\n\nA scene can be added multiple times to the same scene group."
|
||||||
|
AdvSceneSwitcher.kwin.flatpakPermissionWarning="Window detection via KWin is unavailable.\nThe OBS Studio Flatpak sandbox is missing the 'org.kde.KWin' D-Bus permission this feature needs.\nRun the following, then restart OBS:"
|
||||||
|
AdvSceneSwitcher.wayland.flatpakPermissionWarning="Window detection is unavailable.\nThe OBS Studio Flatpak has no X11 access on this Wayland session, and no compatible integration exists yet for this desktop.\nRunning OBS under an X11 session, or a non-Flatpak install, allows this feature to work."
|
||||||
|
AdvSceneSwitcher.flatpakWindowDetectionWarning.doNotShowAgain="Don't show this warning again"
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
#include "platform-funcs.hpp"
|
#include "platform-funcs.hpp"
|
||||||
|
|
||||||
#include "log-helper.hpp"
|
#include "log-helper.hpp"
|
||||||
|
#include "obs-module-helper.hpp"
|
||||||
|
#include "plugin-state-helpers.hpp"
|
||||||
|
#include "ui-helpers.hpp"
|
||||||
|
|
||||||
|
#include <obs-frontend-api.h>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QFontDatabase>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
@@ -628,27 +639,108 @@ int ignoreXerror(Display *d, XErrorEvent *e)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool warnAboutWindowDetectionUnavailable = true;
|
||||||
|
|
||||||
|
static bool setupWindowDetectionWarningPersistence = []() {
|
||||||
|
AddSaveStep([](obs_data_t *obj) {
|
||||||
|
obs_data_set_bool(obj, "warnAboutFlatpakWindowDetection",
|
||||||
|
warnAboutWindowDetectionUnavailable);
|
||||||
|
});
|
||||||
|
AddLoadStep([](obs_data_t *obj) {
|
||||||
|
obs_data_set_default_bool(
|
||||||
|
obj, "warnAboutFlatpakWindowDetection", true);
|
||||||
|
warnAboutWindowDetectionUnavailable = obs_data_get_bool(
|
||||||
|
obj, "warnAboutFlatpakWindowDetection");
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}();
|
||||||
|
|
||||||
|
static void showWindowDetectionWarning(const char *messageId,
|
||||||
|
const char *command)
|
||||||
|
{
|
||||||
|
auto mainWindow =
|
||||||
|
static_cast<QWidget *>(obs_frontend_get_main_window());
|
||||||
|
QMessageBox msgBox(QMessageBox::Warning,
|
||||||
|
obs_module_text("AdvSceneSwitcher.pluginName"),
|
||||||
|
obs_module_text(messageId), QMessageBox::Ok,
|
||||||
|
mainWindow);
|
||||||
|
|
||||||
|
if (command) {
|
||||||
|
auto commandLineEdit = new QLineEdit(command, &msgBox);
|
||||||
|
commandLineEdit->setReadOnly(true);
|
||||||
|
commandLineEdit->setFont(
|
||||||
|
QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||||
|
commandLineEdit->setCursorPosition(0);
|
||||||
|
auto layout = qobject_cast<QGridLayout *>(msgBox.layout());
|
||||||
|
if (layout) {
|
||||||
|
layout->addWidget(commandLineEdit, layout->rowCount(),
|
||||||
|
0, 1, layout->columnCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto checkbox = new QCheckBox(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.flatpakWindowDetectionWarning.doNotShowAgain"));
|
||||||
|
msgBox.setCheckBox(checkbox);
|
||||||
|
msgBox.exec();
|
||||||
|
warnAboutWindowDetectionUnavailable = !checkbox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleWindowDetectionUnavailable(bool hasX11)
|
||||||
|
{
|
||||||
|
if (hasX11 || KWin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qEnvironmentVariableIsSet("FLATPAK_ID")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool onKDE = qEnvironmentVariable("XDG_CURRENT_DESKTOP")
|
||||||
|
.contains("KDE", Qt::CaseInsensitive);
|
||||||
|
const char *messageId =
|
||||||
|
onKDE ? "AdvSceneSwitcher.kwin.flatpakPermissionWarning"
|
||||||
|
: "AdvSceneSwitcher.wayland.flatpakPermissionWarning";
|
||||||
|
const char *command =
|
||||||
|
onKDE ? "flatpak override --user --talk-name=org.kde.KWin com.obsproject.Studio"
|
||||||
|
: nullptr;
|
||||||
|
|
||||||
|
blog(LOG_WARNING,
|
||||||
|
"window detection unavailable: OBS Flatpak sandbox has no X11 "
|
||||||
|
"access on this Wayland session and %s",
|
||||||
|
onKDE ? "the KWin D-Bus compat call was blocked (missing "
|
||||||
|
"'org.kde.KWin' talk-name permission)"
|
||||||
|
: "no compatible native Wayland integration exists for "
|
||||||
|
"this desktop");
|
||||||
|
|
||||||
|
AddFinishedLoadingStep([messageId, command]() {
|
||||||
|
if (!warnAboutWindowDetectionUnavailable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showWindowDetectionWarning(messageId, command);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void PlatformInit()
|
void PlatformInit()
|
||||||
{
|
{
|
||||||
|
const bool kwinAvailable = isKWinAvailable();
|
||||||
|
KWin = kwinAvailable && registerKWinDBusListener(¬ifier) &&
|
||||||
|
startKWinScript(KWinScriptObjectPath);
|
||||||
|
if (KWin) {
|
||||||
|
blog(LOG_INFO, "using KWin compat");
|
||||||
|
} else {
|
||||||
|
blog(LOG_INFO, "not using KWin compat");
|
||||||
|
}
|
||||||
|
|
||||||
|
initProcps();
|
||||||
|
initProc2();
|
||||||
|
|
||||||
auto display = disp();
|
auto display = disp();
|
||||||
|
handleWindowDetectionUnavailable(display != nullptr);
|
||||||
if (!display) {
|
if (!display) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
KWin = isKWinAvailable();
|
|
||||||
if (!(KWin && startKWinScript(KWinScriptObjectPath) &&
|
|
||||||
registerKWinDBusListener(¬ifier))) {
|
|
||||||
// something bad happened while trying to initialize
|
|
||||||
// the KWin script/dbus so disable it
|
|
||||||
KWin = false;
|
|
||||||
blog(LOG_INFO, "not using KWin compat");
|
|
||||||
} else {
|
|
||||||
blog(LOG_INFO, "using KWin compat");
|
|
||||||
}
|
|
||||||
|
|
||||||
initXss();
|
initXss();
|
||||||
initProcps();
|
|
||||||
initProc2();
|
|
||||||
XSetErrorHandler(ignoreXerror);
|
XSetErrorHandler(ignoreXerror);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileDevice>
|
#include <QFileDevice>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QtDBus/QDBusConnectionInterface>
|
#include <QtDBus/QDBusConnectionInterface>
|
||||||
#include <QtDBus/QDBusInterface>
|
#include <QtDBus/QDBusInterface>
|
||||||
@@ -96,12 +97,16 @@ bool isKWinAvailable()
|
|||||||
|
|
||||||
bool startKWinScript(QString &scriptObjectPath)
|
bool startKWinScript(QString &scriptObjectPath)
|
||||||
{
|
{
|
||||||
|
// Not RuntimeLocation: under Flatpak, $XDG_RUNTIME_DIR is private to
|
||||||
|
// the sandbox, so the unsandboxed KWin process can't read it back.
|
||||||
const QString scriptPath =
|
const QString scriptPath =
|
||||||
"/tmp/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
QStandardPaths::writableLocation(
|
||||||
|
QStandardPaths::CacheLocation) +
|
||||||
|
"/AdvancedSceneSwitcher/KWinFocusNotifier.js";
|
||||||
|
|
||||||
const QString script =
|
const QString script =
|
||||||
R"(var adss = "com.github.AdvancedSceneSwitcher";
|
R"(var adss = "com.obsproject.Studio.Plugin.SceneSwitcher";
|
||||||
var adssPath = "/com/github/AdvancedSceneSwitcher";
|
var adssPath = "/com/obsproject/Studio/Plugin/SceneSwitcher";
|
||||||
|
|
||||||
function trackWindow(window) {
|
function trackWindow(window) {
|
||||||
var id = window.internalId.toString();
|
var id = window.internalId.toString();
|
||||||
@@ -129,7 +134,8 @@ workspace.windowActivated.connect(function(client) {
|
|||||||
}))";
|
}))";
|
||||||
|
|
||||||
if (const QDir dir; !dir.mkpath(QFileInfo(scriptPath).absolutePath())) {
|
if (const QDir dir; !dir.mkpath(QFileInfo(scriptPath).absolutePath())) {
|
||||||
blog(LOG_ERROR, "error creating /tmp/AdvancedSceneSwitcher");
|
blog(LOG_ERROR,
|
||||||
|
"error creating KWinFocusNotifier script directory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,8 +204,10 @@ bool stopKWinScript(const QString &scriptObjectPath)
|
|||||||
|
|
||||||
bool registerKWinDBusListener(FocusNotifier *notifier)
|
bool registerKWinDBusListener(FocusNotifier *notifier)
|
||||||
{
|
{
|
||||||
static const QString serviceName = "com.github.AdvancedSceneSwitcher";
|
static const QString serviceName =
|
||||||
static const QString objectPath = "/com/github/AdvancedSceneSwitcher";
|
"com.obsproject.Studio.Plugin.SceneSwitcher";
|
||||||
|
static const QString objectPath =
|
||||||
|
"/com/obsproject/Studio/Plugin/SceneSwitcher";
|
||||||
auto bus = QDBusConnection::sessionBus();
|
auto bus = QDBusConnection::sessionBus();
|
||||||
|
|
||||||
if (bus.objectRegisteredAt(objectPath)) {
|
if (bus.objectRegisteredAt(objectPath)) {
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ namespace advss {
|
|||||||
|
|
||||||
class FocusNotifier final : public QObject {
|
class FocusNotifier final : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_CLASSINFO("D-Bus Interface", "com.github.AdvancedSceneSwitcher")
|
Q_CLASSINFO("D-Bus Interface",
|
||||||
|
"com.obsproject.Studio.Plugin.SceneSwitcher")
|
||||||
|
|
||||||
static std::mutex _mutex;
|
static std::mutex _mutex;
|
||||||
static int activePID;
|
static int activePID;
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#include "macro-action-scene-collection.hpp"
|
#include "macro-action-scene-collection.hpp"
|
||||||
|
|
||||||
#include "layout-helpers.hpp"
|
#include "layout-helpers.hpp"
|
||||||
#include "plugin-state-helpers.hpp"
|
#include "plugin-state-helpers.hpp"
|
||||||
#include "selection-helpers.hpp"
|
#include "selection-helpers.hpp"
|
||||||
#include "ui-helpers.hpp"
|
|
||||||
|
|
||||||
#include <obs-frontend-api.h>
|
#include <obs-frontend-api.h>
|
||||||
|
|
||||||
@@ -17,20 +15,6 @@ bool MacroActionSceneCollection::_registered = MacroActionFactory::Register(
|
|||||||
MacroActionSceneCollectionEdit::Create,
|
MacroActionSceneCollectionEdit::Create,
|
||||||
"AdvSceneSwitcher.action.sceneCollection"});
|
"AdvSceneSwitcher.action.sceneCollection"});
|
||||||
|
|
||||||
template<typename F> void QueueUITaskLambda(F &&func)
|
|
||||||
{
|
|
||||||
using FnType = std::decay_t<F>;
|
|
||||||
auto *heapFunc = new FnType(std::forward<F>(func));
|
|
||||||
|
|
||||||
QueueUITask(
|
|
||||||
[](void *param) {
|
|
||||||
std::unique_ptr<FnType> fn(
|
|
||||||
static_cast<FnType *>(param));
|
|
||||||
(*fn)();
|
|
||||||
},
|
|
||||||
heapFunc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroActionSceneCollection::PerformAction()
|
bool MacroActionSceneCollection::PerformAction()
|
||||||
{
|
{
|
||||||
// Changing the scene collection will also reload the settings of the
|
// Changing the scene collection will also reload the settings of the
|
||||||
@@ -39,13 +23,7 @@ bool MacroActionSceneCollection::PerformAction()
|
|||||||
if (SettingsWindowIsOpened()) {
|
if (SettingsWindowIsOpened()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
obs_frontend_set_current_scene_collection(_sceneCollection.c_str());
|
||||||
const auto collectionName = _sceneCollection;
|
|
||||||
QueueUITaskLambda([collectionName]() {
|
|
||||||
obs_frontend_set_current_scene_collection(
|
|
||||||
collectionName.c_str());
|
|
||||||
});
|
|
||||||
|
|
||||||
// It does not make sense to continue as the current settings will be
|
// It does not make sense to continue as the current settings will be
|
||||||
// invalid after switching scene collection.
|
// invalid after switching scene collection.
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -25,8 +25,6 @@ const static std::map<MacroConditionAudio::Type, std::string> checkTypes = {
|
|||||||
"AdvSceneSwitcher.condition.audio.type.monitor"},
|
"AdvSceneSwitcher.condition.audio.type.monitor"},
|
||||||
{MacroConditionAudio::Type::BALANCE,
|
{MacroConditionAudio::Type::BALANCE,
|
||||||
"AdvSceneSwitcher.condition.audio.type.balance"},
|
"AdvSceneSwitcher.condition.audio.type.balance"},
|
||||||
{MacroConditionAudio::Type::TRACK,
|
|
||||||
"AdvSceneSwitcher.condition.audio.type.track"},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const static std::map<MacroConditionAudio::OutputCondition, std::string>
|
const static std::map<MacroConditionAudio::OutputCondition, std::string>
|
||||||
@@ -247,20 +245,6 @@ bool MacroConditionAudio::CheckBalance()
|
|||||||
return ret && source;
|
return ret && source;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacroConditionAudio::CheckTrack()
|
|
||||||
{
|
|
||||||
if (!_audioSource.GetSource()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
OBSSourceAutoRelease source =
|
|
||||||
obs_weak_source_get_source(_audioSource.GetSource());
|
|
||||||
uint32_t mixers = obs_source_get_audio_mixers(source);
|
|
||||||
bool enabled = (mixers >> (uint32_t)(_track - 1)) & 1u;
|
|
||||||
SetTempVarValue("track_enabled", enabled ? "true" : "false");
|
|
||||||
return enabled && source;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MacroConditionAudio::CheckCondition()
|
bool MacroConditionAudio::CheckCondition()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -280,9 +264,6 @@ bool MacroConditionAudio::CheckCondition()
|
|||||||
case Type::BALANCE:
|
case Type::BALANCE:
|
||||||
ret = CheckBalance();
|
ret = CheckBalance();
|
||||||
break;
|
break;
|
||||||
case Type::TRACK:
|
|
||||||
ret = CheckTrack();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetVariableValue().empty()) {
|
if (GetVariableValue().empty()) {
|
||||||
@@ -300,7 +281,6 @@ bool MacroConditionAudio::Save(obs_data_t *obj) const
|
|||||||
_volumePercent.Save(obj, "volume");
|
_volumePercent.Save(obj, "volume");
|
||||||
_syncOffset.Save(obj, "syncOffset");
|
_syncOffset.Save(obj, "syncOffset");
|
||||||
_balance.Save(obj, "balance");
|
_balance.Save(obj, "balance");
|
||||||
_track.Save(obj, "track");
|
|
||||||
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
|
obs_data_set_int(obj, "checkType", static_cast<int>(_checkType));
|
||||||
obs_data_set_int(obj, "outputCondition",
|
obs_data_set_int(obj, "outputCondition",
|
||||||
static_cast<int>(_outputCondition));
|
static_cast<int>(_outputCondition));
|
||||||
@@ -366,7 +346,6 @@ bool MacroConditionAudio::Load(obs_data_t *obj)
|
|||||||
_useDb = obs_data_get_bool(obj, "useDb");
|
_useDb = obs_data_get_bool(obj, "useDb");
|
||||||
_volumeDB.Load(obj, "volumeDB");
|
_volumeDB.Load(obj, "volumeDB");
|
||||||
}
|
}
|
||||||
_track.Load(obj, "track");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,12 +421,6 @@ void MacroConditionAudio::SetupTempVars()
|
|||||||
obs_module_text(
|
obs_module_text(
|
||||||
"AdvSceneSwitcher.tempVar.audio.balance"));
|
"AdvSceneSwitcher.tempVar.audio.balance"));
|
||||||
break;
|
break;
|
||||||
case Type::TRACK:
|
|
||||||
AddTempvar(
|
|
||||||
"track_enabled",
|
|
||||||
obs_module_text(
|
|
||||||
"AdvSceneSwitcher.tempVar.audio.trackEnabled"));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -495,7 +468,6 @@ static QStringList getAudioSourcesList()
|
|||||||
MacroConditionAudioEdit::MacroConditionAudioEdit(
|
MacroConditionAudioEdit::MacroConditionAudioEdit(
|
||||||
QWidget *parent, std::shared_ptr<MacroConditionAudio> entryData)
|
QWidget *parent, std::shared_ptr<MacroConditionAudio> entryData)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
_layout(new QHBoxLayout),
|
|
||||||
_checkTypes(new QComboBox()),
|
_checkTypes(new QComboBox()),
|
||||||
_sources(new SourceSelectionWidget(this, getAudioSourcesList, true)),
|
_sources(new SourceSelectionWidget(this, getAudioSourcesList, true)),
|
||||||
_condition(new QComboBox()),
|
_condition(new QComboBox()),
|
||||||
@@ -504,8 +476,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
|||||||
_percentDBToggle(new QPushButton),
|
_percentDBToggle(new QPushButton),
|
||||||
_syncOffset(new VariableSpinBox()),
|
_syncOffset(new VariableSpinBox()),
|
||||||
_monitorTypes(new QComboBox),
|
_monitorTypes(new QComboBox),
|
||||||
_balance(new SliderSpinBox(0., 1., "")),
|
_balance(new SliderSpinBox(0., 1., ""))
|
||||||
_track(new VariableSpinBox())
|
|
||||||
{
|
{
|
||||||
_volumePercent->setSuffix("%");
|
_volumePercent->setSuffix("%");
|
||||||
_volumePercent->setMaximum(100);
|
_volumePercent->setMaximum(100);
|
||||||
@@ -520,9 +491,6 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
|||||||
_syncOffset->setMaximum(20000);
|
_syncOffset->setMaximum(20000);
|
||||||
_syncOffset->setSuffix("ms");
|
_syncOffset->setSuffix("ms");
|
||||||
|
|
||||||
_track->setMinimum(1);
|
|
||||||
_track->setMaximum(32);
|
|
||||||
|
|
||||||
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
QWidget::connect(_checkTypes, SIGNAL(currentIndexChanged(int)), this,
|
||||||
SLOT(CheckTypeChanged(int)));
|
SLOT(CheckTypeChanged(int)));
|
||||||
QWidget::connect(
|
QWidget::connect(
|
||||||
@@ -551,16 +519,27 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
|
|||||||
this, SLOT(VolumeDBChanged(const NumberVariable<double> &)));
|
this, SLOT(VolumeDBChanged(const NumberVariable<double> &)));
|
||||||
QWidget::connect(_percentDBToggle, SIGNAL(clicked()), this,
|
QWidget::connect(_percentDBToggle, SIGNAL(clicked()), this,
|
||||||
SLOT(PercentDBClicked()));
|
SLOT(PercentDBClicked()));
|
||||||
QWidget::connect(
|
|
||||||
_track,
|
|
||||||
SIGNAL(NumberVariableChanged(const NumberVariable<int> &)),
|
|
||||||
this, SLOT(TrackChanged(const NumberVariable<int> &)));
|
|
||||||
|
|
||||||
populateCheckTypes(_checkTypes);
|
populateCheckTypes(_checkTypes);
|
||||||
PopulateMonitorTypeSelection(_monitorTypes);
|
PopulateMonitorTypeSelection(_monitorTypes);
|
||||||
|
|
||||||
|
QHBoxLayout *switchLayout = new QHBoxLayout;
|
||||||
|
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||||
|
{"{{checkType}}", _checkTypes},
|
||||||
|
{"{{audioSources}}", _sources},
|
||||||
|
{"{{volume}}", _volumePercent},
|
||||||
|
{"{{syncOffset}}", _syncOffset},
|
||||||
|
{"{{monitorTypes}}", _monitorTypes},
|
||||||
|
{"{{balance}}", _balance},
|
||||||
|
{"{{condition}}", _condition},
|
||||||
|
{"{{volumeDB}}", _volumeDB},
|
||||||
|
{"{{percentDBToggle}}", _percentDBToggle},
|
||||||
|
};
|
||||||
|
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.audio.entry"),
|
||||||
|
switchLayout, widgetPlaceholders);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addLayout(_layout);
|
mainLayout->addLayout(switchLayout);
|
||||||
mainLayout->addWidget(_balance);
|
mainLayout->addWidget(_balance);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
@@ -629,12 +608,6 @@ void MacroConditionAudioEdit::BalanceChanged(const NumberVariable<double> &value
|
|||||||
_entryData->_balance = value;
|
_entryData->_balance = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroConditionAudioEdit::TrackChanged(const NumberVariable<int> &value)
|
|
||||||
{
|
|
||||||
GUARD_LOADING_AND_LOCK();
|
|
||||||
_entryData->_track = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MacroConditionAudioEdit::VolumeDBChanged(
|
void MacroConditionAudioEdit::VolumeDBChanged(
|
||||||
const NumberVariable<double> &value)
|
const NumberVariable<double> &value)
|
||||||
{
|
{
|
||||||
@@ -719,8 +692,6 @@ void MacroConditionAudioEdit::CheckTypeChanged(int idx)
|
|||||||
} else if (_entryData->GetType() ==
|
} else if (_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
MacroConditionAudio::Type::CONFIGURED_VOLUME) {
|
||||||
populateVolumeConditionSelection(_condition);
|
populateVolumeConditionSelection(_condition);
|
||||||
} else if (_entryData->GetType() == MacroConditionAudio::Type::TRACK) {
|
|
||||||
_condition->clear();
|
|
||||||
}
|
}
|
||||||
SetWidgetVisibility();
|
SetWidgetVisibility();
|
||||||
}
|
}
|
||||||
@@ -737,7 +708,6 @@ void MacroConditionAudioEdit::UpdateEntryData()
|
|||||||
_syncOffset->SetValue(_entryData->_syncOffset);
|
_syncOffset->SetValue(_entryData->_syncOffset);
|
||||||
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
_monitorTypes->setCurrentIndex(_entryData->_monitorType);
|
||||||
_balance->SetDoubleValue(_entryData->_balance);
|
_balance->SetDoubleValue(_entryData->_balance);
|
||||||
_track->SetValue(_entryData->_track);
|
|
||||||
_checkTypes->setCurrentIndex(
|
_checkTypes->setCurrentIndex(
|
||||||
_checkTypes->findData(static_cast<int>(_entryData->GetType())));
|
_checkTypes->findData(static_cast<int>(_entryData->GetType())));
|
||||||
|
|
||||||
@@ -778,63 +748,26 @@ void MacroConditionAudioEdit::SetWidgetVisibility()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_layout->removeWidget(_checkTypes);
|
|
||||||
_layout->removeWidget(_sources);
|
|
||||||
_layout->removeWidget(_condition);
|
|
||||||
_layout->removeWidget(_volumePercent);
|
|
||||||
_layout->removeWidget(_volumeDB);
|
|
||||||
_layout->removeWidget(_percentDBToggle);
|
|
||||||
_layout->removeWidget(_syncOffset);
|
|
||||||
_layout->removeWidget(_monitorTypes);
|
|
||||||
_layout->removeWidget(_track);
|
|
||||||
ClearLayout(_layout);
|
|
||||||
|
|
||||||
const std::unordered_map<std::string, QWidget *> placeholders = {
|
|
||||||
{"{{checkType}}", _checkTypes},
|
|
||||||
{"{{audioSources}}", _sources},
|
|
||||||
{"{{condition}}", _condition},
|
|
||||||
{"{{volume}}", _volumePercent},
|
|
||||||
{"{{volumeDB}}", _volumeDB},
|
|
||||||
{"{{percentDBToggle}}", _percentDBToggle},
|
|
||||||
{"{{syncOffset}}", _syncOffset},
|
|
||||||
{"{{monitorTypes}}", _monitorTypes},
|
|
||||||
{"{{track}}", _track},
|
|
||||||
};
|
|
||||||
|
|
||||||
const bool isTrack = _entryData->GetType() ==
|
|
||||||
MacroConditionAudio::Type::TRACK;
|
|
||||||
PlaceWidgets(
|
|
||||||
obs_module_text(
|
|
||||||
isTrack ? "AdvSceneSwitcher.condition.audio.layout.track"
|
|
||||||
: "AdvSceneSwitcher.condition.audio.entry"),
|
|
||||||
_layout, placeholders);
|
|
||||||
|
|
||||||
_condition->setVisible(
|
_condition->setVisible(
|
||||||
!isTrack &&
|
_entryData->GetType() ==
|
||||||
(_entryData->GetType() ==
|
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
MacroConditionAudio::Type::OUTPUT_VOLUME ||
|
||||||
_entryData->GetType() ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::CONFIGURED_VOLUME ||
|
MacroConditionAudio::Type::CONFIGURED_VOLUME ||
|
||||||
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
_entryData->GetType() == MacroConditionAudio::Type::BALANCE ||
|
||||||
_entryData->GetType() ==
|
|
||||||
MacroConditionAudio::Type::SYNC_OFFSET));
|
|
||||||
_syncOffset->setVisible(!isTrack &&
|
|
||||||
_entryData->GetType() ==
|
_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::SYNC_OFFSET);
|
MacroConditionAudio::Type::SYNC_OFFSET);
|
||||||
_monitorTypes->setVisible(!isTrack &&
|
_syncOffset->setVisible(_entryData->GetType() ==
|
||||||
_entryData->GetType() ==
|
MacroConditionAudio::Type::SYNC_OFFSET);
|
||||||
|
_monitorTypes->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::MONITOR);
|
MacroConditionAudio::Type::MONITOR);
|
||||||
_track->setVisible(isTrack);
|
|
||||||
_volumePercent->setVisible(!isTrack && HasVolumeControl() &&
|
|
||||||
!_entryData->_useDb);
|
|
||||||
_volumeDB->setVisible(!isTrack && HasVolumeControl() &&
|
|
||||||
_entryData->_useDb);
|
|
||||||
_percentDBToggle->setText(_entryData->_useDb ? "dB" : "%");
|
|
||||||
_percentDBToggle->setVisible(!isTrack && HasVolumeControl());
|
|
||||||
_balance->setVisible(_entryData->GetType() ==
|
_balance->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::BALANCE);
|
MacroConditionAudio::Type::BALANCE);
|
||||||
_volMeter->setVisible(_entryData->GetType() ==
|
_volMeter->setVisible(_entryData->GetType() ==
|
||||||
MacroConditionAudio::Type::OUTPUT_VOLUME);
|
MacroConditionAudio::Type::OUTPUT_VOLUME);
|
||||||
|
_volumePercent->setVisible(HasVolumeControl() && !_entryData->_useDb);
|
||||||
|
_volumeDB->setVisible(HasVolumeControl() && _entryData->_useDb);
|
||||||
|
_percentDBToggle->setText(_entryData->_useDb ? "dB" : "%");
|
||||||
|
_percentDBToggle->setVisible(HasVolumeControl());
|
||||||
adjustSize();
|
adjustSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "source-selection.hpp"
|
#include "source-selection.hpp"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@@ -37,7 +36,6 @@ public:
|
|||||||
SYNC_OFFSET,
|
SYNC_OFFSET,
|
||||||
MONITOR,
|
MONITOR,
|
||||||
BALANCE,
|
BALANCE,
|
||||||
TRACK,
|
|
||||||
};
|
};
|
||||||
void SetType(const Type &);
|
void SetType(const Type &);
|
||||||
Type GetType() const { return _checkType; }
|
Type GetType() const { return _checkType; }
|
||||||
@@ -62,7 +60,6 @@ public:
|
|||||||
IntVariable _syncOffset = 0;
|
IntVariable _syncOffset = 0;
|
||||||
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
obs_monitoring_type _monitorType = OBS_MONITORING_TYPE_NONE;
|
||||||
DoubleVariable _balance = 0.5;
|
DoubleVariable _balance = 0.5;
|
||||||
IntVariable _track = 1;
|
|
||||||
OutputCondition _outputCondition = OutputCondition::ABOVE;
|
OutputCondition _outputCondition = OutputCondition::ABOVE;
|
||||||
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
|
VolumeCondition _volumeCondition = VolumeCondition::ABOVE;
|
||||||
obs_volmeter_t *_volmeter = nullptr;
|
obs_volmeter_t *_volmeter = nullptr;
|
||||||
@@ -73,7 +70,6 @@ private:
|
|||||||
bool CheckSyncOffset();
|
bool CheckSyncOffset();
|
||||||
bool CheckMonitor();
|
bool CheckMonitor();
|
||||||
bool CheckBalance();
|
bool CheckBalance();
|
||||||
bool CheckTrack();
|
|
||||||
void SetupTempVars();
|
void SetupTempVars();
|
||||||
float GetVolumePeak();
|
float GetVolumePeak();
|
||||||
|
|
||||||
@@ -115,7 +111,6 @@ private slots:
|
|||||||
void VolumeDBChanged(const NumberVariable<double> &value);
|
void VolumeDBChanged(const NumberVariable<double> &value);
|
||||||
void PercentDBClicked();
|
void PercentDBClicked();
|
||||||
void SyncSliderAndValueSelection(bool sliderMoved);
|
void SyncSliderAndValueSelection(bool sliderMoved);
|
||||||
void TrackChanged(const NumberVariable<int> &value);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void HeaderInfoChanged(const QString &);
|
void HeaderInfoChanged(const QString &);
|
||||||
@@ -124,7 +119,6 @@ private:
|
|||||||
void SetWidgetVisibility();
|
void SetWidgetVisibility();
|
||||||
bool HasVolumeControl() const;
|
bool HasVolumeControl() const;
|
||||||
|
|
||||||
QHBoxLayout *_layout;
|
|
||||||
QComboBox *_checkTypes;
|
QComboBox *_checkTypes;
|
||||||
SourceSelectionWidget *_sources;
|
SourceSelectionWidget *_sources;
|
||||||
QComboBox *_condition;
|
QComboBox *_condition;
|
||||||
@@ -134,7 +128,6 @@ private:
|
|||||||
VariableSpinBox *_syncOffset;
|
VariableSpinBox *_syncOffset;
|
||||||
QComboBox *_monitorTypes;
|
QComboBox *_monitorTypes;
|
||||||
SliderSpinBox *_balance;
|
SliderSpinBox *_balance;
|
||||||
VariableSpinBox *_track;
|
|
||||||
VolControl *_volMeter = nullptr;
|
VolControl *_volMeter = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<MacroConditionAudio> _entryData;
|
std::shared_ptr<MacroConditionAudio> _entryData;
|
||||||
|
|||||||
Reference in New Issue
Block a user