Browse Source

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.
jp9000 11 years ago
parent
commit
dcde1dcf2a
2 changed files with 130 additions and 43 deletions
  1. 117 40
      obs/window-basic-main.cpp
  2. 13 3
      obs/window-basic-main.hpp

+ 117 - 40
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<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");
 
-	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<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);
+}
 
-	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<OBSBasic*>(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<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()
 {
 	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);
 		}
 	}

+ 13 - 3
obs/window-basic-main.hpp

@@ -22,11 +22,20 @@
 #include <obs.hpp>
 
 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);