UI: Add option to save projectors

This adds an option to the general settings to save the opened
projectors on exit.

(Note: Fixed conflicts -Jim)

Closes jp9000/obs-studio#743
This commit is contained in:
cg2121 2016-12-29 09:21:53 -06:00 committed by jp9000
parent 7eee8de331
commit 29f22e72a8
9 changed files with 217 additions and 14 deletions

View file

@ -415,6 +415,7 @@ Basic.Settings.General.KeepRecordingWhenStreamStops="Keep recording when stream
Basic.Settings.General.SysTrayEnabled="Enable system tray icon" Basic.Settings.General.SysTrayEnabled="Enable system tray icon"
Basic.Settings.General.SysTrayWhenStarted="Minimize to system tray when started" Basic.Settings.General.SysTrayWhenStarted="Minimize to system tray when started"
Basic.Settings.General.SystemTrayHideMinimize="Hide to system tray instead of minimize to task bar" Basic.Settings.General.SystemTrayHideMinimize="Hide to system tray instead of minimize to task bar"
Basic.Settings.General.SaveProjectors="Save projectors on exit"
# basic mode 'stream' settings # basic mode 'stream' settings
Basic.Settings.Stream="Stream" Basic.Settings.Stream="Stream"

View file

@ -185,21 +185,21 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="8" column="1">
<widget class="QCheckBox" name="recordWhenStreaming"> <widget class="QCheckBox" name="recordWhenStreaming">
<property name="text"> <property name="text">
<string>Basic.Settings.General.RecordWhenStreaming</string> <string>Basic.Settings.General.RecordWhenStreaming</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="10" column="1">
<widget class="QCheckBox" name="systemTrayEnabled"> <widget class="QCheckBox" name="systemTrayEnabled">
<property name="text"> <property name="text">
<string>Basic.Settings.General.SysTrayEnabled</string> <string>Basic.Settings.General.SysTrayEnabled</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="1"> <item row="11" column="1">
<widget class="QCheckBox" name="systemTrayWhenStarted"> <widget class="QCheckBox" name="systemTrayWhenStarted">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -209,7 +209,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="12" column="1">
<widget class="QCheckBox" name="systemTrayAlways"> <widget class="QCheckBox" name="systemTrayAlways">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -219,14 +219,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="0" colspan="2"> <item row="13" column="0" colspan="2">
<widget class="Line" name="line_4"> <widget class="Line" name="line_4">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="0" colspan="2"> <item row="14" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_10"> <widget class="QGroupBox" name="groupBox_10">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -326,7 +326,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="9" column="1">
<widget class="QCheckBox" name="keepRecordStreamStops"> <widget class="QCheckBox" name="keepRecordStreamStops">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -343,6 +343,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1">
<widget class="QCheckBox" name="saveProjectors">
<property name="text">
<string>Basic.Settings.General.SaveProjectors</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="streamPage"> <widget class="QWidget" name="streamPage">
@ -2912,8 +2919,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>800</width> <width>98</width>
<height>69</height> <height>28</height>
</rect> </rect>
</property> </property>
</widget> </widget>
@ -4204,6 +4211,16 @@
<signal>toggled(bool)</signal> <signal>toggled(bool)</signal>
<receiver>systemTrayAlways</receiver> <receiver>systemTrayAlways</receiver>
<slot>setEnabled(bool)</slot> <slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection> </connection>
</connections> </connections>
</ui> </ui>

View file

@ -392,6 +392,8 @@ bool OBSApp::InitGlobalConfigDefaults()
"SysTrayEnabled", true); "SysTrayEnabled", true);
config_set_default_bool(globalConfig, "BasicWindow", config_set_default_bool(globalConfig, "BasicWindow",
"SysTrayWhenStarted", false); "SysTrayWhenStarted", false);
config_set_default_bool(globalConfig, "BasicWindow",
"SaveProjectors", false);
config_set_default_bool(globalConfig, "BasicWindow", config_set_default_bool(globalConfig, "BasicWindow",
"ShowTransitions", true); "ShowTransitions", true);
config_set_default_bool(globalConfig, "BasicWindow", config_set_default_bool(globalConfig, "BasicWindow",

View file

@ -222,6 +222,9 @@ void OBSBasic::RefreshSceneCollections()
EnumSceneCollections(addCollection); EnumSceneCollections(addCollection);
ui->actionRemoveSceneCollection->setEnabled(count > 1); ui->actionRemoveSceneCollection->setEnabled(count > 1);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
main->OpenSavedProjectors();
} }
void OBSBasic::on_actionNewSceneCollection_triggered() void OBSBasic::on_actionNewSceneCollection_triggered()

