diff --git a/build/data/obs-studio/locale/en.txt b/build/data/obs-studio/locale/en.txt index 80070546eb03dbd7f11dd54c3360a5e34e146df1..f229bb2a34e14298e9d0a273b317b0d4e139ca1f 100644 --- a/build/data/obs-studio/locale/en.txt +++ b/build/data/obs-studio/locale/en.txt @@ -12,6 +12,9 @@ MainMenu.FIle.Save="Save" MainWindow.AddSceneDlg.Title="Add Scene" MainWindow.AddSceneDlg.Text="Please enter the name of the scene" +MainWindow.AddSourceDlg.Title="Add Source" +MainWindow.AddSourceDlg.Text="Please enter the name of the source" + MainWindow.NameExists.Title="Name already exists" MainWindow.NameExists.Text="The name is already in use by another source." diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 3c5cfaa309da7ac8f955cf907d6974f198b0ceb0..236d2b1062d734c7282371ff1eb30625994697df 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -147,13 +147,13 @@ int obs_load_module(const char *path) mod.name = bstrdup(path); module_load_exports(&mod, &obs->input_types.da, "inputs", - sizeof(struct source_info), get_source_info); + sizeof(struct source_info), load_source_info); module_load_exports(&mod, &obs->filter_types.da, "filters", - sizeof(struct source_info), get_source_info); + sizeof(struct source_info), load_source_info); module_load_exports(&mod, &obs->transition_types.da, "transitions", - sizeof(struct source_info), get_source_info); + sizeof(struct source_info), load_source_info); module_load_exports(&mod, &obs->output_types.da, "outputs", - sizeof(struct output_info), get_output_info); + sizeof(struct output_info), load_output_info); da_push_back(obs->modules, &mod); return MODULE_SUCCESS; diff --git a/libobs/obs-output.c b/libobs/obs-output.c index bf5478cfa5a2c26a0a52d63e5b422f689d644940..f6520d1582285c73c34bd5584a3ed77f592c920f 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -18,7 +18,7 @@ #include "obs.h" #include "obs-data.h" -bool get_output_info(void *module, const char *module_name, +bool load_output_info(void *module, const char *module_name, const char *output_id, struct output_info *info) { info->getname = load_module_subfunc(module, module_name, diff --git a/libobs/obs-output.h b/libobs/obs-output.h index bdc126e939f96d7c83c2457b4516bb69f71bbf45..a4054ca839b21b742bd2ca02cf47e3d6b8549b6f 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -119,5 +119,5 @@ struct obs_output { struct dstr settings; }; -extern bool get_output_info(void *module, const char *module_name, +extern bool load_output_info(void *module, const char *module_name, const char *output_name, struct output_info *info); diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index b3b2b9e6055de445ed1c278851a0dff13ae7a53d..5386ab5d2ae6409ed801d5f9225e3579eba9c86d 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -119,10 +119,16 @@ obs_scene_t obs_scene_create(const char *name) return scene; } -void obs_scene_release(obs_scene_t scene) +int obs_scene_addref(obs_scene_t scene) +{ + return obs_source_addref(scene->source); +} + +int obs_scene_release(obs_scene_t scene) { if (scene) - obs_source_release(scene->source); + return obs_source_release(scene->source); + return 0; } obs_source_t obs_scene_getsource(obs_scene_t scene) @@ -154,15 +160,23 @@ obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source) return item; } -void obs_sceneitem_destroy(obs_sceneitem_t item) +int obs_sceneitem_destroy(obs_sceneitem_t item) { + int ref = 0; if (item) { if (item->source) - obs_source_release(item->source); + ref = obs_source_release(item->source); da_erase_item(item->parent->items, item); bfree(item); } + + return ref; +} + +obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item) +{ + return item->source; } void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos) diff --git a/libobs/obs-source.c b/libobs/obs-source.c index b3b750452e248c00a242328c15c6064aea46b8c6..cee2c200c89e3627e3fe9caa6b1fa510fcc8feff 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -25,7 +25,7 @@ static void obs_source_destroy(obs_source_t source); -bool get_source_info(void *module, const char *module_name, +bool load_source_info(void *module, const char *module_name, const char *source_id, struct source_info *info) { info->getname = load_module_subfunc(module, module_name, @@ -85,6 +85,24 @@ static inline const struct source_info *find_source(struct darray *list, return NULL; } +static const struct source_info *get_source_info(enum source_type type, + const char *id) +{ + struct darray *list = NULL; + + switch (type) { + case SOURCE_INPUT: list = &obs->input_types.da; break; + case SOURCE_FILTER: list = &obs->filter_types.da; break; + case SOURCE_TRANSITION: list = &obs->transition_types.da; break; + case SOURCE_SCENE: + default: + blog(LOG_WARNING, "get_source_info: invalid source type"); + return NULL; + } + + return find_source(list, id); +} + static inline bool obs_source_init_handlers(struct obs_source *source) { source->signals = signal_handler_create(); @@ -95,6 +113,13 @@ static inline bool obs_source_init_handlers(struct obs_source *source) return (source->procs != NULL); } +const char *obs_source_getdisplayname(enum obs_source_type type, + const char *id, const char *locale) +{ + const struct source_info *info = get_source_info(type, id); + return (info != NULL) ? info->getname(locale) : NULL; +} + /* internal initialization */ bool obs_source_init(struct obs_source *source, const char *settings, const struct source_info *info) @@ -141,21 +166,9 @@ static inline void obs_source_dosignal(struct obs_source *source, obs_source_t obs_source_create(enum obs_source_type type, const char *id, const char *name, const char *settings) { - const struct source_info *info = NULL; - struct darray *list = NULL; struct obs_source *source; - switch (type) { - case SOURCE_INPUT: list = &obs->input_types.da; break; - case SOURCE_FILTER: list = &obs->filter_types.da; break; - case SOURCE_TRANSITION: list = &obs->transition_types.da; break; - case SOURCE_SCENE: - default: - blog(LOG_WARNING, "Tried to create invalid source type"); - return NULL; - } - - info = find_source(list, id); + const struct source_info *info = get_source_info(type, id); if (!info) { blog(LOG_WARNING, "Source '%s' not found", id); return NULL; diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 96c4f8d3e3d88d89c6c2ee8f7373b65e6d32f789..11e08f86abf5bb496eb26bb9595d578f501b0cfa 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -249,7 +249,7 @@ struct obs_source { bool rendering_filter; }; -extern bool get_source_info(void *module, const char *module_name, +extern bool load_source_info(void *module, const char *module_name, const char *source_name, struct source_info *info); extern bool obs_source_init(struct obs_source *source, const char *settings, diff --git a/libobs/obs.h b/libobs/obs.h index 8262c36ab60e4852496a03ef462e113038a2fdcb..e16cc3851735977e9523fea3015721a7492de4eb 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -445,7 +445,9 @@ EXPORT void obs_source_process_filter(obs_source_t filter, * display oriantations. Scenes can also be used like any other source. */ EXPORT obs_scene_t obs_scene_create(const char *name); -EXPORT void obs_scene_release(obs_scene_t scene); + +EXPORT int obs_scene_addref(obs_scene_t scene); +EXPORT int obs_scene_release(obs_scene_t scene); /** Gets the scene's source context */ EXPORT obs_source_t obs_scene_getsource(obs_scene_t scene); @@ -456,8 +458,12 @@ EXPORT obs_scene_t obs_scene_fromsource(obs_source_t source); /** Adds/creates a new scene item for a source */ EXPORT obs_sceneitem_t obs_scene_add(obs_scene_t scene, obs_source_t source); -/** Removes/destroys a scene item */ -EXPORT void obs_sceneitem_destroy(obs_sceneitem_t item); +/** Removes/destroys a scene item. Returns the source reference counter + * (if any) */ +EXPORT int obs_sceneitem_destroy(obs_sceneitem_t item); + +/** Gets the source of a scene item */ +EXPORT obs_source_t obs_sceneitem_getsource(obs_sceneitem_t item); /* Functions for gettings/setting specific oriantation of a scene item */ EXPORT void obs_sceneitem_setpos(obs_sceneitem_t item, const struct vec2 *pos); diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp index a3ce8cd5ff18db2ebf91a19a6d32bf5da39b3dd6..b0a828585c0a8edaf5530cb4834c8a5681258a15 100644 --- a/obs/obs-app.cpp +++ b/obs/obs-app.cpp @@ -136,6 +136,8 @@ bool OBSApp::InitLocale() const char *lang = config_get_string(globalConfig, "General", "Language"); + locale = lang; + stringstream file; file << "locale/" << lang << ".txt"; diff --git a/obs/obs-app.hpp b/obs/obs-app.hpp index 1d6fd1bd54a896cfaaf9d79da3e7beb70f34f66c..b148b9c6ff1d480f445ec38df9f53229d95e67a0 100644 --- a/obs/obs-app.hpp +++ b/obs/obs-app.hpp @@ -22,15 +22,18 @@ #include +#include + class OBSAppBase : public wxApp { public: virtual ~OBSAppBase(); }; class OBSApp : public OBSAppBase { - ConfigFile globalConfig; - TextLookup textLookup; - wxWindow *mainWindow; + std::string locale; + ConfigFile globalConfig; + TextLookup textLookup; + wxWindow *mainWindow; bool InitGlobalConfig(); bool InitGlobalConfigDefaults(); @@ -51,6 +54,11 @@ public: inline config_t GlobalConfig() const {return globalConfig;} + inline const char *GetLocale() const + { + return locale.c_str(); + } + inline const char *GetString(const char *lookupVal) const { return textLookup.GetString(lookupVal); diff --git a/obs/window-basic-main.cpp b/obs/window-basic-main.cpp index 83ac1bb805f3b1ab204ff11a6520b0ac76eb52f9..367244815726837935b925e1edf8d1c74abd0142 100644 --- a/obs/window-basic-main.cpp +++ b/obs/window-basic-main.cpp @@ -91,7 +91,8 @@ bool OBSBasic::Init() //obs_scene_t scene = obs_scene_create("test scene"); //obs_add_source(obs_scene_getsource(scene)); - //obs_load_module("test-input"); + /* TODO: this is a test */ + obs_load_module("test-input"); return true; } @@ -259,13 +260,77 @@ void OBSBasic::sourcesRDown(wxMouseEvent &event) { } -void OBSBasic::sourceAddClicked(wxCommandEvent &event) +void OBSBasic::AddSource(obs_scene_t scene, const char *id) +{ + string name; + + bool success = false; + while (!success) { + int ret = NameDialog::AskForName(this, + Str("MainWindow.AddSourceDlg.Title"), + Str("MainWindow.AddSourceDlg.Text"), + name); + + if (ret == wxID_CANCEL) + break; + + obs_source_t source = obs_get_source_by_name( + name.c_str()); + if (!source) { + success = true; + } else { + wxMessageBox(WXStr("MainWindow.NameExists.Text"), + WXStr("MainWindow.NameExists.Title"), + wxOK|wxCENTRE, this); + obs_source_release(source); + } + } + + if (success) { + obs_source_t source = obs_source_create(SOURCE_INPUT, id, + name.c_str(), NULL); + obs_add_source(source); + obs_sceneitem_t item = obs_scene_add(scene, source); + obs_source_release(source); + } +} + +void OBSBasic::AddSourcePopup() { int sceneSel = scenes->GetSelection(); + size_t idx = 0; + const char *type; + vector types; + if (sceneSel == wxNOT_FOUND) return; - + obs_scene_t scene = (obs_scene_t)scenes->GetClientData(sceneSel); + obs_scene_addref(scene); + + unique_ptr popup(new wxMenu()); + while (obs_enum_input_types(idx, &type)) { + const char *name = obs_source_getdisplayname(SOURCE_INPUT, + type, wxGetApp().GetLocale()); + + types.push_back(type); + popup->Append((int)idx, wxString(name, wxConvUTF8)); + + idx++; + } + + if (idx) { + int id = WXDoPopupMenu(this, popup.get()); + if (id != -1) + AddSource(scene, types[id]); + } + + obs_scene_release(scene); +} + +void OBSBasic::sourceAddClicked(wxCommandEvent &event) +{ + AddSourcePopup(); } void OBSBasic::sourceRemoveClicked(wxCommandEvent &event) diff --git a/obs/window-basic-main.hpp b/obs/window-basic-main.hpp index 83101ff17fb0810cafd27eab0210d1cb13a6f1f0..f44f56d5b17df0372709418fd0be42620dd9b8b6 100644 --- a/obs/window-basic-main.hpp +++ b/obs/window-basic-main.hpp @@ -28,6 +28,9 @@ class OBSBasic : public OBSBasicBase { static void SourceAdded(void *data, calldata_t params); static void SourceDestroyed(void *data, calldata_t params); + void AddSource(obs_scene_t scene, const char *id); + void AddSourcePopup(); + bool InitGraphics(); void NewProject(); diff --git a/test/test-input/test-random.c b/test/test-input/test-random.c index e29850735ab15e292955d5651da6797cec050568..7d56cceea7f8b76bd2ac2f513d4b8d1c0746a24e 100644 --- a/test/test-input/test-random.c +++ b/test/test-input/test-random.c @@ -3,7 +3,7 @@ const char *random_getname(const char *locale) { - return "Random;"; + return "Random Source"; } struct random_tex *random_create(const char *settings, obs_source_t source)