2013-11-07 15:45:03 -08:00
|
|
|
/******************************************************************************
|
2014-02-13 07:58:31 -08:00
|
|
|
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
|
2014-05-15 14:04:18 -07:00
|
|
|
Zachary Lund <admin@computerquip.com>
|
2013-11-07 15:45:03 -08:00
|
|
|
|
|
|
|
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
|
2013-12-02 21:24:38 -08:00
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
2013-11-07 15:45:03 -08:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
2013-11-08 23:19:38 -08:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2013-11-07 15:45:03 -08:00
|
|
|
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-07-13 23:56:28 -07:00
|
|
|
#include <time.h>
|
2013-12-22 16:42:02 -08:00
|
|
|
#include <obs.hpp>
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
#include <QMessageBox>
|
2014-01-25 08:08:56 -08:00
|
|
|
#include <QShowEvent>
|
2014-08-21 18:18:42 -07:00
|
|
|
#include <QDesktopServices>
|
2014-02-10 09:22:35 -08:00
|
|
|
#include <QFileDialog>
|
2014-05-18 17:44:10 -07:00
|
|
|
#include <QNetworkRequest>
|
|
|
|
#include <QNetworkReply>
|
2013-12-29 08:17:00 -08:00
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
#include <util/dstr.h>
|
2014-03-06 20:08:12 -08:00
|
|
|
#include <util/util.hpp>
|
|
|
|
#include <util/platform.h>
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
#include <graphics/math-defs.h>
|
2014-03-06 20:08:12 -08:00
|
|
|
|
2013-11-23 22:38:52 -08:00
|
|
|
#include "obs-app.hpp"
|
2014-03-06 20:08:12 -08:00
|
|
|
#include "platform.hpp"
|
2014-01-24 20:19:50 -08:00
|
|
|
#include "window-basic-settings.hpp"
|
2013-12-29 07:54:06 -08:00
|
|
|
#include "window-namedialog.hpp"
|
2014-05-10 18:47:48 -07:00
|
|
|
#include "window-basic-source-select.hpp"
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
#include "window-basic-main.hpp"
|
2014-03-23 01:07:54 -07:00
|
|
|
#include "window-basic-properties.hpp"
|
2014-05-18 17:44:10 -07:00
|
|
|
#include "window-log-reply.hpp"
|
2014-09-02 19:11:55 -07:00
|
|
|
#include "window-remux.hpp"
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
#include "qt-wrappers.hpp"
|
2014-03-23 01:07:54 -07:00
|
|
|
#include "display-helpers.hpp"
|
2014-05-03 22:54:38 -07:00
|
|
|
#include "volume-control.hpp"
|
2014-01-04 12:53:36 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
#include "ui_OBSBasic.h"
|
2014-01-09 17:51:51 -08:00
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
#include <fstream>
|
Implement RTMP module (still needs drop code)
- Implement the RTMP output module. This time around, we just use a
simple FLV muxer, then just write to the stream with RTMP_Write.
Easy and effective.
- Fix the FLV muxer, the muxer now outputs proper FLV packets.
- Output API:
* When using encoders, automatically interleave encoded packets
before sending it to the output.
* Pair encoders and have them automatically wait for the other to
start to ensure sync.
* Change 'obs_output_signal_start_fail' to 'obs_output_signal_stop'
because it was a bit confusing, and doing this makes a lot more
sense for outputs that need to stop suddenly (disconnections/etc).
- Encoder API:
* Remove some unnecessary encoder functions from the actual API and
make them internal. Most of the encoder functions are handled
automatically by outputs anyway, so there's no real need to expose
them and end up inadvertently confusing plugin writers.
* Have audio encoders wait for the video encoder to get a frame, then
start at the exact data point that the first video frame starts to
ensure the most accrate sync of video/audio possible.
* Add a required 'frame_size' callback for audio encoders that
returns the expected number of frames desired to encode with. This
way, the libobs encoder API can handle the circular buffering
internally automatically for the encoder modules, so encoder
writers don't have to do it themselves.
- Fix a few bugs in the serializer interface. It was passing the wrong
variable for the data in a few cases.
- If a source has video, make obs_source_update defer the actual update
callback until the tick function is called to prevent threading
issues.
2014-04-07 22:00:10 -07:00
|
|
|
#include <sstream>
|
|
|
|
|
2014-04-16 13:35:01 -07:00
|
|
|
#include <QScreen>
|
|
|
|
#include <QWindow>
|
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
#define PREVIEW_EDGE_SIZE 10
|
|
|
|
|
2013-12-29 07:54:06 -08:00
|
|
|
using namespace std;
|
2013-11-22 15:20:52 -08:00
|
|
|
|
2014-02-02 13:26:23 -08:00
|
|
|
Q_DECLARE_METATYPE(OBSScene);
|
|
|
|
Q_DECLARE_METATYPE(OBSSceneItem);
|
2014-10-29 07:53:59 -07:00
|
|
|
Q_DECLARE_METATYPE(OBSSource);
|
2014-08-02 01:33:53 -07:00
|
|
|
Q_DECLARE_METATYPE(obs_order_movement);
|
2014-02-02 13:26:23 -08:00
|
|
|
|
2014-07-27 12:48:14 -07:00
|
|
|
static void AddExtraModulePaths()
|
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char base_module_dir[512];
|
|
|
|
int ret = os_get_config_path(base_module_dir, sizeof(base_module_dir),
|
|
|
|
"obs-studio/plugins/%module%");
|
2014-08-31 07:28:36 -07:00
|
|
|
|
2015-01-15 23:44:38 -08:00
|
|
|
if (ret <= 0)
|
2014-07-27 12:48:14 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
string path = (char*)base_module_dir;
|
|
|
|
obs_add_module_path((path + "/bin").c_str(), (path + "/data").c_str());
|
|
|
|
}
|
|
|
|
|
2014-10-15 13:00:43 -07:00
|
|
|
static QList<QKeySequence> DeleteKeys;
|
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
OBSBasic::OBSBasic(QWidget *parent)
|
2014-05-20 23:27:27 -07:00
|
|
|
: OBSMainWindow (parent),
|
2014-05-18 17:44:10 -07:00
|
|
|
ui (new Ui::OBSBasic)
|
2014-02-02 14:23:38 -08:00
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
2014-04-16 13:35:01 -07:00
|
|
|
|
2014-10-29 07:54:45 -07:00
|
|
|
qRegisterMetaType<OBSScene> ("OBSScene");
|
|
|
|
qRegisterMetaType<OBSSceneItem>("OBSSceneItem");
|
|
|
|
qRegisterMetaType<OBSSource> ("OBSSource");
|
|
|
|
|
2014-04-16 13:35:01 -07:00
|
|
|
connect(windowHandle(), &QWindow::screenChanged, [this]() {
|
|
|
|
struct obs_video_info ovi;
|
|
|
|
|
|
|
|
if (obs_get_video_info(&ovi))
|
|
|
|
ResizePreview(ovi.base_width, ovi.base_height);
|
|
|
|
});
|
2014-05-15 14:04:18 -07:00
|
|
|
|
|
|
|
stringstream name;
|
|
|
|
name << "OBS " << App()->GetVersionString();
|
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
blog(LOG_INFO, "%s", name.str().c_str());
|
2014-05-15 14:04:18 -07:00
|
|
|
setWindowTitle(QT_UTF8(name.str().c_str()));
|
2014-06-30 00:06:01 -07:00
|
|
|
|
|
|
|
connect(ui->scenes->itemDelegate(),
|
|
|
|
SIGNAL(closeEditor(QWidget*,
|
|
|
|
QAbstractItemDelegate::EndEditHint)),
|
|
|
|
this,
|
|
|
|
SLOT(SceneNameEdited(QWidget*,
|
|
|
|
QAbstractItemDelegate::EndEditHint)));
|
|
|
|
|
|
|
|
connect(ui->sources->itemDelegate(),
|
|
|
|
SIGNAL(closeEditor(QWidget*,
|
|
|
|
QAbstractItemDelegate::EndEditHint)),
|
|
|
|
this,
|
|
|
|
SLOT(SceneItemNameEdited(QWidget*,
|
|
|
|
QAbstractItemDelegate::EndEditHint)));
|
2014-07-06 16:18:16 -07:00
|
|
|
|
|
|
|
cpuUsageInfo = os_cpu_usage_info_start();
|
2014-07-06 16:19:27 -07:00
|
|
|
cpuUsageTimer = new QTimer(this);
|
|
|
|
connect(cpuUsageTimer, SIGNAL(timeout()),
|
|
|
|
ui->statusbar, SLOT(UpdateCPUUsage()));
|
|
|
|
cpuUsageTimer->start(3000);
|
2014-07-13 12:46:23 -07:00
|
|
|
|
2014-10-15 13:00:43 -07:00
|
|
|
DeleteKeys =
|
|
|
|
#ifdef __APPLE__
|
|
|
|
QList<QKeySequence>{{Qt::Key_Backspace}} <<
|
|
|
|
#endif
|
|
|
|
QKeySequence::keyBindings(QKeySequence::Delete);
|
|
|
|
|
2014-07-13 12:46:23 -07:00
|
|
|
#ifdef __APPLE__
|
2014-10-15 13:03:22 -07:00
|
|
|
ui->actionRemoveSource->setShortcuts(DeleteKeys);
|
|
|
|
ui->actionRemoveScene->setShortcuts(DeleteKeys);
|
2014-07-20 18:06:02 -07:00
|
|
|
|
|
|
|
ui->action_Settings->setMenuRole(QAction::PreferencesRole);
|
|
|
|
ui->actionE_xit->setMenuRole(QAction::QuitRole);
|
2014-07-13 12:46:23 -07:00
|
|
|
#endif
|
2014-02-02 14:23:38 -08:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent)
|
2014-05-03 22:54:38 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_get_output_source(channel);
|
2014-05-03 22:54:38 -07:00
|
|
|
if (!source)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *data = obs_save_source(source);
|
2014-05-03 22:54:38 -07:00
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_obj(parent, name, data);
|
2014-05-03 22:54:38 -07:00
|
|
|
|
|
|
|
obs_data_release(data);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static obs_data_t *GenerateSaveData()
|
2014-04-26 23:47:50 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *saveData = obs_data_create();
|
|
|
|
obs_data_array_t *sourcesArray = obs_save_sources();
|
|
|
|
obs_source_t *currentScene = obs_get_output_source(0);
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *sceneName = obs_source_get_name(currentScene);
|
2014-04-26 23:47:50 -07:00
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
SaveAudioDevice(DESKTOP_AUDIO_1, 1, saveData);
|
|
|
|
SaveAudioDevice(DESKTOP_AUDIO_2, 2, saveData);
|
|
|
|
SaveAudioDevice(AUX_AUDIO_1, 3, saveData);
|
|
|
|
SaveAudioDevice(AUX_AUDIO_2, 4, saveData);
|
|
|
|
SaveAudioDevice(AUX_AUDIO_3, 5, saveData);
|
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_string(saveData, "current_scene", sceneName);
|
|
|
|
obs_data_set_array(saveData, "sources", sourcesArray);
|
2014-04-26 23:47:50 -07:00
|
|
|
obs_data_array_release(sourcesArray);
|
|
|
|
obs_source_release(currentScene);
|
|
|
|
|
|
|
|
return saveData;
|
|
|
|
}
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
void OBSBasic::ClearVolumeControls()
|
|
|
|
{
|
|
|
|
VolControl *control;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < volumes.size(); i++) {
|
|
|
|
control = volumes[i];
|
|
|
|
delete control;
|
|
|
|
}
|
|
|
|
|
|
|
|
volumes.clear();
|
|
|
|
}
|
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
void OBSBasic::Save(const char *file)
|
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *saveData = GenerateSaveData();
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *jsonData = obs_data_get_json(saveData);
|
2014-04-26 23:47:50 -07:00
|
|
|
|
|
|
|
/* TODO maybe a message box here? */
|
|
|
|
if (!os_quick_write_utf8_file(file, jsonData, strlen(jsonData), false))
|
|
|
|
blog(LOG_ERROR, "Could not save scene data to %s", file);
|
|
|
|
|
|
|
|
obs_data_release(saveData);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void LoadAudioDevice(const char *name, int channel, obs_data_t *parent)
|
2014-05-03 22:54:38 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *data = obs_data_get_obj(parent, name);
|
2014-05-03 22:54:38 -07:00
|
|
|
if (!data)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_load_source(data);
|
2014-05-03 22:54:38 -07:00
|
|
|
if (source) {
|
|
|
|
obs_set_output_source(channel, source);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
obs_data_release(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::CreateDefaultScene()
|
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_scene_create(Str("Basic.Scene"));
|
|
|
|
obs_source_t *source = obs_scene_get_source(scene);
|
2014-05-03 22:54:38 -07:00
|
|
|
|
|
|
|
obs_add_source(source);
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
source = obs_source_create(OBS_SOURCE_TYPE_INPUT, "display_capture",
|
2014-05-12 15:30:36 -07:00
|
|
|
Str("Basic.DisplayCapture"), NULL);
|
2014-05-03 22:54:38 -07:00
|
|
|
|
|
|
|
if (source) {
|
|
|
|
obs_scene_add(scene, source);
|
|
|
|
obs_add_source(source);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-08-04 08:41:15 -07:00
|
|
|
obs_set_output_source(0, obs_scene_get_source(scene));
|
2014-05-03 22:54:38 -07:00
|
|
|
obs_scene_release(scene);
|
|
|
|
}
|
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
void OBSBasic::Load(const char *file)
|
|
|
|
{
|
|
|
|
if (!file) {
|
|
|
|
blog(LOG_ERROR, "Could not find file %s", file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
BPtr<char> jsonData = os_quick_read_utf8_file(file);
|
2014-05-03 22:54:38 -07:00
|
|
|
if (!jsonData) {
|
|
|
|
CreateDefaultScene();
|
2014-04-26 23:47:50 -07:00
|
|
|
return;
|
2014-05-03 22:54:38 -07:00
|
|
|
}
|
2014-04-26 23:47:50 -07:00
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *data = obs_data_create_from_json(jsonData);
|
|
|
|
obs_data_array_t *sources = obs_data_get_array(data, "sources");
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *sceneName = obs_data_get_string(data,
|
|
|
|
"current_scene");
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *curScene;
|
2014-04-26 23:47:50 -07:00
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
LoadAudioDevice(DESKTOP_AUDIO_1, 1, data);
|
|
|
|
LoadAudioDevice(DESKTOP_AUDIO_2, 2, data);
|
|
|
|
LoadAudioDevice(AUX_AUDIO_1, 3, data);
|
|
|
|
LoadAudioDevice(AUX_AUDIO_2, 4, data);
|
|
|
|
LoadAudioDevice(AUX_AUDIO_3, 5, data);
|
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
obs_load_sources(sources);
|
|
|
|
|
|
|
|
curScene = obs_get_source_by_name(sceneName);
|
|
|
|
obs_set_output_source(0, curScene);
|
|
|
|
obs_source_release(curScene);
|
|
|
|
|
|
|
|
obs_data_array_release(sources);
|
|
|
|
obs_data_release(data);
|
|
|
|
}
|
|
|
|
|
2014-03-10 13:59:15 -07:00
|
|
|
static inline bool HasAudioDevices(const char *source_id)
|
|
|
|
{
|
|
|
|
const char *output_id = source_id;
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_properties_t *props = obs_get_source_properties(
|
2014-06-25 00:13:00 -07:00
|
|
|
OBS_SOURCE_TYPE_INPUT, output_id);
|
2014-03-10 13:59:15 -07:00
|
|
|
size_t count = 0;
|
|
|
|
|
|
|
|
if (!props)
|
|
|
|
return false;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_property_t *devices = obs_properties_get(props, "device_id");
|
2014-03-10 13:59:15 -07:00
|
|
|
if (devices)
|
|
|
|
count = obs_property_list_item_count(devices);
|
|
|
|
|
|
|
|
obs_properties_destroy(props);
|
|
|
|
|
|
|
|
return count != 0;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void OBSStartStreaming(void *data, calldata_t *params)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
{
|
|
|
|
UNUSED_PARAMETER(params);
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"StreamingStart");
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void OBSStopStreaming(void *data, calldata_t *params)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
{
|
2014-05-12 15:30:36 -07:00
|
|
|
int code = (int)calldata_int(params, "code");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"StreamingStop", Q_ARG(int, code));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void OBSStartRecording(void *data, calldata_t *params)
|
2014-08-24 18:10:57 -07:00
|
|
|
{
|
|
|
|
UNUSED_PARAMETER(params);
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"RecordingStart");
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void OBSStopRecording(void *data, calldata_t *params)
|
2014-05-20 23:27:27 -07:00
|
|
|
{
|
|
|
|
UNUSED_PARAMETER(params);
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"RecordingStop");
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
#define SERVICE_PATH "obs-studio/basic/service.json"
|
|
|
|
|
|
|
|
void OBSBasic::SaveService()
|
|
|
|
{
|
|
|
|
if (!service)
|
|
|
|
return;
|
|
|
|
|
2015-01-15 23:44:38 -08:00
|
|
|
char serviceJsonPath[512];
|
|
|
|
int ret = os_get_config_path(serviceJsonPath, sizeof(serviceJsonPath),
|
|
|
|
SERVICE_PATH);
|
|
|
|
if (ret <= 0)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *data = obs_data_create();
|
|
|
|
obs_data_t *settings = obs_service_get_settings(service);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_string(data, "type", obs_service_gettype(service));
|
|
|
|
obs_data_set_obj(data, "settings", settings);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *json = obs_data_get_json(data);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
|
|
|
os_quick_write_utf8_file(serviceJsonPath, json, strlen(json), false);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
obs_data_release(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::LoadService()
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
|
2015-01-15 23:44:38 -08:00
|
|
|
char serviceJsonPath[512];
|
|
|
|
int ret = os_get_config_path(serviceJsonPath, sizeof(serviceJsonPath),
|
|
|
|
SERVICE_PATH);
|
|
|
|
if (ret <= 0)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
return false;
|
|
|
|
|
|
|
|
BPtr<char> jsonText = os_quick_read_utf8_file(serviceJsonPath);
|
|
|
|
if (!jsonText)
|
|
|
|
return false;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *data = obs_data_create_from_json(jsonText);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
|
|
|
obs_data_set_default_string(data, "type", "rtmp_common");
|
2014-08-05 11:09:29 -07:00
|
|
|
type = obs_data_get_string(data, "type");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *settings = obs_data_get_obj(data, "settings");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
2014-07-13 05:05:29 -07:00
|
|
|
service = obs_service_create(type, "default_service", settings);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
obs_data_release(data);
|
|
|
|
|
|
|
|
return !!service;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::InitOutputs()
|
|
|
|
{
|
2014-07-13 05:05:29 -07:00
|
|
|
fileOutput = obs_output_create("flv_output", "default_file_output",
|
|
|
|
nullptr);
|
2014-05-20 23:27:27 -07:00
|
|
|
if (!fileOutput)
|
|
|
|
return false;
|
|
|
|
|
2014-07-13 05:05:29 -07:00
|
|
|
streamOutput = obs_output_create("rtmp_output", "default_stream",
|
|
|
|
nullptr);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!streamOutput)
|
|
|
|
return false;
|
|
|
|
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_output_get_signal_handler(streamOutput),
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
"start", OBSStartStreaming, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_output_get_signal_handler(streamOutput),
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
"stop", OBSStopStreaming, this);
|
|
|
|
|
2014-08-24 18:10:57 -07:00
|
|
|
signal_handler_connect(obs_output_get_signal_handler(fileOutput),
|
|
|
|
"start", OBSStartRecording, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_output_get_signal_handler(fileOutput),
|
2014-05-20 23:27:27 -07:00
|
|
|
"stop", OBSStopRecording, this);
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::InitEncoders()
|
|
|
|
{
|
2014-07-13 05:05:29 -07:00
|
|
|
x264 = obs_video_encoder_create("obs_x264", "default_h264", nullptr);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!x264)
|
|
|
|
return false;
|
|
|
|
|
2014-07-13 05:05:29 -07:00
|
|
|
aac = obs_audio_encoder_create("libfdk_aac", "default_aac", nullptr);
|
2014-05-22 03:07:17 -07:00
|
|
|
|
2014-07-13 05:05:29 -07:00
|
|
|
if (!aac)
|
|
|
|
aac = obs_audio_encoder_create("ffmpeg_aac", "default_aac",
|
|
|
|
nullptr);
|
2014-05-22 03:07:17 -07:00
|
|
|
|
|
|
|
if (!aac)
|
|
|
|
return false;
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::InitService()
|
|
|
|
{
|
|
|
|
if (LoadService())
|
|
|
|
return true;
|
|
|
|
|
2014-07-13 05:05:29 -07:00
|
|
|
service = obs_service_create("rtmp_common", "default_service", nullptr);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!service)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
bool OBSBasic::InitBasicConfigDefaults()
|
|
|
|
{
|
2014-03-10 13:59:15 -07:00
|
|
|
bool hasDesktopAudio = HasAudioDevices(App()->OutputAudioSource());
|
|
|
|
bool hasInputAudio = HasAudioDevices(App()->InputAudioSource());
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
config_set_default_int(basicConfig, "Window", "PosX", -1);
|
|
|
|
config_set_default_int(basicConfig, "Window", "PosY", -1);
|
|
|
|
config_set_default_int(basicConfig, "Window", "SizeX", -1);
|
|
|
|
config_set_default_int(basicConfig, "Window", "SizeY", -1);
|
|
|
|
|
|
|
|
vector<MonitorInfo> monitors;
|
|
|
|
GetMonitors(monitors);
|
|
|
|
|
|
|
|
if (!monitors.size()) {
|
|
|
|
OBSErrorBox(NULL, "There appears to be no monitors. Er, this "
|
|
|
|
"technically shouldn't be possible.");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t cx = monitors[0].cx;
|
|
|
|
uint32_t cy = monitors[0].cy;
|
|
|
|
|
2014-03-10 13:10:35 -07:00
|
|
|
/* TODO: temporary */
|
2014-05-20 23:27:27 -07:00
|
|
|
config_set_default_string(basicConfig, "SimpleOutput", "FilePath",
|
|
|
|
GetDefaultVideoSavePath().c_str());
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
config_set_default_uint (basicConfig, "SimpleOutput", "VBitrate",
|
|
|
|
2500);
|
|
|
|
config_set_default_uint (basicConfig, "SimpleOutput", "ABitrate", 128);
|
2014-07-03 18:07:33 -07:00
|
|
|
config_set_default_bool (basicConfig, "SimpleOutput", "Reconnect",
|
|
|
|
true);
|
|
|
|
config_set_default_uint (basicConfig, "SimpleOutput", "RetryDelay", 2);
|
|
|
|
config_set_default_uint (basicConfig, "SimpleOutput", "MaxRetries",
|
|
|
|
20);
|
2014-08-25 07:48:51 -07:00
|
|
|
config_set_default_bool (basicConfig, "SimpleOutput", "UseAdvanced",
|
|
|
|
false);
|
2014-09-24 20:23:42 -07:00
|
|
|
config_set_default_bool (basicConfig, "SimpleOutput", "UseCBR", true);
|
2014-08-25 07:48:51 -07:00
|
|
|
config_set_default_string(basicConfig, "SimpleOutput", "Preset",
|
|
|
|
"veryfast");
|
2014-03-10 13:10:35 -07:00
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
config_set_default_uint (basicConfig, "Video", "BaseCX", cx);
|
|
|
|
config_set_default_uint (basicConfig, "Video", "BaseCY", cy);
|
|
|
|
|
|
|
|
cx = cx * 10 / 15;
|
|
|
|
cy = cy * 10 / 15;
|
|
|
|
config_set_default_uint (basicConfig, "Video", "OutputCX", cx);
|
|
|
|
config_set_default_uint (basicConfig, "Video", "OutputCY", cy);
|
|
|
|
|
|
|
|
config_set_default_uint (basicConfig, "Video", "FPSType", 0);
|
|
|
|
config_set_default_string(basicConfig, "Video", "FPSCommon", "30");
|
|
|
|
config_set_default_uint (basicConfig, "Video", "FPSInt", 30);
|
|
|
|
config_set_default_uint (basicConfig, "Video", "FPSNum", 30);
|
|
|
|
config_set_default_uint (basicConfig, "Video", "FPSDen", 1);
|
2014-12-15 01:08:46 -08:00
|
|
|
config_set_default_string(basicConfig, "Video", "ScaleType", "bicubic");
|
2015-01-09 20:16:30 -08:00
|
|
|
config_set_default_string(basicConfig, "Video", "ColorFormat", "NV12");
|
|
|
|
config_set_default_string(basicConfig, "Video", "ColorSpace", "709");
|
|
|
|
config_set_default_string(basicConfig, "Video", "ColorRange",
|
|
|
|
"Partial");
|
2014-03-06 20:08:12 -08:00
|
|
|
|
|
|
|
config_set_default_uint (basicConfig, "Audio", "SampleRate", 44100);
|
|
|
|
config_set_default_string(basicConfig, "Audio", "ChannelSetup",
|
|
|
|
"Stereo");
|
|
|
|
config_set_default_uint (basicConfig, "Audio", "BufferingTime", 1000);
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
config_set_default_string(basicConfig, "Audio", "DesktopDevice1",
|
2014-03-10 13:59:15 -07:00
|
|
|
hasDesktopAudio ? "default" : "disabled");
|
2014-03-07 11:56:31 -08:00
|
|
|
config_set_default_string(basicConfig, "Audio", "DesktopDevice2",
|
|
|
|
"disabled");
|
|
|
|
config_set_default_string(basicConfig, "Audio", "AuxDevice1",
|
2014-03-10 13:59:15 -07:00
|
|
|
hasInputAudio ? "default" : "disabled");
|
2014-03-07 11:56:31 -08:00
|
|
|
config_set_default_string(basicConfig, "Audio", "AuxDevice2",
|
|
|
|
"disabled");
|
|
|
|
config_set_default_string(basicConfig, "Audio", "AuxDevice3",
|
|
|
|
"disabled");
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::InitBasicConfig()
|
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char configPath[512];
|
|
|
|
int ret = os_get_config_path(configPath, sizeof(configPath),
|
|
|
|
"obs-studio/basic/basic.ini");
|
|
|
|
if (ret <= 0) {
|
|
|
|
OBSErrorBox(nullptr, "Failed to get base.ini path");
|
|
|
|
return false;
|
|
|
|
}
|
2014-03-06 20:08:12 -08:00
|
|
|
|
2014-05-12 15:30:36 -07:00
|
|
|
int code = basicConfig.Open(configPath, CONFIG_OPEN_ALWAYS);
|
|
|
|
if (code != CONFIG_SUCCESS) {
|
|
|
|
OBSErrorBox(NULL, "Failed to open basic.ini: %d", code);
|
2014-03-06 20:08:12 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return InitBasicConfigDefaults();
|
|
|
|
}
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
void OBSBasic::InitOBSCallbacks()
|
|
|
|
{
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "source_add",
|
2014-05-03 22:54:38 -07:00
|
|
|
OBSBasic::SourceAdded, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "source_remove",
|
2014-05-03 22:54:38 -07:00
|
|
|
OBSBasic::SourceRemoved, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "channel_change",
|
2014-05-03 22:54:38 -07:00
|
|
|
OBSBasic::ChannelChanged, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "source_activate",
|
2014-05-03 22:54:38 -07:00
|
|
|
OBSBasic::SourceActivated, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "source_deactivate",
|
2014-05-03 22:54:38 -07:00
|
|
|
OBSBasic::SourceDeactivated, this);
|
2014-08-04 09:09:02 -07:00
|
|
|
signal_handler_connect(obs_get_signal_handler(), "source_rename",
|
2014-06-30 00:06:01 -07:00
|
|
|
OBSBasic::SourceRenamed, this);
|
2014-05-03 22:54:38 -07:00
|
|
|
}
|
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
void OBSBasic::InitPrimitives()
|
|
|
|
{
|
2014-08-04 05:48:58 -07:00
|
|
|
obs_enter_graphics();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_render_start(true);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
gs_vertex2f(0.0f, 0.0f);
|
|
|
|
gs_vertex2f(0.0f, 1.0f);
|
|
|
|
gs_vertex2f(1.0f, 1.0f);
|
|
|
|
gs_vertex2f(1.0f, 0.0f);
|
|
|
|
gs_vertex2f(0.0f, 0.0f);
|
2014-08-07 23:42:07 -07:00
|
|
|
box = gs_render_save();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_render_start(true);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
for (int i = 0; i <= 360; i += (360/20)) {
|
|
|
|
float pos = RAD(float(i));
|
|
|
|
gs_vertex2f(cosf(pos), sinf(pos));
|
|
|
|
}
|
2014-08-07 23:42:07 -07:00
|
|
|
circle = gs_render_save();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-08-04 05:48:58 -07:00
|
|
|
obs_leave_graphics();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
}
|
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
void OBSBasic::OBSInit()
|
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char savePath[512];
|
|
|
|
int ret = os_get_config_path(savePath, sizeof(savePath),
|
|
|
|
"obs-studio/basic/scenes.json");
|
|
|
|
if (ret <= 0)
|
|
|
|
throw "Failed to get scenes.json file path";
|
2014-05-03 22:54:38 -07:00
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
/* make sure it's fully displayed before doing any initialization */
|
|
|
|
show();
|
|
|
|
App()->processEvents();
|
|
|
|
|
2014-06-25 00:21:16 -07:00
|
|
|
if (!obs_startup(App()->GetLocale()))
|
2014-02-02 14:23:38 -08:00
|
|
|
throw "Failed to initialize libobs";
|
2014-03-06 20:08:12 -08:00
|
|
|
if (!InitBasicConfig())
|
|
|
|
throw "Failed to load basic.ini";
|
2014-02-22 19:14:19 -08:00
|
|
|
if (!ResetAudio())
|
2014-02-02 14:23:38 -08:00
|
|
|
throw "Failed to initialize audio";
|
|
|
|
|
2015-01-15 23:44:38 -08:00
|
|
|
ret = ResetVideo();
|
2014-07-20 17:40:57 -07:00
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case OBS_VIDEO_MODULE_NOT_FOUND:
|
|
|
|
throw "Failed to initialize video: Graphics module not found";
|
|
|
|
case OBS_VIDEO_NOT_SUPPORTED:
|
2014-08-25 15:52:54 -07:00
|
|
|
throw "Failed to initialize video: Required graphics API "
|
|
|
|
"functionality not found on these drivers or "
|
|
|
|
"unavailable on this equipment";
|
2014-07-20 17:40:57 -07:00
|
|
|
case OBS_VIDEO_INVALID_PARAM:
|
|
|
|
throw "Failed to initialize video: Invalid parameters";
|
|
|
|
default:
|
|
|
|
if (ret != OBS_VIDEO_SUCCESS)
|
|
|
|
throw "Failed to initialize video: Unspecified error";
|
|
|
|
}
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
InitOBSCallbacks();
|
2014-02-02 14:23:38 -08:00
|
|
|
|
2014-07-27 12:48:14 -07:00
|
|
|
AddExtraModulePaths();
|
(API Change) Refactor module handling
Changed API:
- char *obs_find_plugin_file(const char *sub_path);
Changed to: char *obs_module_file(const char *file);
Cahnge it so you no longer need to specify a sub-path such as:
obs_find_plugin_file("module_name/file.ext")
Instead, now automatically handle the module data path so all you need
to do is:
obs_module_file("file.ext")
- int obs_load_module(const char *name);
Changed to: int obs_open_module(obs_module_t *module,
const char *path,
const char *data_path);
bool obs_init_module(obs_module_t module);
Change the module loading API so that if the front-end chooses, it can
load modules directly from a specified path, and associate a data
directory with it on the spot.
The module will not be initialized immediately; obs_init_module must
be called on the module pointer in order to fully initialize the
module. This is done so a module can be disabled by the front-end if
the it so chooses.
New API:
- void obs_add_module_path(const char *bin, const char *data);
These functions allow you to specify new module search paths to add,
and allow you to search through them, or optionally just load all
modules from them. If the string %module% is included, it will
replace it with the module's name when that string is used as a
lookup. Data paths are now directly added to the module's internal
storage structure, and when obs_find_module_file is used, it will look
up the pointer to the obs_module structure and get its data directory
that way.
Example:
obs_add_module_path("/opt/obs/my-modules/%module%/bin",
"/opt/obs/my-modules/%module%/data");
This would cause it to additionally look for the binary of a
hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so
(or libfoo.so), and then look for the data in
/opt/obs/my-modules/foo/data.
This gives the front-end more flexibility for handling third-party
plugin modules, or handling all plugin modules in a custom way.
- void obs_find_modules(obs_find_module_callback_t callback, void
*param);
This searches the existing paths for modules and calls the callback
function when any are found. Useful for plugin management and custom
handling of the paths by the front-end if desired.
- void obs_load_all_modules(void);
Search through the paths and both loads and initializes all modules
automatically without custom handling.
- void obs_enum_modules(obs_enum_module_callback_t callback,
void *param);
Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
|
|
|
obs_load_all_modules();
|
2014-03-07 16:03:34 -08:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!InitOutputs())
|
|
|
|
throw "Failed to initialize outputs";
|
|
|
|
if (!InitEncoders())
|
|
|
|
throw "Failed to initialize encoders";
|
|
|
|
if (!InitService())
|
|
|
|
throw "Failed to initialize service";
|
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
InitPrimitives();
|
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
Load(savePath);
|
2014-03-07 16:03:34 -08:00
|
|
|
ResetAudioDevices();
|
2014-06-16 19:41:36 -07:00
|
|
|
|
2014-07-13 23:56:28 -07:00
|
|
|
TimedCheckForUpdates();
|
2014-06-16 19:41:36 -07:00
|
|
|
loaded = true;
|
2015-01-04 08:20:15 -08:00
|
|
|
|
|
|
|
QTimer *timer = new QTimer(this);
|
|
|
|
connect(timer, SIGNAL(timeout()), this, SLOT(SaveProject()));
|
|
|
|
timer->start(20000);
|
2014-02-02 14:23:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
OBSBasic::~OBSBasic()
|
|
|
|
{
|
2015-01-04 08:16:59 -08:00
|
|
|
SaveProject();
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
/* XXX: any obs data must be released before calling obs_shutdown.
|
|
|
|
* currently, we can't automate this with C++ RAII because of the
|
|
|
|
* delicate nature of obs_shutdown needing to be freed before the UI
|
|
|
|
* can be freed, and we have no control over the destruction order of
|
|
|
|
* the Qt UI stuff, so we have to manually clear any references to
|
|
|
|
* libobs. */
|
2014-07-06 16:19:27 -07:00
|
|
|
delete cpuUsageTimer;
|
2014-07-06 16:18:16 -07:00
|
|
|
os_cpu_usage_info_destroy(cpuUsageInfo);
|
|
|
|
|
2014-09-15 16:16:16 -07:00
|
|
|
if (interaction)
|
|
|
|
delete interaction;
|
|
|
|
|
2014-07-22 13:16:57 -07:00
|
|
|
if (properties)
|
|
|
|
delete properties;
|
|
|
|
|
|
|
|
if (transformWindow)
|
|
|
|
delete transformWindow;
|
2014-03-23 01:07:54 -07:00
|
|
|
|
2014-12-28 00:38:00 -08:00
|
|
|
if (advAudioWindow)
|
|
|
|
delete advAudioWindow;
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
ClearVolumeControls();
|
2014-02-02 14:23:38 -08:00
|
|
|
ui->sources->clear();
|
|
|
|
ui->scenes->clear();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-08-04 05:48:58 -07:00
|
|
|
obs_enter_graphics();
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_vertexbuffer_destroy(box);
|
|
|
|
gs_vertexbuffer_destroy(circle);
|
2014-08-04 05:48:58 -07:00
|
|
|
obs_leave_graphics();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
obs_shutdown();
|
2014-07-13 12:38:58 -07:00
|
|
|
|
|
|
|
config_set_int(App()->GlobalConfig(), "General", "LastVersion",
|
|
|
|
LIBOBS_API_VER);
|
|
|
|
config_save(App()->GlobalConfig());
|
2014-02-02 14:23:38 -08:00
|
|
|
}
|
|
|
|
|
2015-01-04 08:16:59 -08:00
|
|
|
void OBSBasic::SaveProject()
|
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char savePath[512];
|
|
|
|
int ret = os_get_config_path(savePath, sizeof(savePath),
|
|
|
|
"obs-studio/basic/scenes.json");
|
|
|
|
if (ret <= 0)
|
|
|
|
return;
|
|
|
|
|
2015-01-04 08:16:59 -08:00
|
|
|
SaveService();
|
|
|
|
Save(savePath);
|
|
|
|
}
|
|
|
|
|
2014-02-02 13:26:23 -08:00
|
|
|
OBSScene OBSBasic::GetCurrentScene()
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QListWidgetItem *item = ui->scenes->currentItem();
|
2014-02-02 13:26:23 -08:00
|
|
|
return item ? item->data(Qt::UserRole).value<OBSScene>() : nullptr;
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-09-15 16:04:22 -07:00
|
|
|
OBSSceneItem OBSBasic::GetSceneItem(QListWidgetItem *item)
|
2014-01-30 00:31:52 -08:00
|
|
|
{
|
2014-02-02 13:26:23 -08:00
|
|
|
return item ? item->data(Qt::UserRole).value<OBSSceneItem>() : nullptr;
|
2014-01-30 00:31:52 -08:00
|
|
|
}
|
|
|
|
|
2014-09-15 16:04:22 -07:00
|
|
|
OBSSceneItem OBSBasic::GetCurrentSceneItem()
|
|
|
|
{
|
|
|
|
return GetSceneItem(ui->sources->currentItem());
|
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::UpdateSources(OBSScene scene)
|
|
|
|
{
|
|
|
|
ui->sources->clear();
|
|
|
|
|
|
|
|
obs_scene_enum_items(scene,
|
2014-09-25 17:44:05 -07:00
|
|
|
[] (obs_scene_t *scene, obs_sceneitem_t *item, void *p)
|
2014-02-02 16:03:55 -08:00
|
|
|
{
|
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(p);
|
2014-03-01 04:54:55 -08:00
|
|
|
window->InsertSceneItem(item);
|
2014-02-14 14:13:36 -08:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
2014-02-02 16:03:55 -08:00
|
|
|
return true;
|
|
|
|
}, this);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::InsertSceneItem(obs_sceneitem_t *item)
|
2014-03-01 04:54:55 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-03-01 04:54:55 -08:00
|
|
|
|
|
|
|
QListWidgetItem *listItem = new QListWidgetItem(QT_UTF8(name));
|
|
|
|
listItem->setData(Qt::UserRole,
|
|
|
|
QVariant::fromValue(OBSSceneItem(item)));
|
|
|
|
|
|
|
|
ui->sources->insertItem(0, listItem);
|
2014-06-16 19:41:36 -07:00
|
|
|
ui->sources->setCurrentRow(0);
|
|
|
|
|
|
|
|
/* if the source was just created, open properties dialog */
|
2014-07-22 13:16:57 -07:00
|
|
|
if (sourceSceneRefs[source] == 0 && loaded)
|
|
|
|
CreatePropertiesWindow(source);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::CreateInteractionWindow(obs_source_t *source)
|
2014-09-15 16:16:16 -07:00
|
|
|
{
|
|
|
|
if (interaction)
|
|
|
|
interaction->close();
|
|
|
|
|
|
|
|
interaction = new OBSBasicInteraction(this, source);
|
|
|
|
interaction->Init();
|
|
|
|
interaction->setAttribute(Qt::WA_DeleteOnClose, true);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::CreatePropertiesWindow(obs_source_t *source)
|
2014-07-22 13:16:57 -07:00
|
|
|
{
|
|
|
|
if (properties)
|
|
|
|
properties->close();
|
|
|
|
|
|
|
|
properties = new OBSBasicProperties(this, source);
|
|
|
|
properties->Init();
|
|
|
|
properties->setAttribute(Qt::WA_DeleteOnClose, true);
|
2014-03-01 04:54:55 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
/* Qt callbacks for invokeMethod */
|
|
|
|
|
|
|
|
void OBSBasic::AddScene(OBSSource source)
|
2013-12-28 04:33:16 -08:00
|
|
|
{
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_scene_from_source(source);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
|
|
|
QListWidgetItem *item = new QListWidgetItem(QT_UTF8(name));
|
2014-02-02 13:26:23 -08:00
|
|
|
item->setData(Qt::UserRole, QVariant::fromValue(OBSScene(scene)));
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
ui->scenes->addItem(item);
|
2014-01-04 12:53:36 -08:00
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
signal_handler_t *handler = obs_source_get_signal_handler(source);
|
2014-03-01 04:54:55 -08:00
|
|
|
signal_handler_connect(handler, "item_add",
|
2014-02-23 17:58:01 -08:00
|
|
|
OBSBasic::SceneItemAdded, this);
|
2014-03-01 04:54:55 -08:00
|
|
|
signal_handler_connect(handler, "item_remove",
|
2014-02-23 17:58:01 -08:00
|
|
|
OBSBasic::SceneItemRemoved, this);
|
2014-10-13 13:14:06 -07:00
|
|
|
signal_handler_connect(handler, "item_select",
|
|
|
|
OBSBasic::SceneItemSelected, this);
|
|
|
|
signal_handler_connect(handler, "item_deselect",
|
2015-01-04 08:19:52 -08:00
|
|
|
OBSBasic::SceneItemDeselected, this);
|
2014-05-15 17:40:53 -07:00
|
|
|
signal_handler_connect(handler, "item_move_up",
|
|
|
|
OBSBasic::SceneItemMoveUp, this);
|
|
|
|
signal_handler_connect(handler, "item_move_down",
|
|
|
|
OBSBasic::SceneItemMoveDown, this);
|
|
|
|
signal_handler_connect(handler, "item_move_top",
|
|
|
|
OBSBasic::SceneItemMoveTop, this);
|
|
|
|
signal_handler_connect(handler, "item_move_bottom",
|
|
|
|
OBSBasic::SceneItemMoveBottom, this);
|
2013-12-28 04:33:16 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::RemoveScene(OBSSource source)
|
2013-12-28 21:29:13 -08:00
|
|
|
{
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2013-12-28 21:29:13 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QListWidgetItem *sel = ui->scenes->currentItem();
|
|
|
|
QList<QListWidgetItem*> items = ui->scenes->findItems(QT_UTF8(name),
|
|
|
|
Qt::MatchExactly);
|
2014-01-06 19:20:18 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
if (sel != nullptr) {
|
|
|
|
if (items.contains(sel))
|
|
|
|
ui->sources->clear();
|
|
|
|
delete sel;
|
2014-01-06 19:20:18 -08:00
|
|
|
}
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::AddSceneItem(OBSSceneItem item)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_sceneitem_get_scene(item);
|
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-01-06 19:20:18 -08:00
|
|
|
|
2014-03-01 04:54:55 -08:00
|
|
|
if (GetCurrentScene() == scene)
|
|
|
|
InsertSceneItem(item);
|
2014-01-06 19:20:18 -08:00
|
|
|
|
|
|
|
sourceSceneRefs[source] = sourceSceneRefs[source] + 1;
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::RemoveSceneItem(OBSSceneItem item)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_sceneitem_get_scene(item);
|
2014-01-04 12:53:36 -08:00
|
|
|
|
2014-01-06 19:20:18 -08:00
|
|
|
if (GetCurrentScene() == scene) {
|
2014-01-23 22:58:48 -08:00
|
|
|
for (int i = 0; i < ui->sources->count(); i++) {
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QListWidgetItem *listItem = ui->sources->item(i);
|
|
|
|
QVariant userData = listItem->data(Qt::UserRole);
|
2014-01-06 19:20:18 -08:00
|
|
|
|
2014-02-02 13:26:23 -08:00
|
|
|
if (userData.value<OBSSceneItem>() == item) {
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
delete listItem;
|
2014-01-06 19:20:18 -08:00
|
|
|
break;
|
|
|
|
}
|
2014-01-04 18:26:15 -08:00
|
|
|
}
|
|
|
|
}
|
2014-01-06 19:20:18 -08:00
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-01-06 19:20:18 -08:00
|
|
|
|
|
|
|
int scenes = sourceSceneRefs[source] - 1;
|
2014-05-11 23:20:45 -07:00
|
|
|
sourceSceneRefs[source] = scenes;
|
|
|
|
|
2014-01-06 19:20:18 -08:00
|
|
|
if (scenes == 0) {
|
|
|
|
obs_source_remove(source);
|
|
|
|
sourceSceneRefs.erase(source);
|
|
|
|
}
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::UpdateSceneSelection(OBSSource source)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
|
|
|
if (source) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_scene_from_source(source);
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
if (!scene)
|
|
|
|
return;
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QList<QListWidgetItem*> items =
|
|
|
|
ui->scenes->findItems(QT_UTF8(name), Qt::MatchExactly);
|
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
if (items.count()) {
|
|
|
|
sceneChanging = true;
|
|
|
|
ui->scenes->setCurrentItem(items.first());
|
|
|
|
sceneChanging = false;
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
UpdateSources(scene);
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
2013-12-28 21:29:13 -08:00
|
|
|
}
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-06-30 00:06:01 -07:00
|
|
|
static void RenameListValues(QListWidget *listWidget, const QString &newName,
|
|
|
|
const QString &prevName)
|
|
|
|
{
|
|
|
|
QList<QListWidgetItem*> items =
|
|
|
|
listWidget->findItems(prevName, Qt::MatchExactly);
|
|
|
|
|
|
|
|
for (int i = 0; i < items.count(); i++)
|
|
|
|
items[i]->setText(newName);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::RenameSources(QString newName, QString prevName)
|
|
|
|
{
|
|
|
|
RenameListValues(ui->scenes, newName, prevName);
|
|
|
|
RenameListValues(ui->sources, newName, prevName);
|
2014-07-08 11:58:48 -07:00
|
|
|
|
|
|
|
for (size_t i = 0; i < volumes.size(); i++) {
|
|
|
|
if (volumes[i]->GetName().compare(prevName) == 0)
|
|
|
|
volumes[i]->SetName(newName);
|
|
|
|
}
|
2014-06-30 00:06:01 -07:00
|
|
|
}
|
|
|
|
|
2014-10-13 13:14:06 -07:00
|
|
|
void OBSBasic::SelectSceneItem(OBSScene scene, OBSSceneItem item, bool select)
|
|
|
|
{
|
2014-10-14 16:59:07 -07:00
|
|
|
if (!select || scene != GetCurrentScene())
|
2014-10-13 13:14:06 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (int i = 0; i < ui->sources->count(); i++) {
|
|
|
|
QListWidgetItem *witem = ui->sources->item(i);
|
|
|
|
QVariant data = witem->data(Qt::UserRole);
|
|
|
|
if (!data.canConvert<OBSSceneItem>())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (item != data.value<OBSSceneItem>())
|
|
|
|
continue;
|
|
|
|
|
2014-10-14 16:59:07 -07:00
|
|
|
ui->sources->setCurrentItem(witem);
|
2014-10-13 13:14:06 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-02 01:33:53 -07:00
|
|
|
void OBSBasic::MoveSceneItem(OBSSceneItem item, obs_order_movement movement)
|
2014-05-15 17:40:53 -07:00
|
|
|
{
|
2014-08-03 14:39:19 -07:00
|
|
|
OBSScene scene = obs_sceneitem_get_scene(item);
|
2014-05-15 17:40:53 -07:00
|
|
|
if (scene != GetCurrentScene())
|
|
|
|
return;
|
|
|
|
|
|
|
|
int curRow = ui->sources->currentRow();
|
|
|
|
if (curRow == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QListWidgetItem *listItem = ui->sources->takeItem(curRow);
|
|
|
|
|
|
|
|
switch (movement) {
|
2014-08-02 01:33:53 -07:00
|
|
|
case OBS_ORDER_MOVE_UP:
|
2014-05-15 17:40:53 -07:00
|
|
|
if (curRow > 0)
|
|
|
|
curRow--;
|
|
|
|
break;
|
|
|
|
|
2014-08-02 01:33:53 -07:00
|
|
|
case OBS_ORDER_MOVE_DOWN:
|
2014-05-15 17:40:53 -07:00
|
|
|
if (curRow < ui->sources->count())
|
|
|
|
curRow++;
|
|
|
|
break;
|
|
|
|
|
2014-08-02 01:33:53 -07:00
|
|
|
case OBS_ORDER_MOVE_TOP:
|
2014-05-15 17:40:53 -07:00
|
|
|
curRow = 0;
|
|
|
|
break;
|
|
|
|
|
2014-08-02 01:33:53 -07:00
|
|
|
case OBS_ORDER_MOVE_BOTTOM:
|
2014-05-15 17:40:53 -07:00
|
|
|
curRow = ui->sources->count();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->sources->insertItem(curRow, listItem);
|
|
|
|
ui->sources->setCurrentRow(curRow);
|
|
|
|
}
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
void OBSBasic::ActivateAudioSource(OBSSource source)
|
|
|
|
{
|
|
|
|
VolControl *vol = new VolControl(source);
|
|
|
|
|
|
|
|
volumes.push_back(vol);
|
|
|
|
ui->volumeWidgets->layout()->addWidget(vol);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::DeactivateAudioSource(OBSSource source)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < volumes.size(); i++) {
|
|
|
|
if (volumes[i]->GetSource() == source) {
|
|
|
|
delete volumes[i];
|
|
|
|
volumes.erase(volumes.begin() + i);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
bool OBSBasic::QueryRemoveSource(obs_source_t *source)
|
2014-06-30 01:13:32 -07:00
|
|
|
{
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_name(source);
|
2014-06-30 13:45:58 -07:00
|
|
|
|
|
|
|
QString text = QTStr("ConfirmRemove.Text");
|
|
|
|
text.replace("$1", QT_UTF8(name));
|
2014-06-30 01:13:32 -07:00
|
|
|
|
2014-08-15 10:07:00 -07:00
|
|
|
QMessageBox remove_source;
|
2014-08-24 08:56:50 -07:00
|
|
|
remove_source.setText(text);
|
|
|
|
QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"),
|
|
|
|
QMessageBox::YesRole);
|
2014-08-15 10:07:00 -07:00
|
|
|
remove_source.addButton(QTStr("No"), QMessageBox::NoRole);
|
|
|
|
remove_source.setIcon(QMessageBox::Question);
|
|
|
|
remove_source.setWindowTitle(QTStr("ConfirmRemove.Title"));
|
|
|
|
remove_source.exec();
|
|
|
|
|
|
|
|
return Yes == remove_source.clickedButton();
|
2014-06-30 13:45:58 -07:00
|
|
|
}
|
2014-06-30 01:13:32 -07:00
|
|
|
|
2014-07-13 23:56:28 -07:00
|
|
|
#define UPDATE_CHECK_INTERVAL (60*60*24*4) /* 4 days */
|
|
|
|
|
2014-10-05 15:32:18 -07:00
|
|
|
#ifdef UPDATE_SPARKLE
|
|
|
|
void init_sparkle_updater(bool update_to_undeployed);
|
|
|
|
void trigger_sparkle_update();
|
|
|
|
#endif
|
|
|
|
|
2014-07-13 23:56:28 -07:00
|
|
|
void OBSBasic::TimedCheckForUpdates()
|
|
|
|
{
|
2014-10-05 15:32:18 -07:00
|
|
|
#ifdef UPDATE_SPARKLE
|
|
|
|
init_sparkle_updater(config_get_bool(App()->GlobalConfig(), "General",
|
|
|
|
"UpdateToUndeployed"));
|
|
|
|
#else
|
2014-07-13 23:56:28 -07:00
|
|
|
long long lastUpdate = config_get_int(App()->GlobalConfig(), "General",
|
|
|
|
"LastUpdateCheck");
|
|
|
|
uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General",
|
|
|
|
"LastVersion");
|
|
|
|
|
|
|
|
if (lastVersion < LIBOBS_API_VER) {
|
|
|
|
lastUpdate = 0;
|
|
|
|
config_set_int(App()->GlobalConfig(), "General",
|
|
|
|
"LastUpdateCheck", 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
long long t = (long long)time(nullptr);
|
|
|
|
long long secs = t - lastUpdate;
|
|
|
|
|
|
|
|
if (secs > UPDATE_CHECK_INTERVAL)
|
|
|
|
CheckForUpdates();
|
2014-10-05 15:32:18 -07:00
|
|
|
#endif
|
2014-07-13 23:56:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::CheckForUpdates()
|
|
|
|
{
|
2014-10-05 15:32:18 -07:00
|
|
|
#ifdef UPDATE_SPARKLE
|
|
|
|
trigger_sparkle_update();
|
|
|
|
#else
|
2014-07-13 23:56:28 -07:00
|
|
|
ui->actionCheckForUpdates->setEnabled(false);
|
|
|
|
|
2014-07-14 08:51:57 -07:00
|
|
|
string versionString("obs-basic ");
|
|
|
|
versionString += App()->GetVersionString();
|
|
|
|
|
|
|
|
QNetworkRequest request;
|
|
|
|
request.setUrl(QUrl("https://obsproject.com/obs2_update/basic.json"));
|
|
|
|
request.setRawHeader("User-Agent", versionString.c_str());
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QNetworkReply *reply = networkManager.get(request);
|
|
|
|
connect(reply, SIGNAL(finished()),
|
2014-07-13 23:56:28 -07:00
|
|
|
this, SLOT(updateFileFinished()));
|
2014-10-05 15:32:18 -07:00
|
|
|
#endif
|
2014-07-13 23:56:28 -07:00
|
|
|
}
|
|
|
|
|
2014-07-14 03:48:30 -07:00
|
|
|
#ifdef __APPLE__
|
|
|
|
#define VERSION_ENTRY "mac"
|
2014-07-17 07:03:27 -07:00
|
|
|
#elif _WIN32
|
|
|
|
#define VERSION_ENTRY "windows"
|
2014-07-14 03:48:30 -07:00
|
|
|
#else
|
|
|
|
#define VERSION_ENTRY "other"
|
|
|
|
#endif
|
|
|
|
|
2014-07-13 23:56:28 -07:00
|
|
|
void OBSBasic::updateFileFinished()
|
|
|
|
{
|
|
|
|
ui->actionCheckForUpdates->setEnabled(true);
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
|
|
|
|
if (!reply || reply->error()) {
|
2014-07-13 23:56:28 -07:00
|
|
|
blog(LOG_WARNING, "Update check failed: %s",
|
2014-08-25 12:22:58 -07:00
|
|
|
QT_TO_UTF8(reply->errorString()));
|
2014-07-13 23:56:28 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QByteArray raw = reply->readAll();
|
|
|
|
if (!raw.length())
|
2014-07-13 23:56:28 -07:00
|
|
|
return;
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
obs_data_t *returnData = obs_data_create_from_json(raw.constData());
|
|
|
|
obs_data_t *versionData = obs_data_get_obj(returnData, VERSION_ENTRY);
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *description = obs_data_get_string(returnData,
|
|
|
|
"description");
|
|
|
|
const char *download = obs_data_get_string(versionData, "download");
|
2014-07-13 23:56:28 -07:00
|
|
|
|
|
|
|
if (returnData && versionData && description && download) {
|
2014-08-05 11:09:29 -07:00
|
|
|
long major = obs_data_get_int(versionData, "major");
|
|
|
|
long minor = obs_data_get_int(versionData, "minor");
|
|
|
|
long patch = obs_data_get_int(versionData, "patch");
|
2014-07-13 23:56:28 -07:00
|
|
|
long version = MAKE_SEMANTIC_VERSION(major, minor, patch);
|
|
|
|
|
|
|
|
blog(LOG_INFO, "Update check: latest version is: %ld.%ld.%ld",
|
|
|
|
major, minor, patch);
|
|
|
|
|
|
|
|
if (version > LIBOBS_API_VER) {
|
|
|
|
QString str = QTStr("UpdateAvailable.Text");
|
|
|
|
QMessageBox messageBox(this);
|
|
|
|
|
|
|
|
str = str.arg(QString::number(major),
|
|
|
|
QString::number(minor),
|
|
|
|
QString::number(patch),
|
|
|
|
download);
|
|
|
|
|
|
|
|
messageBox.setWindowTitle(QTStr("UpdateAvailable"));
|
|
|
|
messageBox.setTextFormat(Qt::RichText);
|
|
|
|
messageBox.setText(str);
|
|
|
|
messageBox.setInformativeText(QT_UTF8(description));
|
|
|
|
messageBox.exec();
|
|
|
|
|
|
|
|
long long t = (long long)time(nullptr);
|
|
|
|
config_set_int(App()->GlobalConfig(), "General",
|
|
|
|
"LastUpdateCheck", t);
|
|
|
|
config_save(App()->GlobalConfig());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
blog(LOG_WARNING, "Bad JSON file received from server");
|
|
|
|
}
|
|
|
|
|
|
|
|
obs_data_release(versionData);
|
|
|
|
obs_data_release(returnData);
|
2014-08-25 10:09:57 -07:00
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
reply->deleteLater();
|
2014-07-13 23:56:28 -07:00
|
|
|
}
|
|
|
|
|
2014-06-30 13:45:58 -07:00
|
|
|
void OBSBasic::RemoveSelectedScene()
|
|
|
|
{
|
|
|
|
OBSScene scene = GetCurrentScene();
|
|
|
|
if (scene) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_scene_get_source(scene);
|
2014-06-30 13:45:58 -07:00
|
|
|
if (QueryRemoveSource(source))
|
|
|
|
obs_source_remove(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::RemoveSelectedSceneItem()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
if (item) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-06-30 13:45:58 -07:00
|
|
|
if (QueryRemoveSource(source))
|
2014-06-30 01:13:32 -07:00
|
|
|
obs_sceneitem_remove(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-04 12:53:36 -08:00
|
|
|
/* OBS Callbacks */
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemAdded(void *data, calldata_t *params)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2013-12-28 21:29:13 -08:00
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
QMetaObject::invokeMethod(window, "AddSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)));
|
2013-12-28 21:29:13 -08:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemRemoved(void *data, calldata_t *params)
|
2013-12-28 04:33:16 -08:00
|
|
|
{
|
2014-01-04 12:53:36 -08:00
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
2013-12-28 04:33:16 -08:00
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2014-01-04 12:53:36 -08:00
|
|
|
|
2014-02-02 16:03:55 -08:00
|
|
|
QMetaObject::invokeMethod(window, "RemoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)));
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-10-13 13:14:06 -07:00
|
|
|
void OBSBasic::SceneItemSelected(void *data, calldata_t *params)
|
|
|
|
{
|
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
|
|
|
|
|
|
|
obs_scene_t *scene = (obs_scene_t*)calldata_ptr(params, "scene");
|
|
|
|
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SelectSceneItem",
|
|
|
|
Q_ARG(OBSScene, scene), Q_ARG(OBSSceneItem, item),
|
|
|
|
Q_ARG(bool, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemDeselected(void *data, calldata_t *params)
|
|
|
|
{
|
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
|
|
|
|
|
|
|
obs_scene_t *scene = (obs_scene_t*)calldata_ptr(params, "scene");
|
|
|
|
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(window, "SelectSceneItem",
|
|
|
|
Q_ARG(OBSScene, scene), Q_ARG(OBSSceneItem, item),
|
|
|
|
Q_ARG(bool, false));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SourceAdded(void *data, calldata_t *params)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
2014-05-10 18:47:48 -07:00
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
2013-12-28 04:33:16 -08:00
|
|
|
|
2014-08-04 08:41:15 -07:00
|
|
|
if (obs_scene_from_source(source) != NULL)
|
2014-05-10 18:47:48 -07:00
|
|
|
QMetaObject::invokeMethod(window,
|
2014-02-02 16:03:55 -08:00
|
|
|
"AddScene",
|
|
|
|
Q_ARG(OBSSource, OBSSource(source)));
|
2013-12-28 04:33:16 -08:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SourceRemoved(void *data, calldata_t *params)
|
2013-12-28 04:33:16 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
2013-12-28 04:33:16 -08:00
|
|
|
|
2014-08-04 08:41:15 -07:00
|
|
|
if (obs_scene_from_source(source) != NULL)
|
2014-02-02 16:03:55 -08:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"RemoveScene",
|
|
|
|
Q_ARG(OBSSource, OBSSource(source)));
|
2013-12-28 04:33:16 -08:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SourceActivated(void *data, calldata_t *params)
|
2014-05-03 22:54:38 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
2014-05-03 22:54:38 -07:00
|
|
|
uint32_t flags = obs_source_get_output_flags(source);
|
|
|
|
|
|
|
|
if (flags & OBS_SOURCE_AUDIO)
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"ActivateAudioSource",
|
|
|
|
Q_ARG(OBSSource, OBSSource(source)));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SourceDeactivated(void *data, calldata_t *params)
|
2014-05-03 22:54:38 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
2014-05-03 22:54:38 -07:00
|
|
|
uint32_t flags = obs_source_get_output_flags(source);
|
|
|
|
|
|
|
|
if (flags & OBS_SOURCE_AUDIO)
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"DeactivateAudioSource",
|
|
|
|
Q_ARG(OBSSource, OBSSource(source)));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SourceRenamed(void *data, calldata_t *params)
|
2014-06-30 00:06:01 -07:00
|
|
|
{
|
|
|
|
const char *newName = calldata_string(params, "new_name");
|
|
|
|
const char *prevName = calldata_string(params, "prev_name");
|
|
|
|
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"RenameSources",
|
|
|
|
Q_ARG(QString, QT_UTF8(newName)),
|
|
|
|
Q_ARG(QString, QT_UTF8(prevName)));
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::ChannelChanged(void *data, calldata_t *params)
|
2014-01-04 12:53:36 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = (obs_source_t*)calldata_ptr(params, "source");
|
2014-03-01 04:54:55 -08:00
|
|
|
uint32_t channel = (uint32_t)calldata_int(params, "channel");
|
2014-01-04 12:53:36 -08:00
|
|
|
|
|
|
|
if (channel == 0)
|
2014-02-02 16:03:55 -08:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"UpdateSceneSelection",
|
|
|
|
Q_ARG(OBSSource, OBSSource(source)));
|
2014-01-04 12:53:36 -08:00
|
|
|
}
|
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
void OBSBasic::DrawBackdrop(float cx, float cy)
|
|
|
|
{
|
|
|
|
if (!box)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
gs_effect_t *solid = obs_get_solid_effect();
|
|
|
|
gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color");
|
|
|
|
gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
|
2014-06-15 19:48:02 -07:00
|
|
|
|
|
|
|
vec4 colorVal;
|
|
|
|
vec4_set(&colorVal, 0.0f, 0.0f, 0.0f, 1.0f);
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_effect_set_vec4(color, &colorVal);
|
2014-06-15 19:48:02 -07:00
|
|
|
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_technique_begin(tech);
|
|
|
|
gs_technique_begin_pass(tech, 0);
|
2014-06-15 19:48:02 -07:00
|
|
|
gs_matrix_push();
|
|
|
|
gs_matrix_identity();
|
|
|
|
gs_matrix_scale3f(float(cx), float(cy), 1.0f);
|
|
|
|
|
|
|
|
gs_load_vertexbuffer(box);
|
|
|
|
gs_draw(GS_TRISTRIP, 0, 0);
|
|
|
|
|
|
|
|
gs_matrix_pop();
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_technique_end_pass(tech);
|
|
|
|
gs_technique_end(tech);
|
2014-06-15 19:48:02 -07:00
|
|
|
|
|
|
|
gs_load_vertexbuffer(nullptr);
|
|
|
|
}
|
|
|
|
|
2014-02-13 07:58:31 -08:00
|
|
|
void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy)
|
|
|
|
{
|
2014-03-07 09:19:03 -08:00
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
2014-04-22 11:24:05 -07:00
|
|
|
obs_video_info ovi;
|
|
|
|
|
|
|
|
obs_get_video_info(&ovi);
|
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
window->previewCX = int(window->previewScale * float(ovi.base_width));
|
|
|
|
window->previewCY = int(window->previewScale * float(ovi.base_height));
|
2014-04-22 11:24:05 -07:00
|
|
|
|
|
|
|
gs_viewport_push();
|
|
|
|
gs_projection_push();
|
2014-06-15 19:48:02 -07:00
|
|
|
|
|
|
|
/* --------------------------------------- */
|
|
|
|
|
2014-04-22 11:24:05 -07:00
|
|
|
gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height),
|
|
|
|
-100.0f, 100.0f);
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_set_viewport(window->previewX, window->previewY,
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
window->previewCX, window->previewCY);
|
2014-04-22 11:24:05 -07:00
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height));
|
|
|
|
|
2014-02-13 09:21:16 -08:00
|
|
|
obs_render_main_view();
|
2014-06-15 19:48:02 -07:00
|
|
|
gs_load_vertexbuffer(nullptr);
|
2014-04-22 11:24:05 -07:00
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
/* --------------------------------------- */
|
|
|
|
|
2014-07-15 17:01:59 -07:00
|
|
|
QSize previewSize = GetPixelSize(window->ui->preview);
|
|
|
|
float right = float(previewSize.width()) - window->previewX;
|
|
|
|
float bottom = float(previewSize.height()) - window->previewY;
|
2014-06-15 19:48:02 -07:00
|
|
|
|
|
|
|
gs_ortho(-window->previewX, right,
|
|
|
|
-window->previewY, bottom,
|
|
|
|
-100.0f, 100.0f);
|
2014-08-07 23:42:07 -07:00
|
|
|
gs_reset_viewport();
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
|
|
|
window->ui->preview->DrawSceneEditing();
|
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
/* --------------------------------------- */
|
|
|
|
|
2014-04-22 11:24:05 -07:00
|
|
|
gs_projection_pop();
|
|
|
|
gs_viewport_pop();
|
2014-02-14 14:13:36 -08:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(cx);
|
|
|
|
UNUSED_PARAMETER(cy);
|
2014-02-13 07:58:31 -08:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemMoveUp(void *data, calldata_t *params)
|
2014-05-15 17:40:53 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2014-05-15 17:40:53 -07:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
2014-08-02 01:33:53 -07:00
|
|
|
Q_ARG(obs_order_movement, OBS_ORDER_MOVE_UP));
|
2014-05-15 17:40:53 -07:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemMoveDown(void *data, calldata_t *params)
|
2014-05-15 17:40:53 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2014-05-15 17:40:53 -07:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
2014-08-02 01:33:53 -07:00
|
|
|
Q_ARG(obs_order_movement, OBS_ORDER_MOVE_DOWN));
|
2014-05-15 17:40:53 -07:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemMoveTop(void *data, calldata_t *params)
|
2014-05-15 17:40:53 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2014-05-15 17:40:53 -07:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
2014-08-02 01:33:53 -07:00
|
|
|
Q_ARG(obs_order_movement, OBS_ORDER_MOVE_TOP));
|
2014-05-15 17:40:53 -07:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SceneItemMoveBottom(void *data, calldata_t *params)
|
2014-05-15 17:40:53 -07:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
OBSSceneItem item = (obs_sceneitem_t*)calldata_ptr(params, "item");
|
2014-05-15 17:40:53 -07:00
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
2014-08-02 01:33:53 -07:00
|
|
|
Q_ARG(obs_order_movement, OBS_ORDER_MOVE_BOTTOM));
|
2014-05-15 17:40:53 -07:00
|
|
|
}
|
|
|
|
|
2014-01-04 12:53:36 -08:00
|
|
|
/* Main class functions */
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_service_t *OBSBasic::GetService()
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
{
|
|
|
|
if (!service)
|
|
|
|
service = obs_service_create("rtmp_common", NULL, NULL);
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
void OBSBasic::SetService(obs_service_t *newService)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
{
|
|
|
|
if (newService) {
|
|
|
|
if (service)
|
|
|
|
obs_service_destroy(service);
|
|
|
|
service = newService;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-20 17:49:54 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
#define IS_WIN32 1
|
|
|
|
#else
|
|
|
|
#define IS_WIN32 0
|
|
|
|
#endif
|
|
|
|
|
2014-07-20 17:49:09 -07:00
|
|
|
static inline int AttemptToResetVideo(struct obs_video_info *ovi)
|
|
|
|
{
|
|
|
|
int ret = obs_reset_video(ovi);
|
|
|
|
if (ret == OBS_VIDEO_INVALID_PARAM) {
|
|
|
|
struct obs_video_info new_params = *ovi;
|
|
|
|
|
|
|
|
if (new_params.window_width == 0)
|
|
|
|
new_params.window_width = 512;
|
|
|
|
if (new_params.window_height == 0)
|
|
|
|
new_params.window_height = 512;
|
|
|
|
|
|
|
|
new_params.output_width = new_params.window_width;
|
|
|
|
new_params.output_height = new_params.window_height;
|
|
|
|
new_params.base_width = new_params.window_width;
|
|
|
|
new_params.base_height = new_params.window_height;
|
|
|
|
ret = obs_reset_video(&new_params);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-12-15 01:08:46 -08:00
|
|
|
static inline enum obs_scale_type GetScaleType(ConfigFile &basicConfig)
|
|
|
|
{
|
|
|
|
const char *scaleTypeStr = config_get_string(basicConfig,
|
|
|
|
"Video", "ScaleType");
|
|
|
|
|
|
|
|
if (astrcmpi(scaleTypeStr, "bilinear") == 0)
|
|
|
|
return OBS_SCALE_BILINEAR;
|
|
|
|
else if (astrcmpi(scaleTypeStr, "lanczos") == 0)
|
|
|
|
return OBS_SCALE_LANCZOS;
|
|
|
|
else
|
|
|
|
return OBS_SCALE_BICUBIC;
|
|
|
|
}
|
|
|
|
|
2015-01-09 20:16:30 -08:00
|
|
|
static inline enum video_format GetVideoFormatFromName(const char *name)
|
|
|
|
{
|
|
|
|
if (astrcmpi(name, "I420") == 0)
|
|
|
|
return VIDEO_FORMAT_I420;
|
|
|
|
else if (astrcmpi(name, "NV12") == 0)
|
|
|
|
return VIDEO_FORMAT_NV12;
|
|
|
|
#if 0 //currently unsupported
|
|
|
|
else if (astrcmpi(name, "YVYU") == 0)
|
|
|
|
return VIDEO_FORMAT_YVYU;
|
|
|
|
else if (astrcmpi(name, "YUY2") == 0)
|
|
|
|
return VIDEO_FORMAT_YUY2;
|
|
|
|
else if (astrcmpi(name, "UYVY") == 0)
|
|
|
|
return VIDEO_FORMAT_UYVY;
|
|
|
|
#endif
|
|
|
|
else
|
|
|
|
return VIDEO_FORMAT_BGRA;
|
|
|
|
}
|
|
|
|
|
2014-07-20 17:40:57 -07:00
|
|
|
int OBSBasic::ResetVideo()
|
2013-12-22 22:40:07 -08:00
|
|
|
{
|
|
|
|
struct obs_video_info ovi;
|
2014-07-20 17:40:57 -07:00
|
|
|
int ret;
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
GetConfigFPS(ovi.fps_num, ovi.fps_den);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2015-01-09 20:16:30 -08:00
|
|
|
const char *colorFormat = config_get_string(basicConfig, "Video",
|
|
|
|
"ColorFormat");
|
|
|
|
const char *colorSpace = config_get_string(basicConfig, "Video",
|
|
|
|
"ColorSpace");
|
|
|
|
const char *colorRange = config_get_string(basicConfig, "Video",
|
|
|
|
"ColorRange");
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
ovi.graphics_module = App()->GetRenderModule();
|
2014-03-06 20:08:12 -08:00
|
|
|
ovi.base_width = (uint32_t)config_get_uint(basicConfig,
|
2013-12-22 22:40:07 -08:00
|
|
|
"Video", "BaseCX");
|
2014-03-06 20:08:12 -08:00
|
|
|
ovi.base_height = (uint32_t)config_get_uint(basicConfig,
|
2013-12-22 22:40:07 -08:00
|
|
|
"Video", "BaseCY");
|
2014-03-06 20:08:12 -08:00
|
|
|
ovi.output_width = (uint32_t)config_get_uint(basicConfig,
|
2013-12-22 22:40:07 -08:00
|
|
|
"Video", "OutputCX");
|
2014-03-06 20:08:12 -08:00
|
|
|
ovi.output_height = (uint32_t)config_get_uint(basicConfig,
|
2013-12-22 22:40:07 -08:00
|
|
|
"Video", "OutputCY");
|
2015-01-09 20:16:30 -08:00
|
|
|
ovi.output_format = GetVideoFormatFromName(colorFormat);
|
|
|
|
ovi.colorspace = astrcmpi(colorSpace, "601") == 0 ?
|
|
|
|
VIDEO_CS_601 : VIDEO_CS_709;
|
|
|
|
ovi.range = astrcmpi(colorRange, "Full") == 0 ?
|
|
|
|
VIDEO_RANGE_FULL : VIDEO_RANGE_PARTIAL;
|
2014-02-16 18:28:21 -08:00
|
|
|
ovi.adapter = 0;
|
|
|
|
ovi.gpu_conversion = true;
|
2014-12-15 01:08:46 -08:00
|
|
|
ovi.scale_type = GetScaleType(basicConfig);
|
2014-01-09 17:51:51 -08:00
|
|
|
|
2014-03-07 09:19:03 -08:00
|
|
|
QTToGSWindow(ui->preview->winId(), ovi.window);
|
2013-12-22 22:40:07 -08:00
|
|
|
|
|
|
|
//required to make opengl display stuff on osx(?)
|
2013-12-31 03:02:07 -08:00
|
|
|
ResizePreview(ovi.base_width, ovi.base_height);
|
2013-12-22 22:40:07 -08:00
|
|
|
|
2014-04-16 11:28:02 -07:00
|
|
|
QSize size = GetPixelSize(ui->preview);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
ovi.window_width = size.width();
|
|
|
|
ovi.window_height = size.height();
|
2013-12-31 03:02:07 -08:00
|
|
|
|
2014-07-20 17:49:09 -07:00
|
|
|
ret = AttemptToResetVideo(&ovi);
|
2014-07-20 17:49:54 -07:00
|
|
|
if (IS_WIN32 && ret != OBS_VIDEO_SUCCESS) {
|
|
|
|
/* Try OpenGL if DirectX fails on windows */
|
2015-01-09 11:19:22 -08:00
|
|
|
if (astrcmpi(ovi.graphics_module, DL_OPENGL) != 0) {
|
2014-10-14 09:07:49 -07:00
|
|
|
blog(LOG_WARNING, "Failed to initialize obs video (%d) "
|
|
|
|
"with graphics_module='%s', retrying "
|
|
|
|
"with graphics_module='%s'",
|
|
|
|
ret, ovi.graphics_module,
|
2015-01-09 11:19:22 -08:00
|
|
|
DL_OPENGL);
|
|
|
|
ovi.graphics_module = DL_OPENGL;
|
2014-07-20 17:49:54 -07:00
|
|
|
ret = AttemptToResetVideo(&ovi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-20 17:40:57 -07:00
|
|
|
if (ret == OBS_VIDEO_SUCCESS)
|
|
|
|
obs_add_draw_callback(OBSBasic::RenderMain, this);
|
2014-02-22 19:14:19 -08:00
|
|
|
|
2014-07-20 17:40:57 -07:00
|
|
|
return ret;
|
2014-01-09 18:08:20 -08:00
|
|
|
}
|
2013-12-31 03:02:07 -08:00
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
bool OBSBasic::ResetAudio()
|
2014-01-09 18:08:20 -08:00
|
|
|
{
|
Simplify media i/o interfaces
Completely revamped the entire media i/o data and handlers. The
original idea was to have a system that would have connecting media
inputs and outputs, but at a certain point I realized that this was an
unnecessary complexity for what we wanted to do. (Also, it reminded me
of directshow filters, and I HATE directshow with a passion, and
wouldn't wish it upon my greatest enemy)
Now, audio/video outputs are connected to directly, with better callback
handlers, and will eventually have the ability to automatically handle
conversions such as 4:4:4 to 4:2:0 when connecting to an input that uses
them. Doing this will allow the video/audio i/o handlers to also
prevent duplicate conversion, as well as make it easier/simple to use.
My true goal for this is to make output and encoder plugins as simple to
create as possible. I want to be able to be able to create an output
plugin with almost no real hassle of having to worry about image
conversions, media inputs/outputs, etc. A plugin developer shouldn't
have to handle that sort of stuff when he/she doesn't really need to.
Plugins will be able to simply create a callback via obs_video() and/or
obs_audio(), and they will automatically receive the audio/video data in
the formats requested via a simple callback, without needing to do
almost anything else at all.
2014-01-14 00:58:47 -08:00
|
|
|
struct audio_output_info ai;
|
2014-02-23 15:27:19 -08:00
|
|
|
ai.name = "Main Audio Track";
|
|
|
|
ai.format = AUDIO_FORMAT_FLOAT;
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
ai.samples_per_sec = config_get_uint(basicConfig, "Audio",
|
2014-02-23 15:27:19 -08:00
|
|
|
"SampleRate");
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
const char *channelSetupStr = config_get_string(basicConfig,
|
2014-02-23 15:27:19 -08:00
|
|
|
"Audio", "ChannelSetup");
|
|
|
|
|
|
|
|
if (strcmp(channelSetupStr, "Mono") == 0)
|
|
|
|
ai.speakers = SPEAKERS_MONO;
|
|
|
|
else
|
|
|
|
ai.speakers = SPEAKERS_STEREO;
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
ai.buffer_ms = config_get_uint(basicConfig, "Audio", "BufferingTime");
|
2014-01-09 18:08:20 -08:00
|
|
|
|
|
|
|
return obs_reset_audio(&ai);
|
2013-12-22 22:40:07 -08:00
|
|
|
}
|
|
|
|
|
2014-03-07 16:03:34 -08:00
|
|
|
void OBSBasic::ResetAudioDevice(const char *sourceId, const char *deviceName,
|
2014-05-12 15:30:36 -07:00
|
|
|
const char *deviceDesc, int channel)
|
2014-03-07 16:03:34 -08:00
|
|
|
{
|
|
|
|
const char *deviceId = config_get_string(basicConfig, "Audio",
|
|
|
|
deviceName);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source;
|
|
|
|
obs_data_t *settings;
|
2014-03-07 16:03:34 -08:00
|
|
|
bool same = false;
|
|
|
|
|
|
|
|
source = obs_get_output_source(channel);
|
|
|
|
if (source) {
|
2014-08-04 08:41:15 -07:00
|
|
|
settings = obs_source_get_settings(source);
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *curId = obs_data_get_string(settings, "device_id");
|
2014-03-07 16:03:34 -08:00
|
|
|
|
|
|
|
same = (strcmp(curId, deviceId) == 0);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!same)
|
|
|
|
obs_set_output_source(channel, nullptr);
|
|
|
|
|
|
|
|
if (!same && strcmp(deviceId, "disabled") != 0) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *settings = obs_data_create();
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_string(settings, "device_id", deviceId);
|
2014-03-07 16:03:34 -08:00
|
|
|
source = obs_source_create(OBS_SOURCE_TYPE_INPUT,
|
2014-05-12 15:30:36 -07:00
|
|
|
sourceId, deviceDesc, settings);
|
2014-03-07 16:03:34 -08:00
|
|
|
obs_data_release(settings);
|
|
|
|
|
|
|
|
obs_set_output_source(channel, source);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::ResetAudioDevices()
|
2014-03-07 11:56:31 -08:00
|
|
|
{
|
2014-05-12 15:30:36 -07:00
|
|
|
ResetAudioDevice(App()->OutputAudioSource(), "DesktopDevice1",
|
|
|
|
Str("Basic.DesktopDevice1"), 1);
|
|
|
|
ResetAudioDevice(App()->OutputAudioSource(), "DesktopDevice2",
|
|
|
|
Str("Basic.DesktopDevice2"), 2);
|
|
|
|
ResetAudioDevice(App()->InputAudioSource(), "AuxDevice1",
|
|
|
|
Str("Basic.AuxDevice1"), 3);
|
|
|
|
ResetAudioDevice(App()->InputAudioSource(), "AuxDevice2",
|
|
|
|
Str("Basic.AuxDevice2"), 4);
|
|
|
|
ResetAudioDevice(App()->InputAudioSource(), "AuxDevice3",
|
|
|
|
Str("Basic.AuxDevice3"), 5);
|
2014-03-07 11:56:31 -08:00
|
|
|
}
|
|
|
|
|
2013-12-31 03:02:07 -08:00
|
|
|
void OBSBasic::ResizePreview(uint32_t cx, uint32_t cy)
|
2013-12-06 05:39:19 -08:00
|
|
|
{
|
2014-01-23 16:00:42 -08:00
|
|
|
QSize targetSize;
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2013-12-06 08:16:33 -08:00
|
|
|
/* resize preview panel to fix to the top section of the window */
|
2014-04-16 11:28:02 -07:00
|
|
|
targetSize = GetPixelSize(ui->preview);
|
2014-03-23 01:07:54 -07:00
|
|
|
GetScaleAndCenterPos(int(cx), int(cy),
|
2014-06-15 19:48:02 -07:00
|
|
|
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
|
|
|
|
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
|
2014-03-23 01:07:54 -07:00
|
|
|
previewX, previewY, previewScale);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2014-06-15 19:48:02 -07:00
|
|
|
previewX += float(PREVIEW_EDGE_SIZE);
|
|
|
|
previewY += float(PREVIEW_EDGE_SIZE);
|
|
|
|
|
2014-03-07 09:19:03 -08:00
|
|
|
if (isVisible()) {
|
|
|
|
if (resizeTimer)
|
|
|
|
killTimer(resizeTimer);
|
|
|
|
resizeTimer = startTimer(100);
|
|
|
|
}
|
2013-12-31 03:02:07 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::closeEvent(QCloseEvent *event)
|
2013-12-31 03:02:07 -08:00
|
|
|
{
|
2014-04-17 08:18:51 -07:00
|
|
|
QWidget::closeEvent(event);
|
|
|
|
if (!event->isAccepted())
|
|
|
|
return;
|
|
|
|
|
2015-01-13 18:03:52 -08:00
|
|
|
/* Check all child dialogs and ensure they run their proper closeEvent
|
|
|
|
* methods before exiting the application. Otherwise Qt doesn't send
|
|
|
|
* the proper QCloseEvent messages. */
|
|
|
|
QList<QDialog*> childDialogs = this->findChildren<QDialog *>();
|
|
|
|
if (!childDialogs.isEmpty()) {
|
|
|
|
for (int i = 0; i < childDialogs.size(); ++i) {
|
|
|
|
childDialogs.at(i)->close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-17 08:18:51 -07:00
|
|
|
// remove draw callback in case our drawable surfaces go away before
|
|
|
|
// the destructor gets called
|
|
|
|
obs_remove_draw_callback(OBSBasic::RenderMain, this);
|
2013-12-31 06:10:47 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::changeEvent(QEvent *event)
|
2013-12-31 06:10:47 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
|
|
|
UNUSED_PARAMETER(event);
|
2013-11-23 22:38:52 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::resizeEvent(QResizeEvent *event)
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
struct obs_video_info ovi;
|
|
|
|
|
|
|
|
if (obs_get_video_info(&ovi))
|
|
|
|
ResizePreview(ovi.base_width, ovi.base_height);
|
2014-02-14 14:13:36 -08:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(event);
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
2014-03-07 09:19:03 -08:00
|
|
|
void OBSBasic::timerEvent(QTimerEvent *event)
|
|
|
|
{
|
|
|
|
if (event->timerId() == resizeTimer) {
|
|
|
|
killTimer(resizeTimer);
|
|
|
|
resizeTimer = 0;
|
|
|
|
|
2014-04-16 11:28:02 -07:00
|
|
|
QSize size = GetPixelSize(ui->preview);
|
2014-03-07 09:19:03 -08:00
|
|
|
obs_resize(size.width(), size.height());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_action_New_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_action_Open_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_action_Save_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
2014-08-21 18:18:42 -07:00
|
|
|
void OBSBasic::on_actionShow_Recordings_triggered()
|
|
|
|
{
|
|
|
|
const char *path = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "FilePath");
|
|
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
|
|
|
}
|
|
|
|
|
2014-09-02 19:11:55 -07:00
|
|
|
void OBSBasic::on_actionRemux_triggered()
|
|
|
|
{
|
|
|
|
const char *path = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "FilePath");
|
|
|
|
OBSRemux remux(path, this);
|
|
|
|
remux.exec();
|
|
|
|
}
|
|
|
|
|
2014-04-15 05:19:59 -07:00
|
|
|
void OBSBasic::on_action_Settings_triggered()
|
|
|
|
{
|
|
|
|
OBSBasicSettings settings(this);
|
|
|
|
settings.exec();
|
|
|
|
}
|
|
|
|
|
2014-12-28 00:38:00 -08:00
|
|
|
void OBSBasic::on_actionAdvAudioProperties_triggered()
|
|
|
|
{
|
|
|
|
advAudioWindow = new OBSBasicAdvAudio(this);
|
|
|
|
advAudioWindow->show();
|
|
|
|
advAudioWindow->setAttribute(Qt::WA_DeleteOnClose, true);
|
|
|
|
}
|
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
void OBSBasic::on_scenes_currentItemChanged(QListWidgetItem *current,
|
|
|
|
QListWidgetItem *prev)
|
2013-12-30 00:17:57 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = NULL;
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
if (sceneChanging)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (current) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene;
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
scene = current->data(Qt::UserRole).value<OBSScene>();
|
2014-08-04 08:41:15 -07:00
|
|
|
source = obs_scene_get_source(scene);
|
2013-12-30 00:17:57 -08:00
|
|
|
}
|
|
|
|
|
2014-01-04 12:53:36 -08:00
|
|
|
/* TODO: allow transitions */
|
2013-12-30 00:17:57 -08:00
|
|
|
obs_set_output_source(0, source);
|
2014-02-20 21:04:14 -08:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(prev);
|
2013-12-30 00:17:57 -08:00
|
|
|
}
|
|
|
|
|
2014-06-30 01:13:32 -07:00
|
|
|
void OBSBasic::EditSceneName()
|
|
|
|
{
|
2014-10-15 13:05:21 -07:00
|
|
|
QListWidgetItem *item = ui->scenes->currentItem();
|
|
|
|
Qt::ItemFlags flags = item->flags();
|
|
|
|
|
|
|
|
item->setFlags(flags | Qt::ItemIsEditable);
|
|
|
|
ui->scenes->editItem(item);
|
|
|
|
item->setFlags(flags);
|
2014-06-30 01:13:32 -07:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-06-30 16:03:12 -07:00
|
|
|
QListWidgetItem *item = ui->scenes->itemAt(pos);
|
|
|
|
|
|
|
|
QMenu popup;
|
|
|
|
popup.addAction(QTStr("Add"),
|
|
|
|
this, SLOT(on_actionAddScene_triggered()));
|
|
|
|
|
2014-10-15 13:04:31 -07:00
|
|
|
if (item) {
|
|
|
|
popup.addSeparator();
|
|
|
|
popup.addAction(QTStr("Rename"),
|
|
|
|
this, SLOT(EditSceneName()));
|
2014-06-30 16:03:12 -07:00
|
|
|
popup.addAction(QTStr("Remove"),
|
2014-10-15 13:01:49 -07:00
|
|
|
this, SLOT(RemoveSelectedScene()),
|
|
|
|
DeleteKeys.front());
|
2014-10-15 13:04:31 -07:00
|
|
|
}
|
2014-06-30 16:03:12 -07:00
|
|
|
|
|
|
|
popup.exec(QCursor::pos());
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionAddScene_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2013-12-29 07:54:06 -08:00
|
|
|
string name;
|
2014-05-09 15:09:17 -07:00
|
|
|
QString format{QTStr("Basic.Main.DefaultSceneName.Text")};
|
2014-05-14 11:58:15 -07:00
|
|
|
|
|
|
|
int i = 1;
|
|
|
|
QString placeHolderText = format.arg(i);
|
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(placeHolderText)))) {
|
|
|
|
obs_source_release(source);
|
2014-05-14 11:58:15 -07:00
|
|
|
placeHolderText = format.arg(++i);
|
2014-05-14 13:20:08 -07:00
|
|
|
}
|
2014-05-09 15:09:17 -07:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
bool accepted = NameDialog::AskForName(this,
|
2014-05-12 15:30:36 -07:00
|
|
|
QTStr("Basic.Main.AddSceneDlg.Title"),
|
|
|
|
QTStr("Basic.Main.AddSceneDlg.Text"),
|
2014-05-09 15:09:17 -07:00
|
|
|
name,
|
|
|
|
placeHolderText);
|
2013-12-29 07:54:06 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
if (accepted) {
|
2014-03-10 13:39:51 -07:00
|
|
|
if (name.empty()) {
|
|
|
|
QMessageBox::information(this,
|
2014-08-12 12:09:19 -07:00
|
|
|
QTStr("NoNameEntered.Title"),
|
|
|
|
QTStr("NoNameEntered.Text"));
|
2014-03-10 13:39:51 -07:00
|
|
|
on_actionAddScene_triggered();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_get_source_by_name(name.c_str());
|
2013-12-29 08:17:00 -08:00
|
|
|
if (source) {
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QMessageBox::information(this,
|
2014-05-12 15:30:36 -07:00
|
|
|
QTStr("NameExists.Title"),
|
|
|
|
QTStr("NameExists.Text"));
|
2013-12-29 08:17:00 -08:00
|
|
|
|
|
|
|
obs_source_release(source);
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
on_actionAddScene_triggered();
|
2013-12-29 08:17:00 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_scene_t *scene = obs_scene_create(name.c_str());
|
2014-08-04 08:41:15 -07:00
|
|
|
source = obs_scene_get_source(scene);
|
2014-01-05 20:38:28 -08:00
|
|
|
obs_add_source(source);
|
2013-12-29 07:54:06 -08:00
|
|
|
obs_scene_release(scene);
|
2014-01-05 20:38:28 -08:00
|
|
|
|
|
|
|
obs_set_output_source(0, source);
|
2013-12-29 07:54:06 -08:00
|
|
|
}
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionRemoveScene_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-06-30 13:45:58 -07:00
|
|
|
OBSScene scene = GetCurrentScene();
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_scene_get_source(scene);
|
2014-06-30 13:45:58 -07:00
|
|
|
|
|
|
|
if (source && QueryRemoveSource(source))
|
|
|
|
obs_source_remove(source);
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSceneProperties_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSceneUp_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSceneDown_triggered()
|
2013-12-30 00:17:57 -08:00
|
|
|
{
|
2014-02-14 14:13:36 -08:00
|
|
|
/* TODO */
|
2013-12-30 00:17:57 -08:00
|
|
|
}
|
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
void OBSBasic::on_sources_currentItemChanged(QListWidgetItem *current,
|
|
|
|
QListWidgetItem *prev)
|
2013-12-30 00:17:57 -08:00
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
auto select_one = [] (obs_scene_t *scene, obs_sceneitem_t *item,
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
void *param)
|
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_sceneitem_t *selectedItem =
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
*reinterpret_cast<OBSSceneItem*>(param);
|
|
|
|
obs_sceneitem_select(item, (selectedItem == item));
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!current)
|
|
|
|
return;
|
|
|
|
|
|
|
|
OBSSceneItem item = current->data(Qt::UserRole).value<OBSSceneItem>();
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-07-04 10:58:03 -07:00
|
|
|
if ((obs_source_get_output_flags(source) & OBS_SOURCE_VIDEO) == 0)
|
|
|
|
return;
|
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
obs_scene_enum_items(GetCurrentScene(), select_one, &item);
|
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
UNUSED_PARAMETER(prev);
|
2013-12-30 00:17:57 -08:00
|
|
|
}
|
|
|
|
|
2014-06-30 01:13:32 -07:00
|
|
|
void OBSBasic::EditSceneItemName()
|
|
|
|
{
|
2014-10-15 13:05:21 -07:00
|
|
|
QListWidgetItem *item = ui->sources->currentItem();
|
|
|
|
Qt::ItemFlags flags = item->flags();
|
|
|
|
|
|
|
|
item->setFlags(flags | Qt::ItemIsEditable);
|
|
|
|
ui->sources->editItem(item);
|
|
|
|
item->setFlags(flags);
|
2014-06-30 01:13:32 -07:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_sources_customContextMenuRequested(const QPoint &pos)
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-06-30 01:13:32 -07:00
|
|
|
QListWidgetItem *item = ui->sources->itemAt(pos);
|
|
|
|
|
|
|
|
QMenu popup;
|
|
|
|
QPointer<QMenu> addSourceMenu = CreateAddSourcePopupMenu();
|
|
|
|
if (addSourceMenu)
|
|
|
|
popup.addMenu(addSourceMenu);
|
|
|
|
|
|
|
|
if (item) {
|
|
|
|
if (addSourceMenu)
|
|
|
|
popup.addSeparator();
|
|
|
|
|
2014-09-15 16:16:16 -07:00
|
|
|
OBSSceneItem sceneItem = GetSceneItem(item);
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(sceneItem);
|
2014-09-15 16:16:16 -07:00
|
|
|
QAction *action;
|
|
|
|
|
2014-06-30 01:13:32 -07:00
|
|
|
popup.addAction(QTStr("Rename"), this,
|
|
|
|
SLOT(EditSceneItemName()));
|
2014-06-30 18:21:40 -07:00
|
|
|
popup.addAction(QTStr("Remove"), this,
|
|
|
|
SLOT(on_actionRemoveSource_triggered()),
|
2014-10-15 13:00:43 -07:00
|
|
|
DeleteKeys.front());
|
2014-06-30 19:47:06 -07:00
|
|
|
popup.addSeparator();
|
|
|
|
popup.addMenu(ui->orderMenu);
|
2014-06-30 01:13:32 -07:00
|
|
|
popup.addMenu(ui->transformMenu);
|
|
|
|
popup.addSeparator();
|
2014-09-15 16:16:16 -07:00
|
|
|
|
|
|
|
action = popup.addAction(QTStr("Interact"), this,
|
|
|
|
SLOT(on_actionInteract_triggered()));
|
|
|
|
|
|
|
|
action->setEnabled(obs_source_get_output_flags(source) &
|
|
|
|
OBS_SOURCE_INTERACTION);
|
|
|
|
|
2014-06-30 01:13:32 -07:00
|
|
|
popup.addAction(QTStr("Properties"), this,
|
|
|
|
SLOT(on_actionSourceProperties_triggered()));
|
|
|
|
}
|
|
|
|
|
|
|
|
popup.exec(QCursor::pos());
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
2014-10-15 13:05:56 -07:00
|
|
|
void OBSBasic::on_sources_itemDoubleClicked(QListWidgetItem *witem)
|
|
|
|
{
|
|
|
|
if (!witem)
|
|
|
|
return;
|
|
|
|
|
|
|
|
OBSSceneItem item = GetSceneItem(witem);
|
|
|
|
OBSSource source = obs_sceneitem_get_source(item);
|
|
|
|
|
|
|
|
if (source)
|
|
|
|
CreatePropertiesWindow(source);
|
|
|
|
}
|
|
|
|
|
2014-05-10 18:47:48 -07:00
|
|
|
void OBSBasic::AddSource(const char *id)
|
2013-12-30 05:56:39 -08:00
|
|
|
{
|
2014-06-29 17:33:40 -07:00
|
|
|
if (id && *id) {
|
|
|
|
OBSBasicSourceSelect sourceSelect(this, id);
|
|
|
|
sourceSelect.exec();
|
|
|
|
}
|
2013-12-30 05:56:39 -08:00
|
|
|
}
|
|
|
|
|
2014-06-29 17:33:40 -07:00
|
|
|
QMenu *OBSBasic::CreateAddSourcePopupMenu()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2013-12-30 05:56:39 -08:00
|
|
|
const char *type;
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
bool foundValues = false;
|
|
|
|
size_t idx = 0;
|
2013-12-30 05:56:39 -08:00
|
|
|
|
2014-06-29 18:43:54 -07:00
|
|
|
QMenu *popup = new QMenu(QTStr("Add"));
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
while (obs_enum_input_types(idx++, &type)) {
|
2014-08-04 08:41:15 -07:00
|
|
|
const char *name = obs_source_get_display_name(
|
2014-06-25 00:13:00 -07:00
|
|
|
OBS_SOURCE_TYPE_INPUT, type);
|
2013-12-30 05:56:39 -08:00
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
if (strcmp(type, "scene") == 0)
|
|
|
|
continue;
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
QAction *popupItem = new QAction(QT_UTF8(name), this);
|
|
|
|
popupItem->setData(QT_UTF8(type));
|
2014-06-29 17:33:40 -07:00
|
|
|
connect(popupItem, SIGNAL(triggered(bool)),
|
|
|
|
this, SLOT(AddSourceFromAction()));
|
|
|
|
popup->addAction(popupItem);
|
2013-12-30 05:56:39 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
foundValues = true;
|
2013-12-30 05:56:39 -08:00
|
|
|
}
|
|
|
|
|
2014-06-29 17:33:40 -07:00
|
|
|
if (!foundValues) {
|
|
|
|
delete popup;
|
|
|
|
popup = nullptr;
|
2013-12-30 05:56:39 -08:00
|
|
|
}
|
2014-06-29 17:33:40 -07:00
|
|
|
|
|
|
|
return popup;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::AddSourceFromAction()
|
|
|
|
{
|
|
|
|
QAction *action = qobject_cast<QAction*>(sender());
|
|
|
|
if (!action)
|
|
|
|
return;
|
|
|
|
|
|
|
|
AddSource(QT_TO_UTF8(action->data().toString()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::AddSourcePopupMenu(const QPoint &pos)
|
|
|
|
{
|
|
|
|
if (!GetCurrentScene()) {
|
|
|
|
// Tell the user he needs a scene first (help beginners).
|
|
|
|
QMessageBox::information(this,
|
|
|
|
QTStr("Basic.Main.AddSourceHelp.Title"),
|
|
|
|
QTStr("Basic.Main.AddSourceHelp.Text"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
QPointer<QMenu> popup = CreateAddSourcePopupMenu();
|
|
|
|
if (popup)
|
|
|
|
popup->exec(pos);
|
2013-12-30 05:56:39 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionAddSource_triggered()
|
2013-12-30 05:56:39 -08:00
|
|
|
{
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
AddSourcePopupMenu(QCursor::pos());
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionRemoveSource_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-06-30 13:45:58 -07:00
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-06-30 13:45:58 -07:00
|
|
|
|
|
|
|
if (source && QueryRemoveSource(source))
|
2014-01-30 00:31:52 -08:00
|
|
|
obs_sceneitem_remove(item);
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
2014-09-15 16:16:16 -07:00
|
|
|
void OBSBasic::on_actionInteract_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
OBSSource source = obs_sceneitem_get_source(item);
|
|
|
|
|
|
|
|
if (source)
|
|
|
|
CreateInteractionWindow(source);
|
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSourceProperties_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-03-23 01:07:54 -07:00
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
OBSSource source = obs_sceneitem_get_source(item);
|
2014-03-23 01:07:54 -07:00
|
|
|
|
2014-07-22 13:16:57 -07:00
|
|
|
if (source)
|
|
|
|
CreatePropertiesWindow(source);
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSourceUp_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-05-15 17:40:53 -07:00
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_UP);
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
2013-12-10 10:22:33 -08:00
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_actionSourceDown_triggered()
|
2013-12-10 20:14:45 -08:00
|
|
|
{
|
2014-05-15 17:40:53 -07:00
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_DOWN);
|
2013-12-10 20:14:45 -08:00
|
|
|
}
|
|
|
|
|
2014-06-30 19:47:06 -07:00
|
|
|
void OBSBasic::on_actionMoveUp_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_UP);
|
2014-06-30 19:47:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveDown_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_DOWN);
|
2014-06-30 19:47:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveToTop_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_TOP);
|
2014-06-30 19:47:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveToBottom_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_order(item, OBS_ORDER_MOVE_BOTTOM);
|
2014-06-30 19:47:06 -07:00
|
|
|
}
|
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
static BPtr<char> ReadLogFile(const char *log)
|
2014-05-18 17:44:10 -07:00
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char logDir[512];
|
|
|
|
if (os_get_config_path(logDir, sizeof(logDir), "obs-studio/logs") <= 0)
|
|
|
|
return nullptr;
|
2014-05-18 17:44:10 -07:00
|
|
|
|
|
|
|
string path = (char*)logDir;
|
|
|
|
path += "/";
|
|
|
|
path += log;
|
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
BPtr<char> file = os_quick_read_utf8_file(path.c_str());
|
2014-05-18 17:44:10 -07:00
|
|
|
if (!file)
|
|
|
|
blog(LOG_WARNING, "Failed to read log file %s", path.c_str());
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::UploadLog(const char *file)
|
|
|
|
{
|
2014-08-23 17:02:45 -07:00
|
|
|
BPtr<char> fileString{ReadLogFile(file)};
|
2014-05-18 17:44:10 -07:00
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
if (!fileString)
|
2014-05-18 17:44:10 -07:00
|
|
|
return;
|
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
if (!*fileString)
|
2014-05-18 17:44:10 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
ui->menuLogFiles->setEnabled(false);
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
auto data_deleter = [](obs_data_t *d) { obs_data_release(d); };
|
2014-08-23 17:02:45 -07:00
|
|
|
using data_t = unique_ptr<struct obs_data, decltype(data_deleter)>;
|
2014-05-18 17:44:10 -07:00
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
data_t content{obs_data_create(), data_deleter};
|
|
|
|
data_t files{obs_data_create(), data_deleter};
|
|
|
|
data_t request{obs_data_create(), data_deleter};
|
2014-05-18 17:44:10 -07:00
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
obs_data_set_string(content.get(), "content", fileString);
|
2014-05-18 17:44:10 -07:00
|
|
|
|
2014-08-23 17:02:45 -07:00
|
|
|
obs_data_set_obj(files.get(), file, content.get());
|
|
|
|
|
|
|
|
stringstream ss;
|
|
|
|
ss << "OBS " << App()->GetVersionString()
|
|
|
|
<< " log file uploaded at " << CurrentDateTimeString();
|
|
|
|
obs_data_set_string(request.get(), "description", ss.str().c_str());
|
|
|
|
obs_data_set_bool(request.get(), "public", false);
|
|
|
|
obs_data_set_obj(request.get(), "files", files.get());
|
|
|
|
|
|
|
|
const char *json = obs_data_get_json(request.get());
|
2014-08-25 13:22:57 -07:00
|
|
|
if (!json) {
|
2014-08-23 17:02:45 -07:00
|
|
|
blog(LOG_ERROR, "Failed to get JSON data for log upload");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QBuffer *postData = new QBuffer();
|
|
|
|
postData->setData(json, (int) strlen(json));
|
|
|
|
|
|
|
|
QNetworkRequest postReq(QUrl("https://api.github.com/gists"));
|
|
|
|
postReq.setHeader(QNetworkRequest::ContentTypeHeader,
|
|
|
|
"application/json");
|
|
|
|
|
|
|
|
QNetworkReply *reply = networkManager.post(postReq, postData);
|
2014-05-18 17:44:10 -07:00
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
/* set the reply as parent, so the buffer is deleted with the reply */
|
|
|
|
postData->setParent(reply);
|
|
|
|
|
|
|
|
connect(reply, SIGNAL(finished()),
|
2014-05-18 17:44:10 -07:00
|
|
|
this, SLOT(logUploadFinished()));
|
|
|
|
}
|
|
|
|
|
2014-08-21 18:19:19 -07:00
|
|
|
void OBSBasic::on_actionShowLogs_triggered()
|
|
|
|
{
|
2015-01-15 23:44:38 -08:00
|
|
|
char logDir[512];
|
|
|
|
if (os_get_config_path(logDir, sizeof(logDir), "obs-studio/logs") <= 0)
|
|
|
|
return;
|
|
|
|
|
2014-08-21 18:19:19 -07:00
|
|
|
QUrl url = QUrl::fromLocalFile(QT_UTF8(logDir));
|
|
|
|
QDesktopServices::openUrl(url);
|
|
|
|
}
|
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
void OBSBasic::on_actionUploadCurrentLog_triggered()
|
|
|
|
{
|
|
|
|
UploadLog(App()->GetCurrentLog());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionUploadLastLog_triggered()
|
|
|
|
{
|
|
|
|
UploadLog(App()->GetLastLog());
|
|
|
|
}
|
|
|
|
|
2014-07-13 23:56:28 -07:00
|
|
|
void OBSBasic::on_actionCheckForUpdates_triggered()
|
|
|
|
{
|
|
|
|
CheckForUpdates();
|
|
|
|
}
|
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
void OBSBasic::logUploadFinished()
|
|
|
|
{
|
|
|
|
ui->menuLogFiles->setEnabled(true);
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
|
|
|
|
if (!reply || reply->error()) {
|
2014-05-18 17:44:10 -07:00
|
|
|
QMessageBox::information(this,
|
|
|
|
QTStr("LogReturnDialog.ErrorUploadingLog"),
|
2014-08-25 12:22:58 -07:00
|
|
|
reply->errorString());
|
2014-05-18 17:44:10 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
QByteArray raw = reply->readAll();
|
|
|
|
if (!raw.length())
|
2014-05-18 17:44:10 -07:00
|
|
|
return;
|
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
obs_data_t *returnData = obs_data_create_from_json(raw.constData());
|
|
|
|
QString logURL = obs_data_get_string(returnData, "html_url");
|
2014-05-18 17:44:10 -07:00
|
|
|
obs_data_release(returnData);
|
|
|
|
|
|
|
|
OBSLogReply logDialog(this, logURL);
|
|
|
|
logDialog.exec();
|
2014-08-25 10:09:57 -07:00
|
|
|
|
2014-08-25 12:22:58 -07:00
|
|
|
reply->deleteLater();
|
2014-05-18 17:44:10 -07:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:10:58 -07:00
|
|
|
static void RenameListItem(OBSBasic *parent, QListWidget *listWidget,
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source, const string &name)
|
2014-06-30 01:05:33 -07:00
|
|
|
{
|
2014-10-13 09:09:06 -07:00
|
|
|
const char *prevName = obs_source_get_name(source);
|
|
|
|
if (name == prevName)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *foundSource = obs_get_source_by_name(name.c_str());
|
2014-10-13 09:09:06 -07:00
|
|
|
QListWidgetItem *listItem = listWidget->currentItem();
|
2014-06-30 01:05:33 -07:00
|
|
|
|
2014-10-13 09:09:06 -07:00
|
|
|
if (foundSource || name.empty()) {
|
2014-06-30 01:05:33 -07:00
|
|
|
listItem->setText(QT_UTF8(prevName));
|
2014-08-12 12:09:19 -07:00
|
|
|
|
2014-10-13 09:09:06 -07:00
|
|
|
if (foundSource) {
|
2014-08-12 12:09:19 -07:00
|
|
|
QMessageBox::information(parent,
|
|
|
|
QTStr("NameExists.Title"),
|
|
|
|
QTStr("NameExists.Text"));
|
|
|
|
} else if (name.empty()) {
|
|
|
|
QMessageBox::information(parent,
|
|
|
|
QTStr("NoNameEntered.Title"),
|
|
|
|
QTStr("NoNameEntered.Text"));
|
|
|
|
}
|
|
|
|
|
2014-06-30 01:05:33 -07:00
|
|
|
obs_source_release(foundSource);
|
|
|
|
} else {
|
|
|
|
listItem->setText(QT_UTF8(name.c_str()));
|
2014-08-04 08:41:15 -07:00
|
|
|
obs_source_set_name(source, name.c_str());
|
2014-06-30 01:05:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-30 00:06:01 -07:00
|
|
|
void OBSBasic::SceneNameEdited(QWidget *editor,
|
|
|
|
QAbstractItemDelegate::EndEditHint endHint)
|
|
|
|
{
|
|
|
|
OBSScene scene = GetCurrentScene();
|
|
|
|
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
2014-06-30 01:05:33 -07:00
|
|
|
string text = QT_TO_UTF8(edit->text().trimmed());
|
2014-06-30 00:06:01 -07:00
|
|
|
|
|
|
|
if (!scene)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_scene_get_source(scene);
|
2014-08-12 12:09:19 -07:00
|
|
|
RenameListItem(this, ui->scenes, source, text);
|
2014-06-30 00:06:01 -07:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(endHint);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemNameEdited(QWidget *editor,
|
|
|
|
QAbstractItemDelegate::EndEditHint endHint)
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
|
2014-06-30 01:05:33 -07:00
|
|
|
string text = QT_TO_UTF8(edit->text().trimmed());
|
2014-06-30 00:06:01 -07:00
|
|
|
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_source_t *source = obs_sceneitem_get_source(item);
|
2014-08-12 12:09:19 -07:00
|
|
|
RenameListItem(this, ui->sources, source, text);
|
2014-06-30 00:06:01 -07:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(endHint);
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
void OBSBasic::StreamingStart()
|
Implement RTMP module (still needs drop code)
- Implement the RTMP output module. This time around, we just use a
simple FLV muxer, then just write to the stream with RTMP_Write.
Easy and effective.
- Fix the FLV muxer, the muxer now outputs proper FLV packets.
- Output API:
* When using encoders, automatically interleave encoded packets
before sending it to the output.
* Pair encoders and have them automatically wait for the other to
start to ensure sync.
* Change 'obs_output_signal_start_fail' to 'obs_output_signal_stop'
because it was a bit confusing, and doing this makes a lot more
sense for outputs that need to stop suddenly (disconnections/etc).
- Encoder API:
* Remove some unnecessary encoder functions from the actual API and
make them internal. Most of the encoder functions are handled
automatically by outputs anyway, so there's no real need to expose
them and end up inadvertently confusing plugin writers.
* Have audio encoders wait for the video encoder to get a frame, then
start at the exact data point that the first video frame starts to
ensure the most accrate sync of video/audio possible.
* Add a required 'frame_size' callback for audio encoders that
returns the expected number of frames desired to encode with. This
way, the libobs encoder API can handle the circular buffering
internally automatically for the encoder modules, so encoder
writers don't have to do it themselves.
- Fix a few bugs in the serializer interface. It was passing the wrong
variable for the data in a few cases.
- If a source has video, make obs_source_update defer the actual update
callback until the tick function is called to prevent threading
issues.
2014-04-07 22:00:10 -07:00
|
|
|
{
|
2014-07-12 05:34:23 -07:00
|
|
|
ui->streamButton->setText(QTStr("Basic.Main.StopStreaming"));
|
2014-05-15 14:04:18 -07:00
|
|
|
ui->streamButton->setEnabled(true);
|
2014-07-06 16:19:27 -07:00
|
|
|
ui->statusbar->StreamStarted(streamOutput);
|
2014-03-10 13:10:35 -07:00
|
|
|
}
|
|
|
|
|
2014-05-12 15:30:36 -07:00
|
|
|
void OBSBasic::StreamingStop(int code)
|
2014-03-10 13:10:35 -07:00
|
|
|
{
|
2014-05-12 15:30:36 -07:00
|
|
|
const char *errorMessage;
|
|
|
|
|
|
|
|
switch (code) {
|
|
|
|
case OBS_OUTPUT_BAD_PATH:
|
|
|
|
errorMessage = Str("Output.ConnectFail.BadPath");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBS_OUTPUT_CONNECT_FAILED:
|
|
|
|
errorMessage = Str("Output.ConnectFail.ConnectFailed");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBS_OUTPUT_INVALID_STREAM:
|
|
|
|
errorMessage = Str("Output.ConnectFail.InvalidStream");
|
|
|
|
break;
|
|
|
|
|
2014-06-25 02:03:00 -07:00
|
|
|
default:
|
2014-05-12 15:30:36 -07:00
|
|
|
case OBS_OUTPUT_ERROR:
|
|
|
|
errorMessage = Str("Output.ConnectFail.Error");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case OBS_OUTPUT_DISCONNECTED:
|
|
|
|
/* doesn't happen if output is set to reconnect. note that
|
|
|
|
* reconnects are handled in the output, not in the UI */
|
|
|
|
errorMessage = Str("Output.ConnectFail.Disconnected");
|
|
|
|
}
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
activeRefs--;
|
2014-07-06 16:19:27 -07:00
|
|
|
ui->statusbar->StreamStopped();
|
2014-05-20 23:27:27 -07:00
|
|
|
|
2014-05-12 15:30:36 -07:00
|
|
|
ui->streamButton->setText(QTStr("Basic.Main.StartStreaming"));
|
2014-05-15 14:04:18 -07:00
|
|
|
ui->streamButton->setEnabled(true);
|
2014-05-12 15:30:36 -07:00
|
|
|
|
|
|
|
if (code != OBS_OUTPUT_SUCCESS)
|
|
|
|
QMessageBox::information(this,
|
|
|
|
QTStr("Output.ConnectFail.Title"),
|
|
|
|
QT_UTF8(errorMessage));
|
2014-04-14 02:22:09 -07:00
|
|
|
}
|
|
|
|
|
2014-08-24 18:10:57 -07:00
|
|
|
void OBSBasic::RecordingStart()
|
|
|
|
{
|
|
|
|
ui->statusbar->RecordingStarted(fileOutput);
|
|
|
|
}
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
void OBSBasic::RecordingStop()
|
2014-03-10 13:10:35 -07:00
|
|
|
{
|
2014-08-24 18:10:57 -07:00
|
|
|
ui->statusbar->RecordingStopped();
|
2014-05-20 23:27:27 -07:00
|
|
|
activeRefs--;
|
|
|
|
ui->recordButton->setText(QTStr("Basic.Main.StartRecording"));
|
|
|
|
}
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
void OBSBasic::SetupEncoders()
|
|
|
|
{
|
|
|
|
if (activeRefs == 0) {
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *x264Settings = obs_data_create();
|
|
|
|
obs_data_t *aacSettings = obs_data_create();
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
|
|
|
|
int videoBitrate = config_get_uint(basicConfig, "SimpleOutput",
|
2014-03-10 13:10:35 -07:00
|
|
|
"VBitrate");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
int audioBitrate = config_get_uint(basicConfig, "SimpleOutput",
|
2014-03-10 13:10:35 -07:00
|
|
|
"ABitrate");
|
2014-08-25 07:48:51 -07:00
|
|
|
bool advanced = config_get_bool(basicConfig, "SimpleOutput",
|
|
|
|
"UseAdvanced");
|
2014-09-24 20:23:42 -07:00
|
|
|
bool useCBR = config_get_bool(basicConfig, "SimpleOutput",
|
|
|
|
"UseCBR");
|
2014-08-25 07:48:51 -07:00
|
|
|
const char *preset = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "Preset");
|
|
|
|
const char *custom = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "x264Settings");
|
2014-03-10 13:10:35 -07:00
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_int(x264Settings, "bitrate", videoBitrate);
|
|
|
|
obs_data_set_int(x264Settings, "buffer_size", videoBitrate);
|
Implement RTMP module (still needs drop code)
- Implement the RTMP output module. This time around, we just use a
simple FLV muxer, then just write to the stream with RTMP_Write.
Easy and effective.
- Fix the FLV muxer, the muxer now outputs proper FLV packets.
- Output API:
* When using encoders, automatically interleave encoded packets
before sending it to the output.
* Pair encoders and have them automatically wait for the other to
start to ensure sync.
* Change 'obs_output_signal_start_fail' to 'obs_output_signal_stop'
because it was a bit confusing, and doing this makes a lot more
sense for outputs that need to stop suddenly (disconnections/etc).
- Encoder API:
* Remove some unnecessary encoder functions from the actual API and
make them internal. Most of the encoder functions are handled
automatically by outputs anyway, so there's no real need to expose
them and end up inadvertently confusing plugin writers.
* Have audio encoders wait for the video encoder to get a frame, then
start at the exact data point that the first video frame starts to
ensure the most accrate sync of video/audio possible.
* Add a required 'frame_size' callback for audio encoders that
returns the expected number of frames desired to encode with. This
way, the libobs encoder API can handle the circular buffering
internally automatically for the encoder modules, so encoder
writers don't have to do it themselves.
- Fix a few bugs in the serializer interface. It was passing the wrong
variable for the data in a few cases.
- If a source has video, make obs_source_update defer the actual update
callback until the tick function is called to prevent threading
issues.
2014-04-07 22:00:10 -07:00
|
|
|
|
2014-08-25 07:48:51 -07:00
|
|
|
if (advanced) {
|
|
|
|
obs_data_set_string(x264Settings, "preset", preset);
|
|
|
|
obs_data_set_string(x264Settings, "x264opts", custom);
|
2014-09-24 20:23:42 -07:00
|
|
|
obs_data_set_bool(x264Settings, "cbr", useCBR);
|
|
|
|
} else {
|
|
|
|
obs_data_set_bool(x264Settings, "cbr", true);
|
2014-08-25 07:48:51 -07:00
|
|
|
}
|
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_int(aacSettings, "bitrate", audioBitrate);
|
Implement RTMP module (still needs drop code)
- Implement the RTMP output module. This time around, we just use a
simple FLV muxer, then just write to the stream with RTMP_Write.
Easy and effective.
- Fix the FLV muxer, the muxer now outputs proper FLV packets.
- Output API:
* When using encoders, automatically interleave encoded packets
before sending it to the output.
* Pair encoders and have them automatically wait for the other to
start to ensure sync.
* Change 'obs_output_signal_start_fail' to 'obs_output_signal_stop'
because it was a bit confusing, and doing this makes a lot more
sense for outputs that need to stop suddenly (disconnections/etc).
- Encoder API:
* Remove some unnecessary encoder functions from the actual API and
make them internal. Most of the encoder functions are handled
automatically by outputs anyway, so there's no real need to expose
them and end up inadvertently confusing plugin writers.
* Have audio encoders wait for the video encoder to get a frame, then
start at the exact data point that the first video frame starts to
ensure the most accrate sync of video/audio possible.
* Add a required 'frame_size' callback for audio encoders that
returns the expected number of frames desired to encode with. This
way, the libobs encoder API can handle the circular buffering
internally automatically for the encoder modules, so encoder
writers don't have to do it themselves.
- Fix a few bugs in the serializer interface. It was passing the wrong
variable for the data in a few cases.
- If a source has video, make obs_source_update defer the actual update
callback until the tick function is called to prevent threading
issues.
2014-04-07 22:00:10 -07:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
obs_encoder_update(x264, x264Settings);
|
|
|
|
obs_encoder_update(aac, aacSettings);
|
2014-02-10 09:22:35 -08:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
obs_data_release(x264Settings);
|
|
|
|
obs_data_release(aacSettings);
|
2014-03-10 13:10:35 -07:00
|
|
|
|
2014-08-04 09:09:02 -07:00
|
|
|
obs_encoder_set_video(x264, obs_get_video());
|
|
|
|
obs_encoder_set_audio(aac, obs_get_audio());
|
2014-05-20 23:27:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_streamButton_clicked()
|
|
|
|
{
|
2015-01-04 08:20:15 -08:00
|
|
|
SaveProject();
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
if (obs_output_active(streamOutput)) {
|
|
|
|
obs_output_stop(streamOutput);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
SaveService();
|
|
|
|
SetupEncoders();
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
obs_output_set_video_encoder(streamOutput, x264);
|
|
|
|
obs_output_set_audio_encoder(streamOutput, aac);
|
|
|
|
obs_output_set_service(streamOutput, service);
|
2014-05-20 23:27:27 -07:00
|
|
|
|
2014-07-03 18:07:33 -07:00
|
|
|
bool reconnect = config_get_bool(basicConfig, "SimpleOutput",
|
|
|
|
"Reconnect");
|
|
|
|
int retryDelay = config_get_uint(basicConfig, "SimpleOutput",
|
|
|
|
"RetryDelay");
|
|
|
|
int maxRetries = config_get_uint(basicConfig, "SimpleOutput",
|
|
|
|
"MaxRetries");
|
|
|
|
if (!reconnect)
|
|
|
|
maxRetries = 0;
|
|
|
|
|
2014-07-04 13:21:11 -07:00
|
|
|
obs_output_set_reconnect_settings(streamOutput, maxRetries,
|
|
|
|
retryDelay);
|
2014-07-03 18:07:33 -07:00
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
if (obs_output_start(streamOutput)) {
|
|
|
|
activeRefs++;
|
|
|
|
|
|
|
|
ui->streamButton->setEnabled(false);
|
|
|
|
ui->streamButton->setText(
|
|
|
|
QTStr("Basic.Main.Connecting"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_recordButton_clicked()
|
|
|
|
{
|
2015-01-04 08:20:15 -08:00
|
|
|
SaveProject();
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
if (obs_output_active(fileOutput)) {
|
|
|
|
obs_output_stop(fileOutput);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
const char *path = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "FilePath");
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
os_dir_t *dir = path ? os_opendir(path) : nullptr;
|
2014-05-20 23:27:27 -07:00
|
|
|
|
|
|
|
if (!dir) {
|
|
|
|
QMessageBox::information(this,
|
|
|
|
QTStr("Output.BadPath.Title"),
|
|
|
|
QTStr("Output.BadPath.Text"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
os_closedir(dir);
|
|
|
|
|
|
|
|
string strPath;
|
|
|
|
strPath += path;
|
|
|
|
|
|
|
|
char lastChar = strPath.back();
|
|
|
|
if (lastChar != '/' && lastChar != '\\')
|
|
|
|
strPath += "/";
|
|
|
|
|
|
|
|
strPath += GenerateTimeDateFilename("flv");
|
|
|
|
|
|
|
|
SetupEncoders();
|
|
|
|
|
|
|
|
obs_output_set_video_encoder(fileOutput, x264);
|
|
|
|
obs_output_set_audio_encoder(fileOutput, aac);
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_data_t *settings = obs_data_create();
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_string(settings, "path", strPath.c_str());
|
2014-05-20 23:27:27 -07:00
|
|
|
|
|
|
|
obs_output_update(fileOutput, settings);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
|
|
|
|
if (obs_output_start(fileOutput)) {
|
|
|
|
activeRefs++;
|
|
|
|
|
|
|
|
ui->recordButton->setText(
|
|
|
|
QTStr("Basic.Main.StopRecording"));
|
|
|
|
}
|
2014-02-10 09:22:35 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Change the UI to Qt (work in progress)
--------------------------------------------------
Notes and details
--------------------------------------------------
Why was this done? Because wxWidgets was just lacking in many areas. I
know wxWidgets is designed to be used with native controls, and that's
great, but wxWidgets just is not a feature-complete toolkit for
multiplatform applications. It lacks in dialog editors, its code is
archaic and outdated, and I just feel frustrated every time I try to do
things with it.
Qt on the other hand.. I had to actually try Qt to realize how much
better it was as a toolkit. They've got everything from dialog editors,
to an IDE, a debugger, build tools, just everything, and it's all
top-notch and highly maintained. The focus of the toolkit is
application development, and they spend their time trying to help
people do exactly that: make programs. Great support, great tools,
and because of that, great toolkit. I just didn't want to alienate any
developers by being stubborn about native widgets.
There *are* some things that are rather lackluster about it and design
choices I disagree with though. For example, I realize that to have an
easy to use toolkit you have to have some level of code generation.
However, in my personal and humble opinion, moc just feels like a
terrible way to approach the problem. Even now I feel like there are a
variety of ways you could handle code generation and automatic
management of things like that. I don't like the idea of circumventing
the language itself like that. It feels like one giant massive hack.
--------------------------------------------------
Things that aren't working properly:
--------------------------------------------------
- Settings dialog is not implemented. The dialog is complete but the
code to handle the dialog hasn't been constructed yet.
- There is a problem with using Qt widgets as a device target on
windows, with at least OpenGL: if I have the preview widget
automatically resize itself, it seems to cause some sort of video
card failure that I don't understand.
- Because of the above, resizing the preview widget has been disabled
until I can figure out what's going on, so it's currently only a
32x32 area.
- Direct3D doesn't seem to render correctly either, seems that the
viewport is messed up or something. I'm sort of confused about
what's going on with it.
- The new main window seems to be triggering more race conditions than
the wxWidgets main window dialog did. I'm not entirely sure what's
going on here, but this may just be existing race conditions within
libobs itself that I just never spotted before (even though I tend to
be very thorough with race conditions any time I use variables
cross-thread)
2014-01-23 10:53:55 -08:00
|
|
|
void OBSBasic::on_settingsButton_clicked()
|
2013-12-10 10:22:33 -08:00
|
|
|
{
|
2014-01-24 20:19:50 -08:00
|
|
|
OBSBasicSettings settings(this);
|
|
|
|
settings.exec();
|
2013-12-10 10:22:33 -08:00
|
|
|
}
|
2014-03-06 20:08:12 -08:00
|
|
|
|
|
|
|
void OBSBasic::GetFPSCommon(uint32_t &num, uint32_t &den) const
|
|
|
|
{
|
|
|
|
const char *val = config_get_string(basicConfig, "Video", "FPSCommon");
|
|
|
|
|
|
|
|
if (strcmp(val, "10") == 0) {
|
|
|
|
num = 10;
|
|
|
|
den = 1;
|
|
|
|
} else if (strcmp(val, "20") == 0) {
|
|
|
|
num = 20;
|
|
|
|
den = 1;
|
|
|
|
} else if (strcmp(val, "25") == 0) {
|
|
|
|
num = 25;
|
|
|
|
den = 1;
|
|
|
|
} else if (strcmp(val, "29.97") == 0) {
|
|
|
|
num = 30000;
|
|
|
|
den = 1001;
|
|
|
|
} else if (strcmp(val, "48") == 0) {
|
|
|
|
num = 48;
|
|
|
|
den = 1;
|
|
|
|
} else if (strcmp(val, "59.94") == 0) {
|
|
|
|
num = 60000;
|
|
|
|
den = 1001;
|
|
|
|
} else if (strcmp(val, "60") == 0) {
|
|
|
|
num = 60;
|
|
|
|
den = 1;
|
|
|
|
} else {
|
|
|
|
num = 30;
|
|
|
|
den = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::GetFPSInteger(uint32_t &num, uint32_t &den) const
|
|
|
|
{
|
|
|
|
num = (uint32_t)config_get_uint(basicConfig, "Video", "FPSInt");
|
|
|
|
den = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::GetFPSFraction(uint32_t &num, uint32_t &den) const
|
|
|
|
{
|
|
|
|
num = (uint32_t)config_get_uint(basicConfig, "Video", "FPSNum");
|
|
|
|
den = (uint32_t)config_get_uint(basicConfig, "Video", "FPSDen");
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::GetFPSNanoseconds(uint32_t &num, uint32_t &den) const
|
|
|
|
{
|
|
|
|
num = 1000000000;
|
|
|
|
den = (uint32_t)config_get_uint(basicConfig, "Video", "FPSNS");
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::GetConfigFPS(uint32_t &num, uint32_t &den) const
|
|
|
|
{
|
|
|
|
uint32_t type = config_get_uint(basicConfig, "Video", "FPSType");
|
|
|
|
|
|
|
|
if (type == 1) //"Integer"
|
|
|
|
GetFPSInteger(num, den);
|
|
|
|
else if (type == 2) //"Fraction"
|
|
|
|
GetFPSFraction(num, den);
|
|
|
|
else if (false) //"Nanoseconds", currently not implemented
|
|
|
|
GetFPSNanoseconds(num, den);
|
|
|
|
else
|
|
|
|
GetFPSCommon(num, den);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
config_t *OBSBasic::Config() const
|
2014-03-06 20:08:12 -08:00
|
|
|
{
|
|
|
|
return basicConfig;
|
|
|
|
}
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
|
|
|
void OBSBasic::on_actionEditTransform_triggered()
|
|
|
|
{
|
2014-07-22 13:16:57 -07:00
|
|
|
if (transformWindow)
|
|
|
|
transformWindow->close();
|
|
|
|
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
transformWindow = new OBSBasicTransform(this);
|
|
|
|
transformWindow->show();
|
2014-07-22 13:16:57 -07:00
|
|
|
transformWindow->setAttribute(Qt::WA_DeleteOnClose, true);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionResetTransform_triggered()
|
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
auto func = [] (obs_scene_t *scene, obs_sceneitem_t *item, void *param)
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
{
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
2014-08-01 23:33:45 -07:00
|
|
|
obs_transform_info info;
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
vec2_set(&info.pos, 0.0f, 0.0f);
|
|
|
|
vec2_set(&info.scale, 1.0f, 1.0f);
|
|
|
|
info.rot = 0.0f;
|
|
|
|
info.alignment = OBS_ALIGN_TOP | OBS_ALIGN_LEFT;
|
|
|
|
info.bounds_type = OBS_BOUNDS_NONE;
|
|
|
|
info.bounds_alignment = OBS_ALIGN_CENTER;
|
|
|
|
vec2_set(&info.bounds, 0.0f, 0.0f);
|
|
|
|
obs_sceneitem_set_info(item, &info);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
|
|
|
UNUSED_PARAMETER(param);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), func, nullptr);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void GetItemBox(obs_sceneitem_t *item, vec3 &tl, vec3 &br)
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
{
|
|
|
|
matrix4 boxTransform;
|
|
|
|
obs_sceneitem_get_box_transform(item, &boxTransform);
|
|
|
|
|
|
|
|
vec3_set(&tl, M_INFINITE, M_INFINITE, 0.0f);
|
2014-06-22 23:49:57 -07:00
|
|
|
vec3_set(&br, -M_INFINITE, -M_INFINITE, 0.0f);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
2014-06-22 23:49:57 -07:00
|
|
|
auto GetMinPos = [&] (float x, float y)
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
{
|
|
|
|
vec3 pos;
|
|
|
|
vec3_set(&pos, x, y, 0.0f);
|
|
|
|
vec3_transform(&pos, &pos, &boxTransform);
|
2014-06-22 23:49:57 -07:00
|
|
|
vec3_min(&tl, &tl, &pos);
|
|
|
|
vec3_max(&br, &br, &pos);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
};
|
|
|
|
|
2014-06-22 23:49:57 -07:00
|
|
|
GetMinPos(0.0f, 0.0f);
|
|
|
|
GetMinPos(1.0f, 0.0f);
|
|
|
|
GetMinPos(0.0f, 1.0f);
|
|
|
|
GetMinPos(1.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static vec3 GetItemTL(obs_sceneitem_t *item)
|
2014-06-22 23:49:57 -07:00
|
|
|
{
|
|
|
|
vec3 tl, br;
|
|
|
|
GetItemBox(item, tl, br);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
return tl;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void SetItemTL(obs_sceneitem_t *item, const vec3 &tl)
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
{
|
|
|
|
vec3 newTL;
|
|
|
|
vec2 pos;
|
|
|
|
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_get_pos(item, &pos);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
newTL = GetItemTL(item);
|
|
|
|
pos.x += tl.x - newTL.x;
|
|
|
|
pos.y += tl.y - newTL.y;
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_pos(item, &pos);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static bool RotateSelectedSources(obs_scene_t *scene, obs_sceneitem_t *item,
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
float rot = *reinterpret_cast<float*>(param);
|
|
|
|
|
|
|
|
vec3 tl = GetItemTL(item);
|
|
|
|
|
2014-08-03 14:39:19 -07:00
|
|
|
rot += obs_sceneitem_get_rot(item);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
if (rot >= 360.0f) rot -= 360.0f;
|
|
|
|
else if (rot <= -360.0f) rot += 360.0f;
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_rot(item, rot);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
|
|
|
SetItemTL(item, tl);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
|
|
|
UNUSED_PARAMETER(param);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
void OBSBasic::on_actionRotate90CW_triggered()
|
|
|
|
{
|
|
|
|
float f90CW = 90.0f;
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), RotateSelectedSources, &f90CW);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionRotate90CCW_triggered()
|
|
|
|
{
|
|
|
|
float f90CCW = -90.0f;
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), RotateSelectedSources, &f90CCW);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionRotate180_triggered()
|
|
|
|
{
|
|
|
|
float f180 = 180.0f;
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), RotateSelectedSources, &f180);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static bool MultiplySelectedItemScale(obs_scene_t *scene, obs_sceneitem_t *item,
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
vec2 &mul = *reinterpret_cast<vec2*>(param);
|
|
|
|
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
vec3 tl = GetItemTL(item);
|
|
|
|
|
|
|
|
vec2 scale;
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_get_scale(item, &scale);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
vec2_mul(&scale, &scale, &mul);
|
2014-08-03 14:39:19 -07:00
|
|
|
obs_sceneitem_set_scale(item, &scale);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
|
|
|
|
SetItemTL(item, tl);
|
2014-06-16 17:55:48 -07:00
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionFlipHorizontal_triggered()
|
|
|
|
{
|
2014-06-16 17:55:48 -07:00
|
|
|
vec2 scale;
|
|
|
|
vec2_set(&scale, -1.0f, 1.0f);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
obs_scene_enum_items(GetCurrentScene(), MultiplySelectedItemScale,
|
|
|
|
&scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionFlipVertical_triggered()
|
|
|
|
{
|
2014-06-16 17:55:48 -07:00
|
|
|
vec2 scale;
|
|
|
|
vec2_set(&scale, 1.0f, -1.0f);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
obs_scene_enum_items(GetCurrentScene(), MultiplySelectedItemScale,
|
|
|
|
&scale);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static bool CenterAlignSelectedItems(obs_scene_t *scene, obs_sceneitem_t *item,
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
obs_bounds_type boundsType = *reinterpret_cast<obs_bounds_type*>(param);
|
|
|
|
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
obs_video_info ovi;
|
|
|
|
obs_get_video_info(&ovi);
|
|
|
|
|
2014-08-01 23:33:45 -07:00
|
|
|
obs_transform_info itemInfo;
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
vec2_set(&itemInfo.pos, 0.0f, 0.0f);
|
|
|
|
vec2_set(&itemInfo.scale, 1.0f, 1.0f);
|
|
|
|
itemInfo.alignment = OBS_ALIGN_LEFT | OBS_ALIGN_TOP;
|
|
|
|
itemInfo.rot = 0.0f;
|
|
|
|
|
|
|
|
vec2_set(&itemInfo.bounds,
|
|
|
|
float(ovi.base_width), float(ovi.base_height));
|
|
|
|
itemInfo.bounds_type = boundsType;
|
|
|
|
itemInfo.bounds_alignment = OBS_ALIGN_CENTER;
|
|
|
|
|
|
|
|
obs_sceneitem_set_info(item, &itemInfo);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionFitToScreen_triggered()
|
|
|
|
{
|
|
|
|
obs_bounds_type boundsType = OBS_BOUNDS_SCALE_INNER;
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), CenterAlignSelectedItems,
|
|
|
|
&boundsType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionStretchToScreen_triggered()
|
|
|
|
{
|
|
|
|
obs_bounds_type boundsType = OBS_BOUNDS_STRETCH;
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), CenterAlignSelectedItems,
|
|
|
|
&boundsType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionCenterToScreen_triggered()
|
|
|
|
{
|
2014-09-25 17:44:05 -07:00
|
|
|
auto func = [] (obs_scene_t *scene, obs_sceneitem_t *item, void *param)
|
2014-06-22 23:49:57 -07:00
|
|
|
{
|
|
|
|
vec3 tl, br, itemCenter, screenCenter, offset;
|
|
|
|
obs_video_info ovi;
|
|
|
|
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
obs_get_video_info(&ovi);
|
|
|
|
|
|
|
|
vec3_set(&screenCenter, float(ovi.base_width),
|
|
|
|
float(ovi.base_height), 0.0f);
|
|
|
|
vec3_mulf(&screenCenter, &screenCenter, 0.5f);
|
|
|
|
|
|
|
|
GetItemBox(item, tl, br);
|
|
|
|
|
|
|
|
vec3_sub(&itemCenter, &br, &tl);
|
|
|
|
vec3_mulf(&itemCenter, &itemCenter, 0.5f);
|
|
|
|
vec3_add(&itemCenter, &itemCenter, &tl);
|
|
|
|
|
|
|
|
vec3_sub(&offset, &screenCenter, &itemCenter);
|
|
|
|
vec3_add(&tl, &tl, &offset);
|
|
|
|
|
|
|
|
SetItemTL(item, tl);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(scene);
|
2014-06-25 01:40:39 -07:00
|
|
|
UNUSED_PARAMETER(param);
|
2014-06-22 23:49:57 -07:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
obs_scene_enum_items(GetCurrentScene(), func, nullptr);
|
UI: Add scene editing
So, scene editing was interesting (and by interesting I mean
excruciating). I almost implemented 'manipulator' visuals (ala 3dsmax
for example), and used 3 modes for controlling position/rotation/size,
but in a 2D editing, it felt clunky, so I defaulted back to simply
click-and-drag for movement, and then took a similar though slightly
different looking approach for handling scaling and reszing.
I also added a number of menu item helpers related to positioning,
scaling, rotating, flipping, and resetting the transform back to
default.
There is also a new 'transform' dialog (accessible via menu) which will
allow you to manually edit every single transform variable of a scene
item directly if desired.
If a scene item does not have bounds active, pulling on the sides of a
source will cause it to resize it via base scale rather than by the
bounding box system (if the source resizes that scale will apply). If
bounds are active, it will modify the bounding box only instead.
How a source scales when a bounding box is active depends on the type of
bounds being used. You can set it to scale to the inner bounds, the
outer bounds, scale to bounds width only, scale to bounds height only,
and a setting to stretch to bounds (which forces a source to always draw
at the bounding box size rather than be affected by its internal size).
You can also set it to be used as a 'maximum' size, so that the source
doesn't necessarily get scaled unless it extends beyond the bounds.
Like in OBS1, objects will snap to the edges unless the control key is
pressed. However, this will now happen even if the object is rotated or
oriented in any strange way. Snapping will also occur when stretching
or changing the bounding box size.
2014-06-15 00:54:48 -07:00
|
|
|
}
|