UI: Add ability to change projector type

This commit is contained in:
Clayton Groeneveld 2019-10-08 00:43:10 -05:00
parent 156e2f3aec
commit e832b42f07
5 changed files with 172 additions and 122 deletions

View File

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

View File

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

View File

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

View File

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

View File

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