Adjust to SceneItemSelection and SceneItemSelectionWidget

This commit is contained in:
WarmUpTill 2021-12-31 02:03:05 +01:00 committed by WarmUpTill
parent 3af5897427
commit 2649efe8b3
13 changed files with 492 additions and 373 deletions

View File

@ -214,7 +214,7 @@ AdvSceneSwitcher.condition.sceneOrder.type.above="Is above"
AdvSceneSwitcher.condition.sceneOrder.type.below="Is below"
AdvSceneSwitcher.condition.sceneOrder.type.position="Is at position"
AdvSceneSwitcher.condition.sceneOrder.positionInfo="The position value starts at the bottom with 0 and increases by one for each scene item including the ones in scene groups"
AdvSceneSwitcher.condition.sceneOrder.entry="On {{scenes}} {{sources}} {{conditions}} {{sources2}} {{position}}"
AdvSceneSwitcher.condition.sceneOrder.entry="On{{scenes}}{{sources}}{{conditions}}{{sources2}}{{position}}"
AdvSceneSwitcher.condition.hotkey="Hotkey"
AdvSceneSwitcher.condition.hotkey.name="Macro trigger hotkey"
AdvSceneSwitcher.condition.hotkey.tip="Note: You can configure the keybindings for this hotkey in the OBS settings window"
@ -234,7 +234,7 @@ AdvSceneSwitcher.condition.date.entry.line2="{{repeat}} Repeat every {{duration}
AdvSceneSwitcher.condition.sceneTransform="Scene item transform"
AdvSceneSwitcher.condition.sceneTransform.getTransform="Get transform"
AdvSceneSwitcher.condition.sceneTransform.regex="Use regular expressions"
AdvSceneSwitcher.condition.sceneTransform.entry.line1="On {{scenes}} {{sources}} matches transform"
AdvSceneSwitcher.condition.sceneTransform.entry.line1="On{{scenes}}{{sources}}matches transform"
AdvSceneSwitcher.condition.sceneTransform.entry.line2="{{settings}}"
AdvSceneSwitcher.condition.sceneTransform.entry.line3="{{regex}} {{getSettings}}"
AdvSceneSwitcher.condition.transition="Transition"
@ -249,7 +249,7 @@ AdvSceneSwitcher.condition.transition.entry="{{conditions}}{{transitions}}{{scen
AdvSceneSwitcher.condition.sceneVisibility="Scene item visibility"
AdvSceneSwitcher.condition.sceneVisibility.type.shown="Shown"
AdvSceneSwitcher.condition.sceneVisibility.type.hidden="Hidden"
AdvSceneSwitcher.condition.sceneVisibility.entry="On {{scenes}} {{sources}} is {{conditions}}"
AdvSceneSwitcher.condition.sceneVisibility.entry="On{{scenes}}{{sources}}is{{conditions}}"
AdvSceneSwitcher.condition.studioMode="Studio mode"
AdvSceneSwitcher.condition.studioMode.state.active="Studio mode is active"
AdvSceneSwitcher.condition.studioMode.state.notActive="Studio mode is not active"
@ -298,7 +298,7 @@ AdvSceneSwitcher.action.sceneVisibility.type.show="Show"
AdvSceneSwitcher.action.sceneVisibility.type.hide="Hide"
AdvSceneSwitcher.action.sceneVisibility.type.source="Source"
AdvSceneSwitcher.action.sceneVisibility.type.sourceGroup="Any"
AdvSceneSwitcher.action.sceneVisibility.entry="On {{scenes}} {{actions}} {{sourceTypes}} {{sources}}"
AdvSceneSwitcher.action.sceneVisibility.entry="On{{scenes}}{{actions}}{{sourceTypes}}{{sources}}{{sourceGroups}}"
AdvSceneSwitcher.action.filter="Filter"
AdvSceneSwitcher.action.filter.type.enable="Enable"
AdvSceneSwitcher.action.filter.type.disable="Disable"
@ -354,10 +354,10 @@ AdvSceneSwitcher.action.sceneOrder.type.moveDown="Move down"
AdvSceneSwitcher.action.sceneOrder.type.moveTop="Move to top"
AdvSceneSwitcher.action.sceneOrder.type.moveBottom="Move to bottom"
AdvSceneSwitcher.action.sceneOrder.type.movePosition="Move to position"
AdvSceneSwitcher.action.sceneOrder.entry="On {{scenes}} {{actions}} {{sources}} {{position}}"
AdvSceneSwitcher.action.sceneOrder.entry="On{{scenes}}{{actions}}{{sources}}{{position}}"
AdvSceneSwitcher.action.sceneTransform="Scene item transform"
AdvSceneSwitcher.action.sceneTransform.getTransform="Get transform"
AdvSceneSwitcher.action.sceneTransform.entry="On {{scenes}} transform {{sources}}"
AdvSceneSwitcher.action.sceneTransform.entry="On{{scenes}}transform{{sources}}"
AdvSceneSwitcher.action.file="File"
AdvSceneSwitcher.action.file.type.write="Write"
AdvSceneSwitcher.action.file.type.append="Append"

View File

@ -1,7 +1,9 @@
#pragma once
#include <QSpinBox>
#include "macro-action-edit.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QSpinBox>
enum class SceneOrderAction {
MOVE_UP,
@ -25,7 +27,7 @@ public:
}
SceneSelection _scene;
OBSWeakSource _source;
SceneItemSelection _source;
SceneOrderAction _action = SceneOrderAction::MOVE_UP;
int _position = 0;
@ -53,7 +55,7 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void SourceChanged(const SceneItemSelection &);
void ActionChanged(int value);
void PositionChanged(int value);
signals:
@ -61,7 +63,7 @@ signals:
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sources;
SceneItemSelectionWidget *_sources;
QComboBox *_actions;
QSpinBox *_position;
std::shared_ptr<MacroActionSceneOrder> _entryData;

View File

