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/>.
|
|
|
|
******************************************************************************/
|
|
|
|
|
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-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"
|
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-05-15 17:40:53 -07:00
|
|
|
Q_DECLARE_METATYPE(order_movement);
|
2014-02-02 13:26:23 -08:00
|
|
|
|
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
|
|
|
|
|
|
|
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-02-02 14:23:38 -08:00
|
|
|
}
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
static void SaveAudioDevice(const char *name, int channel, obs_data_t parent)
|
|
|
|
{
|
|
|
|
obs_source_t source = obs_get_output_source(channel);
|
|
|
|
if (!source)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs_data_t data = obs_save_source(source);
|
|
|
|
|
|
|
|
obs_data_setobj(parent, name, data);
|
|
|
|
|
|
|
|
obs_data_release(data);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
static obs_data_t GenerateSaveData()
|
|
|
|
{
|
|
|
|
obs_data_t saveData = obs_data_create();
|
|
|
|
obs_data_array_t sourcesArray = obs_save_sources();
|
|
|
|
obs_source_t currentScene = obs_get_output_source(0);
|
|
|
|
const char *sceneName = obs_source_getname(currentScene);
|
|
|
|
|
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-04-26 23:47:50 -07:00
|
|
|
obs_data_setstring(saveData, "current_scene", sceneName);
|
|
|
|
obs_data_setarray(saveData, "sources", sourcesArray);
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
obs_data_t saveData = GenerateSaveData();
|
|
|
|
const char *jsonData = obs_data_getjson(saveData);
|
|
|
|
|
|
|
|
/* 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-05-03 22:54:38 -07:00
|
|
|
static void LoadAudioDevice(const char *name, int channel, obs_data_t parent)
|
|
|
|
{
|
|
|
|
obs_data_t data = obs_data_getobj(parent, name);
|
|
|
|
if (!data)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs_source_t source = obs_load_source(data);
|
|
|
|
if (source) {
|
|
|
|
obs_set_output_source(channel, source);
|
|
|
|
obs_source_release(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
obs_data_release(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::CreateDefaultScene()
|
|
|
|
{
|
2014-05-12 15:30:36 -07:00
|
|
|
obs_scene_t scene = obs_scene_create(Str("Basic.Scene"));
|
2014-05-03 22:54:38 -07:00
|
|
|
obs_source_t source = obs_scene_getsource(scene);
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
obs_set_output_source(0, obs_scene_getsource(scene));
|
|
|
|
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
|
|
|
|
|
|
|
obs_data_t data = obs_data_create_from_json(jsonData);
|
|
|
|
obs_data_array_t sources = obs_data_getarray(data, "sources");
|
|
|
|
const char *sceneName = obs_data_getstring(data, "current_scene");
|
|
|
|
obs_source_t curScene;
|
|
|
|
|
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-03-23 01:07:54 -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;
|
|
|
|
|
|
|
|
obs_property_t devices = obs_properties_get(props, "device_id");
|
|
|
|
if (devices)
|
|
|
|
count = obs_property_list_item_count(devices);
|
|
|
|
|
|
|
|
obs_properties_destroy(props);
|
|
|
|
|
|
|
|
return count != 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
|
|
|
static void OBSStartStreaming(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
UNUSED_PARAMETER(params);
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"StreamingStart");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void OBSStopStreaming(void *data, calldata_t params)
|
|
|
|
{
|
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-05-20 23:27:27 -07:00
|
|
|
static void OBSStopRecording(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
BPtr<char> serviceJsonPath(os_get_config_path(SERVICE_PATH));
|
|
|
|
if (!serviceJsonPath)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs_data_t data = obs_data_create();
|
|
|
|
obs_data_t settings = obs_service_get_settings(service);
|
|
|
|
|
|
|
|
obs_data_setstring(data, "type", obs_service_gettype(service));
|
|
|
|
obs_data_setobj(data, "settings", settings);
|
|
|
|
|
|
|
|
const char *json = obs_data_getjson(data);
|
|
|
|
|
|
|
|
os_quick_write_utf8_file(serviceJsonPath, json, strlen(json), false);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
obs_data_release(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::LoadService()
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
|
|
|
|
BPtr<char> serviceJsonPath(os_get_config_path(SERVICE_PATH));
|
|
|
|
if (!serviceJsonPath)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
BPtr<char> jsonText = os_quick_read_utf8_file(serviceJsonPath);
|
|
|
|
if (!jsonText)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
obs_data_t data = obs_data_create_from_json(jsonText);
|
|
|
|
|
|
|
|
obs_data_set_default_string(data, "type", "rtmp_common");
|
|
|
|
type = obs_data_getstring(data, "type");
|
|
|
|
|
|
|
|
obs_data_t settings = obs_data_getobj(data, "settings");
|
|
|
|
|
|
|
|
service = obs_service_create(type, "default", settings);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
obs_data_release(data);
|
|
|
|
|
|
|
|
return !!service;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasic::InitOutputs()
|
|
|
|
{
|
2014-05-20 23:27:27 -07:00
|
|
|
fileOutput = obs_output_create("flv_output", "default", nullptr);
|
|
|
|
if (!fileOutput)
|
|
|
|
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
|
|
|
streamOutput = obs_output_create("rtmp_output", "default", nullptr);
|
|
|
|
if (!streamOutput)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
signal_handler_connect(obs_output_signalhandler(streamOutput),
|
|
|
|
"start", OBSStartStreaming, this);
|
|
|
|
signal_handler_connect(obs_output_signalhandler(streamOutput),
|
|
|
|
"stop", OBSStopStreaming, this);
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
signal_handler_connect(obs_output_signalhandler(fileOutput),
|
|
|
|
"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()
|
|
|
|
{
|
|
|
|
x264 = obs_video_encoder_create("obs_x264", "h264", nullptr);
|
|
|
|
if (!x264)
|
|
|
|
return false;
|
|
|
|
|
2014-05-22 03:07:17 -07:00
|
|
|
aac = obs_audio_encoder_create("libfdk_aac", "aac", nullptr);
|
|
|
|
|
|
|
|
if(!aac)
|
|
|
|
aac = obs_audio_encoder_create("ffmpeg_aac", "aac", nullptr);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
service = obs_service_create("rtmp_common", nullptr, nullptr);
|
|
|
|
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-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);
|
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
BPtr<char> configPath(os_get_config_path("obs-studio/basic/basic.ini"));
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
signal_handler_connect(obs_signalhandler(), "source_add",
|
|
|
|
OBSBasic::SourceAdded, this);
|
|
|
|
signal_handler_connect(obs_signalhandler(), "source_remove",
|
|
|
|
OBSBasic::SourceRemoved, this);
|
|
|
|
signal_handler_connect(obs_signalhandler(), "channel_change",
|
|
|
|
OBSBasic::ChannelChanged, this);
|
|
|
|
signal_handler_connect(obs_signalhandler(), "source_activate",
|
|
|
|
OBSBasic::SourceActivated, this);
|
|
|
|
signal_handler_connect(obs_signalhandler(), "source_deactivate",
|
|
|
|
OBSBasic::SourceDeactivated, this);
|
2014-06-30 00:06:01 -07:00
|
|
|
signal_handler_connect(obs_signalhandler(), "source_rename",
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
gs_entercontext(obs_graphics());
|
|
|
|
|
|
|
|
gs_renderstart(true);
|
|
|
|
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);
|
|
|
|
box = gs_rendersave();
|
|
|
|
|
|
|
|
gs_renderstart(true);
|
|
|
|
for (int i = 0; i <= 360; i += (360/20)) {
|
|
|
|
float pos = RAD(float(i));
|
|
|
|
gs_vertex2f(cosf(pos), sinf(pos));
|
|
|
|
}
|
|
|
|
circle = gs_rendersave();
|
|
|
|
|
|
|
|
gs_leavecontext();
|
|
|
|
}
|
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
void OBSBasic::OBSInit()
|
|
|
|
{
|
2014-05-03 22:54:38 -07:00
|
|
|
BPtr<char> savePath(os_get_config_path("obs-studio/basic/scenes.json"));
|
|
|
|
|
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 (!ResetVideo())
|
|
|
|
throw "Failed to initialize video";
|
|
|
|
if (!ResetAudio())
|
2014-02-02 14:23:38 -08:00
|
|
|
throw "Failed to initialize audio";
|
|
|
|
|
2014-05-03 22:54:38 -07:00
|
|
|
InitOBSCallbacks();
|
2014-02-02 14:23:38 -08:00
|
|
|
|
2014-03-04 06:07:13 -08:00
|
|
|
/* TODO: this is a test, all modules will be searched for and loaded
|
|
|
|
* automatically later */
|
2014-06-27 15:39:12 -07:00
|
|
|
obs_load_module("image-source");
|
2014-07-12 12:05:36 -07:00
|
|
|
// obs_load_module("test-input");
|
2014-02-09 04:51:06 -08:00
|
|
|
obs_load_module("obs-ffmpeg");
|
2014-05-22 03:07:17 -07:00
|
|
|
obs_load_module("obs-libfdk");
|
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_load_module("obs-x264");
|
|
|
|
obs_load_module("obs-outputs");
|
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_load_module("rtmp-services");
|
2014-02-26 22:43:31 -08:00
|
|
|
#ifdef __APPLE__
|
2014-04-28 14:58:08 -07:00
|
|
|
obs_load_module("mac-avcapture");
|
2014-02-26 22:43:31 -08:00
|
|
|
obs_load_module("mac-capture");
|
2014-03-04 06:07:13 -08:00
|
|
|
#elif _WIN32
|
|
|
|
obs_load_module("win-wasapi");
|
2014-03-05 09:43:14 -08:00
|
|
|
obs_load_module("win-capture");
|
2014-05-30 03:31:49 -07:00
|
|
|
obs_load_module("win-dshow");
|
2014-03-10 15:02:37 -07:00
|
|
|
#else
|
|
|
|
obs_load_module("linux-xshm");
|
2014-04-28 17:59:53 -07:00
|
|
|
obs_load_module("linux-xcomposite");
|
2014-03-10 15:02:37 -07:00
|
|
|
obs_load_module("linux-pulseaudio");
|
2014-03-11 11:33:04 -07:00
|
|
|
obs_load_module("linux-v4l2");
|
2014-02-26 22:43:31 -08:00
|
|
|
#endif
|
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
|
|
|
|
|
|
|
loaded = true;
|
2014-02-02 14:23:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
OBSBasic::~OBSBasic()
|
|
|
|
{
|
2014-04-26 23:47:50 -07:00
|
|
|
BPtr<char> savePath(os_get_config_path("obs-studio/basic/scenes.json"));
|
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
|
|
|
SaveService();
|
2014-04-26 23:47:50 -07:00
|
|
|
Save(savePath);
|
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-07-06 16:14:04 -07:00
|
|
|
delete properties;
|
|
|
|
delete transformWindow;
|
2014-03-23 01:07:54 -07:00
|
|
|
|
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
|
|
|
|
|
|
|
gs_entercontext(obs_graphics());
|
|
|
|
vertexbuffer_destroy(box);
|
|
|
|
vertexbuffer_destroy(circle);
|
|
|
|
gs_leavecontext();
|
|
|
|
|
2014-02-02 14:23:38 -08:00
|
|
|
obs_shutdown();
|
|
|
|
}
|
|
|
|
|
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-02-02 13:26:23 -08:00
|
|
|
OBSSceneItem OBSBasic::GetCurrentSceneItem()
|
2014-01-30 00:31:52 -08:00
|
|
|
{
|
|
|
|
QListWidgetItem *item = ui->sources->currentItem();
|
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-02-02 16:03:55 -08:00
|
|
|
void OBSBasic::UpdateSources(OBSScene scene)
|
|
|
|
{
|
|
|
|
ui->sources->clear();
|
|
|
|
|
|
|
|
obs_scene_enum_items(scene,
|
|
|
|
[] (obs_scene_t scene, obs_sceneitem_t item, void *p)
|
|
|
|
{
|
|
|
|
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-03-01 04:54:55 -08:00
|
|
|
void OBSBasic::InsertSceneItem(obs_sceneitem_t item)
|
|
|
|
{
|
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
const char *name = obs_source_getname(source);
|
|
|
|
|
|
|
|
QListWidgetItem *listItem = new QListWidgetItem(QT_UTF8(name));
|
2014-06-30 00:06:01 -07:00
|
|
|
listItem->setFlags(listItem->flags() | Qt::ItemIsEditable);
|
2014-03-01 04:54:55 -08:00
|
|
|
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 */
|
|
|
|
if (sourceSceneRefs[source] == 0 && loaded) {
|
|
|
|
delete properties;
|
|
|
|
properties = new OBSBasicProperties(this, source);
|
|
|
|
properties->Init();
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
const char *name = obs_source_getname(source);
|
|
|
|
obs_scene_t scene = obs_scene_fromsource(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-06-30 00:06:01 -07:00
|
|
|
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
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
|
|
|
|
|
|
|
signal_handler_t handler = obs_source_signalhandler(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-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
|
|
|
{
|
|
|
|
const char *name = obs_source_getname(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 *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-02-02 13:26:23 -08:00
|
|
|
obs_scene_t scene = obs_sceneitem_getscene(item);
|
2014-01-04 12:53:36 -08:00
|
|
|
obs_source_t source = obs_sceneitem_getsource(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-01-06 19:20:18 -08:00
|
|
|
obs_scene_t scene = obs_sceneitem_getscene(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
|
|
|
|
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
|
|
|
|
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) {
|
|
|
|
obs_source_type type;
|
|
|
|
obs_source_gettype(source, &type, 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
|
|
|
obs_scene_t scene = obs_scene_fromsource(source);
|
|
|
|
const char *name = obs_source_getname(source);
|
|
|
|
|
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-05-15 17:40:53 -07:00
|
|
|
void OBSBasic::MoveSceneItem(OBSSceneItem item, order_movement movement)
|
|
|
|
{
|
|
|
|
OBSScene scene = obs_sceneitem_getscene(item);
|
|
|
|
if (scene != GetCurrentScene())
|
|
|
|
return;
|
|
|
|
|
|
|
|
int curRow = ui->sources->currentRow();
|
|
|
|
if (curRow == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QListWidgetItem *listItem = ui->sources->takeItem(curRow);
|
|
|
|
|
|
|
|
switch (movement) {
|
|
|
|
case ORDER_MOVE_UP:
|
|
|
|
if (curRow > 0)
|
|
|
|
curRow--;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ORDER_MOVE_DOWN:
|
|
|
|
if (curRow < ui->sources->count())
|
|
|
|
curRow++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ORDER_MOVE_TOP:
|
|
|
|
curRow = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ORDER_MOVE_BOTTOM:
|
|
|
|
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-06-30 13:45:58 -07:00
|
|
|
bool OBSBasic::QueryRemoveSource(obs_source_t source)
|
2014-06-30 01:13:32 -07:00
|
|
|
{
|
2014-06-30 13:45:58 -07:00
|
|
|
const char *name = obs_source_getname(source);
|
|
|
|
|
|
|
|
QString text = QTStr("ConfirmRemove.Text");
|
|
|
|
text.replace("$1", QT_UTF8(name));
|
2014-06-30 01:13:32 -07:00
|
|
|
|
2014-06-30 13:45:58 -07:00
|
|
|
QMessageBox::StandardButton button;
|
|
|
|
button = QMessageBox::question(this,
|
|
|
|
QTStr("ConfirmRemove.Remove"), text);
|
2014-06-30 01:13:32 -07:00
|
|
|
|
2014-06-30 13:45:58 -07:00
|
|
|
return button == QMessageBox::Yes;
|
|
|
|
}
|
2014-06-30 01:13:32 -07:00
|
|
|
|
2014-06-30 13:45:58 -07:00
|
|
|
void OBSBasic::RemoveSelectedScene()
|
|
|
|
{
|
|
|
|
OBSScene scene = GetCurrentScene();
|
|
|
|
if (scene) {
|
|
|
|
obs_source_t source = obs_scene_getsource(scene);
|
|
|
|
if (QueryRemoveSource(source))
|
|
|
|
obs_source_remove(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::RemoveSelectedSceneItem()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
if (item) {
|
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
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 */
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemAdded(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
|
|
|
|
|
|
|
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-01-04 12:53:36 -08: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-01-04 12:53:36 -08:00
|
|
|
obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item");
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SourceAdded(void *data, calldata_t params)
|
|
|
|
{
|
2014-05-10 18:47:48 -07:00
|
|
|
OBSBasic *window = static_cast<OBSBasic*>(data);
|
2014-01-04 12:53:36 -08:00
|
|
|
obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
|
2013-12-28 04:33:16 -08:00
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
if (obs_scene_fromsource(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)));
|
2014-05-10 18:47:48 -07:00
|
|
|
else
|
|
|
|
window->sourceSceneRefs[source] = 0;
|
2013-12-28 04:33:16 -08:00
|
|
|
}
|
|
|
|
|
2014-02-02 13:26:23 -08:00
|
|
|
void OBSBasic::SourceRemoved(void *data, calldata_t params)
|
2013-12-28 04:33:16 -08:00
|
|
|
{
|
2014-01-04 12:53:36 -08:00
|
|
|
obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
|
2013-12-28 04:33:16 -08:00
|
|
|
|
2014-04-26 23:47:50 -07:00
|
|
|
if (obs_scene_fromsource(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-05-03 22:54:38 -07:00
|
|
|
void OBSBasic::SourceActivated(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
|
|
|
|
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)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SourceDeactivated(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
|
|
|
|
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-06-30 00:06:01 -07:00
|
|
|
void OBSBasic::SourceRenamed(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
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-01-04 12:53:36 -08:00
|
|
|
void OBSBasic::ChannelChanged(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
effect_t solid = obs_get_solid_effect();
|
|
|
|
eparam_t color = effect_getparambyname(solid, "color");
|
|
|
|
technique_t tech = effect_gettechnique(solid, "Solid");
|
|
|
|
|
|
|
|
vec4 colorVal;
|
|
|
|
vec4_set(&colorVal, 0.0f, 0.0f, 0.0f, 1.0f);
|
2014-06-25 20:29:46 -07:00
|
|
|
effect_setvec4(color, &colorVal);
|
2014-06-15 19:48:02 -07:00
|
|
|
|
|
|
|
technique_begin(tech);
|
|
|
|
technique_beginpass(tech, 0);
|
|
|
|
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();
|
|
|
|
technique_endpass(tech);
|
|
|
|
technique_end(tech);
|
|
|
|
|
|
|
|
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);
|
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_setviewport(window->previewX, window->previewY,
|
|
|
|
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
|
|
|
/* --------------------------------------- */
|
|
|
|
|
|
|
|
float right = float(window->ui->preview->width()) - window->previewX;
|
|
|
|
float bottom = float(window->ui->preview->height()) - window->previewY;
|
|
|
|
|
|
|
|
gs_ortho(-window->previewX, right,
|
|
|
|
-window->previewY, bottom,
|
|
|
|
-100.0f, 100.0f);
|
|
|
|
gs_resetviewport();
|
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-05-15 17:40:53 -07:00
|
|
|
void OBSBasic::SceneItemMoveUp(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item");
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
|
|
|
Q_ARG(order_movement, ORDER_MOVE_UP));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemMoveDown(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item");
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
|
|
|
Q_ARG(order_movement, ORDER_MOVE_DOWN));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemMoveTop(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item");
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
|
|
|
Q_ARG(order_movement, ORDER_MOVE_TOP));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SceneItemMoveBottom(void *data, calldata_t params)
|
|
|
|
{
|
|
|
|
OBSSceneItem item = (obs_sceneitem_t)calldata_ptr(params, "item");
|
|
|
|
QMetaObject::invokeMethod(static_cast<OBSBasic*>(data),
|
|
|
|
"MoveSceneItem",
|
|
|
|
Q_ARG(OBSSceneItem, OBSSceneItem(item)),
|
|
|
|
Q_ARG(order_movement, ORDER_MOVE_BOTTOM));
|
|
|
|
}
|
|
|
|
|
2014-01-04 12:53:36 -08:00
|
|
|
/* Main class functions */
|
|
|
|
|
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_service_t OBSBasic::GetService()
|
|
|
|
{
|
|
|
|
if (!service)
|
|
|
|
service = obs_service_create("rtmp_common", NULL, NULL);
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::SetService(obs_service_t newService)
|
|
|
|
{
|
|
|
|
if (newService) {
|
|
|
|
if (service)
|
|
|
|
obs_service_destroy(service);
|
|
|
|
service = newService;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
bool OBSBasic::ResetVideo()
|
2013-12-22 22:40:07 -08:00
|
|
|
{
|
|
|
|
struct obs_video_info ovi;
|
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
|
|
|
|
|
|
|
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");
|
2014-04-04 11:54:32 -07:00
|
|
|
ovi.output_format = VIDEO_FORMAT_NV12;
|
2014-02-16 18:28:21 -08:00
|
|
|
ovi.adapter = 0;
|
|
|
|
ovi.gpu_conversion = true;
|
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-02-22 19:14:19 -08:00
|
|
|
if (!obs_reset_video(&ovi))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
obs_add_draw_callback(OBSBasic::RenderMain, this);
|
|
|
|
return true;
|
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);
|
|
|
|
obs_source_t source;
|
|
|
|
obs_data_t settings;
|
|
|
|
bool same = false;
|
|
|
|
|
|
|
|
source = obs_get_output_source(channel);
|
|
|
|
if (source) {
|
|
|
|
settings = obs_source_getsettings(source);
|
|
|
|
const char *curId = obs_data_getstring(settings, "device_id");
|
|
|
|
|
|
|
|
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) {
|
|
|
|
obs_data_t settings = obs_data_create();
|
|
|
|
obs_data_setstring(settings, "device_id", deviceId);
|
|
|
|
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;
|
|
|
|
|
|
|
|
// 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-04-15 05:19:59 -07:00
|
|
|
void OBSBasic::on_action_Settings_triggered()
|
|
|
|
{
|
|
|
|
OBSBasicSettings settings(this);
|
|
|
|
settings.exec();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
|
|
|
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) {
|
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
|
|
|
obs_scene_t scene;
|
|
|
|
|
2014-02-20 21:04:14 -08:00
|
|
|
scene = current->data(Qt::UserRole).value<OBSScene>();
|
2013-12-30 00:17:57 -08:00
|
|
|
source = obs_scene_getsource(scene);
|
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
ui->scenes->editItem(ui->scenes->currentItem());
|
|
|
|
}
|
|
|
|
|
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()));
|
|
|
|
|
|
|
|
if (item)
|
|
|
|
popup.addAction(QTStr("Remove"),
|
|
|
|
this, SLOT(RemoveSelectedScene()));
|
|
|
|
|
|
|
|
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-05-14 13:20:08 -07:00
|
|
|
obs_source_t source = nullptr;
|
|
|
|
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-05-12 15:30:36 -07:00
|
|
|
QTStr("NoNameEntered"),
|
|
|
|
QTStr("NoNameEntered"));
|
2014-03-10 13:39:51 -07:00
|
|
|
on_actionAddScene_triggered();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-29 08:17:00 -08:00
|
|
|
obs_source_t source = obs_get_source_by_name(name.c_str());
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-12-29 07:54:06 -08:00
|
|
|
obs_scene_t scene = obs_scene_create(name.c_str());
|
2014-01-05 20:38:28 -08:00
|
|
|
source = obs_scene_getsource(scene);
|
|
|
|
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();
|
2013-12-29 19:01:19 -08:00
|
|
|
obs_source_t source = obs_scene_getsource(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
|
|
|
{
|
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
|
|
|
auto select_one = [] (obs_scene_t scene, obs_sceneitem_t item,
|
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
obs_sceneitem_t selectedItem =
|
|
|
|
*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-07-04 10:58:03 -07:00
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
ui->sources->editItem(ui->sources->currentItem());
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
popup.addAction(QTStr("Rename"), this,
|
|
|
|
SLOT(EditSceneItemName()));
|
2014-06-30 18:21:40 -07:00
|
|
|
popup.addAction(QTStr("Remove"), this,
|
|
|
|
SLOT(on_actionRemoveSource_triggered()),
|
|
|
|
QKeySequence::Delete);
|
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();
|
|
|
|
popup.addAction(QTStr("Properties"), this,
|
|
|
|
SLOT(on_actionSourceProperties_triggered()));
|
|
|
|
}
|
|
|
|
|
|
|
|
popup.exec(QCursor::pos());
|
2013-11-07 15:45:03 -08:00
|
|
|
}
|
|
|
|
|
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)) {
|
Revamp API and start using doxygen
The API used to be designed in such a way to where it would expect
exports for each individual source/output/encoder/etc. You would export
functions for each and it would automatically load those functions based
on a specific naming scheme from the module.
The idea behind this was that I wanted to limit the usage of structures
in the API so only functions could be used. It was an interesting idea
in theory, but this idea turned out to be flawed in a number of ways:
1.) Requiring exports to create sources/outputs/encoders/etc meant that
you could not create them by any other means, which meant that
things like faruton's .net plugin would become difficult.
2.) Export function declarations could not be checked, therefore if you
created a function with the wrong parameters and parameter types,
the compiler wouldn't know how to check for that.
3.) Required overly complex load functions in libobs just to handle it.
It makes much more sense to just have a load function that you call
manually. Complexity is the bane of all good programs.
4.) It required that you have functions of specific names, which looked
and felt somewhat unsightly.
So, to fix these issues, I replaced it with a more commonly used API
scheme, seen commonly in places like kernels and typical C libraries
with abstraction. You simply create a structure that contains the
callback definitions, and you pass it to a function to register that
definition (such as obs_register_source), which you call in the
obs_module_load of the module.
It will also automatically check the structure size and ensure that it
only loads the required values if the structure happened to add new
values in an API change.
The "main" source file for each module must include obs-module.h, and
must use OBS_DECLARE_MODULE() within that source file.
Also, started writing some doxygen documentation in to the main library
headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
|
|
|
const char *name = obs_source_getdisplayname(
|
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();
|
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
|
|
|
|
if (source && QueryRemoveSource(source))
|
2014-01-30 00:31:52 -08:00
|
|
|
obs_sceneitem_remove(item);
|
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_actionSourceProperties_triggered()
|
2013-11-07 15:45:03 -08:00
|
|
|
{
|
2014-03-23 01:07:54 -07:00
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
OBSSource source = obs_sceneitem_getsource(item);
|
|
|
|
|
|
|
|
if (source) {
|
|
|
|
delete properties;
|
|
|
|
properties = new OBSBasicProperties(this, source);
|
|
|
|
properties->Init();
|
|
|
|
}
|
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();
|
|
|
|
obs_sceneitem_setorder(item, 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();
|
|
|
|
obs_sceneitem_setorder(item, 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();
|
|
|
|
obs_sceneitem_setorder(item, ORDER_MOVE_UP);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveDown_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
obs_sceneitem_setorder(item, ORDER_MOVE_DOWN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveToTop_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
obs_sceneitem_setorder(item, ORDER_MOVE_TOP);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionMoveToBottom_triggered()
|
|
|
|
{
|
|
|
|
OBSSceneItem item = GetCurrentSceneItem();
|
|
|
|
obs_sceneitem_setorder(item, ORDER_MOVE_BOTTOM);
|
|
|
|
}
|
|
|
|
|
2014-05-18 17:44:10 -07:00
|
|
|
static char *ReadLogFile(const char *log)
|
|
|
|
{
|
|
|
|
BPtr<char> logDir(os_get_config_path("obs-studio/logs"));
|
|
|
|
|
|
|
|
string path = (char*)logDir;
|
|
|
|
path += "/";
|
|
|
|
path += log;
|
|
|
|
|
|
|
|
char *file = os_quick_read_utf8_file(path.c_str());
|
|
|
|
if (!file)
|
|
|
|
blog(LOG_WARNING, "Failed to read log file %s", path.c_str());
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::UploadLog(const char *file)
|
|
|
|
{
|
|
|
|
dstr fileString = {};
|
|
|
|
stringstream ss;
|
|
|
|
string jsonData;
|
|
|
|
|
|
|
|
dstr_move_array(&fileString, ReadLogFile(file));
|
|
|
|
|
|
|
|
if (!fileString.array)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!*fileString.array) {
|
|
|
|
dstr_free(&fileString);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->menuLogFiles->setEnabled(false);
|
|
|
|
|
|
|
|
dstr_replace(&fileString, "\\", "\\\\");
|
|
|
|
dstr_replace(&fileString, "\"", "\\\"");
|
|
|
|
dstr_replace(&fileString, "\n", "\\n");
|
|
|
|
dstr_replace(&fileString, "\r", "\\r");
|
|
|
|
dstr_replace(&fileString, "\t", "\\t");
|
|
|
|
dstr_replace(&fileString, "\t", "\\t");
|
|
|
|
dstr_replace(&fileString, "/", "\\/");
|
|
|
|
|
|
|
|
ss << "{ \"public\": false, \"description\": \"OBS " <<
|
|
|
|
App()->GetVersionString() << " log file uploaded at " <<
|
|
|
|
CurrentDateTimeString() << "\", \"files\": { \"" <<
|
|
|
|
file << "\": { \"content\": \"" <<
|
|
|
|
fileString.array << "\" } } }";
|
|
|
|
|
|
|
|
jsonData = std::move(ss.str());
|
|
|
|
|
2014-05-22 03:59:51 -07:00
|
|
|
logUploadPostData.setData(jsonData.c_str(), (int)jsonData.size());
|
2014-05-18 17:44:10 -07:00
|
|
|
|
|
|
|
QUrl url("https://api.github.com/gists");
|
|
|
|
logUploadReply = networkManager.post(QNetworkRequest(url),
|
|
|
|
&logUploadPostData);
|
|
|
|
connect(logUploadReply, SIGNAL(finished()),
|
|
|
|
this, SLOT(logUploadFinished()));
|
|
|
|
connect(logUploadReply, SIGNAL(readyRead()),
|
|
|
|
this, SLOT(logUploadRead()));
|
|
|
|
|
|
|
|
dstr_free(&fileString);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionUploadCurrentLog_triggered()
|
|
|
|
{
|
|
|
|
UploadLog(App()->GetCurrentLog());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionUploadLastLog_triggered()
|
|
|
|
{
|
|
|
|
UploadLog(App()->GetLastLog());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::logUploadRead()
|
|
|
|
{
|
|
|
|
logUploadReturnData.push_back(logUploadReply->readAll());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::logUploadFinished()
|
|
|
|
{
|
|
|
|
ui->menuLogFiles->setEnabled(true);
|
|
|
|
|
|
|
|
if (logUploadReply->error()) {
|
|
|
|
QMessageBox::information(this,
|
|
|
|
QTStr("LogReturnDialog.ErrorUploadingLog"),
|
|
|
|
logUploadReply->errorString());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *jsonReply = logUploadReturnData.constData();
|
|
|
|
if (!jsonReply || !*jsonReply)
|
|
|
|
return;
|
|
|
|
|
|
|
|
obs_data_t returnData = obs_data_create_from_json(jsonReply);
|
|
|
|
QString logURL = obs_data_getstring(returnData, "html_url");
|
|
|
|
obs_data_release(returnData);
|
|
|
|
|
|
|
|
OBSLogReply logDialog(this, logURL);
|
|
|
|
logDialog.exec();
|
|
|
|
}
|
|
|
|
|
2014-06-30 01:05:33 -07:00
|
|
|
static void RenameListItem(QListWidget *listWidget, obs_source_t source,
|
|
|
|
const string &name)
|
|
|
|
{
|
|
|
|
const char *prevName = obs_source_getname(source);
|
|
|
|
obs_source_t foundSource = obs_get_source_by_name(name.c_str());
|
|
|
|
QListWidgetItem *listItem = listWidget->currentItem();
|
|
|
|
|
|
|
|
if (foundSource || name.compare(prevName) == 0 || name.empty()) {
|
|
|
|
listItem->setText(QT_UTF8(prevName));
|
|
|
|
obs_source_release(foundSource);
|
|
|
|
} else {
|
|
|
|
listItem->setText(QT_UTF8(name.c_str()));
|
|
|
|
obs_source_setname(source, name.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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-06-30 01:05:33 -07:00
|
|
|
obs_source_t source = obs_scene_getsource(scene);
|
|
|
|
RenameListItem(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-06-30 01:05:33 -07:00
|
|
|
obs_source_t source = obs_sceneitem_getsource(item);
|
|
|
|
RenameListItem(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-05-20 23:27:27 -07:00
|
|
|
void OBSBasic::RecordingStop()
|
2014-03-10 13:10:35 -07:00
|
|
|
{
|
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) {
|
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_t x264Settings = obs_data_create();
|
|
|
|
obs_data_t aacSettings = obs_data_create();
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
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_setint(x264Settings, "bitrate", videoBitrate);
|
2014-07-13 02:59:34 -07:00
|
|
|
obs_data_setint(x264Settings, "buffer_size", videoBitrate);
|
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_setbool(x264Settings, "cbr", true);
|
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_data_setint(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
|
|
|
|
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_set_video(x264, obs_video());
|
|
|
|
obs_encoder_set_audio(aac, obs_audio());
|
2014-05-20 23:27:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_streamButton_clicked()
|
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
if (obs_output_active(fileOutput)) {
|
|
|
|
obs_output_stop(fileOutput);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
const char *path = config_get_string(basicConfig,
|
|
|
|
"SimpleOutput", "FilePath");
|
|
|
|
|
|
|
|
os_dir_t dir = path ? os_opendir(path) : nullptr;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
obs_data_t settings = obs_data_create();
|
|
|
|
obs_data_setstring(settings, "path", strPath.c_str());
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
config_t OBSBasic::Config() const
|
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
delete transformWindow;
|
|
|
|
transformWindow = new OBSBasicTransform(this);
|
|
|
|
transformWindow->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasic::on_actionResetTransform_triggered()
|
|
|
|
{
|
|
|
|
auto func = [] (obs_scene_t scene, obs_sceneitem_t item, void *param)
|
|
|
|
{
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
obs_sceneitem_info info;
|
|
|
|
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-06-22 23:49:57 -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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static vec3 GetItemTL(obs_sceneitem_t item)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void SetItemTL(obs_sceneitem_t item, const vec3 &tl)
|
|
|
|
{
|
|
|
|
vec3 newTL;
|
|
|
|
vec2 pos;
|
|
|
|
|
|
|
|
obs_sceneitem_getpos(item, &pos);
|
|
|
|
newTL = GetItemTL(item);
|
|
|
|
pos.x += tl.x - newTL.x;
|
|
|
|
pos.y += tl.y - newTL.y;
|
|
|
|
obs_sceneitem_setpos(item, &pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool RotateSelectedSources(obs_scene_t scene, obs_sceneitem_t item,
|
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
float rot = *reinterpret_cast<float*>(param);
|
|
|
|
|
|
|
|
vec3 tl = GetItemTL(item);
|
|
|
|
|
|
|
|
rot += obs_sceneitem_getrot(item);
|
|
|
|
if (rot >= 360.0f) rot -= 360.0f;
|
|
|
|
else if (rot <= -360.0f) rot += 360.0f;
|
|
|
|
obs_sceneitem_setrot(item, rot);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool MultiplySelectedItemScale(obs_scene_t scene, obs_sceneitem_t item,
|
|
|
|
void *param)
|
|
|
|
{
|
|
|
|
vec2 &mul = *reinterpret_cast<vec2*>(param);
|
|
|
|
|
|
|
|
if (!obs_sceneitem_selected(item))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
vec3 tl = GetItemTL(item);
|
|
|
|
|
|
|
|
vec2 scale;
|
|
|
|
obs_sceneitem_getscale(item, &scale);
|
|
|
|
vec2_mul(&scale, &scale, &mul);
|
|
|
|
obs_sceneitem_setscale(item, &scale);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool CenterAlignSelectedItems(obs_scene_t scene, obs_sceneitem_t item,
|
|
|
|
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);
|
|
|
|
|
|
|
|
obs_sceneitem_info itemInfo;
|
|
|
|
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-06-22 23:49:57 -07:00
|
|
|
auto func = [] (obs_scene_t scene, obs_sceneitem_t item, void *param)
|
|
|
|
{
|
|
|
|
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
|
|
|
}
|