Implemented adding sources to scenes via GUI

Sources can now be added to scenes via user interface.  It's a little
convoluted because everything has to work through OBS signals to ensure
that plugins/etc can modify the scenes/sources exernally.

  Also, when switching scenes, it will properly list sources for the
scene you changed to.
master
jp9000 2014-01-04 13:53:36 -07:00
parent 41a73ceeea
commit dcde1dcf2a
2 changed files with 130 additions and 43 deletions

View File

@ -24,58 +24,149 @@
#include "window-basic-settings.hpp" #include "window-basic-settings.hpp"
#include "window-basic-main.hpp" #include "window-basic-main.hpp"
#include "window-namedialog.hpp" #include "window-namedialog.hpp"
using namespace std; using namespace std;
void OBSBasic::SceneAdded(obs_source_t source) obs_scene_t OBSBasic::GetCurrentScene()
{
int sel = scenes->GetSelection();
if (sel == wxNOT_FOUND)
return NULL;
return (obs_scene_t)scenes->GetClientData(sel);
}
void OBSBasic::AddScene(obs_source_t source)
{ {
const char *name = obs_source_getname(source); const char *name = obs_source_getname(source);
obs_scene_t scene = obs_scene_fromsource(source); obs_scene_t scene = obs_scene_fromsource(source);
scenes->Append(wxString(name, wxConvUTF8), scene); scenes->Append(WX_UTF8(name), scene);
signal_handler_t handler = obs_source_signalhandler(source);
signal_handler_connect(handler, "add", OBSBasic::SceneItemAdded,
this);
signal_handler_connect(handler, "remove", OBSBasic::SceneItemRemoved,
this);
} }
void OBSBasic::SceneRemoved(obs_source_t source) void OBSBasic::RemoveScene(obs_source_t source)
{ {
const char *name = obs_source_getname(source); const char *name = obs_source_getname(source);
int item = scenes->FindString(name); int idx = scenes->FindString(name);
if (item != wxNOT_FOUND) { if (idx != wxNOT_FOUND)
scenes->Delete(item); scenes->Delete(idx);
return; }
}
item = sources->FindString(name); void OBSBasic::AddSceneItem(obs_sceneitem_t item)
if (item != wxNOT_FOUND) {
sources->Delete(item); obs_source_t source = obs_sceneitem_getsource(item);
const char *name = obs_source_getname(source);
sources->Insert(WX_UTF8(name), 0, item);
}
void OBSBasic::RemoveSceneItem(obs_sceneitem_t item)
{
obs_source_t source = obs_sceneitem_getsource(item);
const char *name = obs_source_getname(source);
int idx = sources->FindString(WX_UTF8(name));
if (idx != wxNOT_FOUND)
sources->Delete(idx);
}
void OBSBasic::UpdateSources(obs_scene_t scene)
{
sources->Clear();
obs_scene_enum_items(scene,
[] (obs_scene_t scene, obs_sceneitem_t item, void *p)
{
OBSBasic *window = static_cast<OBSBasic*>(p);
window->AddSceneItem(item);
return true;
}, this);
}
void OBSBasic::UpdateSceneSelection(obs_source_t source)
{
if (source) {
obs_source_type type;
obs_source_gettype(source, &type, NULL);
if (type == SOURCE_SCENE) {
obs_scene_t scene = obs_scene_fromsource(source);
const char *name = obs_source_getname(source);
int idx = scenes->FindString(WX_UTF8(name));
int sel = scenes->GetSelection();
if (idx != sel) {
scenes->SetSelection(idx);
UpdateSources(scene);
}
}
} else {
scenes->SetSelection(wxNOT_FOUND);
}
}
/* OBS Callbacks */
void OBSBasic::SceneItemAdded(void *data, calldata_t params)
{
OBSBasic *window = static_cast<OBSBasic*>(data);
obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene");
obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item");
if (window->GetCurrentScene() == scene)
window->AddSceneItem(item);
}
void OBSBasic::SceneItemRemoved(void *data, calldata_t params)
{
OBSBasic *window = static_cast<OBSBasic*>(data);
obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene");
obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item");
if (window->GetCurrentScene() == scene)
window->AddSceneItem(item);
} }
void OBSBasic::SourceAdded(void *data, calldata_t params) void OBSBasic::SourceAdded(void *data, calldata_t params)
{ {
OBSBasic *window = (OBSBasic*)data; obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
obs_source_t source;
calldata_getptr(params, "source", (void**)&source);
obs_source_type type; obs_source_type type;
obs_source_gettype(source, &type, NULL); obs_source_gettype(source, &type, NULL);
if (type == SOURCE_SCENE) if (type == SOURCE_SCENE)
window->SceneAdded(source); static_cast<OBSBasic*>(data)->AddScene(source);
} }
void OBSBasic::SourceDestroyed(void *data, calldata_t params) void OBSBasic::SourceDestroyed(void *data, calldata_t params)
{ {
OBSBasic *window = (OBSBasic*)data; obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
obs_source_t source;
calldata_getptr(params, "source", (void**)&source);
obs_source_type type; obs_source_type type;
obs_source_gettype(source, &type, NULL); obs_source_gettype(source, &type, NULL);
if (type == SOURCE_SCENE) if (type == SOURCE_SCENE)
window->SceneRemoved(source); static_cast<OBSBasic*>(data)->RemoveScene(source);
} }
void OBSBasic::ChannelChanged(void *data, calldata_t params)
{
obs_source_t source = (obs_source_t)calldata_ptr(params, "source");
uint32_t channel = calldata_uint32(params, "channel");
if (channel == 0)
static_cast<OBSBasic*>(data)->UpdateSceneSelection(source);
}
/* Main class functions */
bool OBSBasic::Init() bool OBSBasic::Init()
{ {
if (!obs_startup()) if (!obs_startup())
@ -87,28 +178,12 @@ bool OBSBasic::Init()
OBSBasic::SourceAdded, this); OBSBasic::SourceAdded, this);
signal_handler_connect(obs_signalhandler(), "source-destroy", signal_handler_connect(obs_signalhandler(), "source-destroy",
OBSBasic::SourceDestroyed, this); OBSBasic::SourceDestroyed, this);
signal_handler_connect(obs_signalhandler(), "channel-change",
//obs_scene_t scene = obs_scene_create("test scene"); OBSBasic::ChannelChanged, this);
//obs_add_source(obs_scene_getsource(scene));
/* TODO: this is a test */ /* TODO: this is a test */
obs_load_module("test-input"); obs_load_module("test-input");
obs_source_t test = obs_source_create(SOURCE_INPUT, "random", "test",
NULL);
obs_add_source(test);
obs_set_output_source(0, test);
/*obs_scene_t scene = obs_scene_create("test2");
obs_set_output_source(0, obs_scene_getsource(scene));
obs_sceneitem_t bla = obs_scene_add(scene, test);
struct vec2 ddd = {100.0f, 100.0f};
obs_sceneitem_setscale(bla, &ddd);
obs_scene_release(scene);*/
obs_source_release(test);
return true; return true;
} }
@ -226,8 +301,10 @@ void OBSBasic::scenesClicked(wxCommandEvent &event)
if (sel != wxNOT_FOUND) { if (sel != wxNOT_FOUND) {
obs_scene_t scene = (obs_scene_t)scenes->GetClientData(sel); obs_scene_t scene = (obs_scene_t)scenes->GetClientData(sel);
source = obs_scene_getsource(scene); source = obs_scene_getsource(scene);
UpdateSources(scene);
} }
/* TODO: allow transitions */
obs_set_output_source(0, source); obs_set_output_source(0, source);
} }
@ -316,8 +393,8 @@ void OBSBasic::AddSource(obs_scene_t scene, const char *id)
success = true; success = true;
} else { } else {
wxMessageBox(WXStr("MainWindow.NameExists.Text"), wxMessageBox(WXStr("MainWindow.NameExists.Text"),
WXStr("MainWindow.NameExists.Title"), WXStr("MainWindow.NameExists.Title"),
wxOK|wxCENTRE, this); wxOK|wxCENTRE, this);
obs_source_release(source); obs_source_release(source);
} }
} }

