Ver código fonte

UI: Add ability to change projector type

Clayton Groeneveld 6 anos atrás
pai
commit
e832b42f07

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

@@ -88,6 +88,8 @@ Group="Group"
 DoNotShowAgain="Do not show again"
 Default="(Default)"
 Calculating="Calculating..."
+Fullscreen="Fullscreen"
+Windowed="Windowed"
 
 # warning if program already open
 AlreadyRunning.Title="OBS is already running"

+ 43 - 72
UI/window-basic-main.cpp

@@ -601,11 +601,8 @@ obs_data_array_t *OBSBasic::SaveProjectors()
 		obs_data_release(data);
 	};
 
-	for (QPointer<QWidget> &proj : projectors)
-		saveProjector(static_cast<OBSProjector *>(proj.data()));
-
-	for (QPointer<QWidget> &proj : windowProjectors)
-		saveProjector(static_cast<OBSProjector *>(proj.data()));
+	for (size_t i = 0; i < projectors.size(); i++)
+		saveProjector(static_cast<OBSProjector *>(projectors[i]));
 
 	return savedProjectors;
 }
@@ -2678,7 +2675,10 @@ void OBSBasic::RenameSources(OBSSource source, QString newName,
 			volumes[i]->SetName(newName);
 	}
 
-	OBSProjector::RenameProjector(prevName, newName);
+	for (size_t i = 0; i < projectors.size(); i++) {
+		if (projectors[i]->GetSource() == source)
+			projectors[i]->RenameProjector(prevName, newName);
+	}
 
 	SaveProject();
 
@@ -3738,15 +3738,6 @@ void OBSBasic::CloseDialogs()
 		}
 	}
 
-	for (QPointer<QWidget> &projector : windowProjectors) {
-		delete projector;
-		projector.clear();
-	}
-	for (QPointer<QWidget> &projector : projectors) {
-		delete projector;
-		projector.clear();
-	}
-
 	if (!stats.isNull())
 		stats->close(); //call close to save Stats geometry
 	if (!remux.isNull())
@@ -3788,6 +3779,13 @@ void OBSBasic::ClearSceneData()
 	ClearQuickTransitions();
 	ui->transitions->clear();
 
+	for (size_t i = 0; i < projectors.size(); i++) {
+		if (projectors[i])
+			delete projectors[i];
+	}
+
+	projectors.clear();
+
 	obs_set_output_source(0, nullptr);
 	obs_set_output_source(1, nullptr);
 	obs_set_output_source(2, nullptr);
@@ -4017,8 +4015,8 @@ void OBSBasic::EditSceneName()
 	item->setFlags(flags);
 }
 
-static void AddProjectorMenuMonitors(QMenu *parent, QObject *target,
-				     const char *slot)
+void OBSBasic::AddProjectorMenuMonitors(QMenu *parent, QObject *target,
+					const char *slot)
 {
 	QAction *action;
 	QList<QScreen *> screens = QGuiApplication::screens();
@@ -6438,32 +6436,29 @@ void OBSBasic::NudgeRight()
 	Nudge(1, MoveDir::Right);
 }
 
+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,
-				      QString title, ProjectorType type)
+				      ProjectorType type)
 {
 	/* seriously?  10 monitors? */
 	if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
 		return nullptr;
 
 	OBSProjector *projector =
-		new OBSProjector(nullptr, source, monitor, title, type);
+		new OBSProjector(nullptr, source, monitor, type);
 
-	if (monitor < 0) {
-		for (auto &projPtr : windowProjectors) {
-			if (!projPtr) {
-				projPtr = projector;
-				projector = nullptr;
-			}
-		}
-
-		if (projector)
-			windowProjectors.push_back(projector);
-	} else {
-		delete projectors[monitor];
-		projectors[monitor].clear();
-
-		projectors[monitor] = projector;
-	}
+	if (projector)
+		projectors.emplace_back(projector);
 
 	return projector;
 }
