Explorar o código

UI: Add ability to output to window

Closes jp9000/obs-studio#841
cg2121 %!s(int64=8) %!d(string=hai) anos
pai
achega
71c5753207
Modificáronse 5 ficheiros con 143 adicións e 35 borrados
  1. 3 0
      UI/data/locale/en-US.ini
  2. 100 18
      UI/window-basic-main.cpp
  3. 7 1
      UI/window-basic-main.hpp
  4. 30 14
      UI/window-projector.cpp
  5. 3 2
      UI/window-projector.hpp

+ 3 - 0
UI/data/locale/en-US.ini

@@ -36,6 +36,9 @@ DroppedFrames="Dropped Frames %1 (%2%)"
 PreviewProjector="Fullscreen Projector (Preview)"
 SceneProjector="Fullscreen Projector (Scene)"
 SourceProjector="Fullscreen Projector (Source)"
+PreviewWindow="Windowed Projector (Preview)"
+SceneWindow="Windowed Projector (Scene)"
+SourceWindow="Windowed Projector (Source)"
 Clear="Clear"
 Revert="Revert"
 Show="Show"

+ 100 - 18
UI/window-basic-main.cpp

@@ -2807,6 +2807,10 @@ void OBSBasic::CloseDialogs()
 		}
 	}
 
+	for (QPointer<QWidget> &projector : windowProjectors) {
+		delete projector;
+		projector.clear();
+	}
 	for (QPointer<QWidget> &projector : projectors) {
 		delete projector;
 		projector.clear();
@@ -3068,6 +3072,12 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 		AddProjectorMenuMonitors(sceneProjectorMenu, this,
 				SLOT(OpenSceneProjector()));
 		popup.addMenu(sceneProjectorMenu);
+
+		QAction *sceneWindow = popup.addAction(
+				QTStr("SceneWindow"),
+				this, SLOT(OpenSceneWindow()));
+
+		popup.addAction(sceneWindow);
 		popup.addSeparator();
 		popup.addAction(QTStr("Filters"), this,
 				SLOT(OpenSceneFilters()));
@@ -3335,6 +3345,12 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
 
 		popup.addMenu(previewProjector);
 
+		QAction *previewWindow = popup.addAction(
+				QTStr("PreviewWindow"),
+				this, SLOT(OpenPreviewWindow()));
+
+		popup.addAction(previewWindow);
+
 		popup.addSeparator();
 	}
 
@@ -3379,6 +3395,12 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
 		AddProjectorMenuMonitors(sourceProjector, this,
 				SLOT(OpenSourceProjector()));
 
+		QAction *sourceWindow = popup.addAction(
+				QTStr("SourceWindow"),
+				this, SLOT(OpenSourceWindow()));
+
+		popup.addAction(sourceWindow);
+
 		popup.addSeparator();
 		if (isAsyncVideo) {
 			popup.addMenu(AddDeinterlacingMenu(source));
@@ -3389,6 +3411,7 @@ void OBSBasic::CreateSourcePopupMenu(QListWidgetItem *item, bool preview)
 		popup.addSeparator();
 
 		popup.addMenu(sourceProjector);
+		popup.addAction(sourceWindow);
 		popup.addSeparator();
 
 		action = popup.addAction(QTStr("Interact"), this,
@@ -4465,7 +4488,12 @@ void OBSBasic::on_previewDisabledLabel_customContextMenuRequested(
 	AddProjectorMenuMonitors(previewProjector, this,
 			SLOT(OpenPreviewProjector()));
 
+	QAction *previewWindow = popup.addAction(
+			QTStr("PreviewWindow"),
+			this, SLOT(OpenPreviewWindow()));
+
 	popup.addMenu(previewProjector);
+	popup.addAction(previewWindow);
 	popup.exec(QCursor::pos());
 
 	UNUSED_PARAMETER(pos);
@@ -4901,7 +4929,8 @@ 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)
+void OBSBasic::OpenProjector(obs_source_t *source, int monitor, bool window,
+		QString title)
 {
 	/* seriously?  10 monitors? */
 	if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
@@ -4912,29 +4941,45 @@ void OBSBasic::OpenProjector(obs_source_t *source, int monitor)
 	if (source == nullptr)
 		isPreview = true;
 
-	delete projectors[monitor];
-	projectors[monitor].clear();
-
-	RemoveSavedProjectors(monitor);
-
-	OBSProjector *projector = new OBSProjector(nullptr, source);
+	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 (isPreview) {
-		previewProjectorArray.at((size_t)monitor) = 1;
-	} else {
-		projectorArray.at((size_t)monitor) = name;
+	if (!window) {
+		if (isPreview) {
+			previewProjectorArray.at((size_t)monitor) = 1;
+		} else {
+			projectorArray.at((size_t)monitor) = name;
+		}
 	}
 
-	projector->Init(monitor);
-	projectors[monitor] = projector;
+	if (!window) {
+		projector->Init(monitor, false, nullptr);
+		projectors[monitor] = projector;
+	} else {
+		projector->Init(monitor, true, title);
+
+		for (auto &projPtr : windowProjectors) {
+			if (!projPtr) {
+				projPtr = projector;
+				projector = nullptr;
+			}
+		}
+
+		if (projector)
+			windowProjectors.push_back(projector);
+	}
 }
 
 void OBSBasic::OpenPreviewProjector()
 {
 	int monitor = sender()->property("monitor").toInt();
-	OpenProjector(nullptr, monitor);
+	OpenProjector(nullptr, monitor, false);
 }
 
 void OBSBasic::OpenSourceProjector()
@@ -4944,7 +4989,7 @@ void OBSBasic::OpenSourceProjector()
 	if (!item)
 		return;
 
-	OpenProjector(obs_sceneitem_get_source(item), monitor);
+	OpenProjector(obs_sceneitem_get_source(item), monitor, false);
 }
 
 void OBSBasic::OpenSceneProjector()
@@ -4954,7 +4999,44 @@ void OBSBasic::OpenSceneProjector()
 	if (!scene)
 		return;
 
-	OpenProjector(obs_scene_get_source(scene), monitor);
+	OpenProjector(obs_scene_get_source(scene), monitor, false);
+}
+
+void OBSBasic::OpenPreviewWindow()
+{
+	int monitor = sender()->property("monitor").toInt();
+	QString title = QTStr("PreviewWindow");
+	OpenProjector(nullptr, monitor, true, title);
+}
+
+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);
+}
+
+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);
 }
 
 void OBSBasic::OpenSavedProjectors()
