diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index a98cd639503e809a4d718c0284e3076d11ce8ac2..09da6049a54e62a57ff99af3d71febed407f85a4 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -24,58 +24,149 @@ #include "window-basic-settings.hpp" #include "window-basic-main.hpp" #include "window-namedialog.hpp" + 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); 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); - int item = scenes->FindString(name); - if (item != wxNOT_FOUND) { - scenes->Delete(item); - return; + int idx = scenes->FindString(name); + if (idx != wxNOT_FOUND) + scenes->Delete(idx); +} + +void OBSBasic::AddSceneItem(obs_sceneitem_t 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(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(data); + + obs_scene_t scene = (obs_scene_t)calldata_ptr(params, "scene"); + obs_sceneitem_t item = (obs_sceneitem_t)calldata_ptr(params, "item"); - item = sources->FindString(name); - if (item != wxNOT_FOUND) - sources->Delete(item); + if (window->GetCurrentScene() == scene) + window->AddSceneItem(item); } -void OBSBasic::SourceAdded(void *data, calldata_t params) +void OBSBasic::SceneItemRemoved(void *data, calldata_t params) { - OBSBasic *window = (OBSBasic*)data; + OBSBasic *window = static_cast(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); +} - obs_source_t source; - calldata_getptr(params, "source", (void**)&source); +void OBSBasic::SourceAdded(void *data, calldata_t params) +{ + obs_source_t source = (obs_source_t)calldata_ptr(params, "source"); obs_source_type type; obs_source_gettype(source, &type, NULL); if (type == SOURCE_SCENE) - window->SceneAdded(source); + static_cast(data)->AddScene(source); } void OBSBasic::SourceDestroyed(void *data, calldata_t params) { - OBSBasic *window = (OBSBasic*)data; - - obs_source_t source; - calldata_getptr(params, "source", (void**)&source); + obs_source_t source = (obs_source_t)calldata_ptr(params, "source"); obs_source_type type; obs_source_gettype(source, &type, NULL); if (type == SOURCE_SCENE) - window->SceneRemoved(source); + static_cast(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(data)->UpdateSceneSelection(source); +} + +/* Main class functions */ + bool OBSBasic::Init() { if (!obs_startup()) @@ -87,28 +178,12 @@ bool OBSBasic::Init() OBSBasic::SourceAdded, this); signal_handler_connect(obs_signalhandler(), "source-destroy", OBSBasic::SourceDestroyed, this); - - //obs_scene_t scene = obs_scene_create("test scene"); - //obs_add_source(obs_scene_getsource(scene)); + signal_handler_connect(obs_signalhandler(), "channel-change", + OBSBasic::ChannelChanged, this); /* TODO: this is a test */ 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; } @@ -226,8 +301,10 @@ void OBSBasic::scenesClicked(wxCommandEvent &event) if (sel != wxNOT_FOUND) { obs_scene_t scene = (obs_scene_t)scenes->GetClientData(sel); source = obs_scene_getsource(scene); + UpdateSources(scene); } + /* TODO: allow transitions */ obs_set_output_source(0, source); } @@ -316,8 +393,8 @@ void OBSBasic::AddSource(obs_scene_t scene, const char *id) success = true; } else { wxMessageBox(WXStr("MainWindow.NameExists.Text"), - WXStr("MainWindow.NameExists.Title"), - wxOK|wxCENTRE, this); + WXStr("MainWindow.NameExists.Title"), + wxOK|wxCENTRE, this); obs_source_release(source); } } diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index 24696bebc382772992586a12d0d1280b4712d549..ca30694f154f2711d78f72582148a24331a580af 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -22,11 +22,20 @@ #include class OBSBasic : public OBSBasicBase { - void SceneAdded(obs_source_t scene); - void SceneRemoved(obs_source_t scene); - + obs_scene_t GetCurrentScene(); + 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 SourceDestroyed(void *data, calldata_t params); + static void ChannelChanged(void *data, calldata_t params); void ResizePreview(uint32_t cx, uint32_t cy); @@ -40,6 +49,7 @@ class OBSBasic : public OBSBasicBase { void LoadProject(); protected: + /* wxWidgets callbacks */ virtual void OnClose(wxCloseEvent &event); virtual void OnMinimize(wxIconizeEvent &event); virtual void OnSize(wxSizeEvent &event);