@@ -6471,13 +6466,13 @@ OBSProjector *OBSBasic::OpenProjector(obs_source_t *source, int monitor,
 void OBSBasic::OpenStudioProgramProjector()
 {
 	int monitor = sender()->property("monitor").toInt();
-	OpenProjector(nullptr, monitor, nullptr, ProjectorType::StudioProgram);
+	OpenProjector(nullptr, monitor, ProjectorType::StudioProgram);
 }
 
 void OBSBasic::OpenPreviewProjector()
 {
 	int monitor = sender()->property("monitor").toInt();
-	OpenProjector(nullptr, monitor, nullptr, ProjectorType::Preview);
+	OpenProjector(nullptr, monitor, ProjectorType::Preview);
 }
 
 void OBSBasic::OpenSourceProjector()
@@ -6487,14 +6482,14 @@ void OBSBasic::OpenSourceProjector()
 	if (!item)
 		return;
 
-	OpenProjector(obs_sceneitem_get_source(item), monitor, nullptr,
+	OpenProjector(obs_sceneitem_get_source(item), monitor,
 		      ProjectorType::Source);
 }
 
 void OBSBasic::OpenMultiviewProjector()
 {
 	int monitor = sender()->property("monitor").toInt();
-	OpenProjector(nullptr, monitor, nullptr, ProjectorType::Multiview);
+	OpenProjector(nullptr, monitor, ProjectorType::Multiview);
 }
 
 void OBSBasic::OpenSceneProjector()
@@ -6504,20 +6499,18 @@ void OBSBasic::OpenSceneProjector()
 	if (!scene)
 		return;
 
-	OpenProjector(obs_scene_get_source(scene), monitor, nullptr,
+	OpenProjector(obs_scene_get_source(scene), monitor,
 		      ProjectorType::Scene);
 }
 
 void OBSBasic::OpenStudioProgramWindow()
 {
-	OpenProjector(nullptr, -1, QTStr("StudioProgramWindow"),
-		      ProjectorType::StudioProgram);
+	OpenProjector(nullptr, -1, ProjectorType::StudioProgram);
 }
 
 void OBSBasic::OpenPreviewWindow()
 {
-	OpenProjector(nullptr, -1, QTStr("PreviewWindow"),
-		      ProjectorType::Preview);
+	OpenProjector(nullptr, -1, ProjectorType::Preview);
 }
 
 void OBSBasic::OpenSourceWindow()
@@ -6527,16 +6520,14 @@ void OBSBasic::OpenSourceWindow()
 		return;
 
 	OBSSource source = obs_sceneitem_get_source(item);
-	QString title = QString::fromUtf8(obs_source_get_name(source));
 
-	OpenProjector(obs_sceneitem_get_source(item), -1, title,
+	OpenProjector(obs_sceneitem_get_source(item), -1,
 		      ProjectorType::Source);
 }
 
 void OBSBasic::OpenMultiviewWindow()
 {
-	OpenProjector(nullptr, -1, QTStr("MultiviewWindowed"),
-		      ProjectorType::Multiview);
+	OpenProjector(nullptr, -1, ProjectorType::Multiview);
 }
 
 void OBSBasic::OpenSceneWindow()
@@ -6546,10 +6537,8 @@ void OBSBasic::OpenSceneWindow()
 		return;
 
 	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);
+	OpenProjector(obs_scene_get_source(scene), -1, ProjectorType::Scene);
 }
 
 void OBSBasic::OpenSavedProjectors()
@@ -6564,33 +6553,15 @@ void OBSBasic::OpenSavedProjectors()
 			if (!source)
 				continue;
 
-			QString title = nullptr;
-			if (info->monitor < 0)
-				title = QString::fromUtf8(
-					obs_source_get_name(source));
-
-			projector = OpenProjector(source, info->monitor, title,
+			projector = OpenProjector(source, info->monitor,
 						  info->type);
 
 			obs_source_release(source);
 			break;
 		}
-		case ProjectorType::Preview: {
+		default: {
 			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);
+						  info->type);
 			break;
 		}
 		}

+ 6 - 3
UI/window-basic-main.hpp

@@ -199,8 +199,7 @@ private:
 	ConfigFile basicConfig;
 
 	std::vector<SavedProjectorInfo *> savedProjectorsArray;
-	QPointer<QWidget> projectors[10];
-	QList<QPointer<QWidget>> windowProjectors;
+	std::vector<OBSProjector *> projectors;
 
 	QPointer<QWidget> stats;
 	QPointer<QWidget> remux;
@@ -305,7 +304,7 @@ private:
 	void Nudge(int dist, MoveDir dir);
 
 	OBSProjector *OpenProjector(obs_source_t *source, int monitor,
-				    QString title, ProjectorType type);
+				    ProjectorType type);
 
 	void GetAudioSourceFilters();
 	void GetAudioSourceProperties();
@@ -689,6 +688,10 @@ public:
 
 	const char *GetCurrentOutputPath();
 
+	void DeleteProjector(OBSProjector *projector);
+	void AddProjectorMenuMonitors(QMenu *parent, QObject *target,
+				      const char *slot);
+
 protected:
 	virtual void closeEvent(QCloseEvent *event) override;
 	virtual void changeEvent(QEvent *event) override;