@ -1,8 +1,10 @@
#pragma once
#include <QSpinBox>
#include <QPlainTextEdit>
#include "macro-action-edit.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QSpinBox>
#include <QPlainTextEdit>
class MacroActionSceneTransform : public MacroAction {
public:
@ -20,7 +22,7 @@ public:
void SetSettings(std::string &);
SceneSelection _scene;
OBSWeakSource _source;
SceneItemSelection _source;
struct obs_transform_info _info = {};
struct obs_sceneitem_crop _crop = {};
@ -48,7 +50,7 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void SourceChanged(const SceneItemSelection &);
void GetSettingsClicked();
void SettingsChanged();
signals:
@ -56,7 +58,7 @@ signals:
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sources;
SceneItemSelectionWidget *_sources;
QPushButton *_getSettings;
QPlainTextEdit *_settings;
std::shared_ptr<MacroActionSceneTransform> _entryData;

View File

@ -1,7 +1,9 @@
#pragma once
#include <QSpinBox>
#include "macro-action-edit.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QSpinBox>
enum class SceneVisibilityAction {
SHOW,
@ -28,7 +30,7 @@ public:
SceneSelection _scene;
SceneItemSourceType _sourceType = SceneItemSourceType::SOURCE;
OBSWeakSource _source;
SceneItemSelection _source;
std::string _sourceGroup = "";
SceneVisibilityAction _action = SceneVisibilityAction::SHOW;
@ -57,7 +59,8 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceTypeChanged(int value);
void SourceChanged(const QString &text);
void SourceChanged(const SceneItemSelection &);
void SourceGroupChanged(const QString &text);
void ActionChanged(int value);
signals:
void HeaderInfoChanged(const QString &);
@ -65,11 +68,14 @@ signals:
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sourceTypes;
QComboBox *_sources;
SceneItemSelectionWidget *_sources;
QComboBox *_sourceGroups;
QComboBox *_actions;
std::shared_ptr<MacroActionSceneVisibility> _entryData;
private:
void SetWidgetVisibility();
QHBoxLayout *_mainLayout;
bool _loading = true;
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "macro.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QWidget>
#include <QComboBox>
@ -24,8 +25,8 @@ public:
}
SceneSelection _scene;
OBSWeakSource _source;
OBSWeakSource _source2;
SceneItemSelection _source;
SceneItemSelection _source2;
int _position = 0;
SceneOrderCondition _condition = SceneOrderCondition::ABOVE;
@ -53,8 +54,8 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void Source2Changed(const QString &text);
void SourceChanged(const SceneItemSelection &);
void Source2Changed(const SceneItemSelection &);
void ConditionChanged(int cond);
void PositionChanged(int cond);
signals:
@ -63,8 +64,8 @@ signals:
protected:
SceneSelectionWidget *_scenes;
QComboBox *_conditions;
QComboBox *_sources;
QComboBox *_sources2;
SceneItemSelectionWidget *_sources;
SceneItemSelectionWidget *_sources2;
QSpinBox *_position;
QLabel *_posInfo;

View File

@ -1,6 +1,7 @@
#pragma once
#include "macro.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QSpinBox>
#include <QPlainTextEdit>
@ -19,7 +20,7 @@ public:
}
SceneSelection _scene;
OBSWeakSource _source;
SceneItemSelection _source;
bool _regex = false;
std::string _settings = "";
@ -48,7 +49,7 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void SourceChanged(const SceneItemSelection &);
void GetSettingsClicked();
void SettingsChanged();
void RegexChanged(int);
@ -57,7 +58,7 @@ signals:
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sources;
SceneItemSelectionWidget *_sources;
QPushButton *_getSettings;
QPlainTextEdit *_settings;
QCheckBox *_regex;

View File

@ -1,6 +1,7 @@
#pragma once
#include "macro.hpp"
#include "scene-selection.hpp"
#include "scene-item-selection.hpp"
#include <QComboBox>
@ -22,7 +23,7 @@ public:
}
SceneSelection _scene;
OBSWeakSource _source;
SceneItemSelection _source;
SceneVisibilityCondition _condition = SceneVisibilityCondition::SHOWN;
private:
@ -49,14 +50,14 @@ public:
private slots:
void SceneChanged(const SceneSelection &);
void SourceChanged(const QString &text);
void SourceChanged(const SceneItemSelection &);
void ConditionChanged(int cond);
signals:
void HeaderInfoChanged(const QString &);
protected:
SceneSelectionWidget *_scenes;
QComboBox *_sources;
SceneItemSelectionWidget *_sources;
QComboBox *_conditions;
std::shared_ptr<MacroConditionSceneVisibility> _entryData;

View File

