Merge pull request #1195 from admshao/fix-save-projectors-on-exit
Save Windowed Projectors on exit
This commit is contained in:
commit
7481f5b389
@ -137,11 +137,6 @@ OBSBasic::OBSBasic(QWidget *parent)
|
||||
{
|
||||
setAttribute(Qt::WA_NativeWindow);
|
||||
|
||||
projectorArray.resize(10, "");
|
||||
previewProjectorArray.resize(10, 0);
|
||||
multiviewProjectorArray.resize(10, 0);
|
||||
studioProgramProjectorArray.resize(10, 0);
|
||||
|
||||
setAcceptDrops(true);
|
||||
|
||||
ui->setupUi(this);
|
||||
@ -319,10 +314,7 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
|
||||
obs_data_array_t *quickTransitionData, int transitionDuration,
|
||||
obs_data_array_t *transitions,
|
||||
OBSScene &scene, OBSSource &curProgramScene,
|
||||
obs_data_array_t *savedProjectorList,
|
||||
obs_data_array_t *savedPreviewProjectorList,
|
||||
obs_data_array_t *savedStudioProgramProjectorList,
|
||||
obs_data_array_t *savedMultiviewProjectorList)
|
||||
obs_data_array_t *savedProjectorList)
|
||||
{
|
||||
obs_data_t *saveData = obs_data_create();
|
||||
|
||||
@ -364,12 +356,6 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
|
||||
obs_data_set_array(saveData, "quick_transitions", quickTransitionData);
|
||||
obs_data_set_array(saveData, "transitions", transitions);
|
||||
obs_data_set_array(saveData, "saved_projectors", savedProjectorList);
|
||||
obs_data_set_array(saveData, "saved_preview_projectors",
|
||||
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",
|
||||
@ -439,62 +425,41 @@ obs_data_array_t *OBSBasic::SaveSceneListOrder()
|
||||
|
||||
obs_data_array_t *OBSBasic::SaveProjectors()
|
||||
{
|
||||
obs_data_array_t *saveProjector = obs_data_array_create();
|
||||
obs_data_array_t *savedProjectors = obs_data_array_create();
|
||||
|
||||
auto saveProjector = [savedProjectors](OBSProjector *projector) {
|
||||
if (!projector)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < projectorArray.size(); i++) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_string(data, "saved_projectors",
|
||||
projectorArray.at(i).c_str());
|
||||
obs_data_array_push_back(saveProjector, data);
|
||||
ProjectorType type = projector->GetProjectorType();
|
||||
switch (type) {
|
||||
case ProjectorType::Scene:
|
||||
case ProjectorType::Source: {
|
||||
obs_source_t *source = projector->GetSource();
|
||||
const char *name = obs_source_get_name(source);
|
||||
obs_data_set_string(data, "name", name);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
obs_data_set_int(data, "monitor", projector->GetMonitor());
|
||||
obs_data_set_int(data, "type", static_cast<int>(type));
|
||||
obs_data_set_string(data, "geometry",
|
||||
projector->saveGeometry().toBase64()
|
||||
.constData());
|
||||
obs_data_array_push_back(savedProjectors, data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
};
|
||||
|
||||
return saveProjector;
|
||||
}
|
||||
for (QPointer<QWidget> &proj : projectors)
|
||||
saveProjector(static_cast<OBSProjector *>(proj.data()));
|
||||
|
||||
obs_data_array_t *OBSBasic::SavePreviewProjectors()
|
||||
{
|
||||
obs_data_array_t *saveProjector = obs_data_array_create();
|
||||
for (QPointer<QWidget> &proj : windowProjectors)
|
||||
saveProjector(static_cast<OBSProjector *>(proj.data()));
|
||||
|
||||
for (size_t i = 0; i < previewProjectorArray.size(); i++) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_int(data, "saved_preview_projectors",
|
||||
previewProjectorArray.at(i));
|
||||
obs_data_array_push_back(saveProjector, data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
return saveProjector;
|
||||
}
|
||||
|
||||
obs_data_array_t *OBSBasic::SaveStudioProgramProjectors()
|
||||
{
|
||||
obs_data_array_t *saveProjector = obs_data_array_create();
|
||||
|
||||
for (size_t i = 0; i < studioProgramProjectorArray.size(); i++) {
|
||||
obs_data_t *data = obs_data_create();
|
||||
obs_data_set_int(data, "saved_studio_preview_projectors",
|
||||
studioProgramProjectorArray.at(i));
|
||||
obs_data_array_push_back(saveProjector, data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
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;
|
||||
return savedProjectors;
|
||||
}
|
||||
|
||||
void OBSBasic::Save(const char *file)
|
||||
@ -508,17 +473,9 @@ void OBSBasic::Save(const char *file)
|
||||
obs_data_array_t *transitions = SaveTransitions();
|
||||
obs_data_array_t *quickTrData = SaveQuickTransitions();
|
||||
obs_data_array_t *savedProjectorList = SaveProjectors();
|
||||
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,
|
||||
savedMultiviewProjectorList);
|
||||
scene, curProgramScene, savedProjectorList);
|
||||
|
||||
obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
|
||||
obs_data_set_bool(saveData, "scaling_enabled",
|
||||
@ -545,9 +502,6 @@ void OBSBasic::Save(const char *file)
|
||||
obs_data_array_release(quickTrData);
|
||||
obs_data_array_release(transitions);
|
||||
obs_data_array_release(savedProjectorList);
|
||||
obs_data_array_release(savedPreviewProjectorList);
|
||||
obs_data_array_release(savedStudioProgramProjectorList);
|
||||
obs_data_array_release(savedMultiviewProjectorList);
|
||||
}
|
||||
|
||||
void OBSBasic::DeferSaveBegin()
|
||||
@ -666,47 +620,15 @@ void OBSBasic::LoadSavedProjectors(obs_data_array_t *array)
|
||||
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
obs_data_t *data = obs_data_array_item(array, i);
|
||||
projectorArray.at(i) = obs_data_get_string(data,
|
||||
"saved_projectors");
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasic::LoadSavedPreviewProjectors(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);
|
||||
previewProjectorArray.at(i) = obs_data_get_int(data,
|
||||
"saved_preview_projectors");
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
}
|
||||
|
||||
void OBSBasic::LoadSavedStudioProgramProjectors(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);
|
||||
studioProgramProjectorArray.at(i) = obs_data_get_int(data,
|
||||
"saved_studio_preview_projectors");
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
SavedProjectorInfo *info = new SavedProjectorInfo();
|
||||
info->monitor = obs_data_get_int(data, "monitor");
|
||||
info->type = static_cast<ProjectorType>(obs_data_get_int(data,
|
||||
"type"));
|
||||
info->geometry = std::string(
|
||||
obs_data_get_string(data, "geometry"));
|
||||
info->name = std::string(obs_data_get_string(data, "name"));
|
||||
savedProjectorsArray.emplace_back(info);
|
||||
|
||||
obs_data_release(data);
|
||||
}
|
||||
@ -847,47 +769,6 @@ void OBSBasic::Load(const char *file)
|
||||
ui->transitionDuration->setValue(newDuration);
|
||||
SetTransition(curTransition);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
obs_data_array_t *savedProjectors = obs_data_get_array(data,
|
||||
"saved_projectors");
|
||||
|
||||
if (savedProjectors)
|
||||
LoadSavedProjectors(savedProjectors);
|
||||
|
||||
obs_data_array_release(savedProjectors);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
obs_data_array_t *savedPreviewProjectors = obs_data_get_array(data,
|
||||
"saved_preview_projectors");
|
||||
|
||||
if (savedPreviewProjectors)
|
||||
LoadSavedPreviewProjectors(savedPreviewProjectors);
|
||||
|
||||
obs_data_array_release(savedPreviewProjectors);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
obs_data_array_t *savedStudioProgramProjectors = obs_data_get_array(data,
|
||||
"saved_studio_preview_projectors");
|
||||
|
||||
if (savedStudioProgramProjectors)
|
||||
LoadSavedStudioProgramProjectors(savedStudioProgramProjectors);
|
||||
|
||||
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);
|
||||
curProgramScene = obs_get_source_by_name(programSceneName);
|
||||
@ -918,6 +799,23 @@ retryScene:
|
||||
obs_data_array_release(sources);
|
||||
obs_data_array_release(sceneOrder);
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
bool projectorSave = config_get_bool(GetGlobalConfig(), "BasicWindow",
|
||||
"SaveProjectors");
|
||||
|
||||
if (projectorSave) {
|
||||
obs_data_array_t *savedProjectors = obs_data_get_array(data,
|
||||
"saved_projectors");
|
||||
|
||||
if (savedProjectors)
|
||||
LoadSavedProjectors(savedProjectors);
|
||||
|
||||
obs_data_array_release(savedProjectors);
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
std::string file_base = strrchr(file, '/') + 1;
|
||||
file_base.erase(file_base.size() - 5, 5);
|
||||
|
||||
@ -1608,8 +1506,6 @@ void OBSBasic::OBSInit()
|
||||
|
||||
SystemTray(true);
|
||||
|
||||
OpenSavedProjectors();
|
||||
|
||||
if (windowState().testFlag(Qt::WindowFullScreen))
|
||||
fullscreenInterface = true;
|
||||
|
||||
@ -2365,13 +2261,7 @@ void OBSBasic::RenameSources(OBSSource source, QString newName,
|
||||
volumes[i]->SetName(newName);
|
||||
}
|
||||
|
||||
std::string newText = newName.toUtf8().constData();
|
||||
std::string prevText = prevName.toUtf8().constData();
|
||||
|
||||
for (size_t j = 0; j < projectorArray.size(); j++) {
|
||||
if (projectorArray.at(j) == prevText)
|
||||
projectorArray.at(j) = newText;
|
||||
}
|
||||
OBSProjector::RenameProjector(prevName, newName);
|
||||
|
||||
SaveProject();
|
||||
|
||||
@ -5615,40 +5505,17 @@ void OBSBasic::NudgeDown() {Nudge(1, MoveDir::Down);}
|
||||
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,
|
||||
OBSProjector *OBSBasic::OpenProjector(obs_source_t *source, int monitor,
|
||||
QString title, ProjectorType type)
|
||||
{
|
||||
/* seriously? 10 monitors? */
|
||||
if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
|
||||
return;
|
||||
return nullptr;
|
||||
|
||||
if (!window) {
|
||||
delete projectors[monitor];
|
||||
projectors[monitor].clear();
|
||||
RemoveSavedProjectors(monitor);
|
||||
}
|
||||
|
||||
OBSProjector *projector = new OBSProjector(nullptr, source, !!window);
|
||||
const char *name = obs_source_get_name(source);
|
||||
|
||||
if (!window) {
|
||||
if (type == ProjectorType::StudioProgram) {
|
||||
studioProgramProjectorArray.at((size_t)monitor) = 1;
|
||||
} 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, type);
|
||||
projectors[monitor] = projector;
|
||||
} else {
|
||||
projector->Init(monitor, true, title, type);
|
||||
OBSProjector *projector = new OBSProjector(nullptr, source, monitor,
|
||||
title, type);
|
||||
|
||||
if (monitor < 0) {
|
||||
for (auto &projPtr : windowProjectors) {
|
||||
if (!projPtr) {
|
||||
projPtr = projector;
|
||||
@ -5658,20 +5525,27 @@ void OBSBasic::OpenProjector(obs_source_t *source, int monitor, bool window,
|
||||
|
||||
if (projector)
|
||||
windowProjectors.push_back(projector);
|
||||
} else {
|
||||
delete projectors[monitor];
|
||||
projectors[monitor].clear();
|
||||
|
||||
projectors[monitor] = projector;
|
||||
}
|
||||
|
||||
projector->Init();
|
||||
return projector;
|
||||
}
|
||||
|
||||
void OBSBasic::OpenStudioProgramProjector()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OpenProjector(nullptr, monitor, false, nullptr,
|
||||
ProjectorType::StudioProgram);
|
||||
OpenProjector(nullptr, monitor, nullptr, ProjectorType::StudioProgram);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenPreviewProjector()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OpenProjector(nullptr, monitor, false, nullptr, ProjectorType::Preview);
|
||||
OpenProjector(nullptr, monitor, nullptr, ProjectorType::Preview);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenSourceProjector()
|
||||
@ -5681,14 +5555,14 @@ void OBSBasic::OpenSourceProjector()
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
OpenProjector(obs_sceneitem_get_source(item), monitor, false);
|
||||
OpenProjector(obs_sceneitem_get_source(item), monitor, nullptr,
|
||||
ProjectorType::Source);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenMultiviewProjector()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OpenProjector(nullptr, monitor, false, nullptr,
|
||||
ProjectorType::Multiview);
|
||||
OpenProjector(nullptr, monitor, nullptr, ProjectorType::Multiview);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenSceneProjector()
|
||||
@ -5698,59 +5572,52 @@ void OBSBasic::OpenSceneProjector()
|
||||
if (!scene)
|
||||
return;
|
||||
|
||||
OpenProjector(obs_scene_get_source(scene), monitor, false);
|
||||
OpenProjector(obs_scene_get_source(scene), monitor, nullptr,
|
||||
ProjectorType::Scene);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenStudioProgramWindow()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
QString title = QTStr("StudioProgramWindow");
|
||||
OpenProjector(nullptr, monitor, true, title,
|
||||
OpenProjector(nullptr, -1, QTStr("StudioProgramWindow"),
|
||||
ProjectorType::StudioProgram);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenPreviewWindow()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
QString title = QTStr("PreviewWindow");
|
||||
OpenProjector(nullptr, monitor, true, nullptr, ProjectorType::Preview);
|
||||
OpenProjector(nullptr, -1, QTStr("PreviewWindow"),
|
||||
ProjectorType::Preview);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenSourceWindow()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OBSSceneItem item = GetCurrentSceneItem();
|
||||
OBSSource source = obs_sceneitem_get_source(item);
|
||||
QString text = QString::fromUtf8(obs_source_get_name(source));
|
||||
|
||||
QString title = QTStr("SourceWindow") + " - " + text;
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
OpenProjector(obs_sceneitem_get_source(item), monitor, true, title);
|
||||
OBSSource source = obs_sceneitem_get_source(item);
|
||||
QString title = QString::fromUtf8(obs_source_get_name(source));
|
||||
|
||||
OpenProjector(obs_sceneitem_get_source(item), -1, title,
|
||||
ProjectorType::Source);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenMultiviewWindow()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OpenProjector(nullptr, monitor, true, "Multiview",
|
||||
OpenProjector(nullptr, -1, QTStr("MultiviewWindowed"),
|
||||
ProjectorType::Multiview);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenSceneWindow()
|
||||
{
|
||||
int monitor = sender()->property("monitor").toInt();
|
||||
OBSScene scene = GetCurrentScene();
|
||||
OBSSource source = obs_scene_get_source(scene);
|
||||
QString text = QString::fromUtf8(obs_source_get_name(source));
|
||||
|
||||
QString title = QTStr("SceneWindow") + " - " + text;
|
||||
|
||||
if (!scene)
|
||||
return;
|
||||
|
||||
OpenProjector(obs_scene_get_source(scene), monitor, true, title);
|
||||
OBSSource source = obs_scene_get_source(scene);
|
||||
QString title = QString::fromUtf8(obs_source_get_name(source));
|
||||
|
||||
OpenProjector(obs_scene_get_source(scene), -1, title,
|
||||
ProjectorType::Scene);
|
||||
}
|
||||
|
||||
void OBSBasic::OpenSavedProjectors()
|
||||
@ -5758,54 +5625,65 @@ void OBSBasic::OpenSavedProjectors()
|
||||
bool projectorSave = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "SaveProjectors");
|
||||
|
||||
if (projectorSave) {
|
||||
for (size_t i = 0; i < projectorArray.size(); i++) {
|
||||
if (projectorArray.at(i).empty() == false) {
|
||||
OBSSource source = obs_get_source_by_name(
|
||||
projectorArray.at(i).c_str());
|
||||
if (!projectorSave)
|
||||
return;
|
||||
|
||||
if (!source) {
|
||||
RemoveSavedProjectors((int)i);
|
||||
obs_source_release(source);
|
||||
continue;
|
||||
}
|
||||
for (SavedProjectorInfo *info : savedProjectorsArray) {
|
||||
OBSProjector *projector = nullptr;
|
||||
switch (info->type) {
|
||||
case ProjectorType::Source:
|
||||
case ProjectorType::Scene: {
|
||||
OBSSource source = obs_get_source_by_name(
|
||||
info->name.c_str());
|
||||
if (!source)
|
||||
continue;
|
||||
|
||||
OpenProjector(source, (int)i, false);
|
||||
obs_source_release(source);
|
||||
}
|
||||
QString title = nullptr;
|
||||
if (info->monitor < 0)
|
||||
title = QString::fromUtf8(
|
||||
obs_source_get_name(source));
|
||||
|
||||
projector = OpenProjector(source, info->monitor, title,
|
||||
info->type);
|
||||
|
||||
obs_source_release(source);
|
||||
break;
|
||||
}
|
||||
case ProjectorType::Preview: {
|
||||
projector = OpenProjector(nullptr, info->monitor,
|
||||
QTStr("PreviewWindow"),
|
||||
ProjectorType::Preview);
|
||||
break;
|
||||
}
|
||||
case ProjectorType::StudioProgram: {
|
||||
projector = OpenProjector(nullptr, info->monitor,
|
||||
QTStr("StudioProgramWindow"),
|
||||
ProjectorType::StudioProgram);
|
||||
break;
|
||||
}
|
||||
case ProjectorType::Multiview: {
|
||||
projector = OpenProjector(nullptr, info->monitor,
|
||||
QTStr("MultiviewWindowed"),
|
||||
ProjectorType::Multiview);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < studioProgramProjectorArray.size(); i++) {
|
||||
if (studioProgramProjectorArray.at(i) == 1) {
|
||||
OpenProjector(nullptr, (int)i, false, nullptr,
|
||||
ProjectorType::StudioProgram);
|
||||
}
|
||||
}
|
||||
if (!info->geometry.empty()) {
|
||||
QByteArray byteArray = QByteArray::fromBase64(
|
||||
QByteArray(info->geometry.c_str()));
|
||||
projector->restoreGeometry(byteArray);
|
||||
|
||||
for (size_t i = 0; i < previewProjectorArray.size(); i++) {
|
||||
if (previewProjectorArray.at(i) == 1) {
|
||||
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);
|
||||
if (!WindowPositionValid(projector->normalGeometry())) {
|
||||
QRect rect = App()->desktop()->geometry();
|
||||
projector->setGeometry(QStyle::alignedRect(
|
||||
Qt::LeftToRight,
|
||||
Qt::AlignCenter, size(), rect));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) = "";
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionFullscreenInterface_triggered()
|
||||
{
|
||||
if (!fullscreenInterface)
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "window-basic-transform.hpp"
|
||||
#include "window-basic-adv-audio.hpp"
|
||||
#include "window-basic-filters.hpp"
|
||||
#include "window-projector.hpp"
|
||||
|
||||
#include <obs-frontend-internal.hpp>
|
||||
|
||||
@ -67,11 +68,11 @@ enum class QtDataRole {
|
||||
OBSSignals,
|
||||
};
|
||||
|
||||
enum class ProjectorType {
|
||||
Source,
|
||||
Preview,
|
||||
StudioProgram,
|
||||
Multiview
|
||||
struct SavedProjectorInfo {
|
||||
ProjectorType type;
|
||||
int monitor;
|
||||
std::string geometry;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct QuickTransition {
|
||||
@ -120,11 +121,6 @@ private:
|
||||
|
||||
std::vector<OBSSignal> signalHandlers;
|
||||
|
||||
std::vector<std::string> projectorArray;
|
||||
std::vector<int> studioProgramProjectorArray;
|
||||
std::vector<int> multiviewProjectorArray;
|
||||
std::vector<int> previewProjectorArray;
|
||||
|
||||
bool loaded = false;
|
||||
long disableSaving = 1;
|
||||
bool projectChanged = false;
|
||||
@ -169,6 +165,7 @@ private:
|
||||
|
||||
ConfigFile basicConfig;
|
||||
|
||||
std::vector<SavedProjectorInfo*> savedProjectorsArray;
|
||||
QPointer<QWidget> projectors[10];
|
||||
QList<QPointer<QWidget>> windowProjectors;
|
||||
|
||||
@ -252,9 +249,9 @@ private:
|
||||
void ClearSceneData();
|
||||
|
||||
void Nudge(int dist, MoveDir dir);
|
||||
void OpenProjector(obs_source_t *source, int monitor, bool window,
|
||||
QString title = nullptr,
|
||||
ProjectorType type = ProjectorType::Source);
|
||||
|
||||
OBSProjector *OpenProjector(obs_source_t *source, int monitor,
|
||||
QString title, ProjectorType type);
|
||||
|
||||
void GetAudioSourceFilters();
|
||||
void GetAudioSourceProperties();
|
||||
@ -367,18 +364,6 @@ private:
|
||||
obs_data_array_t *SaveProjectors();
|
||||
void LoadSavedProjectors(obs_data_array_t *savedProjectors);
|
||||
|
||||
obs_data_array_t *SavePreviewProjectors();
|
||||
void LoadSavedPreviewProjectors(
|
||||
obs_data_array_t *savedPreviewProjectors);
|
||||
|
||||
obs_data_array_t *SaveStudioProgramProjectors();
|
||||
void LoadSavedStudioProgramProjectors(
|
||||
obs_data_array_t *savedStudioProgramProjectors);
|
||||
|
||||
obs_data_array_t *SaveMultiviewProjectors();
|
||||
void LoadSavedMultiviewProjectors(
|
||||
obs_data_array_t *savedMultiviewProjectors);
|
||||
|
||||
public slots:
|
||||
void DeferSaveBegin();
|
||||
void DeferSaveEnd();
|
||||
@ -571,7 +556,6 @@ public:
|
||||
void SystemTray(bool firstStarted);
|
||||
|
||||
void OpenSavedProjectors();
|
||||
void RemoveSavedProjectors(int monitor);
|
||||
|
||||
protected:
|
||||
virtual void closeEvent(QCloseEvent *event) override;
|
||||
|
@ -3,7 +3,8 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QMenu>
|
||||
#include <QScreen>
|
||||
#include "window-projector.hpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
#include "display-helpers.hpp"
|
||||
#include "qt-wrappers.hpp"
|
||||
#include "platform.hpp"
|
||||
@ -13,18 +14,25 @@
|
||||
#define VERTICAL_LEFT 2
|
||||
#define VERTICAL_RIGHT 3
|
||||
|
||||
static QList<OBSProjector *> windowedProjectors;
|
||||
static QList<OBSProjector *> multiviewProjectors;
|
||||
static bool updatingMultiview = false;
|
||||
static int multiviewLayout = HORIZONTAL_TOP;
|
||||
|
||||
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, bool window)
|
||||
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
||||
QString title, ProjectorType type_)
|
||||
: OBSQTDisplay (widget,
|
||||
Qt::Window),
|
||||
source (source_),
|
||||
removedSignal (obs_source_get_signal_handler(source),
|
||||
"remove", OBSSourceRemoved, this)
|
||||
{
|
||||
if (!window) {
|
||||
projectorTitle = title;
|
||||
savedMonitor = monitor;
|
||||
isWindow = savedMonitor < 0;
|
||||
type = type_;
|
||||
|
||||
if (!isWindow) {
|
||||
setWindowFlags(Qt::FramelessWindowHint |
|
||||
Qt::X11BypassWindowManagerHint);
|
||||
}
|
||||
@ -49,123 +57,12 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, bool window)
|
||||
|
||||
bool hideCursor = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "HideProjectorCursor");
|
||||
if (hideCursor && !window) {
|
||||
if (hideCursor && !isWindow) {
|
||||
QPixmap empty(16, 16);
|
||||
empty.fill(Qt::transparent);
|
||||
setCursor(QCursor(empty));
|
||||
}
|
||||
|
||||
App()->IncrementSleepInhibition();
|
||||
resize(480, 270);
|
||||
}
|
||||
|
||||
OBSProjector::~OBSProjector()
|
||||
{
|
||||
bool isMultiview = type == ProjectorType::Multiview;
|
||||
obs_display_remove_draw_callback(GetDisplay(),
|
||||
isMultiview ? OBSRenderMultiview : OBSRender, this);
|
||||
|
||||
if (source)
|
||||
obs_source_dec_showing(source);
|
||||
|
||||
if (isMultiview) {
|
||||
for (OBSWeakSource &weakSrc : multiviewScenes) {
|
||||
OBSSource src = OBSGetStrongRef(weakSrc);
|
||||
if (src)
|
||||
obs_source_dec_showing(src);
|
||||
}
|
||||
|
||||
obs_enter_graphics();
|
||||
gs_vertexbuffer_destroy(outerBox);
|
||||
gs_vertexbuffer_destroy(innerBox);
|
||||
gs_vertexbuffer_destroy(leftVLine);
|
||||
gs_vertexbuffer_destroy(rightVLine);
|
||||
gs_vertexbuffer_destroy(leftLine);
|
||||
gs_vertexbuffer_destroy(topLine);
|
||||
gs_vertexbuffer_destroy(rightLine);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
if (type == ProjectorType::Multiview)
|
||||
multiviewProjectors.removeAll(this);
|
||||
|
||||
App()->DecrementSleepInhibition();
|
||||
}
|
||||
|
||||
static OBSSource CreateLabel(const char *name, size_t h)
|
||||
{
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_t *font = obs_data_create();
|
||||
|
||||
std::string text;
|
||||
text += " ";
|
||||
text += name;
|
||||
text += " ";
|
||||
|
||||
#if defined(_WIN32)
|
||||
obs_data_set_string(font, "face", "Arial");
|
||||
#elif defined(__APPLE__)
|
||||
obs_data_set_string(font, "face", "Helvetica");
|
||||
#else
|
||||
obs_data_set_string(font, "face", "Monospace");
|
||||
#endif
|
||||
obs_data_set_int(font, "flags", 1); // Bold text
|
||||
obs_data_set_int(font, "size", int(h / 9.81));
|
||||
|
||||
obs_data_set_obj(settings, "font", font);
|
||||
obs_data_set_string(settings, "text", text.c_str());
|
||||
obs_data_set_bool(settings, "outline", false);
|
||||
|
||||
#ifdef _WIN32
|
||||
const char *text_source_id = "text_gdiplus";
|
||||
#else
|
||||
const char *text_source_id = "text_ft2_source";
|
||||
#endif
|
||||
|
||||
OBSSource txtSource = obs_source_create_private(text_source_id, name,
|
||||
settings);
|
||||
obs_source_release(txtSource);
|
||||
|
||||
obs_data_release(font);
|
||||
obs_data_release(settings);
|
||||
|
||||
return txtSource;
|
||||
}
|
||||
|
||||
void OBSProjector::Init(int monitor, bool window, QString title,
|
||||
ProjectorType type_)
|
||||
{
|
||||
QScreen *screen = QGuiApplication::screens()[monitor];
|
||||
|
||||
if (!window)
|
||||
setGeometry(screen->geometry());
|
||||
|
||||
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "ProjectorAlwaysOnTop");
|
||||
if (alwaysOnTop && !window)
|
||||
SetAlwaysOnTop(this, true);
|
||||
|
||||
if (window)
|
||||
setWindowTitle(title);
|
||||
|
||||
show();
|
||||
|
||||
if (source)
|
||||
obs_source_inc_showing(source);
|
||||
|
||||
if (!window) {
|
||||
QAction *action = new QAction(this);
|
||||
action->setShortcut(Qt::Key_Escape);
|
||||
addAction(action);
|
||||
connect(action, SIGNAL(triggered()), this,
|
||||
SLOT(EscapeTriggered()));
|
||||
activateWindow();
|
||||
}
|
||||
|
||||
savedMonitor = monitor;
|
||||
isWindow = window;
|
||||
type = type_;
|
||||
|
||||
if (type == ProjectorType::Multiview) {
|
||||
obs_enter_graphics();
|
||||
gs_render_start(true);
|
||||
@ -215,6 +112,113 @@ void OBSProjector::Init(int monitor, bool window, QString title,
|
||||
multiviewProjectors.push_back(this);
|
||||
}
|
||||
|
||||
App()->IncrementSleepInhibition();
|
||||
resize(480, 270);
|
||||
}
|
||||
|
||||
OBSProjector::~OBSProjector()
|
||||
{
|
||||
bool isMultiview = type == ProjectorType::Multiview;
|
||||
obs_display_remove_draw_callback(GetDisplay(),
|
||||
isMultiview ? OBSRenderMultiview : OBSRender, this);
|
||||
|
||||
if (source)
|
||||
obs_source_dec_showing(source);
|
||||
|
||||
if (isMultiview) {
|
||||
for (OBSWeakSource &weakSrc : multiviewScenes) {
|
||||
OBSSource src = OBSGetStrongRef(weakSrc);
|
||||
if (src)
|
||||
obs_source_dec_showing(src);
|
||||
}
|
||||
|
||||
obs_enter_graphics();
|
||||
gs_vertexbuffer_destroy(outerBox);
|
||||
gs_vertexbuffer_destroy(innerBox);
|
||||
gs_vertexbuffer_destroy(leftVLine);
|
||||
gs_vertexbuffer_destroy(rightVLine);
|
||||
gs_vertexbuffer_destroy(leftLine);
|
||||
gs_vertexbuffer_destroy(topLine);
|
||||
gs_vertexbuffer_destroy(rightLine);
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
if (type == ProjectorType::Multiview)
|
||||
multiviewProjectors.removeAll(this);
|
||||
|
||||
if (isWindow)
|
||||
windowedProjectors.removeAll(this);
|
||||
|
||||
App()->DecrementSleepInhibition();
|
||||
}
|
||||
|
||||
static OBSSource CreateLabel(const char *name, size_t h)
|
||||
{
|
||||
obs_data_t *settings = obs_data_create();
|
||||
obs_data_t *font = obs_data_create();
|
||||
|
||||
std::string text;
|
||||
text += " ";
|
||||
text += name;
|
||||
text += " ";
|
||||
|
||||
#if defined(_WIN32)
|
||||
obs_data_set_string(font, "face", "Arial");
|
||||
#elif defined(__APPLE__)
|
||||
obs_data_set_string(font, "face", "Helvetica");
|
||||
#else
|
||||
obs_data_set_string(font, "face", "Monospace");
|
||||
#endif
|
||||
obs_data_set_int(font, "flags", 1); // Bold text
|
||||
obs_data_set_int(font, "size", int(h / 9.81));
|
||||
|
||||
obs_data_set_obj(settings, "font", font);
|
||||
obs_data_set_string(settings, "text", text.c_str());
|
||||
obs_data_set_bool(settings, "outline", false);
|
||||
|
||||
#ifdef _WIN32
|
||||
const char *text_source_id = "text_gdiplus";
|
||||
#else
|
||||
const char *text_source_id = "text_ft2_source";
|
||||
#endif
|
||||
|
||||
OBSSource txtSource = obs_source_create_private(text_source_id, name,
|
||||
settings);
|
||||
obs_source_release(txtSource);
|
||||
|
||||
obs_data_release(font);
|
||||
obs_data_release(settings);
|
||||
|
||||
return txtSource;
|
||||
}
|
||||
|
||||
void OBSProjector::Init()
|
||||
{
|
||||
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
|
||||
"BasicWindow", "ProjectorAlwaysOnTop");
|
||||
if (alwaysOnTop && !isWindow)
|
||||
SetAlwaysOnTop(this, true);
|
||||
|
||||
show();
|
||||
|
||||
if (isWindow) {
|
||||
UpdateProjectorTitle(projectorTitle);
|
||||
windowedProjectors.push_back(this);
|
||||
} else {
|
||||
QScreen *screen = QGuiApplication::screens()[savedMonitor];
|
||||
setGeometry(screen->geometry());
|
||||
|
||||
QAction *action = new QAction(this);
|
||||
action->setShortcut(Qt::Key_Escape);
|
||||
addAction(action);
|
||||
connect(action, SIGNAL(triggered()), this,
|
||||
SLOT(EscapeTriggered()));
|
||||
activateWindow();
|
||||
}
|
||||
|
||||
if (source)
|
||||
obs_source_inc_showing(source);
|
||||
|
||||
ready = true;
|
||||
}
|
||||
|
||||
@ -588,6 +592,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
|
||||
return;
|
||||
|
||||
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
||||
OBSSource source = window->source;
|
||||
|
||||
uint32_t targetCX;
|
||||
uint32_t targetCY;
|
||||
@ -595,9 +600,9 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
|
||||
int newCX, newCY;
|
||||
float scale;
|
||||
|
||||
if (window->source) {
|
||||
targetCX = std::max(obs_source_get_width(window->source), 1u);
|
||||
targetCY = std::max(obs_source_get_height(window->source), 1u);
|
||||
if (source) {
|
||||
targetCX = std::max(obs_source_get_width(source), 1u);
|
||||
targetCY = std::max(obs_source_get_height(source), 1u);
|
||||
} else {
|
||||
struct obs_video_info ovi;
|
||||
obs_get_video_info(&ovi);
|
||||
@ -615,14 +620,12 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
|
||||
gs_ortho(0.0f, float(targetCX), 0.0f, float(targetCY), -100.0f, 100.0f);
|
||||
gs_set_viewport(x, y, newCX, newCY);
|
||||
|
||||
OBSSource source = window->source;
|
||||
|
||||
if (window->type == ProjectorType::Preview &&
|
||||
main->IsPreviewProgramMode()) {
|
||||
OBSSource curSource = main->GetCurrentSceneSource();
|
||||
|
||||
if (window->source != curSource) {
|
||||
obs_source_dec_showing(window->source);
|
||||
if (source != curSource) {
|
||||
obs_source_dec_showing(source);
|
||||
obs_source_inc_showing(curSource);
|
||||
source = curSource;
|
||||
}
|
||||
@ -796,11 +799,6 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
void OBSProjector::EscapeTriggered()
|
||||
{
|
||||
if (!isWindow) {
|
||||
OBSBasic *main = (OBSBasic*)obs_frontend_get_main_window();
|
||||
main->RemoveSavedProjectors(savedMonitor);
|
||||
}
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
@ -861,6 +859,41 @@ void OBSProjector::UpdateMultiview()
|
||||
multiviewLayout = HORIZONTAL_TOP;
|
||||
}
|
||||
|
||||
void OBSProjector::UpdateProjectorTitle(QString name)
|
||||
{
|
||||
projectorTitle = name;
|
||||
|
||||
QString title = nullptr;
|
||||
switch (type) {
|
||||
case ProjectorType::Scene:
|
||||
title = QTStr("SceneWindow") + " - " + name;
|
||||
break;
|
||||
case ProjectorType::Source:
|
||||
title = QTStr("SourceWindow") + " - " + name;
|
||||
break;
|
||||
default:
|
||||
title = name;
|
||||
break;
|
||||
}
|
||||
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
OBSSource OBSProjector::GetSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
ProjectorType OBSProjector::GetProjectorType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
int OBSProjector::GetMonitor()
|
||||
{
|
||||
return savedMonitor;
|
||||
}
|
||||
|
||||
void OBSProjector::UpdateMultiviewProjectors()
|
||||
{
|
||||
obs_enter_graphics();
|
||||
@ -874,3 +907,10 @@ void OBSProjector::UpdateMultiviewProjectors()
|
||||
updatingMultiview = false;
|
||||
obs_leave_graphics();
|
||||
}
|
||||
|
||||
void OBSProjector::RenameProjector(QString oldName, QString newName)
|
||||
{
|
||||
for (auto &projector : windowedProjectors)
|
||||
if (projector->projectorTitle == oldName)
|
||||
projector->UpdateProjectorTitle(newName);
|
||||
}
|
||||
|
@ -2,7 +2,14 @@
|
||||
|
||||
#include <obs.hpp>
|
||||
#include "qt-display.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
|
||||
enum class ProjectorType {
|
||||
Source,
|
||||
Scene,
|
||||
Preview,
|
||||
StudioProgram,
|
||||
Multiview
|
||||
};
|
||||
|
||||
class QMouseEvent;
|
||||
|
||||
@ -20,8 +27,9 @@ private:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
|
||||
int savedMonitor = 0;
|
||||
bool isWindow = false;
|
||||
int savedMonitor;
|
||||
bool isWindow;
|
||||
QString projectorTitle;
|
||||
ProjectorType type = ProjectorType::Source;
|
||||
OBSWeakSource multiviewScenes[8];
|
||||
OBSSource multiviewLabels[10];
|
||||
@ -35,16 +43,21 @@ private:
|
||||
bool ready = false;
|
||||
|
||||
void UpdateMultiview();
|
||||
void UpdateProjectorTitle(QString name);
|
||||
|
||||
private slots:
|
||||
void EscapeTriggered();
|
||||
|
||||
public:
|
||||
OBSProjector(QWidget *parent, obs_source_t *source, bool window);
|
||||
OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
|
||||
QString title, ProjectorType type_);
|
||||
~OBSProjector();
|
||||
|
||||
void Init(int monitor, bool window, QString title,
|
||||
ProjectorType type = ProjectorType::Source);
|
||||
void Init();
|
||||
|
||||
OBSSource GetSource();
|
||||
ProjectorType GetProjectorType();
|
||||
int GetMonitor();
|
||||
static void UpdateMultiviewProjectors();
|
||||
static void RenameProjector(QString oldName, QString newName);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user