+ 111 - 42
UI/window-projector.cpp

@@ -9,7 +9,6 @@
 #include "qt-wrappers.hpp"
 #include "platform.hpp"
 
-static QList<OBSProjector *> windowedProjectors;
 static QList<OBSProjector *> multiviewProjectors;
 static bool updatingMultiview = false, drawLabel, drawSafeArea, mouseSwitching,
 	    transitionOnDoubleClick;
@@ -17,38 +16,26 @@ static MultiviewLayout multiviewLayout;
 static size_t maxSrcs, numSrcs;
 
 OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
-			   QString title, ProjectorType type_)
+			   ProjectorType type_)
 	: OBSQTDisplay(widget, Qt::Window),
 	  source(source_),
 	  removedSignal(obs_source_get_signal_handler(source), "remove",
 			OBSSourceRemoved, this)
 {
-	projectorTitle = std::move(title);
-	savedMonitor = monitor;
-	isWindow = savedMonitor < 0;
 	type = type_;
 
-	if (isWindow) {
-		setWindowIcon(
-			QIcon::fromTheme("obs", QIcon(":/res/images/obs.png")));
-
-		UpdateProjectorTitle(projectorTitle);
-		windowedProjectors.push_back(this);
+	setWindowIcon(QIcon::fromTheme("obs", QIcon(":/res/images/obs.png")));
+	UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source)));
 
+	if (monitor == -1)
 		resize(480, 270);
-	} else {
-		setWindowFlags(Qt::FramelessWindowHint |
-			       Qt::X11BypassWindowManagerHint);
-
-		QScreen *screen = QGuiApplication::screens()[savedMonitor];
-		setGeometry(screen->geometry());
+	else
+		SetMonitor(monitor);
 
-		QAction *action = new QAction(this);
-		action->setShortcut(Qt::Key_Escape);
-		addAction(action);
-		connect(action, SIGNAL(triggered()), this,
-			SLOT(EscapeTriggered()));
-	}
+	QAction *action = new QAction(this);
+	action->setShortcut(Qt::Key_Escape);
+	addAction(action);
+	connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
 
 	SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), "BasicWindow",
 					     "ProjectorAlwaysOnTop"));
@@ -70,13 +57,8 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
 
 	connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
 
-	bool hideCursor = config_get_bool(GetGlobalConfig(), "BasicWindow",
-					  "HideProjectorCursor");
-	if (hideCursor && !isWindow && type != ProjectorType::Multiview) {
-		QPixmap empty(16, 16);
-		empty.fill(Qt::transparent);
-		setCursor(QCursor(empty));
-	}
+	if (isFullScreen())
+		SetHideCursor();
 
 	if (type == ProjectorType::Multiview) {
 		obs_enter_graphics();
@@ -146,8 +128,7 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
 	show();
 
 	// We need it here to allow keyboard input in X11 to listen to Escape
-	if (!isWindow)
-		activateWindow();
+	activateWindow();
 }
 
 OBSProjector::~OBSProjector()
@@ -180,12 +161,28 @@ OBSProjector::~OBSProjector()
 	if (type == ProjectorType::Multiview)
 		multiviewProjectors.removeAll(this);
 
-	if (isWindow)
-		windowedProjectors.removeAll(this);
-
 	App()->DecrementSleepInhibition();
 }
 