View file

@ -123,6 +123,9 @@ OBSBasic::OBSBasic(QWidget *parent)
: OBSMainWindow (parent), : OBSMainWindow (parent),
ui (new Ui::OBSBasic) ui (new Ui::OBSBasic)
{ {
projectorArray.resize(10, "");
previewProjectorArray.resize(10, 0);
setAcceptDrops(true); setAcceptDrops(true);
ui->setupUi(this); ui->setupUi(this);
@ -262,7 +265,9 @@ static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent,
static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
obs_data_array_t *quickTransitionData, int transitionDuration, obs_data_array_t *quickTransitionData, int transitionDuration,
obs_data_array_t *transitions, obs_data_array_t *transitions,
OBSScene &scene, OBSSource &curProgramScene) OBSScene &scene, OBSSource &curProgramScene,
obs_data_array_t *savedProjectorList,
obs_data_array_t *savedPreviewProjectorList)
{ {
obs_data_t *saveData = obs_data_create(); obs_data_t *saveData = obs_data_create();
@ -303,6 +308,9 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder,
obs_data_set_array(saveData, "sources", sourcesArray); obs_data_set_array(saveData, "sources", sourcesArray);
obs_data_set_array(saveData, "quick_transitions", quickTransitionData); obs_data_set_array(saveData, "quick_transitions", quickTransitionData);
obs_data_set_array(saveData, "transitions", transitions); 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_array_release(sourcesArray); obs_data_array_release(sourcesArray);
obs_data_set_string(saveData, "current_transition", obs_data_set_string(saveData, "current_transition",
@ -360,6 +368,36 @@ obs_data_array_t *OBSBasic::SaveSceneListOrder()
return sceneOrder; return sceneOrder;
} }
obs_data_array_t *OBSBasic::SaveProjectors()
{
obs_data_array_t *saveProjector = obs_data_array_create();
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);
obs_data_release(data);
}
return saveProjector;
}
obs_data_array_t *OBSBasic::SavePreviewProjectors()
{
obs_data_array_t *saveProjector = obs_data_array_create();
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;
}
void OBSBasic::Save(const char *file) void OBSBasic::Save(const char *file)
{ {
OBSScene scene = GetCurrentScene(); OBSScene scene = GetCurrentScene();
@ -370,9 +408,12 @@ void OBSBasic::Save(const char *file)
obs_data_array_t *sceneOrder = SaveSceneListOrder(); obs_data_array_t *sceneOrder = SaveSceneListOrder();
obs_data_array_t *transitions = SaveTransitions(); obs_data_array_t *transitions = SaveTransitions();
obs_data_array_t *quickTrData = SaveQuickTransitions(); obs_data_array_t *quickTrData = SaveQuickTransitions();
obs_data_array_t *savedProjectorList = SaveProjectors();
obs_data_array_t *savedPreviewProjectorList = SavePreviewProjectors();
obs_data_t *saveData = GenerateSaveData(sceneOrder, quickTrData, obs_data_t *saveData = GenerateSaveData(sceneOrder, quickTrData,
ui->transitionDuration->value(), transitions, ui->transitionDuration->value(), transitions,
scene, curProgramScene); scene, curProgramScene, savedProjectorList,
savedPreviewProjectorList);
obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked()); obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
obs_data_set_int(saveData, "scaling_mode", obs_data_set_int(saveData, "scaling_mode",
@ -392,6 +433,8 @@ void OBSBasic::Save(const char *file)
obs_data_array_release(sceneOrder); obs_data_array_release(sceneOrder);
obs_data_array_release(quickTrData); obs_data_array_release(quickTrData);
obs_data_array_release(transitions); obs_data_array_release(transitions);
obs_data_array_release(savedProjectorList);
obs_data_array_release(savedPreviewProjectorList);
} }
static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent) static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent)
@ -491,6 +534,32 @@ void OBSBasic::LoadSceneListOrder(obs_data_array_t *array)
} }
} }
void OBSBasic::LoadSavedProjectors(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);
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);
}
}
static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val) static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val)
{ {
const char *name = obs_source_get_name(filter); const char *name = obs_source_get_name(filter);
@ -618,6 +687,23 @@ void OBSBasic::Load(const char *file)
ui->transitionDuration->setValue(newDuration); ui->transitionDuration->setValue(newDuration);
SetTransition(curTransition); 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);
retryScene: retryScene:
curScene = obs_get_source_by_name(sceneName); curScene = obs_get_source_by_name(sceneName);
curProgramScene = obs_get_source_by_name(programSceneName); curProgramScene = obs_get_source_by_name(programSceneName);
@ -1259,6 +1345,8 @@ void OBSBasic::OBSInit()
ui->mainSplitter->setSizes(defSizes); ui->mainSplitter->setSizes(defSizes);
SystemTray(true); SystemTray(true);
OpenSavedProjectors();
} }
void OBSBasic::InitHotkeys() void OBSBasic::InitHotkeys()
@ -1891,6 +1979,14 @@ void OBSBasic::RenameSources(QString newName, QString prevName)
volumes[i]->SetName(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;
}
SaveProject(); SaveProject();
} }
@ -4751,15 +4847,30 @@ 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)
{ {
/* seriously? 10 monitors? */ /* seriously? 10 monitors? */
if (monitor > 9) if (monitor > 9 || monitor > QGuiApplication::screens().size() - 1)
return; return;
bool isPreview = false;
if (source == nullptr)
isPreview = true;
delete projectors[monitor]; delete projectors[monitor];
projectors[monitor].clear(); projectors[monitor].clear();
OBSProjector *projector = new OBSProjector(nullptr, source); RemoveSavedProjectors(monitor);
projector->Init(monitor);
OBSProjector *projector = new OBSProjector(nullptr, source);
const char *name = obs_source_get_name(source);
if (isPreview) {
previewProjectorArray.at((size_t)monitor) = 1;
} else {
projectorArray.at((size_t)monitor) = name;
}
projector->Init(monitor);
projectors[monitor] = projector; projectors[monitor] = projector;
} }
@ -4789,6 +4900,42 @@ void OBSBasic::OpenSceneProjector()
OpenProjector(obs_scene_get_source(scene), monitor); OpenProjector(obs_scene_get_source(scene), monitor);
} }
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 (!source) {
RemoveSavedProjectors((int)i);
obs_source_release(source);
continue;
}
OpenProjector(source, (int)i);
obs_source_release(source);
}
}
for (size_t i = 0; i < previewProjectorArray.size(); i++) {
if (previewProjectorArray.at(i) == 1) {
OpenProjector(nullptr, (int)i);
}
}
}
}
void OBSBasic::RemoveSavedProjectors(int monitor)
{
previewProjectorArray.at((size_t)monitor) = 0;
projectorArray.at((size_t)monitor) = "";
}
void OBSBasic::UpdateTitleBar() void OBSBasic::UpdateTitleBar()
{ {
stringstream name; stringstream name;

View file

@ -111,6 +111,9 @@ private:
std::vector<OBSSignal> signalHandlers; std::vector<OBSSignal> signalHandlers;
std::vector<std::string> projectorArray;
std::vector<int> previewProjectorArray;
bool loaded = false; bool loaded = false;
long disableSaving = 1; long disableSaving = 1;
bool projectChanged = false; bool projectChanged = false;
@ -331,6 +334,13 @@ private:
QList<QPoint> visDlgPositions; QList<QPoint> visDlgPositions;
obs_data_array_t *SaveProjectors();
void LoadSavedProjectors(obs_data_array_t *savedProjectors);
obs_data_array_t *SavePreviewProjectors();
void LoadSavedPreviewProjectors(
obs_data_array_t *savedPreviewProjectors);
public slots: public slots:
void StartStreaming(); void StartStreaming();
void StopStreaming(); void StopStreaming();
@ -482,6 +492,9 @@ public:
void SystemTrayInit(); void SystemTrayInit();
void SystemTray(bool firstStarted); void SystemTray(bool firstStarted);
void OpenSavedProjectors();
void RemoveSavedProjectors(int monitor);
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

@ -282,6 +282,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->systemTrayEnabled, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->systemTrayEnabled, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->systemTrayWhenStarted,CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->systemTrayWhenStarted,CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->systemTrayAlways, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->systemTrayAlways, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->saveProjectors, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->snappingEnabled, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->snappingEnabled, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->screenSnapping, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->screenSnapping, CHECK_CHANGED, GENERAL_CHANGED);
HookWidget(ui->centerSnapping, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->centerSnapping, CHECK_CHANGED, GENERAL_CHANGED);
@ -896,6 +897,10 @@ void OBSBasicSettings::LoadGeneralSettings()
"BasicWindow", "SysTrayMinimizeToTray"); "BasicWindow", "SysTrayMinimizeToTray");
ui->systemTrayAlways->setChecked(systemTrayAlways); ui->systemTrayAlways->setChecked(systemTrayAlways);
bool saveProjectors = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SaveProjectors");
ui->saveProjectors->setChecked(saveProjectors);
bool snappingEnabled = config_get_bool(GetGlobalConfig(), bool snappingEnabled = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SnappingEnabled"); "BasicWindow", "SnappingEnabled");
ui->snappingEnabled->setChecked(snappingEnabled); ui->snappingEnabled->setChecked(snappingEnabled);
@ -2351,6 +2356,11 @@ void OBSBasicSettings::SaveGeneralSettings()
config_set_bool(GetGlobalConfig(), config_set_bool(GetGlobalConfig(),
"BasicWindow", "SysTrayMinimizeToTray", "BasicWindow", "SysTrayMinimizeToTray",
ui->systemTrayAlways->isChecked()); ui->systemTrayAlways->isChecked());
if (WidgetChanged(ui->saveProjectors))
config_set_bool(GetGlobalConfig(), "BasicWindow",
"SaveProjectors",
ui->saveProjectors->isChecked());
} }
void OBSBasicSettings::SaveStream1Settings() void OBSBasicSettings::SaveStream1Settings()