@ -22,37 +22,77 @@ const static std::map<SceneOrderAction, std::string> actionTypes = {
"AdvSceneSwitcher.action.sceneOrder.type.movePosition"},
};
bool MacroActionSceneOrder::PerformAction()
void moveSceneItemsUp(std::vector<obs_scene_item *> &items)
{
auto s = obs_weak_source_get_source(_scene.GetScene());
auto scene = obs_scene_from_source(s);
auto name = GetWeakSourceName(_source);
auto items = getSceneItemsWithName(scene, name);
// In the case of the same source being in two sequential positions
// moving the sources up will cause the sources to swap positions due to
// the order scene items are being iterated over, which is most likely
// not the desired effect.
// Instead we reverse the order of the scene items so all scene items
// will be moved up.
std::reverse(items.begin(), items.end());
for (auto &i : items) {
switch (_action) {
case SceneOrderAction::MOVE_UP:
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_UP);
break;
case SceneOrderAction::MOVE_DOWN:
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_DOWN);
break;
case SceneOrderAction::MOVE_TOP:
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_TOP);
break;
case SceneOrderAction::MOVE_BOTTOM:
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_BOTTOM);
break;
case SceneOrderAction::POSITION:
obs_sceneitem_set_order_position(i, _position);
break;
default:
break;
}
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_UP);
obs_sceneitem_release(i);
}
}
obs_source_release(s);
void moveSceneItemsDown(std::vector<obs_scene_item *> &items)
{
for (auto &i : items) {
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_DOWN);
obs_sceneitem_release(i);
}
}
void moveSceneItemsTop(std::vector<obs_scene_item *> &items)
{
for (auto &i : items) {
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_TOP);
obs_sceneitem_release(i);
}
}
void moveSceneItemsBottom(std::vector<obs_scene_item *> &items)
{
for (auto &i : items) {
obs_sceneitem_set_order(i, OBS_ORDER_MOVE_BOTTOM);
obs_sceneitem_release(i);
}
}
void moveSceneItemsPos(std::vector<obs_scene_item *> &items, int pos)
{
for (auto &i : items) {
obs_sceneitem_set_order_position(i, pos);
obs_sceneitem_release(i);
}
}
bool MacroActionSceneOrder::PerformAction()
{
auto items = _source.GetSceneItems(_scene);
switch (_action) {
case SceneOrderAction::MOVE_UP:
moveSceneItemsUp(items);
break;
case SceneOrderAction::MOVE_DOWN:
moveSceneItemsDown(items);
break;
case SceneOrderAction::MOVE_TOP:
moveSceneItemsTop(items);
break;
case SceneOrderAction::MOVE_BOTTOM:
moveSceneItemsBottom(items);
break;
case SceneOrderAction::POSITION:
moveSceneItemsPos(items, _position);
break;
default:
break;
}
return true;
}
@ -62,7 +102,7 @@ void MacroActionSceneOrder::LogAction()
if (it != actionTypes.end()) {
vblog(LOG_INFO,
"performed order action \"%s\" for source \"%s\" on scene \"%s\"",
it->second.c_str(), GetWeakSourceName(_source).c_str(),
it->second.c_str(), _source.ToString().c_str(),
_scene.ToString().c_str());
} else {
blog(LOG_WARNING, "ignored unknown scene order action %d",
@ -74,7 +114,7 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj)
{
MacroAction::Save(obj);
_scene.Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
_source.Save(obj);
obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "position", _position);
return true;
@ -82,10 +122,16 @@ bool MacroActionSceneOrder::Save(obs_data_t *obj)
bool MacroActionSceneOrder::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
}
MacroAction::Load(obj);
_scene.Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_source.Load(obj);
_action =
static_cast<SceneOrderAction>(obs_data_get_int(obj, "action"));
_position = obs_data_get_int(obj, "position");
@ -94,10 +140,10 @@ bool MacroActionSceneOrder::Load(obs_data_t *obj)
std::string MacroActionSceneOrder::GetShortDesc()
{
if (_source) {
return _scene.ToString() + " - " + GetWeakSourceName(_source);
if (_source.ToString().empty()) {
return "";
}
return "";
return _scene.ToString() + " - " + _source.ToString();
}
static inline void populateActionSelection(QComboBox *list)
@ -112,7 +158,7 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), false, false, true);
_sources = new QComboBox();
_sources = new SceneItemSelectionWidget(parent);
_actions = new QComboBox();
_position = new QSpinBox();
@ -122,8 +168,11 @@ MacroActionSceneOrderEdit::MacroActionSceneOrderEdit(
SLOT(ActionChanged(int)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_position, SIGNAL(valueChanged(int)), this,
SLOT(PositionChanged(int)));
@ -152,9 +201,7 @@ void MacroActionSceneOrderEdit::UpdateEntryData()
_actions->setCurrentIndex(static_cast<int>(_entryData->_action));
_scenes->SetScene(_entryData->_scene);
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
_sources->SetSceneItem(_entryData->_source);
_position->setValue(_entryData->_position);
_position->setVisible(_entryData->_action ==
SceneOrderAction::POSITION);
@ -165,22 +212,19 @@ void MacroActionSceneOrderEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
void MacroActionSceneOrderEdit::SourceChanged(const QString &text)
void MacroActionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}

View File