+void OBSProjector::SetMonitor(int monitor)
+{
+	savedMonitor = monitor;
+	QScreen *screen = QGuiApplication::screens()[monitor];
+	showFullScreen();
+	setGeometry(screen->geometry());
+}
+
+void OBSProjector::SetHideCursor()
+{
+	bool hideCursor = config_get_bool(GetGlobalConfig(), "BasicWindow",
+					  "HideProjectorCursor");
+
+	if (hideCursor && type != ProjectorType::Multiview)
+		setCursor(Qt::BlankCursor);
+	else
+		setCursor(Qt::ArrowCursor);
+}
+
 static OBSSource CreateLabel(const char *name, size_t h)
 {
 	obs_data_t *settings = obs_data_create();
@@ -820,7 +817,19 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 	OBSQTDisplay::mousePressEvent(event);
 
 	if (event->button() == Qt::RightButton) {
+		OBSBasic *main =
+			reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
 		QMenu popup(this);
+
+		QMenu *projectorMenu = new QMenu(QTStr("Fullscreen"));
+		main->AddProjectorMenuMonitors(projectorMenu, this,
+					       SLOT(OpenFullScreenProjector()));
+		popup.addMenu(projectorMenu);
+
+		if (GetMonitor() > -1)
+			popup.addAction(QTStr("Windowed"), this,
+					SLOT(OpenWindowedProjector()));
+
 		popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
 		popup.exec(QCursor::pos());
 	}
@@ -844,7 +853,8 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 
 void OBSProjector::EscapeTriggered()
 {
-	deleteLater();
+	OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
+	main->DeleteProjector(this);
 }
 
 void OBSProjector::UpdateMultiview()
@@ -937,15 +947,39 @@ void OBSProjector::UpdateMultiview()
 
 void OBSProjector::UpdateProjectorTitle(QString name)
 {
-	projectorTitle = name;
+	bool window = (GetMonitor() == -1);
 
 	QString title = nullptr;
 	switch (type) {
 	case ProjectorType::Scene:
-		title = QTStr("SceneWindow") + " - " + name;
+		if (!window)
+			title = QTStr("SceneProjector") + " - " + name;
+		else
+			title = QTStr("SceneWindow") + " - " + name;
 		break;
 	case ProjectorType::Source:
-		title = QTStr("SourceWindow") + " - " + name;
+		if (!window)
+			title = QTStr("SourceProjector") + " - " + name;
+		else
+			title = QTStr("SourceWindow") + " - " + name;
+		break;
+	case ProjectorType::Preview:
+		if (!window)
+			title = QTStr("PreviewProjector");
+		else
+			title = QTStr("PreviewWindow");
+		break;
+	case ProjectorType::StudioProgram:
+		if (!window)
+			title = QTStr("StudioProgramProjector");
+		else
+			title = QTStr("StudioProgramWindow");
+		break;
+	case ProjectorType::Multiview:
+		if (!window)
+			title = QTStr("MultiviewProjector");
+		else
+			title = QTStr("MultiviewWindow");
 		break;
 	default:
 		title = name;
@@ -986,7 +1020,42 @@ void OBSProjector::UpdateMultiviewProjectors()
 
 void OBSProjector::RenameProjector(QString oldName, QString newName)
 {
-	for (auto &projector : windowedProjectors)
-		if (projector->projectorTitle == oldName)
-			projector->UpdateProjectorTitle(newName);
+	if (oldName == newName)
+		return;
+
+	UpdateProjectorTitle(newName);
+}
+
+void OBSProjector::OpenFullScreenProjector()
+{
+	if (!isFullScreen())
+		prevGeometry = geometry();
+
+	int monitor = sender()->property("monitor").toInt();
+	SetMonitor(monitor);
+	SetHideCursor();
+
+	UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source)));
+}
+
+void OBSProjector::OpenWindowedProjector()
+{
+	showFullScreen();
+	showNormal();
+	setCursor(Qt::ArrowCursor);
+
+	if (!prevGeometry.isNull())
+		setGeometry(prevGeometry);
+	else
+		resize(480, 270);
+
+	savedMonitor = -1;
+
+	UpdateProjectorTitle(QT_UTF8(obs_source_get_name(source)));
+}
+
+void OBSProjector::closeEvent(QCloseEvent *event)
+{
+	EscapeTriggered();
+	event->accept();
 }

+ 10 - 5
UI/window-projector.hpp

@@ -34,10 +34,9 @@ private:
 
 	void mousePressEvent(QMouseEvent *event) override;
 	void mouseDoubleClickEvent(QMouseEvent *event) override;
+	void closeEvent(QCloseEvent *event) override;
 
-	int savedMonitor;
-	bool isWindow;
-	QString projectorTitle;
+	int savedMonitor = -1;
 	ProjectorType type = ProjectorType::Source;
 	std::vector<OBSWeakSource> multiviewScenes;
 	std::vector<OBSSource> multiviewLabels;
@@ -73,17 +72,23 @@ private:
 	void UpdateMultiview();
 	void UpdateProjectorTitle(QString name);
 
+	QRect prevGeometry;
+	void SetHideCursor();
+	void SetMonitor(int monitor);
+
 private slots:
 	void EscapeTriggered();
+	void OpenFullScreenProjector();
+	void OpenWindowedProjector();
 
 public:
 	OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
-		     QString title, ProjectorType type_);
+		     ProjectorType type_);
 	~OBSProjector();
 
 	OBSSource GetSource();
 	ProjectorType GetProjectorType();
 	int GetMonitor();
 	static void UpdateMultiviewProjectors();
-	static void RenameProjector(QString oldName, QString newName);
+	void RenameProjector(QString oldName, QString newName);
 };