View file

@ -53,6 +53,7 @@ OBSProjector::~OBSProjector()
void OBSProjector::Init(int monitor) void OBSProjector::Init(int monitor)
{ {
QScreen *screen = QGuiApplication::screens()[monitor]; QScreen *screen = QGuiApplication::screens()[monitor];
setGeometry(screen->geometry()); setGeometry(screen->geometry());
bool alwaysOnTop = config_get_bool(GetGlobalConfig(), bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
@ -70,6 +71,8 @@ void OBSProjector::Init(int monitor)
addAction(action); addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered())); connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
savedMonitor = monitor;
} }
void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
@ -114,6 +117,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params) void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params)
{ {
OBSProjector *window = reinterpret_cast<OBSProjector*>(data); OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
window->deleteLater(); window->deleteLater();
UNUSED_PARAMETER(params); UNUSED_PARAMETER(params);
@ -132,5 +136,8 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
void OBSProjector::EscapeTriggered() void OBSProjector::EscapeTriggered()
{ {
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
main->RemoveSavedProjectors(savedMonitor);
deleteLater(); deleteLater();
} }

View file

@ -2,6 +2,7 @@
#include <obs.hpp> #include <obs.hpp>
#include "qt-display.hpp" #include "qt-display.hpp"
#include "window-basic-main.hpp"
class QMouseEvent; class QMouseEvent;
@ -17,6 +18,8 @@ private:
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
int savedMonitor = 0;
private slots: private slots:
void EscapeTriggered(); void EscapeTriggered();