@ -12,13 +12,8 @@ bool MacroActionSceneTransform::_registered = MacroActionFactory::Register(
bool MacroActionSceneTransform::PerformAction()
{
auto s = obs_weak_source_get_source(_scene.GetScene(false));
auto scene = obs_scene_from_source(s);
auto name = GetWeakSourceName(_source);
auto items = getSceneItemsWithName(scene, name);
auto items = _source.GetSceneItems(_scene);
for (auto &item : items) {
// Apply settings
obs_sceneitem_defer_update_begin(item);
obs_sceneitem_set_info(item, &_info);
obs_sceneitem_set_crop(item, &_crop);
@ -26,8 +21,6 @@ bool MacroActionSceneTransform::PerformAction()
obs_sceneitem_release(item);
}
obs_source_release(s);
return true;
}
@ -35,34 +28,40 @@ void MacroActionSceneTransform::LogAction()
{
vblog(LOG_INFO,
"performed transform action for source \"%s\" on scene \"%s\"",
GetWeakSourceName(_source).c_str(), _scene.ToString().c_str());
_source.ToString().c_str(), _scene.ToString().c_str());
}
bool MacroActionSceneTransform::Save(obs_data_t *obj)
{
MacroAction::Save(obj);
_scene.Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
_source.Save(obj);
saveTransformState(obj, _info, _crop);
return true;
}
bool MacroActionSceneTransform::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
}
MacroAction::Load(obj);
_scene.Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_source.Load(obj);
loadTransformState(obj, _info, _crop);
return true;
}
std::string MacroActionSceneTransform::GetShortDesc()
{
if (_source) {
return _scene.ToString() + " - " + GetWeakSourceName(_source);
if (_source.ToString().empty()) {
return "";
}
return "";
return _scene.ToString() + " - " + _source.ToString();
}
std::string MacroActionSceneTransform::GetSettings()
@ -81,9 +80,13 @@ void MacroActionSceneTransform::SetSettings(std::string &settings)
return;
}
loadTransformState(data, _info, _crop);
auto items = _source.GetSceneItems(_scene);
if (items.empty()) {
return;
}
if (obs_data_has_user_value(data, "size")) {
auto obj = obs_data_get_obj(data, "size");
auto source = obs_weak_source_get_source(_source);
auto source = obs_sceneitem_get_source(items[0]);
if (double h = obs_data_get_double(obj, "height")) {
_info.scale.y =
h / double(obs_source_get_height(source));
@ -93,9 +96,10 @@ void MacroActionSceneTransform::SetSettings(std::string &settings)
w / double(obs_source_get_width(source));
}
obs_data_release(obj);
obs_source_release(source);
}
for (auto item : items) {
obs_sceneitem_release(item);
}
obs_data_release(data);
}
@ -104,15 +108,18 @@ MacroActionSceneTransformEdit::MacroActionSceneTransformEdit(
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), false, false, true);
_sources = new QComboBox();
_sources = new SceneItemSelectionWidget(parent);
_getSettings = new QPushButton(obs_module_text(
"AdvSceneSwitcher.action.sceneTransform.getTransform"));
_settings = new QPlainTextEdit();
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
SLOT(GetSettingsClicked()));
QWidget::connect(_settings, SIGNAL(textChanged()), this,
@ -152,13 +159,8 @@ void MacroActionSceneTransformEdit::UpdateEntryData()
}
_scenes->SetScene(_entryData->_scene);
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
if (_entryData->_source) {
_settings->setPlainText(
formatJsonString(_entryData->GetSettings()));
}
_sources->SetSceneItem(_entryData->_source);
_settings->setPlainText(formatJsonString(_entryData->GetSettings()));
}
void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s)
@ -166,44 +168,39 @@ void MacroActionSceneTransformEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
void MacroActionSceneTransformEdit::SourceChanged(const QString &text)
void MacroActionSceneTransformEdit::SourceChanged(const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroActionSceneTransformEdit::GetSettingsClicked()
{
if (_loading || !_entryData || !_entryData->_scene.GetScene(false) ||
!_entryData->_source) {
if (_loading || !_entryData || !_entryData->_scene.GetScene(false)) {
return;
}
auto s = obs_weak_source_get_source(_entryData->_scene.GetScene(false));
auto scene = obs_scene_from_source(s);
auto name = GetWeakSourceName(_entryData->_source);
auto item = obs_scene_find_source_recursive(scene, name.c_str());
obs_source_release(s);
if (!item) {
auto items = _entryData->_source.GetSceneItems(_entryData->_scene);
if (items.empty()) {
return;
}
_settings->setPlainText(formatJsonString(getSceneItemTransform(item)));
auto settings = getSceneItemTransform(items[0]);
_settings->setPlainText(formatJsonString(settings));
for (auto item : items) {
obs_sceneitem_release(item);
}
}
void MacroActionSceneTransformEdit::SettingsChanged()

View File

@ -29,23 +29,6 @@ struct VisibilityData {
bool visible;
};
static bool visibilitySourceEnum(obs_scene_t *, obs_sceneitem_t *item,
void *ptr)
{
VisibilityData *vInfo = reinterpret_cast<VisibilityData *>(ptr);
auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item));
if (vInfo->name == sourceName) {
obs_sceneitem_set_visible(item, vInfo->visible);
}
if (obs_sceneitem_is_group(item)) {
obs_scene_t *scene = obs_sceneitem_group_get_scene(item);
obs_scene_enum_items(scene, visibilitySourceEnum, ptr);
}
return true;
}
static bool visibilitySourceTypeEnum(obs_scene_t *, obs_sceneitem_t *item,
void *ptr)
{
@ -67,25 +50,29 @@ static bool visibilitySourceTypeEnum(obs_scene_t *, obs_sceneitem_t *item,
bool MacroActionSceneVisibility::PerformAction()
{
auto s = obs_weak_source_get_source(_scene.GetScene());
auto scene = obs_scene_from_source(s);
auto sourceName = GetWeakSourceName(_source);
VisibilityData vInfo = {"", _action == SceneVisibilityAction::SHOW};
switch (_sourceType) {
case SceneItemSourceType::SOURCE:
vInfo.name = sourceName;
obs_scene_enum_items(scene, visibilitySourceEnum, &vInfo);
case SceneItemSourceType::SOURCE: {
auto items = _source.GetSceneItems(_scene);
for (auto item : items) {
obs_sceneitem_set_visible(
item, _action == SceneVisibilityAction::SHOW);
obs_sceneitem_release(item);
}
break;
case SceneItemSourceType::SOURCE_GROUP:
vInfo.name = _sourceGroup;
}
case SceneItemSourceType::SOURCE_GROUP: {
auto s = obs_weak_source_get_source(_scene.GetScene());
auto scene = obs_scene_from_source(s);
VisibilityData vInfo = {_sourceGroup,
_action == SceneVisibilityAction::SHOW};
obs_scene_enum_items(scene, visibilitySourceTypeEnum, &vInfo);
obs_source_release(s);
break;
}
default:
break;
}
obs_source_release(s);
return true;
}
@ -96,8 +83,7 @@ void MacroActionSceneVisibility::LogAction()
if (_sourceType == SceneItemSourceType::SOURCE) {
vblog(LOG_INFO,
"performed visibility action \"%s\" for source \"%s\" on scene \"%s\"",
it->second.c_str(),
GetWeakSourceName(_source).c_str(),
it->second.c_str(), _source.ToString().c_str(),
_scene.ToString().c_str());
} else {
vblog(LOG_INFO,
@ -116,10 +102,9 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj)
MacroAction::Save(obj);
_scene.Save(obj);
if (_sourceType == SceneItemSourceType::SOURCE) {
obs_data_set_string(obj, "source",
GetWeakSourceName(_source).c_str());
_source.Save(obj);
} else {
obs_data_set_string(obj, "source", _sourceGroup.c_str());
obs_data_set_string(obj, "sourceGroup", _sourceGroup.c_str());
}
obs_data_set_int(obj, "action", static_cast<int>(_action));
obs_data_set_int(obj, "sourceType", static_cast<int>(_sourceType));
@ -128,13 +113,20 @@ bool MacroActionSceneVisibility::Save(obs_data_t *obj)
bool MacroActionSceneVisibility::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
obs_data_set_string(obj, "sourceGroup", sourceName);
}
MacroAction::Load(obj);
_scene.Load(obj);
_source.Load(obj);
_sourceType = static_cast<SceneItemSourceType>(
obs_data_get_int(obj, "sourceType"));
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_sourceGroup = sourceName;
_sourceGroup = obs_data_get_string(obj, "sourceGroup");
_action = static_cast<SceneVisibilityAction>(
obs_data_get_int(obj, "action"));
return true;
@ -142,8 +134,9 @@ bool MacroActionSceneVisibility::Load(obs_data_t *obj)
std::string MacroActionSceneVisibility::GetShortDesc()
{
if (_sourceType == SceneItemSourceType::SOURCE && _source) {
return _scene.ToString() + " - " + GetWeakSourceName(_source);
if (_sourceType == SceneItemSourceType::SOURCE &&
!_source.ToString().empty()) {
return _scene.ToString() + " - " + _source.ToString();
}
if (_sourceType == SceneItemSourceType::SOURCE_GROUP &&
!_sourceGroup.empty()) {
@ -175,11 +168,12 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
{
_scenes = new SceneSelectionWidget(window(), false, true, true);
_sourceTypes = new QComboBox();
_sources = new QComboBox();
_sources->setSizeAdjustPolicy(QComboBox::AdjustToContents);
_sources = new SceneItemSelectionWidget(parent);
_sourceGroups = new QComboBox();
_actions = new QComboBox();
populateSourceItemTypeSelection(_sourceTypes);
populateSourceGroupSelection(_sourceGroups);
populateActionSelection(_actions);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
@ -188,14 +182,19 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sourceTypes, SIGNAL(currentIndexChanged(int)), this,
SLOT(SourceTypeChanged(int)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_sourceGroups,
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(SourceGroupChanged(const QString &)));
QHBoxLayout *mainLayout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{scenes}}", _scenes},
{"{{sourceTypes}}", _sourceTypes},
{"{{sources}}", _sources},
{"{{scenes}}", _scenes}, {"{{sourceTypes}}", _sourceTypes},
{"{{sources}}", _sources}, {"{{sourceGroups}}", _sourceGroups},
{"{{actions}}", _actions},
};
placeWidgets(obs_module_text(
@ -218,14 +217,10 @@ void MacroActionSceneVisibilityEdit::UpdateEntryData()
_sourceTypes->setCurrentIndex(
static_cast<int>(_entryData->_sourceType));
_scenes->SetScene(_entryData->_scene);
if (_entryData->_sourceType == SceneItemSourceType::SOURCE) {
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
} else {
populateSourceTypeSelection(_sources);
_sources->setCurrentText(_entryData->_sourceGroup.c_str());
}
_sources->SetSceneItem((_entryData->_source));
_sourceGroups->setCurrentText(
QString::fromStdString(_entryData->_sourceGroup));
SetWidgetVisibility();
}
void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
@ -233,13 +228,9 @@ void MacroActionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->adjustSize();
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
void MacroActionSceneVisibilityEdit::SourceTypeChanged(int value)
@ -247,35 +238,36 @@ void MacroActionSceneVisibilityEdit::SourceTypeChanged(int value)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_sourceType =
static_cast<SceneItemSourceType>(value);
}
_sources->clear();
if (_entryData->_sourceType == SceneItemSourceType::SOURCE) {
populateSceneItemSelection(_sources, _entryData->_scene);
} else {
populateSourceTypeSelection(_sources);
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_sourceType = static_cast<SceneItemSourceType>(value);
SetWidgetVisibility();
}
void MacroActionSceneVisibilityEdit::SourceChanged(const QString &text)
void MacroActionSceneVisibilityEdit::SourceChanged(
const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
if (_entryData->_sourceType == SceneItemSourceType::SOURCE) {
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroActionSceneVisibilityEdit::SourceGroupChanged(const QString &text)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
if (text == obs_module_text("AdvSceneSwitcher.selectItem")) {
_entryData->_sourceGroup = "";
} else {
if (text == obs_module_text("AdvSceneSwitcher.selectItem")) {
_entryData->_sourceGroup = "";
} else {
_entryData->_sourceGroup = text.toStdString();
}
_entryData->_sourceGroup = text.toStdString();
}
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
@ -290,3 +282,15 @@ void MacroActionSceneVisibilityEdit::ActionChanged(int value)
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_action = static_cast<SceneVisibilityAction>(value);
}
void MacroActionSceneVisibilityEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
}
_sources->setVisible(_entryData->_sourceType ==
SceneItemSourceType::SOURCE);
_sourceGroups->setVisible(_entryData->_sourceType ==
SceneItemSourceType::SOURCE_GROUP);
adjustSize();
}

View File

@ -19,78 +19,110 @@ static std::map<SceneOrderCondition, std::string> sceneOrderConditionTypes = {
"AdvSceneSwitcher.condition.sceneOrder.type.position"},
};
struct PosInfo {
std::string name;
std::vector<int> pos = {};
struct PosInfo2 {
obs_scene_item *item;
int pos = -1;
int curPos = 0;
};
static bool getSceneItemPositions(obs_scene_t *, obs_sceneitem_t *item,
void *ptr)
static bool getSceneItemPositionHelper(obs_scene_t *, obs_sceneitem_t *item,
void *ptr)
{
PosInfo *posInfo = reinterpret_cast<PosInfo *>(ptr);
auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item));
if (posInfo->name == sourceName) {
posInfo->pos.push_back(posInfo->curPos);
PosInfo2 *posInfo = reinterpret_cast<PosInfo2 *>(ptr);
if (posInfo->item == item) {
posInfo->pos = posInfo->curPos;
return false;
}
if (obs_sceneitem_is_group(item)) {
obs_scene_t *scene = obs_sceneitem_group_get_scene(item);
obs_scene_enum_items(scene, getSceneItemPositions, ptr);
obs_scene_enum_items(scene, getSceneItemPositionHelper, ptr);
}
posInfo->curPos += 1;
return true;
}
static bool isAbove(std::vector<int> &v1, std::vector<int> &v2)
PosInfo2 getSceneItemPos(obs_scene_item *item, obs_scene *scene)
{
for (int i : v1) {
for (int j : v2) {
if (i > j) {
return true;
}
}
}
return false;
PosInfo2 pos{item};
obs_scene_enum_items(scene, getSceneItemPositionHelper, &pos);
return pos;
}
static bool isBelow(std::vector<int> &v1, std::vector<int> &v2)
std::vector<int> getSceneItemPositions(std::vector<obs_scene_item *> &items,
obs_scene *scene)
{
for (int i : v1) {
for (int j : v2) {
if (i < j) {
return true;
std::vector<int> positions;
for (auto item : items) {
auto pos = getSceneItemPos(item, scene);
if (pos.pos != -1) {
positions.emplace_back(pos.pos);
}
}
return positions;
}
static bool isAbove(std::vector<int> &pos1, std::vector<int> &pos2)
{
if (pos1.empty() || pos2.empty()) {
return false;
}
for (int i : pos1) {
for (int j : pos2) {
if (i <= j) {
return false;
}
}
}
return false;
return true;
}
static bool isBelow(std::vector<int> &pos1, std::vector<int> &pos2)
{
if (pos1.empty() || pos2.empty()) {
return false;
}
for (int i : pos1) {
for (int j : pos2) {
if (i >= j) {
return false;
}
}
}
return true;
}
bool MacroConditionSceneOrder::CheckCondition()
{
if (!_source) {
auto items1 = _source.GetSceneItems(_scene);
if (items1.empty()) {
return false;
}
bool ret = false;
auto items2 = _source2.GetSceneItems(_scene);
auto s = obs_weak_source_get_source(_scene.GetScene(false));
auto scene = obs_scene_from_source(s);
auto name1 = GetWeakSourceName(_source);
auto name2 = GetWeakSourceName(_source2);
PosInfo pos1 = {name1};
PosInfo pos2 = {name2};
obs_scene_enum_items(scene, getSceneItemPositions, &pos1);
obs_scene_enum_items(scene, getSceneItemPositions, &pos2);
auto positions1 = getSceneItemPositions(items1, scene);
auto positions2 = getSceneItemPositions(items2, scene);
for (auto i : items1) {
obs_sceneitem_release(i);
}
for (auto i : items2) {
obs_sceneitem_release(i);
}
bool ret = false;
switch (_condition) {
case SceneOrderCondition::ABOVE:
ret = isAbove(pos1.pos, pos2.pos);
ret = isAbove(positions1, positions2);
break;
case SceneOrderCondition::BELOW:
ret = isBelow(pos1.pos, pos2.pos);
ret = isBelow(positions1, positions2);
break;
case SceneOrderCondition::POSITION:
for (int p : pos1.pos) {
for (int p : positions1) {
if (p == _position)
ret = true;
}
@ -100,7 +132,6 @@ bool MacroConditionSceneOrder::CheckCondition()
}
obs_source_release(s);
return ret;
}
@ -108,9 +139,8 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj)
{
MacroCondition::Save(obj);
_scene.Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
obs_data_set_string(obj, "source2",
GetWeakSourceName(_source2).c_str());
_source.Save(obj);
_source2.Save(obj, "sceneItem2", "sceneItemTarget2", "sceneItemIdx2");
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
obs_data_set_int(obj, "position", _position);
return true;
@ -118,12 +148,19 @@ bool MacroConditionSceneOrder::Save(obs_data_t *obj)
bool MacroConditionSceneOrder::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
auto sourceName2 = obs_data_get_string(obj, "source2");
obs_data_set_string(obj, "sceneItem2", sourceName2);
}
MacroCondition::Load(obj);
_scene.Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
const char *source2Name = obs_data_get_string(obj, "source2");
_source2 = GetWeakSourceByName(source2Name);
_source.Load(obj);
_source2.Load(obj, "sceneItem2", "sceneItemTarget2", "sceneItemIdx2");
_condition = static_cast<SceneOrderCondition>(
obs_data_get_int(obj, "condition"));
_position = obs_data_get_int(obj, "position");
@ -132,15 +169,15 @@ bool MacroConditionSceneOrder::Load(obs_data_t *obj)
std::string MacroConditionSceneOrder::GetShortDesc()
{
if (_source) {
std::string header =
_scene.ToString() + " - " + GetWeakSourceName(_source);
if (_source2 && _condition != SceneOrderCondition::POSITION) {
header += " - " + GetWeakSourceName(_source2);
}
return header;
if (_source.ToString().empty()) {
return "";
}
return "";
std::string header = _scene.ToString() + " - " + _source.ToString();
if (!_source2.ToString().empty() &&
_condition != SceneOrderCondition::POSITION) {
header += " - " + _source2.ToString();
}
return header;
}
static inline void populateConditionSelection(QComboBox *list)
@ -155,21 +192,37 @@ MacroConditionSceneOrderEdit::MacroConditionSceneOrderEdit(
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), false, false, true);
_sources = new QComboBox();
_sources2 = new QComboBox();
_sources = new SceneItemSelectionWidget(parent);
_sources2 = new SceneItemSelectionWidget(parent);
_conditions = new QComboBox();
_position = new QSpinBox();
_posInfo = new QLabel(obs_module_text(
"AdvSceneSwitcher.condition.sceneOrder.positionInfo"));
populateConditionSelection(_conditions);
if (entryData.get()) {
if (entryData->_condition == SceneOrderCondition::POSITION) {
_sources->SetShowAllSelectionType(
SceneItemSelectionWidget::AllSelectionType::ANY);
} else {
_sources->SetShowAllSelectionType(
SceneItemSelectionWidget::AllSelectionType::ALL);
}
}
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_sources2, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(Source2Changed(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources2, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_sources2,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this,
SLOT(Source2Changed(const SceneItemSelection &)));
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
QWidget::connect(_position, SIGNAL(valueChanged(int)), this,
@ -199,36 +252,31 @@ void MacroConditionSceneOrderEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
_sources2->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
populateSceneItemSelection(_sources2, _entryData->_scene);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
void MacroConditionSceneOrderEdit::SourceChanged(const QString &text)
void MacroConditionSceneOrderEdit::SourceChanged(const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroConditionSceneOrderEdit::Source2Changed(const QString &text)
void MacroConditionSceneOrderEdit::Source2Changed(const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source2 = GetWeakSourceByQString(text);
_entryData->_source2 = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
@ -238,11 +286,21 @@ void MacroConditionSceneOrderEdit::ConditionChanged(int index)
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_condition = static_cast<SceneOrderCondition>(index);
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_condition =
static_cast<SceneOrderCondition>(index);
}
SetWidgetVisibility(_entryData->_condition ==
SceneOrderCondition::POSITION);
if (_entryData->_condition == SceneOrderCondition::POSITION) {
_sources->SetShowAllSelectionType(
SceneItemSelectionWidget::AllSelectionType::ANY);
} else {
_sources->SetShowAllSelectionType(
SceneItemSelectionWidget::AllSelectionType::ALL);
}
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
@ -272,12 +330,9 @@ void MacroConditionSceneOrderEdit::UpdateEntryData()
}
_scenes->SetScene(_entryData->_scene);
populateSceneItemSelection(_sources, _entryData->_scene);
populateSceneItemSelection(_sources2, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
_sources2->setCurrentText(
GetWeakSourceName(_entryData->_source2).c_str());
_sources->SetSceneItem(_entryData->_source);
_sources2->SetSceneItem(_entryData->_source2);
_position->setValue(_entryData->_position);
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
SetWidgetVisibility(_entryData->_condition ==
SceneOrderCondition::POSITION);

View File

@ -15,10 +15,7 @@ bool MacroConditionSceneTransform::_registered =
bool MacroConditionSceneTransform::CheckCondition()
{
bool ret = false;
auto s = obs_weak_source_get_source(_scene.GetScene(false));
auto scene = obs_scene_from_source(s);
auto name = GetWeakSourceName(_source);
auto items = getSceneItemsWithName(scene, name);
auto items = _source.GetSceneItems(_scene);
for (auto &item : items) {
auto json = getSceneItemTransform(item);
@ -27,8 +24,6 @@ bool MacroConditionSceneTransform::CheckCondition()
}
obs_sceneitem_release(item);
}
obs_source_release(s);
return ret;
}
@ -36,7 +31,7 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj)
{
MacroCondition::Save(obj);
_scene.Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
_source.Save(obj);
obs_data_set_string(obj, "settings", _settings.c_str());
obs_data_set_bool(obj, "regex", _regex);
return true;
@ -44,10 +39,16 @@ bool MacroConditionSceneTransform::Save(obs_data_t *obj)
bool MacroConditionSceneTransform::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
}
MacroCondition::Load(obj);
_scene.Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_source.Load(obj);
_settings = obs_data_get_string(obj, "settings");
_regex = obs_data_get_bool(obj, "regex");
return true;
@ -55,10 +56,11 @@ bool MacroConditionSceneTransform::Load(obs_data_t *obj)
std::string MacroConditionSceneTransform::GetShortDesc()
{
if (_source) {
return _scene.ToString() + " - " + GetWeakSourceName(_source);
if (_source.ToString().empty()) {
return "";
}
return "";
return _scene.ToString() + " - " + _source.ToString();
}
MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
@ -67,7 +69,8 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), false, false, true);
_sources = new QComboBox();
_sources = new SceneItemSelectionWidget(
parent, true, SceneItemSelectionWidget::AllSelectionType::ANY);
_getSettings = new QPushButton(obs_module_text(
"AdvSceneSwitcher.condition.sceneTransform.getTransform"));
_settings = new QPlainTextEdit();
@ -76,8 +79,11 @@ MacroConditionSceneTransformEdit::MacroConditionSceneTransformEdit(
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_getSettings, SIGNAL(clicked()), this,
SLOT(GetSettingsClicked()));
QWidget::connect(_settings, SIGNAL(textChanged()), this,
@ -125,14 +131,9 @@ void MacroConditionSceneTransformEdit::UpdateEntryData()
}
_scenes->SetScene(_entryData->_scene);
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
_sources->SetSceneItem(_entryData->_source);
_regex->setChecked(_entryData->_regex);
if (_entryData->_source) {
_settings->setPlainText(
QString::fromStdString(_entryData->_settings));
}
_settings->setPlainText(QString::fromStdString(_entryData->_settings));
}
void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
@ -140,48 +141,45 @@ void MacroConditionSceneTransformEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
void MacroConditionSceneTransformEdit::SourceChanged(const QString &text)
void MacroConditionSceneTransformEdit::SourceChanged(
const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroConditionSceneTransformEdit::GetSettingsClicked()
{
if (_loading || !_entryData || !_entryData->_scene.GetScene(false) ||
!_entryData->_source) {
if (_loading || !_entryData || !_entryData->_scene.GetScene(false)) {
return;
}
auto s = obs_weak_source_get_source(_entryData->_scene.GetScene(false));
auto scene = obs_scene_from_source(s);
auto name = GetWeakSourceName(_entryData->_source);
auto item = obs_scene_find_source_recursive(scene, name.c_str());
obs_source_release(s);
if (!item) {
auto items = _entryData->_source.GetSceneItems(_entryData->_scene);
if (items.empty()) {
return;
}
QString json = formatJsonString(getSceneItemTransform(item));
auto settings = formatJsonString(getSceneItemTransform(items[0]));
if (_entryData->_regex) {
json = escapeForRegex(json);
settings = escapeForRegex(settings);
}
_settings->setPlainText(settings);
for (auto item : items) {
obs_sceneitem_release(item);
}
_settings->setPlainText(json);
}
void MacroConditionSceneTransformEdit::SettingsChanged()

View File

@ -22,52 +22,54 @@ static std::map<SceneVisibilityCondition, std::string>
"AdvSceneSwitcher.condition.sceneVisibility.type.hidden"},
};
struct VisibilityData {
std::string name;
bool visible;
bool result;
};
static bool visibilityEnum(obs_scene_t *, obs_sceneitem_t *item, void *ptr)
bool areAllSceneItemsShown(std::vector<obs_scene_item *> &items)
{
VisibilityData *vInfo = reinterpret_cast<VisibilityData *>(ptr);
auto sourceName = obs_source_get_name(obs_sceneitem_get_source(item));
if (vInfo->name == sourceName &&
obs_sceneitem_visible(item) == vInfo->visible) {
vInfo->result = true;
return false;
bool ret = true;
for (auto item : items) {
if (!obs_sceneitem_visible(item)) {
ret = false;
}
obs_sceneitem_release(item);
}
return ret;
}
if (obs_sceneitem_is_group(item)) {
obs_scene_t *scene = obs_sceneitem_group_get_scene(item);
obs_scene_enum_items(scene, visibilityEnum, ptr);
bool areAllSceneItemsHidden(std::vector<obs_scene_item *> &items)
{
bool ret = true;
for (auto item : items) {
if (obs_sceneitem_visible(item)) {
ret = false;
}
obs_sceneitem_release(item);
}
return true;
return ret;
}
bool MacroConditionSceneVisibility::CheckCondition()
{
if (!_source) {
auto items = _source.GetSceneItems(_scene);
if (items.empty()) {
return false;
}
auto s = obs_weak_source_get_source(_scene.GetScene());
auto scene = obs_scene_from_source(s);
auto sourceName = GetWeakSourceName(_source);
VisibilityData data = {sourceName,
_condition == SceneVisibilityCondition::SHOWN,
false};
obs_scene_enum_items(scene, visibilityEnum, &data);
obs_source_release(s);
return data.result;
switch (_condition) {
case SceneVisibilityCondition::SHOWN:
return areAllSceneItemsShown(items);
case SceneVisibilityCondition::HIDDEN:
return areAllSceneItemsHidden(items);
break;
default:
break;
}
return false;
}
bool MacroConditionSceneVisibility::Save(obs_data_t *obj)
{
MacroCondition::Save(obj);
_scene.Save(obj);
obs_data_set_string(obj, "source", GetWeakSourceName(_source).c_str());
_source.Save(obj);
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
@ -76,10 +78,16 @@ bool MacroConditionSceneVisibility::Save(obs_data_t *obj)
bool MacroConditionSceneVisibility::Load(obs_data_t *obj)
{
// Convert old data format
// TODO: Remove in future version
if (obs_data_has_user_value(obj, "source")) {
auto sourceName = obs_data_get_string(obj, "source");
obs_data_set_string(obj, "sceneItem", sourceName);
}
MacroCondition::Load(obj);
_scene.Load(obj);
const char *sourceName = obs_data_get_string(obj, "source");
_source = GetWeakSourceByName(sourceName);
_source.Load(obj);
_condition = static_cast<SceneVisibilityCondition>(
obs_data_get_int(obj, "condition"));
return true;
@ -87,10 +95,10 @@ bool MacroConditionSceneVisibility::Load(obs_data_t *obj)
std::string MacroConditionSceneVisibility::GetShortDesc()
{
if (_source) {
return _scene.ToString() + " - " + GetWeakSourceName(_source);
if (_source.ToString().empty()) {
return "";
}
return "";
return _scene.ToString() + " - " + _source.ToString();
}
static inline void populateConditionSelection(QComboBox *list)
@ -106,16 +114,18 @@ MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit(
: QWidget(parent)
{
_scenes = new SceneSelectionWidget(window(), false, true, true);
_sources = new QComboBox();
_sources->setSizeAdjustPolicy(QComboBox::AdjustToContents);
_sources = new SceneItemSelectionWidget(parent);
_conditions = new QComboBox();
populateConditionSelection(_conditions);
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
this, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources, SIGNAL(currentTextChanged(const QString &)),
this, SLOT(SourceChanged(const QString &)));
QWidget::connect(_scenes, SIGNAL(SceneChanged(const SceneSelection &)),
_sources, SLOT(SceneChanged(const SceneSelection &)));
QWidget::connect(_sources,
SIGNAL(SceneItemChanged(const SceneItemSelection &)),
this, SLOT(SourceChanged(const SceneItemSelection &)));
QWidget::connect(_conditions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ConditionChanged(int)));
@ -136,14 +146,17 @@ MacroConditionSceneVisibilityEdit::MacroConditionSceneVisibilityEdit(
_loading = false;
}
void MacroConditionSceneVisibilityEdit::SourceChanged(const QString &text)
void MacroConditionSceneVisibilityEdit::SourceChanged(
const SceneItemSelection &item)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_source = GetWeakSourceByQString(text);
_entryData->_source = item;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroConditionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
@ -151,13 +164,10 @@ void MacroConditionSceneVisibilityEdit::SceneChanged(const SceneSelection &s)
if (_loading || !_entryData) {
return;
}
{
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
}
_sources->clear();
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->adjustSize();
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_scene = s;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroConditionSceneVisibilityEdit::ConditionChanged(int index)
@ -178,7 +188,5 @@ void MacroConditionSceneVisibilityEdit::UpdateEntryData()
_conditions->setCurrentIndex(static_cast<int>(_entryData->_condition));
_scenes->SetScene(_entryData->_scene);
populateSceneItemSelection(_sources, _entryData->_scene);
_sources->setCurrentText(
GetWeakSourceName(_entryData->_source).c_str());
_sources->SetSceneItem(_entryData->_source);
}