Requests: Add AddSceneItem

New request `AddSceneItem` which allows you to add a
source to a scene. Returns an itemId which can be used
to manipulate the item further if necessary.
This commit is contained in:
tt2468 2020-05-28 21:45:52 -07:00
parent 5822992b44
commit d2865b9f4f
3 changed files with 71 additions and 4 deletions

@ -60,6 +60,7 @@ const QHash<QString, RpcMethodHandler> WSRequestHandler::messageMap {
{ "SetSceneItemProperties", &WSRequestHandler::SetSceneItemProperties },
{ "ResetSceneItem", &WSRequestHandler::ResetSceneItem },
{ "DeleteSceneItem", &WSRequestHandler::DeleteSceneItem },
{ "AddSceneItem", &WSRequestHandler::AddSceneItem },
{ "DuplicateSceneItem", &WSRequestHandler::DuplicateSceneItem },
{ "ReorderSceneItems", &WSRequestHandler::ReorderSceneItems },

@ -78,6 +78,7 @@ class WSRequestHandler {
RpcResponse ResetSceneItem(const RpcRequest&);
RpcResponse DuplicateSceneItem(const RpcRequest&);
RpcResponse DeleteSceneItem(const RpcRequest&);
RpcResponse AddSceneItem(const RpcRequest&);
RpcResponse ReorderSceneItems(const RpcRequest&);
RpcResponse GetStreamingStatus(const RpcRequest&);

@ -2,6 +2,18 @@
#include "WSRequestHandler.h"
struct AddSourceData {
obs_source_t *source;
obs_sceneitem_t *sceneItem;
bool setVisible;
};
void AddSourceHelper(void *_data, obs_scene_t *scene) {
auto *data = reinterpret_cast<AddSourceData*>(_data);
data->sceneItem = obs_scene_add(scene, data->source);
obs_sceneitem_set_visible(data->sceneItem, data->setVisible);
}
/**
* 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).
@ -37,7 +49,7 @@
* @return {int} `alignment` The point on the source that the item is manipulated from. The sum of 1=Left or 2=Right, and 4=Top or 8=Bottom, or omit to center on that axis.
* @return {String (optional)} `parentGroupName` Name of the item's parent (if this item belongs to a group)
* @return {Array<SceneItemTransform> (optional)} `groupChildren` List of children (if this item is a group)
*
*
* @api requests
* @name GetSceneItemProperties
* @category scene items
@ -164,7 +176,7 @@ RpcResponse WSRequestHandler::SetSceneItemProperties(const RpcRequest& request)
vec2 newScale = oldScale;
OBSDataAutoRelease reqScale = obs_data_get_obj(params, "scale");
if (obs_data_has_user_value(reqScale, "x")) {
newScale.x = obs_data_get_double(reqScale, "x");
}
@ -252,7 +264,7 @@ RpcResponse WSRequestHandler::SetSceneItemProperties(const RpcRequest& request)
}
obs_sceneitem_set_bounds(sceneItem, &newBounds);
if (obs_data_has_user_value(reqBounds, "alignment")) {
const uint32_t bounds_alignment = obs_data_get_int(reqBounds, "alignment");
if (Utils::IsValidAlignment(bounds_alignment)) {
@ -455,7 +467,7 @@ RpcResponse WSRequestHandler::SetSceneItemTransform(const RpcRequest& request) {
obs_sceneitem_set_scale(sceneItem, &scale);
obs_sceneitem_set_rot(sceneItem, rotation);
obs_sceneitem_defer_update_end(sceneItem);
return request.success();
@ -544,6 +556,59 @@ RpcResponse WSRequestHandler::DeleteSceneItem(const RpcRequest& request) {
return request.success();
}
/**
* Creates a scene item in a scene. In other words, this is how you add a source into a scene.
*
* @param {String} `sceneName` Name of the scene to create the scene item in
* @param {String} `sourceName` Name of the source to be added
* @param {boolean} `setVisible` Whether to make the sceneitem visible on creation or not. Default `true`
*
* @return {int} `itemId` Numerical ID of the created scene item
*
* @api requests
* @name AddSceneItem
* @category scene items
* @since unreleased
*/
RpcResponse WSRequestHandler::AddSceneItem(const RpcRequest& request) {
if (!request.hasField("sceneName") || !request.hasField("sourceName")) {
return request.failed("missing request parameters");
}
const char* sceneName = obs_data_get_string(request.parameters(), "sceneName");
OBSSourceAutoRelease sceneSource = obs_get_source_by_name(sceneName);
OBSScene scene = obs_scene_from_source(sceneSource);
if (!scene) {
return request.failed("requested scene is invalid or doesnt exist");
}
const char* sourceName = obs_data_get_string(request.parameters(), "sourceName");
OBSSourceAutoRelease source = obs_get_source_by_name(sourceName);
if (!source) {
return request.failed("requested source does not exist");
}
if (source == sceneSource) {
return request.failed("you cannot add a scene as a sceneitem to itself");
}
AddSourceData data;
data.source = source;
data.setVisible = true;
if (request.hasField("setVisible")) {
data.setVisible = obs_data_get_bool(request.parameters(), "setVisible");
}
obs_enter_graphics();
obs_scene_atomic_update(scene, AddSourceHelper, &data);
obs_leave_graphics();
OBSDataAutoRelease responseData = obs_data_create();
obs_data_set_int(responseData, "itemID", obs_sceneitem_get_id(data.sceneItem));
return request.success(responseData);
}
/**
* Duplicates a scene item.
*