diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index eff069977..719d70697 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -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(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 &proj : projectors) + saveProjector(static_cast(proj.data())); -obs_data_array_t *OBSBasic::SavePreviewProjectors() -{ - obs_data_array_t *saveProjector = obs_data_array_create(); + for (QPointer &proj : windowProjectors) + saveProjector(static_cast(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(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) diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 558ddf800..0221b29d8 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -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 @@ -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 signalHandlers; - std::vector projectorArray; - std::vector studioProgramProjectorArray; - std::vector multiviewProjectorArray; - std::vector previewProjectorArray; - bool loaded = false; long disableSaving = 1; bool projectChanged = false; @@ -169,6 +165,7 @@ private: ConfigFile basicConfig; + std::vector savedProjectorsArray; QPointer projectors[10]; QList> 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; diff --git a/UI/window-projector.cpp b/UI/window-projector.cpp index 0ad9755ad..3adc295c5 100644 --- a/UI/window-projector.cpp +++ b/UI/window-projector.cpp @@ -3,7 +3,8 @@ #include #include #include -#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 windowedProjectors; static QList 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(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); +} diff --git a/UI/window-projector.hpp b/UI/window-projector.hpp index 606ab616b..35badccee 100644 --- a/UI/window-projector.hpp +++ b/UI/window-projector.hpp @@ -2,7 +2,14 @@ #include #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); };