2014-05-10 18:47:48 -07:00
|
|
|
/******************************************************************************
|
|
|
|
Copyright (C) 2014 by Hugh Bailey <obs.jim@gmail.com>
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
******************************************************************************/
|
|
|
|
|
2014-05-12 15:32:55 -07:00
|
|
|
#include <QMessageBox>
|
2014-05-10 18:47:48 -07:00
|
|
|
#include "window-basic-main.hpp"
|
|
|
|
#include "window-basic-source-select.hpp"
|
|
|
|
#include "qt-wrappers.hpp"
|
2014-05-09 15:09:17 -07:00
|
|
|
#include "obs-app.hpp"
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2015-09-19 03:49:37 -07:00
|
|
|
struct AddSourceData {
|
|
|
|
obs_source_t *source;
|
|
|
|
bool visible;
|
|
|
|
};
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
bool OBSBasicSourceSelect::EnumSources(void *data, obs_source_t *source)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
|
|
|
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-08-02 12:42:47 -07:00
|
|
|
const char *id = obs_source_get_id(source);
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2014-08-02 12:38:55 -07:00
|
|
|
if (strcmp(id, window->id) == 0)
|
2014-05-10 18:47:48 -07:00
|
|
|
window->ui->sourceList->addItem(QT_UTF8(name));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasicSourceSelect::OBSSourceAdded(void *data, calldata_t *calldata)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
|
|
|
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(calldata, "source");
|
2014-05-10 18:47:48 -07:00
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SourceAdded",
|
|
|
|
Q_ARG(OBSSource, source));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasicSourceSelect::OBSSourceRemoved(void *data, calldata_t *calldata)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
|
|
|
OBSBasicSourceSelect *window = static_cast<OBSBasicSourceSelect*>(data);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(calldata, "source");
|
2014-05-10 18:47:48 -07:00
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SourceRemoved",
|
|
|
|
Q_ARG(OBSSource, source));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSourceSelect::SourceAdded(OBSSource source)
|
|
|
|
{
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-08-02 12:42:47 -07:00
|
|
|
const char *sourceId = obs_source_get_id(source);
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2014-08-02 12:38:55 -07:00
|
|
|
if (strcmp(sourceId, id) != 0)
|
2014-05-10 18:47:48 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
ui->sourceList->addItem(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSourceSelect::SourceRemoved(OBSSource source)
|
|
|
|
{
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-08-02 12:42:47 -07:00
|
|
|
const char *sourceId = obs_source_get_id(source);
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2014-08-02 12:38:55 -07:00
|
|
|
if (strcmp(sourceId, id) != 0)
|
2014-05-10 18:47:48 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
QList<QListWidgetItem*> items =
|
|
|
|
ui->sourceList->findItems(name, Qt::MatchFixedString);
|
|
|
|
|
|
|
|
if (!items.count())
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete items[0];
|
|
|
|
}
|
|
|
|
|
2015-09-19 03:49:37 -07:00
|
|
|
static void AddSource(void *_data, obs_scene_t *scene)
|
|
|
|
{
|
|
|
|
AddSourceData *data = (AddSourceData *)_data;
|
|
|
|
obs_sceneitem_t *sceneitem;
|
|
|
|
|
|
|
|
sceneitem = obs_scene_add(scene, data->source);
|
|
|
|
obs_sceneitem_set_visible(sceneitem, data->visible);
|
|
|
|
}
|
|
|
|
|
2017-03-25 04:19:29 -07:00
|
|
|
static char *get_new_source_name(const char *name)
|
|
|
|
{
|
|
|
|
struct dstr new_name = {0};
|
|
|
|
int inc = 0;
|
|
|
|
|
|
|
|
dstr_copy(&new_name, name);
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
obs_source_t *existing_source = obs_get_source_by_name(
|
|
|
|
new_name.array);
|
|
|
|
if (!existing_source)
|
|
|
|
break;
|
|
|
|
|
|
|
|
obs_source_release(existing_source);
|
|
|
|
|
|
|
|
dstr_printf(&new_name, "%s %d", name, ++inc + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new_name.array;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void AddExisting(const char *name, bool visible, bool duplicate)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
UI: Implement transitions and preview/program mode
Implements transitions, and introduces "Studio Mode" which allows live
editing of the same or different scenes while preserving what's
currently being displayed.
Studio Mode offers a number of new features:
- The ability to edit different scenes or the same scene without
modifying what's currently being displayed (of course)
- The ability to set up "quick transitions" with a desired transition
and duration that can be assigned hotkeys
- The option to create full copies of all sources in the program scene
to allow editing of source properties of the same scene live without
modifying the output, or (by default) just use references. (Note
however that certain sources cannot be duplicated, such as capture
sources, media sources, and device sources)
- Swap Mode (enabled by default) which swaps the program scene with
the preview scene when a transition completes
Currently, only non-configurable transitions (transitions without
properties) are listed, and the only transitions available as of this
writing are fade and cut. In future versions more transitions will be
added, such as swipe, stingers, and many other various sort of
transitions, and the UI will support being able to add/configure/remove
those sort of configurable transitions.
2016-01-23 11:19:29 -08:00
|
|
|
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
|
|
|
OBSScene scene = main->GetCurrentScene();
|
2014-05-10 18:47:48 -07:00
|
|
|
if (!scene)
|
|
|
|
return;
|
|
|
|
|
UI: Implement transitions and preview/program mode
Implements transitions, and introduces "Studio Mode" which allows live
editing of the same or different scenes while preserving what's
currently being displayed.
Studio Mode offers a number of new features:
- The ability to edit different scenes or the same scene without
modifying what's currently being displayed (of course)
- The ability to set up "quick transitions" with a desired transition
and duration that can be assigned hotkeys
- The option to create full copies of all sources in the program scene
to allow editing of source properties of the same scene live without
modifying the output, or (by default) just use references. (Note
however that certain sources cannot be duplicated, such as capture
sources, media sources, and device sources)
- Swap Mode (enabled by default) which swaps the program scene with
the preview scene when a transition completes
Currently, only non-configurable transitions (transitions without
properties) are listed, and the only transitions available as of this
writing are fade and cut. In future versions more transitions will be
added, such as swipe, stingers, and many other various sort of
transitions, and the UI will support being able to add/configure/remove
those sort of configurable transitions.
2016-01-23 11:19:29 -08:00
|
|
|
obs_source_t *source = obs_get_source_by_name(name);
|
2014-05-10 18:47:48 -07:00
|
|
|
if (source) {
|
2017-03-25 04:19:29 -07:00
|
|
|
if (duplicate) {
|
|
|
|
obs_source_t *from = source;
|
|
|
|
char *new_name = get_new_source_name(name);
|
|
|
|
source = obs_source_duplicate(from, new_name, false);
|
|
|
|
bfree(new_name);
|
|
|
|
obs_source_release(from);
|
|
|
|
|
|
|
|
if (!source)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-09-19 03:49:37 -07:00
|
|
|
AddSourceData data;
|
|
|
|
data.source = source;
|
|
|
|
data.visible = visible;
|
|
|
|
obs_scene_atomic_update(scene, AddSource, &data);
|
|
|
|
|
2014-05-10 18:47:48 -07:00
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-19 03:49:37 -07:00
|
|
|
bool AddNew(QWidget *parent, const char *id, const char *name,
|
2015-10-24 07:07:05 -07:00
|
|
|
const bool visible, OBSSource &newSource)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
UI: Implement transitions and preview/program mode
Implements transitions, and introduces "Studio Mode" which allows live
editing of the same or different scenes while preserving what's
currently being displayed.
Studio Mode offers a number of new features:
- The ability to edit different scenes or the same scene without
modifying what's currently being displayed (of course)
- The ability to set up "quick transitions" with a desired transition
and duration that can be assigned hotkeys
- The option to create full copies of all sources in the program scene
to allow editing of source properties of the same scene live without
modifying the output, or (by default) just use references. (Note
however that certain sources cannot be duplicated, such as capture
sources, media sources, and device sources)
- Swap Mode (enabled by default) which swaps the program scene with
the preview scene when a transition completes
Currently, only non-configurable transitions (transitions without
properties) are listed, and the only transitions available as of this
writing are fade and cut. In future versions more transitions will be
added, such as swipe, stingers, and many other various sort of
transitions, and the UI will support being able to add/configure/remove
those sort of configurable transitions.
2016-01-23 11:19:29 -08:00
|
|
|
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
|
|
|
OBSScene scene = main->GetCurrentScene();
|
2014-05-12 15:32:55 -07:00
|
|
|
bool success = false;
|
UI: Implement transitions and preview/program mode
Implements transitions, and introduces "Studio Mode" which allows live
editing of the same or different scenes while preserving what's
currently being displayed.
Studio Mode offers a number of new features:
- The ability to edit different scenes or the same scene without
modifying what's currently being displayed (of course)
- The ability to set up "quick transitions" with a desired transition
and duration that can be assigned hotkeys
- The option to create full copies of all sources in the program scene
to allow editing of source properties of the same scene live without
modifying the output, or (by default) just use references. (Note
however that certain sources cannot be duplicated, such as capture
sources, media sources, and device sources)
- Swap Mode (enabled by default) which swaps the program scene with
the preview scene when a transition completes
Currently, only non-configurable transitions (transitions without
properties) are listed, and the only transitions available as of this
writing are fade and cut. In future versions more transitions will be
added, such as swipe, stingers, and many other various sort of
transitions, and the UI will support being able to add/configure/remove
those sort of configurable transitions.
2016-01-23 11:19:29 -08:00
|
|
|
if (!scene)
|
2014-05-12 15:32:55 -07:00
|
|
|
return false;
|
2014-05-10 18:47:48 -07:00
|
|
|
|
UI: Implement transitions and preview/program mode
Implements transitions, and introduces "Studio Mode" which allows live
editing of the same or different scenes while preserving what's
currently being displayed.
Studio Mode offers a number of new features:
- The ability to edit different scenes or the same scene without
modifying what's currently being displayed (of course)
- The ability to set up "quick transitions" with a desired transition
and duration that can be assigned hotkeys
- The option to create full copies of all sources in the program scene
to allow editing of source properties of the same scene live without
modifying the output, or (by default) just use references. (Note
however that certain sources cannot be duplicated, such as capture
sources, media sources, and device sources)
- Swap Mode (enabled by default) which swaps the program scene with
the preview scene when a transition completes
Currently, only non-configurable transitions (transitions without
properties) are listed, and the only transitions available as of this
writing are fade and cut. In future versions more transitions will be
added, such as swipe, stingers, and many other various sort of
transitions, and the UI will support being able to add/configure/remove
those sort of configurable transitions.
2016-01-23 11:19:29 -08:00
|
|
|
obs_source_t *source = obs_get_source_by_name(name);
|
2014-05-12 15:32:55 -07:00
|
|
|
if (source) {
|
2017-05-13 14:06:32 -07:00
|
|
|
OBSMessageBox::information(parent,
|
2014-05-12 15:32:55 -07:00
|
|
|
QTStr("NameExists.Title"),
|
|
|
|
QTStr("NameExists.Text"));
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2014-05-12 15:32:55 -07:00
|
|
|
} else {
|
2015-12-29 15:25:45 -08:00
|
|
|
source = obs_source_create(id, name, NULL, nullptr);
|
2014-05-10 18:47:48 -07:00
|
|
|
|
2014-05-12 15:32:55 -07:00
|
|
|
if (source) {
|
2015-09-19 03:49:37 -07:00
|
|
|
AddSourceData data;
|
|
|
|
data.source = source;
|
|
|
|
data.visible = visible;
|
|
|
|
obs_scene_atomic_update(scene, AddSource, &data);
|
2014-05-12 15:32:55 -07:00
|
|
|
|
2015-10-24 07:07:05 -07:00
|
|
|
newSource = source;
|
|
|
|
|
2014-05-12 15:32:55 -07:00
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
obs_source_release(source);
|
|
|
|
return success;
|
2014-05-10 18:47:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSourceSelect::on_buttonBox_accepted()
|
|
|
|
{
|
|
|
|
bool useExisting = ui->selectExisting->isChecked();
|
2015-09-19 03:49:37 -07:00
|
|
|
bool visible = ui->sourceVisible->isChecked();
|
2014-05-10 18:47:48 -07:00
|
|
|
|
|
|
|
if (useExisting) {
|
|
|
|
QListWidgetItem *item = ui->sourceList->currentItem();
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
2017-03-25 04:19:29 -07:00
|
|
|
AddExisting(QT_TO_UTF8(item->text()), visible, false);
|
2014-05-10 18:47:48 -07:00
|
|
|
} else {
|
2014-05-12 15:32:55 -07:00
|
|
|
if (ui->sourceName->text().isEmpty()) {
|
2017-05-13 14:06:32 -07:00
|
|
|
OBSMessageBox::information(this,
|
2014-08-12 12:09:19 -07:00
|
|
|
QTStr("NoNameEntered.Title"),
|
|
|
|
QTStr("NoNameEntered.Text"));
|
2014-05-12 15:32:55 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-09-19 03:49:37 -07:00
|
|
|
if (!AddNew(this, id, QT_TO_UTF8(ui->sourceName->text()),
|
2015-10-24 07:07:05 -07:00
|
|
|
visible, newSource))
|
2014-05-12 15:32:55 -07:00
|
|
|
return;
|
2014-05-10 18:47:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
done(DialogCode::Accepted);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSourceSelect::on_buttonBox_rejected()
|
|
|
|
{
|
|
|
|
done(DialogCode::Rejected);
|
|
|
|
}
|
|
|
|
|
2016-07-01 15:23:06 -07:00
|
|
|
static inline const char *GetSourceDisplayName(const char *id)
|
|
|
|
{
|
|
|
|
if (strcmp(id, "scene") == 0)
|
|
|
|
return Str("Basic.Scene");
|
|
|
|
return obs_source_get_display_name(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(OBSScene);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static inline T GetOBSRef(QListWidgetItem *item)
|
|
|
|
{
|
|
|
|
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
|
|
|
|
}
|
|
|
|
|
2014-08-02 12:38:55 -07:00
|
|
|
OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_)
|
2014-05-10 18:47:48 -07:00
|
|
|
: QDialog (parent),
|
|
|
|
ui (new Ui::OBSBasicSourceSelect),
|
2014-08-02 12:38:55 -07:00
|
|
|
id (id_)
|
2014-05-10 18:47:48 -07:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
2014-10-29 09:18:00 -07:00
|
|
|
ui->sourceList->setAttribute(Qt::WA_MacShowFocusRect, false);
|
|
|
|
|
2016-07-01 15:23:06 -07:00
|
|
|
QString placeHolderText{QT_UTF8(GetSourceDisplayName(id))};
|
2014-05-09 15:09:17 -07:00
|
|
|
|
2014-05-12 16:12:22 -07:00
|
|
|
QString text{placeHolderText};
|
2017-02-26 08:23:31 -08:00
|
|
|
int i = 2;
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = nullptr;
|
2014-05-14 13:20:08 -07:00
|
|
|
while ((source = obs_get_source_by_name(QT_TO_UTF8(text)))) {
|
|
|
|
obs_source_release(source);
|
2014-05-12 16:12:22 -07:00
|
|
|
text = QString("%1 %2").arg(placeHolderText).arg(i++);
|
2014-05-14 13:20:08 -07:00
|
|
|
}
|
2014-05-12 16:12:22 -07:00
|
|
|
|
|
|
|
ui->sourceName->setText(text);
|
2014-05-09 15:09:17 -07:00
|
|
|
ui->sourceName->setFocus(); //Fixes deselect of text.
|
|
|
|
ui->sourceName->selectAll();
|
|
|
|
|
2014-11-01 13:48:58 -07:00
|
|
|
installEventFilter(CreateShortcutFilter());
|
|
|
|
|
2016-07-01 15:23:06 -07:00
|
|
|
if (strcmp(id_, "scene") == 0) {
|
|
|
|
OBSBasic *main = reinterpret_cast<OBSBasic*>(
|
|
|
|
App()->GetMainWindow());
|
|
|
|
OBSSource curSceneSource = main->GetCurrentSceneSource();
|
|
|
|
|
|
|
|
ui->selectExisting->setChecked(true);
|
|
|
|
ui->createNew->setChecked(false);
|
|
|
|
ui->createNew->setEnabled(false);
|
|
|
|
ui->sourceName->setEnabled(false);
|
|
|
|
|
|
|
|
int count = main->ui->scenes->count();
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
QListWidgetItem *item = main->ui->scenes->item(i);
|
|
|
|
OBSScene scene = GetOBSRef<OBSScene>(item);
|
|
|
|
OBSSource sceneSource = obs_scene_get_source(scene);
|
|
|
|
|
|
|
|
if (curSceneSource == sceneSource)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const char *name = obs_source_get_name(sceneSource);
|
|
|
|
ui->sourceList->addItem(QT_UTF8(name));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
obs_enum_sources(EnumSources, this);
|
|
|
|
}
|
2014-05-10 18:47:48 -07:00
|
|
|
}
|
2017-03-25 04:19:29 -07:00
|
|
|
|
|
|
|
void OBSBasicSourceSelect::SourcePaste(const char *name, bool visible, bool dup)
|
|
|
|
{
|
|
|
|
AddExisting(name, visible, dup);
|
|
|
|
}
|