@@ -4974,14 +5056,14 @@ void OBSBasic::OpenSavedProjectors()
 					continue;
 				}
 
-				OpenProjector(source, (int)i);
+				OpenProjector(source, (int)i, false);
 				obs_source_release(source);
 			}
 		}
 
 		for (size_t i = 0; i < previewProjectorArray.size(); i++) {
 			if (previewProjectorArray.at(i) == 1) {
-				OpenProjector(nullptr, (int)i);
+				OpenProjector(nullptr, (int)i, false);
 			}
 		}
 	}

+ 7 - 1
UI/window-basic-main.hpp

@@ -158,6 +158,7 @@ private:
 	ConfigFile    basicConfig;
 
 	QPointer<QWidget> projectors[10];
+	QList<QPointer<QWidget>> windowProjectors;
 
 	QPointer<QMenu> startStreamMenu;
 
@@ -233,7 +234,8 @@ private:
 	void ClearSceneData();
 
 	void Nudge(int dist, MoveDir dir);
-	void OpenProjector(obs_source_t *source, int monitor);
+	void OpenProjector(obs_source_t *source, int monitor, bool window,
+			QString title = nullptr);
 
 	void GetAudioSourceFilters();
 	void GetAudioSourceProperties();
@@ -636,6 +638,10 @@ private slots:
 	void OpenSourceProjector();
 	void OpenSceneProjector();
 
+	void OpenPreviewWindow();
+	void OpenSourceWindow();
+	void OpenSceneWindow();
+
 public slots:
 	void on_actionResetTransform_triggered();
 

+ 30 - 14
UI/window-projector.cpp

@@ -9,14 +9,18 @@
 #include "platform.hpp"
 #include "obs-app.hpp"
 
-OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_)
+OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, bool window)
 	: OBSQTDisplay                 (widget,
-	                                Qt::Window | Qt::FramelessWindowHint |
-					Qt::X11BypassWindowManagerHint),
+	                                Qt::Window),
 	  source                       (source_),
 	  removedSignal                (obs_source_get_signal_handler(source),
 	                                "remove", OBSSourceRemoved, this)
 {
+	if (!window) {
+		setWindowFlags(Qt::FramelessWindowHint |
+				Qt::X11BypassWindowManagerHint);
+	}
+
 	setAttribute(Qt::WA_DeleteOnClose, true);
 
 	//disable application quit when last window closed
@@ -34,13 +38,14 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_)
 
 	bool hideCursor = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "HideProjectorCursor");
-	if (hideCursor) {
+	if (hideCursor && !window) {
 		QPixmap empty(16, 16);
 		empty.fill(Qt::transparent);
 		setCursor(QCursor(empty));
 	}
 
 	App()->IncrementSleepInhibition();
+	resize(480, 270);
 }
 
 OBSProjector::~OBSProjector()
@@ -50,29 +55,36 @@ OBSProjector::~OBSProjector()
 	App()->DecrementSleepInhibition();
 }
 
-void OBSProjector::Init(int monitor)
+void OBSProjector::Init(int monitor, bool window, QString title)
 {
 	QScreen *screen = QGuiApplication::screens()[monitor];
 
-	setGeometry(screen->geometry());
+	if (!window)
+		setGeometry(screen->geometry());
 
 	bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
 			"BasicWindow", "ProjectorAlwaysOnTop");
-	if (alwaysOnTop)
+	if (alwaysOnTop && !window)
 		SetAlwaysOnTop(this, true);
 
+	if (window)
+		setWindowTitle(title);
+
 	show();
 
 	if (source)
 		obs_source_inc_showing(source);
 
-	QAction *action = new QAction(this);
-	action->setShortcut(Qt::Key_Escape);
-	addAction(action);
-
-	connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
+	if (!window) {
+		QAction *action = new QAction(this);
+		action->setShortcut(Qt::Key_Escape);
+		addAction(action);
+		connect(action, SIGNAL(triggered()), this,
+				SLOT(EscapeTriggered()));
+	}
 
 	savedMonitor = monitor;
+	isWindow = window;
 }
 
 void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
@@ -136,8 +148,12 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 
 void OBSProjector::EscapeTriggered()
 {
-	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
-	main->RemoveSavedProjectors(savedMonitor);
+	if (!isWindow) {
+		OBSBasic *main =
+			reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
+
+		main->RemoveSavedProjectors(savedMonitor);
+	}
 
 	deleteLater();
 }

+ 3 - 2
UI/window-projector.hpp

@@ -19,13 +19,14 @@ private:
 	void mousePressEvent(QMouseEvent *event) override;
 
 	int savedMonitor = 0;
+	bool isWindow = false;
 
 private slots:
 	void EscapeTriggered();
 
 public:
-	OBSProjector(QWidget *parent, obs_source_t *source);
+	OBSProjector(QWidget *parent, obs_source_t *source, bool window);
 	~OBSProjector();
 
-	void Init(int monitor);
+	void Init(int monitor, bool window, QString title);
 };