|
|
@@ -139,6 +139,7 @@ OBSBasic::OBSBasic(QWidget *parent)
|
|
|
|
|
|
projectorArray.resize(10, "");
|
|
|
previewProjectorArray.resize(10, 0);
|
|
|
+ multiviewProjectorArray.resize(10, 0);
|
|
|
studioProgramProjectorArray.resize(10, 0);
|
|
|
|
|
|
setAcceptDrops(true);
|
|
|
@@ -320,7 +321,8 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
|
|
|
OBSScene &scene, OBSSource &curProgramScene,
|
|
|
obs_data_array_t *savedProjectorList,
|
|
|
obs_data_array_t *savedPreviewProjectorList,
|
|
|
- obs_data_array_t *savedStudioProgramProjectorList)
|
|
|
+ obs_data_array_t *savedStudioProgramProjectorList,
|
|
|
+ obs_data_array_t *savedMultiviewProjectorList)
|
|
|
{
|
|
|
obs_data_t *saveData = obs_data_create();
|
|
|
|
|
|
@@ -366,6 +368,8 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
|
|
|
savedPreviewProjectorList);
|
|
|
obs_data_set_array(saveData, "saved_studio_preview_projectors",
|
|
|
savedStudioProgramProjectorList);
|
|
|
+ obs_data_set_array(saveData, "saved_multiview_projectors",
|
|
|
+ savedMultiviewProjectorList);
|
|
|
obs_data_array_release(sourcesArray);
|
|
|
|
|
|
obs_data_set_string(saveData, "current_transition",
|
|
|
@@ -468,6 +472,21 @@ obs_data_array_t *OBSBasic::SaveStudioProgramProjectors()
|
|
|
return saveProjector;
|
|
|
}
|
|
|
|
|
|
+obs_data_array_t *OBSBasic::SaveMultiviewProjectors()
|
|
|
+{
|
|
|
+ obs_data_array_t *saveProjector = obs_data_array_create();
|
|
|
+
|
|
|
+ for (size_t i = 0; i < multiviewProjectorArray.size(); i++) {
|
|
|
+ obs_data_t *data = obs_data_create();
|
|
|
+ obs_data_set_int(data, "saved_multiview_projectors",
|
|
|
+ multiviewProjectorArray.at(i));
|
|
|
+ obs_data_array_push_back(saveProjector, data);
|
|
|
+ obs_data_release(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ return saveProjector;
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasic::Save(const char *file)
|
|
|
{
|
|
|
OBSScene scene = GetCurrentScene();
|
|
|
@@ -482,11 +501,14 @@ void OBSBasic::Save(const char *file)
|
|
|
obs_data_array_t *savedPreviewProjectorList = SavePreviewProjectors();
|
|
|
obs_data_array_t *savedStudioProgramProjectorList =
|
|
|
SaveStudioProgramProjectors();
|
|
|
+ obs_data_array_t *savedMultiviewProjectorList =
|
|
|
+ SaveMultiviewProjectors();
|
|
|
obs_data_t *saveData = GenerateSaveData(sceneOrder, quickTrData,
|
|
|
ui->transitionDuration->value(), transitions,
|
|
|
scene, curProgramScene, savedProjectorList,
|
|
|
savedPreviewProjectorList,
|
|
|
- savedStudioProgramProjectorList);
|
|
|
+ savedStudioProgramProjectorList,
|
|
|
+ savedMultiviewProjectorList);
|
|
|
|
|
|
obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
|
|
|
obs_data_set_bool(saveData, "scaling_enabled",
|
|
|
@@ -515,6 +537,7 @@ void OBSBasic::Save(const char *file)
|
|
|
obs_data_array_release(savedProjectorList);
|
|
|
obs_data_array_release(savedPreviewProjectorList);
|
|
|
obs_data_array_release(savedStudioProgramProjectorList);
|
|
|
+ obs_data_array_release(savedMultiviewProjectorList);
|
|
|
}
|
|
|
|
|
|
static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent)
|
|
|
@@ -653,6 +676,19 @@ void OBSBasic::LoadSavedStudioProgramProjectors(obs_data_array_t *array)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void OBSBasic::LoadSavedMultiviewProjectors(obs_data_array_t *array)
|
|
|
+{
|
|
|
+ size_t num = obs_data_array_count(array);
|
|
|
+
|
|
|
+ for (size_t i = 0; i < num; i++) {
|
|
|
+ obs_data_t *data = obs_data_array_item(array, i);
|
|
|
+ multiviewProjectorArray.at(i) = obs_data_get_int(data,
|
|
|
+ "saved_multiview_projectors");
|
|
|
+
|
|
|
+ obs_data_release(data);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val)
|
|
|
{
|
|
|
const char *name = obs_source_get_name(filter);
|
|
|
@@ -784,6 +820,8 @@ void OBSBasic::Load(const char *file)
|
|
|
ui->transitionDuration->setValue(newDuration);
|
|
|
SetTransition(curTransition);
|
|
|
|
|
|
+ /* ------------------- */
|
|
|
+
|
|
|
obs_data_array_t *savedProjectors = obs_data_get_array(data,
|
|
|
"saved_projectors");
|
|
|
|
|
|
@@ -792,6 +830,8 @@ void OBSBasic::Load(const char *file)
|
|
|
|
|
|
obs_data_array_release(savedProjectors);
|
|
|
|
|
|
+ /* ------------------- */
|
|
|
+
|
|
|
obs_data_array_t *savedPreviewProjectors = obs_data_get_array(data,
|
|
|
"saved_preview_projectors");
|
|
|
|
|
|
@@ -800,6 +840,8 @@ void OBSBasic::Load(const char *file)
|
|
|
|
|
|
obs_data_array_release(savedPreviewProjectors);
|
|
|
|
|
|
+ /* ------------------- */
|
|
|
+
|
|
|
obs_data_array_t *savedStudioProgramProjectors = obs_data_get_array(data,
|
|
|
"saved_studio_preview_projectors");
|
|
|
|
|
|
@@ -808,6 +850,16 @@ void OBSBasic::Load(const char *file)
|
|
|
|
|
|
obs_data_array_release(savedStudioProgramProjectors);
|
|
|
|
|
|
+ /* ------------------- */
|
|
|
+
|
|
|
+ obs_data_array_t *savedMultiviewProjectors = obs_data_get_array(data,
|
|
|
+ "saved_multiview_projectors");
|
|
|
+
|
|
|
+ if (savedMultiviewProjectors)
|
|
|
+ LoadSavedMultiviewProjectors(savedMultiviewProjectors);
|
|
|
+
|
|
|
+ obs_data_array_release(savedMultiviewProjectors);
|
|
|
+
|
|
|
|
|
|
retryScene:
|
|
|
curScene = obs_get_source_by_name(sceneName);
|
|
|
@@ -1927,6 +1979,11 @@ void OBSBasic::SaveProjectDeferred()
|
|
|
Save(savePath);
|
|
|
}
|
|
|
|
|
|
+OBSSource OBSBasic::GetProgramSource()
|
|
|
+{
|
|
|
+ return OBSGetStrongRef(programScene);
|
|
|
+}
|
|
|
+
|
|
|
OBSScene OBSBasic::GetCurrentScene()
|
|
|
{
|
|
|
QListWidgetItem *item = ui->scenes->currentItem();
|
|
|
@@ -2088,6 +2145,8 @@ void OBSBasic::AddScene(OBSSource source)
|
|
|
obs_source_t *source = obs_scene_get_source(scene);
|
|
|
blog(LOG_INFO, "User added scene '%s'",
|
|
|
obs_source_get_name(source));
|
|
|
+
|
|
|
+ OBSProjector::UpdateMultiviewProjectors();
|
|
|
}
|
|
|
|
|
|
if (api)
|
|
|
@@ -2122,6 +2181,8 @@ void OBSBasic::RemoveScene(OBSSource source)
|
|
|
if (!disableSaving) {
|
|
|
blog(LOG_INFO, "User Removed scene '%s'",
|
|
|
obs_source_get_name(source));
|
|
|
+
|
|
|
+ OBSProjector::UpdateMultiviewProjectors();
|
|
|
}
|
|
|
|
|
|
if (api)
|
|
|
@@ -2203,7 +2264,8 @@ static void RenameListValues(QListWidget *listWidget, const QString &newName,
|
|
|
items[i]->setText(newName);
|
|
|
}
|
|
|
|
|
|
-void OBSBasic::RenameSources(QString newName, QString prevName)
|
|
|
+void OBSBasic::RenameSources(OBSSource source, QString newName,
|
|
|
+ QString prevName)
|
|
|
{
|
|
|
RenameListValues(ui->scenes, newName, prevName);
|
|
|
|
|
|
@@ -2221,6 +2283,10 @@ void OBSBasic::RenameSources(QString newName, QString prevName)
|
|
|
}
|
|
|
|
|
|
SaveProject();
|
|
|
+
|
|
|
+ obs_scene_t *scene = obs_scene_from_source(source);
|
|
|
+ if (scene)
|
|
|
+ OBSProjector::UpdateMultiviewProjectors();
|
|
|
}
|
|
|
|
|
|
void OBSBasic::SelectSceneItem(OBSScene scene, OBSSceneItem item, bool select)
|
|
|
@@ -2816,11 +2882,13 @@ void OBSBasic::SourceDeactivated(void *data, calldata_t *params)
|
|
|
|
|
|
void OBSBasic::SourceRenamed(void *data, calldata_t *params)
|
|
|
{
|
|
|
+ obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
|
|
const char *newName = calldata_string(params, "new_name");
|
|
|
const char *prevName = calldata_string(params, "prev_name");
|
|
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
"RenameSources",
|
|
|
+ Q_ARG(OBSSource, source),
|
|
|
Q_ARG(QString, QT_UTF8(newName)),
|
|
|
Q_ARG(QString, QT_UTF8(prevName)));
|
|
|
|
|
|
@@ -3457,6 +3525,7 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
|
|
|
popup.addMenu(&order);
|
|
|
|
|
|
popup.addSeparator();
|
|
|
+
|
|
|
sceneProjectorMenu = new QMenu(QTStr("SceneProjector"));
|
|
|
AddProjectorMenuMonitors(sceneProjectorMenu, this,
|
|
|
SLOT(OpenSceneProjector()));
|
|
|
@@ -3475,6 +3544,36 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
|
|
|
|
|
|
QMenu *transitionMenu = CreatePerSceneTransitionMenu();
|
|
|
popup.addMenu(transitionMenu);
|
|
|
+
|
|
|
+ /* ---------------------- */
|
|
|
+
|
|
|
+ if (IsPreviewProgramMode()) {
|
|
|
+ QAction *multiviewAction = popup.addAction(
|
|
|
+ QTStr("ShowInMultiview"));
|
|
|
+
|
|
|
+ OBSSource source = GetCurrentSceneSource();
|
|
|
+ OBSData data = obs_source_get_private_settings(source);
|
|
|
+ obs_data_release(data);
|
|
|
+
|
|
|
+ obs_data_set_default_bool(data, "show_in_multiview",
|
|
|
+ true);
|
|
|
+ bool show = obs_data_get_bool(data, "show_in_multiview");
|
|
|
+
|
|
|
+ multiviewAction->setCheckable(true);
|
|
|
+ multiviewAction->setChecked(show);
|
|
|
+
|
|
|
+ auto showInMultiview = [this] (OBSData data)
|
|
|
+ {
|
|
|
+ bool show = obs_data_get_bool(data,
|
|
|
+ "show_in_multiview");
|
|
|
+ obs_data_set_bool(data, "show_in_multiview",
|
|
|
+ !show);
|
|
|
+ OBSProjector::UpdateMultiviewProjectors();
|
|
|
+ };
|
|
|
+
|
|
|
+ connect(multiviewAction, &QAction::triggered,
|
|
|
+ std::bind(showInMultiview, data));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
popup.exec(QCursor::pos());
|
|
|
@@ -3719,6 +3818,7 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
|
|
|
QMenu popup(this);
|
|
|
QPointer<QMenu> previewProjector;
|
|
|
QPointer<QMenu> sourceProjector;
|
|
|
+ QPointer<QMenu> multiviewProjectorMenu;
|
|
|
|
|
|
if (preview) {
|
|
|
QAction *action = popup.addAction(
|
|
|
@@ -3733,6 +3833,20 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
|
|
|
popup.addAction(ui->actionLockPreview);
|
|
|
popup.addMenu(ui->scalingMenu);
|
|
|
|
|
|
+ if (IsPreviewProgramMode()) {
|
|
|
+ multiviewProjectorMenu = new QMenu(
|
|
|
+ "Multiview Projector");
|
|
|
+ AddProjectorMenuMonitors(multiviewProjectorMenu, this,
|
|
|
+ SLOT(OpenMultiviewProjector()));
|
|
|
+ popup.addMenu(multiviewProjectorMenu);
|
|
|
+
|
|
|
+ QAction *multiviewWindow = popup.addAction(
|
|
|
+ "Multiview Windowed",
|
|
|
+ this, SLOT(OpenMultiviewWindow()));
|
|
|
+
|
|
|
+ popup.addAction(multiviewWindow);
|
|
|
+ }
|
|
|
+
|
|
|
previewProjector = new QMenu(QTStr("PreviewProjector"));
|
|
|
AddProjectorMenuMonitors(previewProjector, this,
|
|
|
SLOT(OpenPreviewProjector()));
|
|
|
@@ -5417,17 +5531,12 @@ void OBSBasic::NudgeLeft() {Nudge(1, MoveDir::Left);}
|
|
|
void OBSBasic::NudgeRight() {Nudge(1, MoveDir::Right);}
|
|
|
|
|
|
void OBSBasic::OpenProjector(obs_source_t *source, int monitor, bool window,
|
|
|
- QString title, bool studioProgram)
|
|
|
+ QString title, ProjectorType type)
|
|
|
{
|
|
|
/* seriously? 10 monitors? */
|
|
|
if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
|
|
|
return;
|
|
|
|
|
|
- bool isPreview = false;
|
|
|
-
|
|
|
- if (source == nullptr)
|
|
|
- isPreview = true;
|
|
|
-
|
|
|
if (!window) {
|
|
|
delete projectors[monitor];
|
|
|
projectors[monitor].clear();
|
|
|
@@ -5438,20 +5547,22 @@ void OBSBasic::OpenProjector(obs_source_t *source, int monitor, bool window,
|
|
|
const char *name = obs_source_get_name(source);
|
|
|
|
|
|
if (!window) {
|
|
|
- if (studioProgram) {
|
|
|
+ if (type == ProjectorType::StudioProgram) {
|
|
|
studioProgramProjectorArray.at((size_t)monitor) = 1;
|
|
|
- } else if (isPreview) {
|
|
|
+ } else if (type == ProjectorType::Preview) {
|
|
|
previewProjectorArray.at((size_t)monitor) = 1;
|
|
|
+ } else if (type == ProjectorType::Multiview) {
|
|
|
+ multiviewProjectorArray.at((size_t)monitor) = 1;
|
|
|
} else {
|
|
|
projectorArray.at((size_t)monitor) = name;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!window) {
|
|
|
- projector->Init(monitor, false, nullptr, studioProgram);
|
|
|
+ projector->Init(monitor, false, nullptr, type);
|
|
|
projectors[monitor] = projector;
|
|
|
} else {
|
|
|
- projector->Init(monitor, true, title, studioProgram);
|
|
|
+ projector->Init(monitor, true, title, type);
|
|
|
|
|
|
for (auto &projPtr : windowProjectors) {
|
|
|
if (!projPtr) {
|
|
|
@@ -5468,13 +5579,14 @@ void OBSBasic::OpenProjector(obs_source_t *source, int monitor, bool window,
|
|
|
void OBSBasic::OpenStudioProgramProjector()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
- OpenProjector(nullptr, monitor, false, nullptr, true);
|
|
|
+ OpenProjector(nullptr, monitor, false, nullptr,
|
|
|
+ ProjectorType::StudioProgram);
|
|
|
}
|
|
|
|
|
|
void OBSBasic::OpenPreviewProjector()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
- OpenProjector(nullptr, monitor, false);
|
|
|
+ OpenProjector(nullptr, monitor, false, nullptr, ProjectorType::Preview);
|
|
|
}
|
|
|
|
|
|
void OBSBasic::OpenSourceProjector()
|
|
|
@@ -5487,6 +5599,13 @@ void OBSBasic::OpenSourceProjector()
|
|
|
OpenProjector(obs_sceneitem_get_source(item), monitor, false);
|
|
|
}
|
|
|
|
|
|
+void OBSBasic::OpenMultiviewProjector()
|
|
|
+{
|
|
|
+ int monitor = sender()->property("monitor").toInt();
|
|
|
+ OpenProjector(nullptr, monitor, false, nullptr,
|
|
|
+ ProjectorType::Multiview);
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasic::OpenSceneProjector()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
@@ -5501,14 +5620,15 @@ void OBSBasic::OpenStudioProgramWindow()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
QString title = QTStr("StudioProgramWindow");
|
|
|
- OpenProjector(nullptr, monitor, true, title, true);
|
|
|
+ OpenProjector(nullptr, monitor, true, title,
|
|
|
+ ProjectorType::StudioProgram);
|
|
|
}
|
|
|
|
|
|
void OBSBasic::OpenPreviewWindow()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
QString title = QTStr("PreviewWindow");
|
|
|
- OpenProjector(nullptr, monitor, true, title);
|
|
|
+ OpenProjector(nullptr, monitor, true, nullptr, ProjectorType::Preview);
|
|
|
}
|
|
|
|
|
|
void OBSBasic::OpenSourceWindow()
|
|
|
@@ -5526,6 +5646,13 @@ void OBSBasic::OpenSourceWindow()
|
|
|
OpenProjector(obs_sceneitem_get_source(item), monitor, true, title);
|
|
|
}
|
|
|
|
|
|
+void OBSBasic::OpenMultiviewWindow()
|
|
|
+{
|
|
|
+ int monitor = sender()->property("monitor").toInt();
|
|
|
+ OpenProjector(nullptr, monitor, true, "Multiview",
|
|
|
+ ProjectorType::Multiview);
|
|
|
+}
|
|
|
+
|
|
|
void OBSBasic::OpenSceneWindow()
|
|
|
{
|
|
|
int monitor = sender()->property("monitor").toInt();
|
|
|
@@ -5566,13 +5693,21 @@ void OBSBasic::OpenSavedProjectors()
|
|
|
for (size_t i = 0; i < studioProgramProjectorArray.size(); i++) {
|
|
|
if (studioProgramProjectorArray.at(i) == 1) {
|
|
|
OpenProjector(nullptr, (int)i, false, nullptr,
|
|
|
- true);
|
|
|
+ ProjectorType::StudioProgram);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
for (size_t i = 0; i < previewProjectorArray.size(); i++) {
|
|
|
if (previewProjectorArray.at(i) == 1) {
|
|
|
- OpenProjector(nullptr, (int)i, false);
|
|
|
+ OpenProjector(nullptr, (int)i, false, nullptr,
|
|
|
+ ProjectorType::Preview);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (size_t i = 0; i < multiviewProjectorArray.size(); i++) {
|
|
|
+ if (multiviewProjectorArray.at(i) == 1) {
|
|
|
+ OpenProjector(nullptr, (int)i, false, nullptr,
|
|
|
+ ProjectorType::Multiview);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -5581,6 +5716,7 @@ void OBSBasic::OpenSavedProjectors()
|
|
|
void OBSBasic::RemoveSavedProjectors(int monitor)
|
|
|
{
|
|
|
studioProgramProjectorArray.at((size_t)monitor) = 0;
|
|
|
+ multiviewProjectorArray.at((size_t)monitor) = 0;
|
|
|
previewProjectorArray.at((size_t)monitor) = 0;
|
|
|
projectorArray.at((size_t)monitor) = "";
|
|
|
}
|