Merge pull request #317 from Palakis/group-fixes

Groups fixes
This commit is contained in:
Stéphane Lepin 2019-05-19 10:06:08 +02:00 committed by GitHub
commit 061ab12b10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 25 deletions

View File

@ -97,6 +97,23 @@ obs_data_array_t* Utils::GetSceneItems(obs_source_t* source) {
return items;
}
/**
* @typedef {Object} `SceneItem` An OBS Scene Item.
* @property {Number} `cy`
* @property {Number} `cx`
* @property {String} `name` The name of this Scene Item.
* @property {int} `id` Scene item ID
* @property {Boolean} `render` Whether or not this Scene Item is set to "visible".
* @property {Boolean} `locked` Whether or not this Scene Item is locked and can't be moved around
* @property {Number} `source_cx`
* @property {Number} `source_cy`
* @property {String} `type` Source type. Value is one of the following: "input", "filter", "transition", "scene" or "unknown"
* @property {Number} `volume`
* @property {Number} `x`
* @property {Number} `y`
* @property {String (optional)} `parentGroupName` Name of the item's parent (if this item belongs to a group)
* @property {Array<SceneItem> (optional)} `groupChildren` List of children (if this item is a group)
*/
obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
if (!item) {
return nullptr;
@ -131,6 +148,28 @@ obs_data_t* Utils::GetSceneItemData(obs_sceneitem_t* item) {
obs_data_set_bool(data, "render", obs_sceneitem_visible(item));
obs_data_set_bool(data, "locked", obs_sceneitem_locked(item));
obs_scene_t* parent = obs_sceneitem_get_scene(item);
if (parent) {
OBSSource parentSource = obs_scene_get_source(parent);
QString parentKind = obs_source_get_id(parentSource);
if (parentKind == "group") {
obs_data_set_string(data, "parentGroupName", obs_source_get_name(parentSource));
}
}
if (obs_sceneitem_is_group(item)) {
OBSDataArrayAutoRelease children = obs_data_array_create();
obs_sceneitem_group_enum_items(item, [](obs_scene_t*, obs_sceneitem_t* currentItem, void* param) {
obs_data_array_t* items = reinterpret_cast<obs_data_array_t*>(param);
OBSDataAutoRelease itemData = GetSceneItemData(currentItem);
obs_data_array_push_back(items, itemData);
return true;
}, children);
obs_data_set_array(data, "groupChildren", children);
}
return data;
}
@ -154,23 +193,32 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name)
struct current_search {
QString query;
obs_sceneitem_t* result;
bool (*enumCallback)(obs_scene_t*, obs_sceneitem_t*, void*);
};
current_search search;
search.query = name;
search.result = nullptr;
search.enumCallback = nullptr;
OBSScene scene = obs_scene_from_source(source);
if (!scene)
return nullptr;
obs_scene_enum_items(scene, [](
search.enumCallback = [](
obs_scene_t* scene,
obs_sceneitem_t* currentItem,
void* param)
{
current_search* search = reinterpret_cast<current_search*>(param);
if (obs_sceneitem_is_group(currentItem)) {
obs_sceneitem_group_enum_items(currentItem, search->enumCallback, search);
if (search->result) {
return false;
}
}
QString currentItemName =
obs_source_get_name(obs_sceneitem_get_source(currentItem));
@ -181,32 +229,44 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, QString name)
}
return true;
}, &search);
};
obs_scene_enum_items(scene, search.enumCallback, &search);
return search.result;
}
// TODO refactor this to unify it with GetSceneItemFromName
obs_sceneitem_t* Utils::GetSceneItemFromId(obs_source_t* source, size_t id) {
struct current_search {
size_t query;
obs_sceneitem_t* result;
bool (*enumCallback)(obs_scene_t*, obs_sceneitem_t*, void*);
};
current_search search;
search.query = id;
search.result = nullptr;
search.enumCallback = nullptr;
OBSScene scene = obs_scene_from_source(source);
if (!scene)
return nullptr;
obs_scene_enum_items(scene, [](
search.enumCallback = [](
obs_scene_t* scene,
obs_sceneitem_t* currentItem,
void* param)
{
current_search* search = reinterpret_cast<current_search*>(param);
if (obs_sceneitem_is_group(currentItem)) {
obs_sceneitem_group_enum_items(currentItem, search->enumCallback, param);
if (search->result) {
return false;
}
}
if (obs_sceneitem_get_id(currentItem) == search->query) {
search->result = currentItem;
obs_sceneitem_addref(search->result);
@ -214,7 +274,9 @@ obs_sceneitem_t* Utils::GetSceneItemFromId(obs_source_t* source, size_t id) {
}
return true;
}, &search);
};
obs_scene_enum_items(scene, search.enumCallback, &search);
return search.result;
}
@ -593,6 +655,8 @@ bool Utils::SetFilenameFormatting(const char* filenameFormatting) {
* @property {int} `sourceHeight` Base source (without scaling) of the source
* @property {double} `width` Scene item width (base source width multiplied by the horizontal scaling factor)
* @property {double} `height` Scene item height (base source height multiplied by the vertical scaling factor)
* @property {String (optional)} `parentGroupName` Name of the item's parent (if this item belongs to a group)
* @property {Array<SceneItemTransform> (optional)} `groupChildren` List of children (if this item is a group)
*/
obs_data_t* Utils::GetSceneItemPropertiesData(obs_sceneitem_t* sceneItem) {
if (!sceneItem) {
@ -655,6 +719,28 @@ obs_data_t* Utils::GetSceneItemPropertiesData(obs_sceneitem_t* sceneItem) {
obs_data_set_double(data, "width", baseSourceWidth * scale.x);
obs_data_set_double(data, "height", baseSourceHeight * scale.y);
obs_scene_t* parent = obs_sceneitem_get_scene(sceneItem);
if (parent) {
OBSSource parentSource = obs_scene_get_source(parent);
QString parentKind = obs_source_get_id(parentSource);
if (parentKind == "group") {
obs_data_set_string(data, "parentGroupName", obs_source_get_name(parentSource));
}
}
if (obs_sceneitem_is_group(sceneItem)) {
OBSDataArrayAutoRelease children = obs_data_array_create();
obs_sceneitem_group_enum_items(sceneItem, [](obs_scene_t*, obs_sceneitem_t* subItem, void* param) {
obs_data_array_t* items = reinterpret_cast<obs_data_array_t*>(param);
OBSDataAutoRelease itemData = GetSceneItemPropertiesData(subItem);
obs_data_array_push_back(items, itemData);
return true;
}, children);
obs_data_set_array(data, "groupChildren", children);
}
return data;
}

View File

@ -344,7 +344,7 @@ const char* WSEvents::GetRecordingTimecode() {
* Indicates a scene change.
*
* @return {String} `scene-name` The new scene.
* @return {Array<Source>} `sources` List of sources in the new scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
* @return {Array<SceneItem>} `sources` List of scene items in the new scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
*
* @api events
* @name SwitchScenes
@ -1435,7 +1435,7 @@ void WSEvents::OnSceneItemDeselected(void* param, calldata_t* data) {
* The selected preview scene has changed (only available in Studio Mode).
*
* @return {String} `scene-name` Name of the scene being previewed.
* @return {Array<Source>} `sources` List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
* @return {Array<SceneItem>} `sources` List of sources composing the scene. Same specification as [`GetCurrentScene`](#getcurrentscene).
*
* @api events
* @name PreviewSceneChanged

View File

@ -2,24 +2,9 @@
#include "WSRequestHandler.h"
/**
* @typedef {Object} `Source` An OBS Scene Item.
* @property {Number} `cy`
* @property {Number} `cx`
* @property {String} `name` The name of this Scene Item.
* @property {int} `id` Scene item ID
* @property {Boolean} `render` Whether or not this Scene Item is set to "visible".
* @property {Boolean} `locked` Whether or not this Scene Item is locked and can't be moved around
* @property {Number} `source_cx`
* @property {Number} `source_cy`
* @property {String} `type` Source type. Value is one of the following: "input", "filter", "transition", "scene" or "unknown"
* @property {Number} `volume`
* @property {Number} `x`
* @property {Number} `y`
*/
/**
* Gets the scene specific properties of the specified source item.
* Coordinates are relative to the item's parent (the scene or group it belongs to).
*
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
* @param {String} `item` The name of the source.
@ -45,6 +30,8 @@
* @return {int} `sourceHeight` Base source (without scaling) of the source
* @return {double} `width` Scene item width (base source width multiplied by the horizontal scaling factor)
* @return {double} `height` Scene item height (base source height multiplied by the vertical scaling factor)
* @property {String (optional)} `parentGroupName` Name of the item's parent (if this item belongs to a group)
* @property {Array<SceneItemTransform> (optional)} `groupChildren` List of children (if this item is a group)
*
* @api requests
* @name GetSceneItemProperties
@ -81,6 +68,7 @@ HandlerResponse WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler*
/**
* Sets the scene specific properties of a source. Unspecified properties will remain unchanged.
* Coordinates are relative to the item's parent (the scene or group it belongs to).
*
* @param {String (optional)} `scene-name` the name of the scene that the source item belongs to. Defaults to the current scene.
* @param {String} `item` The name of the source.

View File

@ -5,7 +5,7 @@
/**
* @typedef {Object} `Scene`
* @property {String} `name` Name of the currently active scene.
* @property {Array<Source>} `sources` Ordered list of the current scene's source items.
* @property {Array<SceneItem>} `sources` Ordered list of the current scene's source items.
*/
/**
@ -38,7 +38,7 @@ HandlerResponse WSRequestHandler::HandleSetCurrentScene(WSRequestHandler* req) {
* Get the current scene's name and source items.
*
* @return {String} `name` Name of the currently active scene.
* @return {Array<Source>} `sources` Ordered list of the current scene's source items.
* @return {Array<SceneItem>} `sources` Ordered list of the current scene's source items.
*
* @api requests
* @name GetCurrentScene

View File

@ -26,7 +26,7 @@ HandlerResponse WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler* re
* Will return an `error` if Studio Mode is not enabled.
*
* @return {String} `name` The name of the active preview scene.
* @return {Array<Source>} `sources`
* @return {Array<SceneItem>} `sources`
*
* @api requests
* @name GetPreviewScene