123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /******************************************************************************
- Copyright (C) 2023 by Lain Bailey <[email protected]>
- Zachary Lund <[email protected]>
- Philippe Groarke <[email protected]>
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- ******************************************************************************/
- #include "OBSBasic.hpp"
- #include "OBSProjector.hpp"
- obs_data_array_t *OBSBasic::SaveProjectors()
- {
- obs_data_array_t *savedProjectors = obs_data_array_create();
- auto saveProjector = [savedProjectors](OBSProjector *projector) {
- if (!projector)
- return;
- OBSDataAutoRelease data = obs_data_create();
- ProjectorType type = projector->GetProjectorType();
- switch (type) {
- case ProjectorType::Scene:
- case ProjectorType::Source: {
- OBSSource 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());
- if (projector->IsAlwaysOnTopOverridden())
- obs_data_set_bool(data, "alwaysOnTop", projector->IsAlwaysOnTop());
- obs_data_set_bool(data, "alwaysOnTopOverridden", projector->IsAlwaysOnTopOverridden());
- obs_data_array_push_back(savedProjectors, data);
- };
- for (size_t i = 0; i < projectors.size(); i++)
- saveProjector(static_cast<OBSProjector *>(projectors[i]));
- return savedProjectors;
- }
- void OBSBasic::LoadSavedProjectors(obs_data_array_t *array)
- {
- size_t num = obs_data_array_count(array);
- for (size_t i = 0; i < num; i++) {
- OBSDataAutoRelease data = obs_data_array_item(array, i);
- SavedProjectorInfo info = {};
- 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"));
- info.alwaysOnTop = obs_data_get_bool(data, "alwaysOnTop");
- info.alwaysOnTopOverridden = obs_data_get_bool(data, "alwaysOnTopOverridden");
- OpenSavedProjector(&info);
- }
- }
- void OBSBasic::updateMultiviewProjectorMenu()
- {
- ui->multiviewProjectorMenu->clear();
- AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this, &OBSBasic::OpenMultiviewProjector);
- ui->multiviewProjectorMenu->addSeparator();
- ui->multiviewProjectorMenu->addAction(QTStr("Projector.Window"), this, &OBSBasic::openMultiviewWindow);
- }
- void OBSBasic::ClearProjectors()
- {
- for (size_t i = 0; i < projectors.size(); i++) {
- if (projectors[i])
- delete projectors[i];
- }
- projectors.clear();
- }
- QList<QString> OBSBasic::GetProjectorMenuMonitorsFormatted()
- {
- QList<QString> projectorsFormatted;
- QList<QScreen *> screens = QGuiApplication::screens();
- for (int i = 0; i < screens.size(); i++) {
- QScreen *screen = screens[i];
- QRect screenGeometry = screen->geometry();
- qreal ratio = screen->devicePixelRatio();
- QString name = "";
- #if defined(__APPLE__) || defined(_WIN32)
- name = screen->name();
- #else
- name = screen->model().simplified();
- if (name.length() > 1 && name.endsWith("-"))
- name.chop(1);
- #endif
- name = name.simplified();
- if (name.length() == 0) {
- name = QString("%1 %2").arg(QTStr("Display")).arg(QString::number(i + 1));
- }
- QString str = QString("%1: %2x%3 @ %4,%5")
- .arg(name, QString::number(screenGeometry.width() * ratio),
- QString::number(screenGeometry.height() * ratio),
- QString::number(screenGeometry.x()), QString::number(screenGeometry.y()));
- projectorsFormatted.push_back(str);
- }
- return projectorsFormatted;
- }
- void OBSBasic::DeleteProjector(OBSProjector *projector)
- {
- for (size_t i = 0; i < projectors.size(); i++) {
- if (projectors[i] == projector) {
- projectors[i]->deleteLater();
- projectors.erase(projectors.begin() + i);
- break;
- }
- }
- }
- OBSProjector *OBSBasic::OpenProjector(obs_source_t *source, int monitor, ProjectorType type)
- {
- /* seriously? 10 monitors? */
- if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
- return nullptr;
- bool closeProjectors = config_get_bool(App()->GetUserConfig(), "BasicWindow", "CloseExistingProjectors");
- if (closeProjectors && monitor > -1) {
- for (size_t i = projectors.size(); i > 0; i--) {
- size_t idx = i - 1;
- if (projectors[idx]->GetMonitor() == monitor)
- DeleteProjector(projectors[idx]);
- }
- }
- OBSProjector *projector = new OBSProjector(nullptr, source, monitor, type);
- projectors.emplace_back(projector);
- return projector;
- }
- void OBSBasic::OpenPreviewProjector()
- {
- int monitor = sender()->property("monitor").toInt();
- OpenProjector(nullptr, monitor, ProjectorType::Preview);
- }
- void OBSBasic::OpenSourceProjector()
- {
- int monitor = sender()->property("monitor").toInt();
- OBSSceneItem item = GetCurrentSceneItem();
- if (!item)
- return;
- OpenProjector(obs_sceneitem_get_source(item), monitor, ProjectorType::Source);
- }
- void OBSBasic::OpenMultiviewProjector()
- {
- int monitor = sender()->property("monitor").toInt();
- OpenProjector(nullptr, monitor, ProjectorType::Multiview);
- }
- void OBSBasic::OpenSceneProjector()
- {
- int monitor = sender()->property("monitor").toInt();
- OBSScene scene = GetCurrentScene();
- if (!scene)
- return;
- OpenProjector(obs_scene_get_source(scene), monitor, ProjectorType::Scene);
- }
- void OBSBasic::OpenPreviewWindow()
- {
- OpenProjector(nullptr, -1, ProjectorType::Preview);
- }
- void OBSBasic::OpenSourceWindow()
- {
- OBSSceneItem item = GetCurrentSceneItem();
- if (!item)
- return;
- OBSSource source = obs_sceneitem_get_source(item);
- OpenProjector(obs_sceneitem_get_source(item), -1, ProjectorType::Source);
- }
- void OBSBasic::OpenSceneWindow()
- {
- OBSScene scene = GetCurrentScene();
- if (!scene)
- return;
- OBSSource source = obs_scene_get_source(scene);
- OpenProjector(obs_scene_get_source(scene), -1, ProjectorType::Scene);
- }
- void OBSBasic::OpenSavedProjector(SavedProjectorInfo *info)
- {
- if (info) {
- OBSProjector *projector = nullptr;
- switch (info->type) {
- case ProjectorType::Source:
- case ProjectorType::Scene: {
- OBSSourceAutoRelease source = obs_get_source_by_name(info->name.c_str());
- if (!source)
- return;
- projector = OpenProjector(source, info->monitor, info->type);
- break;
- }
- default: {
- projector = OpenProjector(nullptr, info->monitor, info->type);
- break;
- }
- }
- if (projector && !info->geometry.empty() && info->monitor < 0) {
- QByteArray byteArray = QByteArray::fromBase64(QByteArray(info->geometry.c_str()));
- projector->restoreGeometry(byteArray);
- if (!WindowPositionValid(projector->normalGeometry())) {
- QRect rect = QGuiApplication::primaryScreen()->geometry();
- projector->setGeometry(
- QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, size(), rect));
- }
- if (info->alwaysOnTopOverridden)
- projector->SetIsAlwaysOnTop(info->alwaysOnTop, true);
- }
- }
- }
- void OBSBasic::openMultiviewWindow()
- {
- OpenProjector(nullptr, -1, ProjectorType::Multiview);
- }
|