View File

@ -22,11 +22,20 @@
#include <obs.hpp> #include <obs.hpp>
class OBSBasic : public OBSBasicBase { class OBSBasic : public OBSBasicBase {
void SceneAdded(obs_source_t scene); obs_scene_t GetCurrentScene();
void SceneRemoved(obs_source_t scene); void AddSceneItem(obs_sceneitem_t item);
void RemoveSceneItem(obs_sceneitem_t item);
void AddScene(obs_source_t scene);
void RemoveScene(obs_source_t scene);
void UpdateSources(obs_scene_t scene);
void UpdateSceneSelection(obs_source_t source);
/* OBS Callbacks */
static void SceneItemAdded(void *data, calldata_t params);
static void SceneItemRemoved(void *data, calldata_t params);
static void SourceAdded(void *data, calldata_t params); static void SourceAdded(void *data, calldata_t params);
static void SourceDestroyed(void *data, calldata_t params); static void SourceDestroyed(void *data, calldata_t params);
static void ChannelChanged(void *data, calldata_t params);
void ResizePreview(uint32_t cx, uint32_t cy); void ResizePreview(uint32_t cx, uint32_t cy);
@ -40,6 +49,7 @@ class OBSBasic : public OBSBasicBase {
void LoadProject(); void LoadProject();
protected: protected:
/* wxWidgets callbacks */
virtual void OnClose(wxCloseEvent &event); virtual void OnClose(wxCloseEvent &event);
virtual void OnMinimize(wxIconizeEvent &event); virtual void OnMinimize(wxIconizeEvent &event);
virtual void OnSize(wxSizeEvent &event); virtual void OnSize(wxSizeEvent &event);