From f58da1254b016c7e57348af46caa22a589e38051 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 3 Oct 2017 20:23:55 -0400 Subject: [PATCH 01/28] wip --- WSRequestHandler.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 66740ca3..1f2c11dd 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1342,6 +1342,104 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { obs_source_release(scene); } +/** + * Gets the scene specific properties of the specified source item. + * + * @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. + * + * @return SOMESTUFF HERE + * + * @api requests + * @name GetSceneItemSceneProperties + * @category sources + * @since 4.1.3? + */ +void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) { + if (!req->hasField("item")) { + req->SendErrorResponse("missing request parameters"); + return; + } + + const char* item_name = obs_data_get_string(req->data, "item"); + if (!str_valid(item_name)) { + req->SendErrorResponse("invalid request parameters"); + return; + } + + const char* scene_name = obs_data_get_string(req->data, "scene-name"); + obs_source_t* scene = Utils::GetSceneFromNameOrCurrent(scene_name); + if (!scene) { + req->SendErrorResponse("requested scene doesn't exist"); + return; + } + + obs_sceneitem_t* scene_item = Utils::GetSceneItemFromName(scene, item_name); + if (scene_item) { + obs_data_t* data = obs_data_create(); + + // is name even needed here? + obs_data_set_string(data, "name", obs_source_get_name(obs_sceneitem_get_source(scene_item))); + + obs_data_t* pos_data = obs_data_create(); + vec2 pos; + obs_sceneitem_get_pos(scene_item, &pos); + obs_data_set_double(pos_data, "x", pos.x); + obs_data_set_double(pos_data, "y", pos.y); + obs_data_set_obj(data, "position", pos_data); + + obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); + + // investigate this and maybe convert so string in switch statment + obs_data_set_int(data, "alignment", obs_sceneitem_get_alignment(scene_item)); + + obs_data_t* scale_data = obs_data_create(); + vec2 scale; + obs_sceneitem_get_scale(scene_item, &scale); + obs_data_set_double(scale_data, "x", scale.x); + obs_data_set_double(scale_data, "y", scale.y); + obs_data_set_obj(data, "scale", scale_data); + + obs_data_t* crop_data = obs_data_create(); + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(scene_item, &crop); + obs_data_set_int(crop_data, "left", crop.left); + obs_data_set_int(crop_data, "top", crop.top); + obs_data_set_int(crop_data, "right", crop.right); + obs_data_set_int(crop_data, "bottom", crop.bottom); + obs_data_set_obj(data, "crop", crop_data); + + obs_data_set_bool(data, "visible", obs_sceneitem_visible(scene_item)); + + obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); // enum obs_bounds_type + if (bounds_type != OBS_BOUNDS_NONE) { + obs_data_t bounds_data; + // same with alignment above, decide if it should convert to string + obs_data_set_int(bounds_data, obs_sceneitem_get_bounds_alignment(scene_item)); + vec2 bounds; + obs_sceneitem_get_bounds(scene_item, &bounds); + obs_data_set_float(bounds_data, "width", bounds.x); + obs_data_set_float(bounds_data, "height", bounds.y); + obs_data_set_obj(data, "bounds", bounds_data); + } + + // source width? + // source height? + // locked? + + // obs_source_t* item_source = obs_sceneitem_get_source(item); + // float item_width = float(obs_source_get_width(item_source)); + // float item_height = float(obs_source_get_height(item_source)); + + obs_sceneitem_release(scene_item); + req->SendOKResponse(data); + } else { + req->SendErrorResponse("specified scene item doesn't exist"); + } + + obs_source_release(scene); +} + /** * Change the active scene collection. * From 9621ea90f72240e93a2d5122388f65568a079983 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 3 Oct 2017 20:30:51 -0400 Subject: [PATCH 02/28] more WIP --- WSRequestHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 1f2c11dd..01fab203 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -56,6 +56,7 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["SetSceneItemPosition"] = WSRequestHandler::HandleSetSceneItemPosition; messageMap["SetSceneItemTransform"] = WSRequestHandler::HandleSetSceneItemTransform; messageMap["SetSceneItemCrop"] = WSRequestHandler::HandleSetSceneItemCrop; + messageMap["GetSceneItemSceneProperties"] = WSRequestHandler::HandleGetSceneItemSceneProperties; messageMap["ResetSceneItem"] = WSRequestHandler::HandleResetSceneItem; messageMap["GetStreamingStatus"] = WSRequestHandler::HandleGetStreamingStatus; From 2e9829ddd1fa081d346184ce252d7ecb955186a4 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 00:51:16 -0400 Subject: [PATCH 03/28] WIP questions to be answered --- WSRequestHandler.cpp | 62 +++++++++++++++++++++++++++++++++++--------- WSRequestHandler.h | 1 + 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 01fab203..a10fbeb1 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -56,6 +56,7 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["SetSceneItemPosition"] = WSRequestHandler::HandleSetSceneItemPosition; messageMap["SetSceneItemTransform"] = WSRequestHandler::HandleSetSceneItemTransform; messageMap["SetSceneItemCrop"] = WSRequestHandler::HandleSetSceneItemCrop; + // This method name needs work. Perhaps just "GetSceneItemProperties" messageMap["GetSceneItemSceneProperties"] = WSRequestHandler::HandleGetSceneItemSceneProperties; messageMap["ResetSceneItem"] = WSRequestHandler::HandleResetSceneItem; @@ -1349,7 +1350,7 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @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. * - * @return SOMESTUFF HERE + * @return TO POPULATE * * @api requests * @name GetSceneItemSceneProperties @@ -1380,8 +1381,9 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_t* data = obs_data_create(); // is name even needed here? - obs_data_set_string(data, "name", obs_source_get_name(obs_sceneitem_get_source(scene_item))); + obs_data_set_string(data, "name", item_name); + // is nested ideal? obs_data_t* pos_data = obs_data_create(); vec2 pos; obs_sceneitem_get_pos(scene_item, &pos); @@ -1392,6 +1394,11 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); // investigate this and maybe convert so string in switch statment + // #define OBS_ALIGN_CENTER (0) + // #define OBS_ALIGN_LEFT (1<<0) + // #define OBS_ALIGN_RIGHT (1<<1) + // #define OBS_ALIGN_TOP (1<<2) + // #define OBS_ALIGN_BOTTOM (1<<3) obs_data_set_int(data, "alignment", obs_sceneitem_get_alignment(scene_item)); obs_data_t* scale_data = obs_data_create(); @@ -1412,10 +1419,45 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_set_bool(data, "visible", obs_sceneitem_visible(scene_item)); - obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); // enum obs_bounds_type - if (bounds_type != OBS_BOUNDS_NONE) { - obs_data_t bounds_data; + obs_data_t* bounds_data = obs_data_create(); + obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); + if (bounds_type == OBS_BOUNDS_NONE) { + obs_data_set_bool(data, "bounds", false); + } + else { + switch(bounds_type) { + case OBS_BOUNDS_STRETCH: { + obs_data_set_string(bounds_data, "type", "Stretch"); + break; + } + case OBS_BOUNDS_SCALE_INNER: { + obs_data_set_string(bounds_data, "type", "Inner"); + break; + } + case OBS_BOUNDS_SCALE_OUTER: { + obs_data_set_string(bounds_data, "type", "Outer"); + break; + } + case OBS_BOUNDS_SCALE_TO_WIDTH: { + obs_data_set_string(bounds_data, "type", "Width"); + break; + } + case OBS_BOUNDS_SCALE_TO_HEIGHT: { + obs_data_set_string(bounds_data, "type", "Height"); + break; + } + case OBS_BOUNDS_MAX_ONLY: { + obs_data_set_string(bounds_data, "type", "Max"); + break; + } + } + // same with alignment above, decide if it should convert to string + // #define OBS_ALIGN_CENTER (0) + // #define OBS_ALIGN_LEFT (1<<0) + // #define OBS_ALIGN_RIGHT (1<<1) + // #define OBS_ALIGN_TOP (1<<2) + // #define OBS_ALIGN_BOTTOM (1<<3) obs_data_set_int(bounds_data, obs_sceneitem_get_bounds_alignment(scene_item)); vec2 bounds; obs_sceneitem_get_bounds(scene_item, &bounds); @@ -1424,13 +1466,9 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_set_obj(data, "bounds", bounds_data); } - // source width? - // source height? - // locked? - - // obs_source_t* item_source = obs_sceneitem_get_source(item); - // float item_width = float(obs_source_get_width(item_source)); - // float item_height = float(obs_source_get_height(item_source)); + // add source width? + // add source height? + // add locked? obs_sceneitem_release(scene_item); req->SendOKResponse(data); diff --git a/WSRequestHandler.h b/WSRequestHandler.h index c22ccba3..560b4135 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -63,6 +63,7 @@ class WSRequestHandler : public QObject { static void HandleSetSceneItemPosition(WSRequestHandler* req); static void HandleSetSceneItemTransform(WSRequestHandler* req); static void HandleSetSceneItemCrop(WSRequestHandler* req); + // Add handler here static void HandleResetSceneItem(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); From d6caa872b86af71c55e5ee31f2197f0612396a72 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 02:06:38 -0400 Subject: [PATCH 04/28] WIP some small fixes --- WSRequestHandler.cpp | 28 +++++++++++++++++++++------- WSRequestHandler.h | 2 +- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index a10fbeb1..255f56ff 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -56,8 +56,7 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["SetSceneItemPosition"] = WSRequestHandler::HandleSetSceneItemPosition; messageMap["SetSceneItemTransform"] = WSRequestHandler::HandleSetSceneItemTransform; messageMap["SetSceneItemCrop"] = WSRequestHandler::HandleSetSceneItemCrop; - // This method name needs work. Perhaps just "GetSceneItemProperties" - messageMap["GetSceneItemSceneProperties"] = WSRequestHandler::HandleGetSceneItemSceneProperties; + messageMap["GetSceneItemProperties"] = WSRequestHandler::HandleGetSceneItemProperties; messageMap["ResetSceneItem"] = WSRequestHandler::HandleResetSceneItem; messageMap["GetStreamingStatus"] = WSRequestHandler::HandleGetStreamingStatus; @@ -1350,7 +1349,23 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @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. * - * @return TO POPULATE + * @return {String} `name` The name of the source. + * @return {int} `position.x` The x position of the source from the left. + * @return {int} `position.y` The y position of the source from the top. + * @return {double} `rotation` The clockwise rotation of the item in degrees around the point of alignment. + * @return {int?string?} `alignment` The point on the source that the item is manipulated from. + * @return {double} `scale.x` The x-scale factor of the source. + * @return {double} `scale.y` The y-scale factor of the source. + * @return {int} `crop.top` The number of pixels cropped off the top of the source before scaling. + * @return {int} `crop.right` The number of pixels cropped off the right of the source before scaling. + * @return {int} `crop.bottom` The number of pixels cropped off the bottom of the source before scaling. + * @return {int} `crop.left` The number of pixels cropped off the left of the source before scaling. + * @return {bool} `visible` If the source is visible. + * @return {bool/Object} `bounds` False if bounds are not turned on. Object if bounds are turned on. + * @return {String} `bounds.type` Type of bounding box. + * @return {int?string?} `bounds.alignment` Alignment of the bounding box. + * @return {double} `bounds.width` Width of the bounding box. + * @return {double} `bounds.height` Height of the bounding box. * * @api requests * @name GetSceneItemSceneProperties @@ -1383,7 +1398,6 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) // is name even needed here? obs_data_set_string(data, "name", item_name); - // is nested ideal? obs_data_t* pos_data = obs_data_create(); vec2 pos; obs_sceneitem_get_pos(scene_item, &pos); @@ -1393,7 +1407,7 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); - // investigate this and maybe convert so string in switch statment + // investigate this and maybe convert so string in switch statement // #define OBS_ALIGN_CENTER (0) // #define OBS_ALIGN_LEFT (1<<0) // #define OBS_ALIGN_RIGHT (1<<1) @@ -1461,8 +1475,8 @@ void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) obs_data_set_int(bounds_data, obs_sceneitem_get_bounds_alignment(scene_item)); vec2 bounds; obs_sceneitem_get_bounds(scene_item, &bounds); - obs_data_set_float(bounds_data, "width", bounds.x); - obs_data_set_float(bounds_data, "height", bounds.y); + obs_data_set_double(bounds_data, "width", bounds.x); + obs_data_set_double(bounds_data, "height", bounds.y); obs_data_set_obj(data, "bounds", bounds_data); } diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 560b4135..c5d7e48f 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -63,7 +63,7 @@ class WSRequestHandler : public QObject { static void HandleSetSceneItemPosition(WSRequestHandler* req); static void HandleSetSceneItemTransform(WSRequestHandler* req); static void HandleSetSceneItemCrop(WSRequestHandler* req); - // Add handler here + static void GetSceneItemProperties(WSRequestHandler* req);s static void HandleResetSceneItem(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); From 7571dd504278e5ecde03d5121085bcace33bf1ea Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 12:13:52 -0400 Subject: [PATCH 05/28] fixing typo --- WSRequestHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.h b/WSRequestHandler.h index c5d7e48f..19e6da7e 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -63,7 +63,7 @@ class WSRequestHandler : public QObject { static void HandleSetSceneItemPosition(WSRequestHandler* req); static void HandleSetSceneItemTransform(WSRequestHandler* req); static void HandleSetSceneItemCrop(WSRequestHandler* req); - static void GetSceneItemProperties(WSRequestHandler* req);s + static void GetSceneItemProperties(WSRequestHandler* req); static void HandleResetSceneItem(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); From dc06900f7ff6d5c501d332165bced45e7ee93d20 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 12:44:07 -0400 Subject: [PATCH 06/28] another typo --- WSRequestHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 19e6da7e..85506e7b 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -63,7 +63,7 @@ class WSRequestHandler : public QObject { static void HandleSetSceneItemPosition(WSRequestHandler* req); static void HandleSetSceneItemTransform(WSRequestHandler* req); static void HandleSetSceneItemCrop(WSRequestHandler* req); - static void GetSceneItemProperties(WSRequestHandler* req); + static void HandleGetSceneItemProperties(WSRequestHandler* req); static void HandleResetSceneItem(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); From 2120381c0ef225b5c9a80882db80adb8f8e237a3 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 12:48:40 -0400 Subject: [PATCH 07/28] correnting method name --- WSRequestHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 255f56ff..f5bd229f 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1372,7 +1372,7 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @category sources * @since 4.1.3? */ -void WSRequestHandler::HandleGetSceneItemSceneProperties(WSRequestHandler* req) { +void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { if (!req->hasField("item")) { req->SendErrorResponse("missing request parameters"); return; From 2556dd320fd07d5ac47d72b0c58db8d405500b16 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 13:05:01 -0400 Subject: [PATCH 08/28] fixing bounds alignemnt getter --- WSRequestHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index f5bd229f..87da2c82 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1472,7 +1472,7 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { // #define OBS_ALIGN_RIGHT (1<<1) // #define OBS_ALIGN_TOP (1<<2) // #define OBS_ALIGN_BOTTOM (1<<3) - obs_data_set_int(bounds_data, obs_sceneitem_get_bounds_alignment(scene_item)); + obs_data_set_int(bounds_data, "alignment", obs_sceneitem_get_bounds_alignment(scene_item)); vec2 bounds; obs_sceneitem_get_bounds(scene_item, &bounds); obs_data_set_double(bounds_data, "width", bounds.x); From ab1a43163bd9b1412772ac4b64ab580cad310af4 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 4 Oct 2017 13:26:15 -0400 Subject: [PATCH 09/28] early return on bad param --- WSRequestHandler.cpp | 177 ++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 87da2c82..674ee1c0 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1392,104 +1392,105 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { } obs_sceneitem_t* scene_item = Utils::GetSceneItemFromName(scene, item_name); - if (scene_item) { - obs_data_t* data = obs_data_create(); + if (!scene_item) { + req->SendErrorResponse("specified scene item doesn't exist"); + obs_source_release(scene); + return; + } - // is name even needed here? - obs_data_set_string(data, "name", item_name); - - obs_data_t* pos_data = obs_data_create(); - vec2 pos; - obs_sceneitem_get_pos(scene_item, &pos); - obs_data_set_double(pos_data, "x", pos.x); - obs_data_set_double(pos_data, "y", pos.y); - obs_data_set_obj(data, "position", pos_data); + obs_data_t* data = obs_data_create(); - obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); + // is name even needed here? + obs_data_set_string(data, "name", item_name); - // investigate this and maybe convert so string in switch statement + obs_data_t* pos_data = obs_data_create(); + vec2 pos; + obs_sceneitem_get_pos(scene_item, &pos); + obs_data_set_double(pos_data, "x", pos.x); + obs_data_set_double(pos_data, "y", pos.y); + obs_data_set_obj(data, "position", pos_data); + + obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); + + // investigate this and maybe convert so string in switch statement + // #define OBS_ALIGN_CENTER (0) + // #define OBS_ALIGN_LEFT (1<<0) + // #define OBS_ALIGN_RIGHT (1<<1) + // #define OBS_ALIGN_TOP (1<<2) + // #define OBS_ALIGN_BOTTOM (1<<3) + obs_data_set_int(data, "alignment", obs_sceneitem_get_alignment(scene_item)); + + obs_data_t* scale_data = obs_data_create(); + vec2 scale; + obs_sceneitem_get_scale(scene_item, &scale); + obs_data_set_double(scale_data, "x", scale.x); + obs_data_set_double(scale_data, "y", scale.y); + obs_data_set_obj(data, "scale", scale_data); + + obs_data_t* crop_data = obs_data_create(); + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(scene_item, &crop); + obs_data_set_int(crop_data, "left", crop.left); + obs_data_set_int(crop_data, "top", crop.top); + obs_data_set_int(crop_data, "right", crop.right); + obs_data_set_int(crop_data, "bottom", crop.bottom); + obs_data_set_obj(data, "crop", crop_data); + + obs_data_set_bool(data, "visible", obs_sceneitem_visible(scene_item)); + + obs_data_t* bounds_data = obs_data_create(); + obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); + if (bounds_type == OBS_BOUNDS_NONE) { + obs_data_set_bool(data, "bounds", false); + } + else { + switch(bounds_type) { + case OBS_BOUNDS_STRETCH: { + obs_data_set_string(bounds_data, "type", "Stretch"); + break; + } + case OBS_BOUNDS_SCALE_INNER: { + obs_data_set_string(bounds_data, "type", "Inner"); + break; + } + case OBS_BOUNDS_SCALE_OUTER: { + obs_data_set_string(bounds_data, "type", "Outer"); + break; + } + case OBS_BOUNDS_SCALE_TO_WIDTH: { + obs_data_set_string(bounds_data, "type", "Width"); + break; + } + case OBS_BOUNDS_SCALE_TO_HEIGHT: { + obs_data_set_string(bounds_data, "type", "Height"); + break; + } + case OBS_BOUNDS_MAX_ONLY: { + obs_data_set_string(bounds_data, "type", "Max"); + break; + } + } + + // same with alignment above, decide if it should convert to string // #define OBS_ALIGN_CENTER (0) // #define OBS_ALIGN_LEFT (1<<0) // #define OBS_ALIGN_RIGHT (1<<1) // #define OBS_ALIGN_TOP (1<<2) // #define OBS_ALIGN_BOTTOM (1<<3) - obs_data_set_int(data, "alignment", obs_sceneitem_get_alignment(scene_item)); - - obs_data_t* scale_data = obs_data_create(); - vec2 scale; - obs_sceneitem_get_scale(scene_item, &scale); - obs_data_set_double(scale_data, "x", scale.x); - obs_data_set_double(scale_data, "y", scale.y); - obs_data_set_obj(data, "scale", scale_data); - - obs_data_t* crop_data = obs_data_create(); - obs_sceneitem_crop crop; - obs_sceneitem_get_crop(scene_item, &crop); - obs_data_set_int(crop_data, "left", crop.left); - obs_data_set_int(crop_data, "top", crop.top); - obs_data_set_int(crop_data, "right", crop.right); - obs_data_set_int(crop_data, "bottom", crop.bottom); - obs_data_set_obj(data, "crop", crop_data); - - obs_data_set_bool(data, "visible", obs_sceneitem_visible(scene_item)); - - obs_data_t* bounds_data = obs_data_create(); - obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); - if (bounds_type == OBS_BOUNDS_NONE) { - obs_data_set_bool(data, "bounds", false); - } - else { - switch(bounds_type) { - case OBS_BOUNDS_STRETCH: { - obs_data_set_string(bounds_data, "type", "Stretch"); - break; - } - case OBS_BOUNDS_SCALE_INNER: { - obs_data_set_string(bounds_data, "type", "Inner"); - break; - } - case OBS_BOUNDS_SCALE_OUTER: { - obs_data_set_string(bounds_data, "type", "Outer"); - break; - } - case OBS_BOUNDS_SCALE_TO_WIDTH: { - obs_data_set_string(bounds_data, "type", "Width"); - break; - } - case OBS_BOUNDS_SCALE_TO_HEIGHT: { - obs_data_set_string(bounds_data, "type", "Height"); - break; - } - case OBS_BOUNDS_MAX_ONLY: { - obs_data_set_string(bounds_data, "type", "Max"); - break; - } - } - - // same with alignment above, decide if it should convert to string - // #define OBS_ALIGN_CENTER (0) - // #define OBS_ALIGN_LEFT (1<<0) - // #define OBS_ALIGN_RIGHT (1<<1) - // #define OBS_ALIGN_TOP (1<<2) - // #define OBS_ALIGN_BOTTOM (1<<3) - obs_data_set_int(bounds_data, "alignment", obs_sceneitem_get_bounds_alignment(scene_item)); - vec2 bounds; - obs_sceneitem_get_bounds(scene_item, &bounds); - obs_data_set_double(bounds_data, "width", bounds.x); - obs_data_set_double(bounds_data, "height", bounds.y); - obs_data_set_obj(data, "bounds", bounds_data); - } - - // add source width? - // add source height? - // add locked? - - obs_sceneitem_release(scene_item); - req->SendOKResponse(data); - } else { - req->SendErrorResponse("specified scene item doesn't exist"); + obs_data_set_int(bounds_data, "alignment", obs_sceneitem_get_bounds_alignment(scene_item)); + vec2 bounds; + obs_sceneitem_get_bounds(scene_item, &bounds); + obs_data_set_double(bounds_data, "width", bounds.x); + obs_data_set_double(bounds_data, "height", bounds.y); + obs_data_set_obj(data, "bounds", bounds_data); } + // add source width? + // add source height? + // add locked? + + obs_sceneitem_release(scene_item); + req->SendOKResponse(data); obs_source_release(scene); } From de2e73c9d4ab6fcb1d89be3973945e857064b050 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 10 Oct 2017 21:14:27 -0400 Subject: [PATCH 10/28] WIP setter and fixing small typo --- WSRequestHandler.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++- WSRequestHandler.h | 1 + 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 674ee1c0..60440e76 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -57,6 +57,7 @@ WSRequestHandler::WSRequestHandler(QWebSocket* client) : messageMap["SetSceneItemTransform"] = WSRequestHandler::HandleSetSceneItemTransform; messageMap["SetSceneItemCrop"] = WSRequestHandler::HandleSetSceneItemCrop; messageMap["GetSceneItemProperties"] = WSRequestHandler::HandleGetSceneItemProperties; + messageMap["SetSceneItemProperties"] = WSRequestHandler::HandleSetSceneItemProperties; messageMap["ResetSceneItem"] = WSRequestHandler::HandleResetSceneItem; messageMap["GetStreamingStatus"] = WSRequestHandler::HandleGetStreamingStatus; @@ -1328,8 +1329,8 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { if (scene_item) { struct obs_sceneitem_crop crop = { 0 }; crop.top = obs_data_get_int(req->data, "top"); - crop.bottom = obs_data_get_int(req->data, "bottom");; - crop.left = obs_data_get_int(req->data, "left");; + crop.bottom = obs_data_get_int(req->data, "bottom"); + crop.left = obs_data_get_int(req->data, "left"); crop.right = obs_data_get_int(req->data, "right"); obs_sceneitem_set_crop(scene_item, &crop); @@ -1494,6 +1495,88 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_source_release(scene); } +/** + * Sets the scene specific properties of a source. + * + * @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. + * @param {int} `position.x` + * @param {int} `position.y` + * @param {int} `crop.top` + * @param {int} `crop.bottom` + * @param {int} `crop.left` + * @param {int} `crop.right` + * + * @api requests + * @name SetSceneItemCrop + * @category sources + * @since 4.1.0 + */ +void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { + if (!req->hasField("item")) { + req->SendErrorResponse("missing request parameters"); + return; + } + + const char* item_name = obs_data_get_string(req->data, "item"); + if (!str_valid(item_name)) { + req->SendErrorResponse("invalid request parameters"); + return; + } + + const char* scene_name = obs_data_get_string(req->data, "scene-name"); + obs_source_t* scene = Utils::GetSceneFromNameOrCurrent(scene_name); + if (!scene) { + req->SendErrorResponse("requested scene doesn't exist"); + return; + } + + obs_sceneitem_t* scene_item = Utils::GetSceneItemFromName(scene, item_name); + if (!scene_item) { + req->SendErrorResponse("specified scene item doesn't exist"); + obs_source_release(scene); + return; + } + + if (req->hasField("position")) { + vec2 old_position; + obs_sceneitem_get_pos(scene_item, &old_position); + vec2 req_position = obs_data_get_obj(req->data, "position"); + vec2 new_position = old_position; + if (req_crop->hasField("x")) { + new_position.x = obs_data_get_int(req_position, "x"); + } + if (req_crop->hasField("y")) { + new_position.y = obs_data_get_int(req_position, "y"); + } + obs_sceneitem_set_pos(scene_item, &new_position); + } + + if (req->hasField("crop")) { + obs_sceneitem_crop old_crop; + obs_sceneitem_get_crop(scene_item, &old_crop); + obs_data_t req_crop = obs_data_get_obj(req->data, "crop"); + obs_sceneitem_crop new_crop = old_crop; + if (req_crop->hasField("top")) { + new_crop.top = obs_data_get_int(req_crop, "top"); + } + if (req_crop->hasField("right")) { + new_crop.right = obs_data_get_int(req_crop, "right"); + } + if (req_crop->hasField("bottom")) { + new_crop.bottom = obs_data_get_int(req_crop, "bottom"); + } + if (req_crop->hasField("left")) { + new_crop.left = obs_data_get_int(req_crop, "left"); + } + obs_sceneitem_set_crop(scene_item, &new_crop); + } + + obs_sceneitem_release(scene_item); + req->SendOKResponse(); + obs_source_release(scene); +} + /** * Change the active scene collection. * diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 85506e7b..890d5317 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -64,6 +64,7 @@ class WSRequestHandler : public QObject { static void HandleSetSceneItemTransform(WSRequestHandler* req); static void HandleSetSceneItemCrop(WSRequestHandler* req); static void HandleGetSceneItemProperties(WSRequestHandler* req); + static void HandleSetSceneItemProperties(WSRequestHandler* req); static void HandleResetSceneItem(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); From 47505547afe5d4826b3b19ddb48ef831fdaa8796 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 11 Oct 2017 11:51:05 -0400 Subject: [PATCH 11/28] fixing some types --- WSRequestHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 60440e76..8a9a246c 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1541,7 +1541,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (req->hasField("position")) { vec2 old_position; obs_sceneitem_get_pos(scene_item, &old_position); - vec2 req_position = obs_data_get_obj(req->data, "position"); + obs_data_t* req_position = obs_data_get_obj(req->data, "position"); vec2 new_position = old_position; if (req_crop->hasField("x")) { new_position.x = obs_data_get_int(req_position, "x"); @@ -1555,7 +1555,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (req->hasField("crop")) { obs_sceneitem_crop old_crop; obs_sceneitem_get_crop(scene_item, &old_crop); - obs_data_t req_crop = obs_data_get_obj(req->data, "crop"); + obs_data_t* req_crop = obs_data_get_obj(req->data, "crop"); obs_sceneitem_crop new_crop = old_crop; if (req_crop->hasField("top")) { new_crop.top = obs_data_get_int(req_crop, "top"); From d418b4e6242bb50ebe60faa1590ef61f3b628df7 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Wed, 11 Oct 2017 12:07:33 -0400 Subject: [PATCH 12/28] fixing methods for getting inner object keys --- WSRequestHandler.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 8a9a246c..d31706e8 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1543,10 +1543,10 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_get_pos(scene_item, &old_position); obs_data_t* req_position = obs_data_get_obj(req->data, "position"); vec2 new_position = old_position; - if (req_crop->hasField("x")) { + if (obs_data_has_user_value(req_position, "x")) { new_position.x = obs_data_get_int(req_position, "x"); } - if (req_crop->hasField("y")) { + if (obs_data_has_user_value(req_position, "y")) { new_position.y = obs_data_get_int(req_position, "y"); } obs_sceneitem_set_pos(scene_item, &new_position); @@ -1557,16 +1557,16 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_get_crop(scene_item, &old_crop); obs_data_t* req_crop = obs_data_get_obj(req->data, "crop"); obs_sceneitem_crop new_crop = old_crop; - if (req_crop->hasField("top")) { + if (obs_data_has_user_value(req_crop, "top")) { new_crop.top = obs_data_get_int(req_crop, "top"); } - if (req_crop->hasField("right")) { + if (obs_data_has_user_value(req_crop, "right")) { new_crop.right = obs_data_get_int(req_crop, "right"); } - if (req_crop->hasField("bottom")) { + if (obs_data_has_user_value(req_crop, "bottom")) { new_crop.bottom = obs_data_get_int(req_crop, "bottom"); } - if (req_crop->hasField("left")) { + if (obs_data_has_user_value(req_crop, "left")) { new_crop.left = obs_data_get_int(req_crop, "left"); } obs_sceneitem_set_crop(scene_item, &new_crop); From b0170ef6719794d30709d0c1be47bf601b423a27 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sat, 14 Oct 2017 13:10:40 -0400 Subject: [PATCH 13/28] more WIP on setter --- Utils.cpp | 17 +++++++++++++++++ Utils.h | 2 ++ WSRequestHandler.cpp | 30 +++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/Utils.cpp b/Utils.cpp index fcc45d23..91d04a76 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -142,6 +142,23 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* n return search.result; } +bool Utils::IsValidAlignment(const bool alignment) { + switch (alignment) { + case OBS_ALIGN_CENTER: + case OBS_ALIGN_LEFT: + case OBS_ALIGN_RIGHT: + case OBS_ALIGN_TOP: + case OBS_ALIGN_BOTTOM: + case OBS_ALIGN_TOP & OBS_ALIGN_LEFT: + case OBS_ALIGN_TOP & OBS_ALIGN_RIGHT: + case OBS_ALIGN_BOTTOM & OBS_ALIGN_LEFT: + case OBS_ALIGN_BOTTOM & OBS_ALIGN_RIGHT: { + return true; + } + } + return false; +} + obs_source_t* Utils::GetTransitionFromName(const char* search_name) { obs_source_t* found_transition = NULL; diff --git a/Utils.h b/Utils.h index 6b75e9c4..ea53c0e1 100644 --- a/Utils.h +++ b/Utils.h @@ -39,6 +39,8 @@ class Utils { static obs_source_t* GetTransitionFromName(const char* search_name); static obs_source_t* GetSceneFromNameOrCurrent(const char* scene_name); + static bool IsValidAlignment(const bool alignment); + static obs_data_array_t* GetScenes(); static obs_data_t* GetSceneData(obs_source* source); diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index d31706e8..9280892a 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1353,8 +1353,8 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @return {String} `name` The name of the source. * @return {int} `position.x` The x position of the source from the left. * @return {int} `position.y` The y position of the source from the top. + * @return {int} `position.alignment` The point on the source that the item is manipulated from. * @return {double} `rotation` The clockwise rotation of the item in degrees around the point of alignment. - * @return {int?string?} `alignment` The point on the source that the item is manipulated from. * @return {double} `scale.x` The x-scale factor of the source. * @return {double} `scale.y` The y-scale factor of the source. * @return {int} `crop.top` The number of pixels cropped off the top of the source before scaling. @@ -1364,7 +1364,7 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @return {bool} `visible` If the source is visible. * @return {bool/Object} `bounds` False if bounds are not turned on. Object if bounds are turned on. * @return {String} `bounds.type` Type of bounding box. - * @return {int?string?} `bounds.alignment` Alignment of the bounding box. + * @return {int} `bounds.alignment` Alignment of the bounding box. * @return {double} `bounds.width` Width of the bounding box. * @return {double} `bounds.height` Height of the bounding box. * @@ -1409,17 +1409,16 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_get_pos(scene_item, &pos); obs_data_set_double(pos_data, "x", pos.x); obs_data_set_double(pos_data, "y", pos.y); - obs_data_set_obj(data, "position", pos_data); - - obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); - - // investigate this and maybe convert so string in switch statement // #define OBS_ALIGN_CENTER (0) // #define OBS_ALIGN_LEFT (1<<0) // #define OBS_ALIGN_RIGHT (1<<1) // #define OBS_ALIGN_TOP (1<<2) // #define OBS_ALIGN_BOTTOM (1<<3) - obs_data_set_int(data, "alignment", obs_sceneitem_get_alignment(scene_item)); + obs_data_set_int(pos_data, "alignment", obs_sceneitem_get_alignment(scene_item)); + obs_data_set_obj(data, "position", pos_data); + + obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); + obs_data_t* scale_data = obs_data_create(); vec2 scale; @@ -1472,7 +1471,6 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { } } - // same with alignment above, decide if it should convert to string // #define OBS_ALIGN_CENTER (0) // #define OBS_ALIGN_LEFT (1<<0) // #define OBS_ALIGN_RIGHT (1<<1) @@ -1502,6 +1500,8 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { * @param {String} `item` The name of the source. * @param {int} `position.x` * @param {int} `position.y` + * @param {int} `position.alignment` + * @param {double} `rotation` The new clockwise rotation of the item in degrees * @param {int} `crop.top` * @param {int} `crop.bottom` * @param {int} `crop.left` @@ -1549,9 +1549,21 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (obs_data_has_user_value(req_position, "y")) { new_position.y = obs_data_get_int(req_position, "y"); } + if (obs_data_has_user_value(req_position, "alignment")) { + const uint32_t alignment = obs_data_get_int(req_position, "alignment"); + if (Utils::IsValidAlignment(alignment)) { + obs_sceneitem_set_alignment(alignment); + } + // Send an error in the else statement? + // Append an error message to the response? + } obs_sceneitem_set_pos(scene_item, &new_position); } + if (req->hasField("rotation")) { + obs_sceneitem_set_rot(scene_item, (float)obs_data_get_double(req->data, "rotation")); + } + if (req->hasField("crop")) { obs_sceneitem_crop old_crop; obs_sceneitem_get_crop(scene_item, &old_crop); From 90aebecc5bc39c655cd10d3f37171d193576faaa Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sat, 14 Oct 2017 14:36:23 -0400 Subject: [PATCH 14/28] small fixes --- WSRequestHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 9280892a..5df4ed22 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1552,7 +1552,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (obs_data_has_user_value(req_position, "alignment")) { const uint32_t alignment = obs_data_get_int(req_position, "alignment"); if (Utils::IsValidAlignment(alignment)) { - obs_sceneitem_set_alignment(alignment); + obs_sceneitem_set_alignment(scene_item, alignment); } // Send an error in the else statement? // Append an error message to the response? From 45f86b17f1117eb82dde6a49b727faa045688436 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sat, 14 Oct 2017 15:18:06 -0400 Subject: [PATCH 15/28] more WIP on setter --- Utils.cpp | 2 +- Utils.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Utils.cpp b/Utils.cpp index 91d04a76..147f21f3 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -142,7 +142,7 @@ obs_sceneitem_t* Utils::GetSceneItemFromName(obs_source_t* source, const char* n return search.result; } -bool Utils::IsValidAlignment(const bool alignment) { +bool Utils::IsValidAlignment(const uint32_t alignment) { switch (alignment) { case OBS_ALIGN_CENTER: case OBS_ALIGN_LEFT: diff --git a/Utils.h b/Utils.h index ea53c0e1..657477dc 100644 --- a/Utils.h +++ b/Utils.h @@ -39,7 +39,7 @@ class Utils { static obs_source_t* GetTransitionFromName(const char* search_name); static obs_source_t* GetSceneFromNameOrCurrent(const char* scene_name); - static bool IsValidAlignment(const bool alignment); + static bool IsValidAlignment(const uint32_t alignment); static obs_data_array_t* GetScenes(); static obs_data_t* GetSceneData(obs_source* source); From ccc2bd8667524224daebb0ee6743d9e09dd60cac Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sat, 14 Oct 2017 16:35:36 -0400 Subject: [PATCH 16/28] trying to fix duplicate case statment error --- Utils.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Utils.cpp b/Utils.cpp index 147f21f3..f8819700 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -149,10 +149,10 @@ bool Utils::IsValidAlignment(const uint32_t alignment) { case OBS_ALIGN_RIGHT: case OBS_ALIGN_TOP: case OBS_ALIGN_BOTTOM: - case OBS_ALIGN_TOP & OBS_ALIGN_LEFT: - case OBS_ALIGN_TOP & OBS_ALIGN_RIGHT: - case OBS_ALIGN_BOTTOM & OBS_ALIGN_LEFT: - case OBS_ALIGN_BOTTOM & OBS_ALIGN_RIGHT: { + case (OBS_ALIGN_TOP & OBS_ALIGN_LEFT): + case (OBS_ALIGN_TOP & OBS_ALIGN_RIGHT): + case (OBS_ALIGN_BOTTOM & OBS_ALIGN_LEFT): + case (OBS_ALIGN_BOTTOM & OBS_ALIGN_RIGHT): { return true; } } From 3e14b41600261579f34ec3713b1e466b43f05fc3 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sat, 14 Oct 2017 16:44:02 -0400 Subject: [PATCH 17/28] ands to ors --- Utils.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Utils.cpp b/Utils.cpp index f8819700..aea546fc 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -149,10 +149,10 @@ bool Utils::IsValidAlignment(const uint32_t alignment) { case OBS_ALIGN_RIGHT: case OBS_ALIGN_TOP: case OBS_ALIGN_BOTTOM: - case (OBS_ALIGN_TOP & OBS_ALIGN_LEFT): - case (OBS_ALIGN_TOP & OBS_ALIGN_RIGHT): - case (OBS_ALIGN_BOTTOM & OBS_ALIGN_LEFT): - case (OBS_ALIGN_BOTTOM & OBS_ALIGN_RIGHT): { + case OBS_ALIGN_TOP | OBS_ALIGN_LEFT: + case OBS_ALIGN_TOP | OBS_ALIGN_RIGHT: + case OBS_ALIGN_BOTTOM | OBS_ALIGN_LEFT: + case OBS_ALIGN_BOTTOM | OBS_ALIGN_RIGHT: { return true; } } From cc5f9c9aa72ec40edd0f34b4620ec027c92b24dc Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sun, 15 Oct 2017 11:57:21 -0400 Subject: [PATCH 18/28] refining bounds and adding scale to setter --- WSRequestHandler.cpp | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 5df4ed22..730c7dc0 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1362,7 +1362,6 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @return {int} `crop.bottom` The number of pixels cropped off the bottom of the source before scaling. * @return {int} `crop.left` The number of pixels cropped off the left of the source before scaling. * @return {bool} `visible` If the source is visible. - * @return {bool/Object} `bounds` False if bounds are not turned on. Object if bounds are turned on. * @return {String} `bounds.type` Type of bounding box. * @return {int} `bounds.alignment` Alignment of the bounding box. * @return {double} `bounds.width` Width of the bounding box. @@ -1441,48 +1440,42 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_t* bounds_data = obs_data_create(); obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); if (bounds_type == OBS_BOUNDS_NONE) { - obs_data_set_bool(data, "bounds", false); + obs_data_set_string(bounds_data, "type", "none"); } else { switch(bounds_type) { case OBS_BOUNDS_STRETCH: { - obs_data_set_string(bounds_data, "type", "Stretch"); + obs_data_set_string(bounds_data, "type", "stretch"); break; } case OBS_BOUNDS_SCALE_INNER: { - obs_data_set_string(bounds_data, "type", "Inner"); + obs_data_set_string(bounds_data, "type", "inner"); break; } case OBS_BOUNDS_SCALE_OUTER: { - obs_data_set_string(bounds_data, "type", "Outer"); + obs_data_set_string(bounds_data, "type", "outer"); break; } case OBS_BOUNDS_SCALE_TO_WIDTH: { - obs_data_set_string(bounds_data, "type", "Width"); + obs_data_set_string(bounds_data, "type", "width"); break; } case OBS_BOUNDS_SCALE_TO_HEIGHT: { - obs_data_set_string(bounds_data, "type", "Height"); + obs_data_set_string(bounds_data, "type", "height"); break; } case OBS_BOUNDS_MAX_ONLY: { - obs_data_set_string(bounds_data, "type", "Max"); + obs_data_set_string(bounds_data, "type", "max"); break; } } - - // #define OBS_ALIGN_CENTER (0) - // #define OBS_ALIGN_LEFT (1<<0) - // #define OBS_ALIGN_RIGHT (1<<1) - // #define OBS_ALIGN_TOP (1<<2) - // #define OBS_ALIGN_BOTTOM (1<<3) obs_data_set_int(bounds_data, "alignment", obs_sceneitem_get_bounds_alignment(scene_item)); vec2 bounds; obs_sceneitem_get_bounds(scene_item, &bounds); obs_data_set_double(bounds_data, "width", bounds.x); obs_data_set_double(bounds_data, "height", bounds.y); - obs_data_set_obj(data, "bounds", bounds_data); } + obs_data_set_obj(data, "bounds", bounds_data); // add source width? // add source height? @@ -1502,10 +1495,13 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { * @param {int} `position.y` * @param {int} `position.alignment` * @param {double} `rotation` The new clockwise rotation of the item in degrees + * @param {double} `scale.x` + * @param {double} `scale.y` * @param {int} `crop.top` * @param {int} `crop.bottom` * @param {int} `crop.left` * @param {int} `crop.right` + * @param {bool} `visible` * * @api requests * @name SetSceneItemCrop @@ -1564,6 +1560,19 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_set_rot(scene_item, (float)obs_data_get_double(req->data, "rotation")); } + if (req->hasField("scale")) { + vec2 old_scale; + obs_sceneitem_get_scale(scene_item, &old_scale); + obs_data_t* req_scale = obs_data_get_obj(req->data, "crop"); + vec2 new_scale = old_scale; + if (obs_data_has_user_value(req_scale, "x")) { + new_scale.x = obs_data_get_double(req_scale, "x"); + } + if (obs_data_has_user_value(req_scale, "y")) { + new_scale.y = obs_data_get_double(req_scale, "y"); + } + } + if (req->hasField("crop")) { obs_sceneitem_crop old_crop; obs_sceneitem_get_crop(scene_item, &old_crop); @@ -1584,6 +1593,10 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_set_crop(scene_item, &new_crop); } + if (req->hasField("visible")) { + obs_sceneitem_set_visible(scene_item, obs_data_get_bool(req->data, "visible")); + } + obs_sceneitem_release(scene_item); req->SendOKResponse(); obs_source_release(scene); From 096a8ec6ba82aa4c48e81ea01c08dc15ca6c1697 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sun, 15 Oct 2017 14:21:45 -0400 Subject: [PATCH 19/28] wip on setter and getter --- WSRequestHandler.cpp | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 730c7dc0..fdd0d179 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1364,8 +1364,8 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @return {bool} `visible` If the source is visible. * @return {String} `bounds.type` Type of bounding box. * @return {int} `bounds.alignment` Alignment of the bounding box. - * @return {double} `bounds.width` Width of the bounding box. - * @return {double} `bounds.height` Height of the bounding box. + * @return {double} `bounds.x` Width of the bounding box. + * @return {double} `bounds.y` Height of the bounding box. * * @api requests * @name GetSceneItemSceneProperties @@ -1408,11 +1408,6 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_get_pos(scene_item, &pos); obs_data_set_double(pos_data, "x", pos.x); obs_data_set_double(pos_data, "y", pos.y); - // #define OBS_ALIGN_CENTER (0) - // #define OBS_ALIGN_LEFT (1<<0) - // #define OBS_ALIGN_RIGHT (1<<1) - // #define OBS_ALIGN_TOP (1<<2) - // #define OBS_ALIGN_BOTTOM (1<<3) obs_data_set_int(pos_data, "alignment", obs_sceneitem_get_alignment(scene_item)); obs_data_set_obj(data, "position", pos_data); @@ -1443,7 +1438,7 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_set_string(bounds_data, "type", "none"); } else { - switch(bounds_type) { + switch(bounds_type) { // Is this implementation of bounds type good? Is passing an int better? case OBS_BOUNDS_STRETCH: { obs_data_set_string(bounds_data, "type", "stretch"); break; @@ -1472,8 +1467,8 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_set_int(bounds_data, "alignment", obs_sceneitem_get_bounds_alignment(scene_item)); vec2 bounds; obs_sceneitem_get_bounds(scene_item, &bounds); - obs_data_set_double(bounds_data, "width", bounds.x); - obs_data_set_double(bounds_data, "height", bounds.y); + obs_data_set_double(bounds_data, "x", bounds.x); + obs_data_set_double(bounds_data, "y", bounds.y); } obs_data_set_obj(data, "bounds", bounds_data); @@ -1502,6 +1497,10 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { * @param {int} `crop.left` * @param {int} `crop.right` * @param {bool} `visible` + * @param {int} `bounds.type` + * @param {int} `bounds.alignment` + * @param {double} `bounds.x` + * @param {double} `bounds.y' * * @api requests * @name SetSceneItemCrop @@ -1597,6 +1596,30 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_set_visible(scene_item, obs_data_get_bool(req->data, "visible")); } + if (req->hasField("bounds")) { + // TODO: figure out what to do with bounds type + vec2 old_bounds; + obs_sceneitem_get_bounds(scene_item, &old_bounds); + obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); + vec2 new_bounds = old_bounds; + if (obs_data_has_user_value(req_bounds, "x")) { + new_bounds.x = obs_data_get_double(req_bounds, "x"); + } + if (obs_data_has_user_value(req_bounds, "y")) { + new_bounds.y = obs_data_get_double(req_bounds, "y"); + } + obs_sceneitem_set_bounds(scene_item, &new_bounds); + if (obs_data_has_user_value(req_bounds, "alignment")) { + const uint32_t bounds_alignment = obs_data_get_int(req_bounds, "alignment"); + if (Utils::IsValidAlignment(bounds_alignment)) { + obs_sceneitem_set_bounds_alignment(scene_item, bounds_alignment); + } + // Send an error in the else statement? + // Append an error message to the response? + } + obs_sceneitem_set_pos(scene_item, &new_position); + } + obs_sceneitem_release(scene_item); req->SendOKResponse(); obs_source_release(scene); From fe724db12dc01e564da2358face4db375eada2e1 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Sun, 15 Oct 2017 17:28:07 -0400 Subject: [PATCH 20/28] removing copy paste error --- WSRequestHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index fdd0d179..4c1310ff 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1617,7 +1617,6 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { // Send an error in the else statement? // Append an error message to the response? } - obs_sceneitem_set_pos(scene_item, &new_position); } obs_sceneitem_release(scene_item); From 399815525f7eea92791c8d3cce4674011192785d Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Mon, 16 Oct 2017 12:01:41 -0400 Subject: [PATCH 21/28] wrapping up setter and getter --- WSRequestHandler.cpp | 79 ++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 4c1310ff..e9bd3372 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1370,7 +1370,7 @@ void WSRequestHandler::HandleSetSceneItemCrop(WSRequestHandler* req) { * @api requests * @name GetSceneItemSceneProperties * @category sources - * @since 4.1.3? + * @since unreleased */ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { if (!req->hasField("item")) { @@ -1482,30 +1482,30 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { } /** - * Sets the scene specific properties of a source. + * Sets the scene specific properties of a source. Unspecified properties will remain unchanged. * * @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. - * @param {int} `position.x` - * @param {int} `position.y` - * @param {int} `position.alignment` - * @param {double} `rotation` The new clockwise rotation of the item in degrees - * @param {double} `scale.x` - * @param {double} `scale.y` - * @param {int} `crop.top` - * @param {int} `crop.bottom` - * @param {int} `crop.left` - * @param {int} `crop.right` - * @param {bool} `visible` - * @param {int} `bounds.type` - * @param {int} `bounds.alignment` - * @param {double} `bounds.x` - * @param {double} `bounds.y' + * @param {int} `position.x` The new x position of the source. + * @param {int} `position.y` The new y position of the source. + * @param {int} `position.alignment` The new alignment of the source. + * @param {double} `rotation` The new clockwise rotation of the item in degrees. + * @param {double} `scale.x` The new x scale of the item. + * @param {double} `scale.y` The new y scale of the item. + * @param {int} `crop.top` The new amount of pixels cropped off the top of the source before scaling. + * @param {int} `crop.bottom` The new amount of pixels cropped off the bottom of the source before scaling. + * @param {int} `crop.left` The new amount of pixels cropped off the left of the source before scaling. + * @param {int} `crop.right` The new amount of pixels cropped off the right of the source before scaling. + * @param {bool} `visible` The new visibility of the source. 'true' shows source, 'false' hides source. + * @param {String} `bounds.type` The new bounds type of the source: 'none' 'stretch' 'inner' 'outer' 'width' 'height' 'max' + * @param {int} `bounds.alignment` The new alignment of the bounding box. (0-2, 4-6, 8-10) + * @param {double} `bounds.x` The new width of the bounding box. + * @param {double} `bounds.y' The new height of the bounding box. * * @api requests - * @name SetSceneItemCrop + * @name SetSceneItemProperties * @category sources - * @since 4.1.0 + * @since unreleased */ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (!req->hasField("item")) { @@ -1597,10 +1597,47 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { } if (req->hasField("bounds")) { - // TODO: figure out what to do with bounds type + obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); + if (obs_data_has_user_value(req_bounds, "type")) { + const char* new_bounds_type = obs_data_get_string(req_bounds, "type"); + switch(new_bounds_type) { + case "none": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_NONE); + break; + } + case "stretch": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_STRETCH); + break; + } + case "inner": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_INNER); + break; + } + case "outer": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_OUTER); + break; + } + case "width": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_WIDTH); + break; + } + case "height": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_HEIGHT); + break; + } + case "max": { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_MAX_ONLY); + break; + } + default: { + // Is this the right course of action? + // Should we just append an error to the response for a bad bounds type? + break; + } + } + } vec2 old_bounds; obs_sceneitem_get_bounds(scene_item, &old_bounds); - obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); vec2 new_bounds = old_bounds; if (obs_data_has_user_value(req_bounds, "x")) { new_bounds.x = obs_data_get_double(req_bounds, "x"); From 9b2d30b4d59d64dfc8c362fc16d2532549fd2ac8 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Mon, 16 Oct 2017 12:17:29 -0400 Subject: [PATCH 22/28] switch string to ifelseif --- WSRequestHandler.cpp | 58 ++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index e9bd3372..6879fb7f 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1600,40 +1600,30 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); if (obs_data_has_user_value(req_bounds, "type")) { const char* new_bounds_type = obs_data_get_string(req_bounds, "type"); - switch(new_bounds_type) { - case "none": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_NONE); - break; - } - case "stretch": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_STRETCH); - break; - } - case "inner": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_INNER); - break; - } - case "outer": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_OUTER); - break; - } - case "width": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_WIDTH); - break; - } - case "height": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_HEIGHT); - break; - } - case "max": { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_MAX_ONLY); - break; - } - default: { - // Is this the right course of action? - // Should we just append an error to the response for a bad bounds type? - break; - } + if (new_bounds_type == "none") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_NONE); + } + else if (new_bounds_type == "stretch") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_STRETCH); + } + else if (new_bounds_type == "inner") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_INNER); + } + else if (new_bounds_type == "outer") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_OUTER); + } + else if (new_bounds_type == "width") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_WIDTH); + } + else if (new_bounds_type == "height") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_HEIGHT); + } + else if (new_bounds_type == "max") { + obs_sceneitem_set_bounds_type(OBS_BOUNDS_MAX_ONLY); + } + else { + // Is this the right course of action? + // Should we just append an error to the response for a bad bounds type? } } vec2 old_bounds; From 67f7e2886766b4fdf689ff0d39cd8621fcd5245d Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Mon, 16 Oct 2017 12:29:49 -0400 Subject: [PATCH 23/28] fixing bounds type setter --- WSRequestHandler.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 6879fb7f..2e482a76 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1601,25 +1601,25 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (obs_data_has_user_value(req_bounds, "type")) { const char* new_bounds_type = obs_data_get_string(req_bounds, "type"); if (new_bounds_type == "none") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_NONE); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_NONE); } else if (new_bounds_type == "stretch") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_STRETCH); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_STRETCH); } else if (new_bounds_type == "inner") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_INNER); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_INNER); } else if (new_bounds_type == "outer") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_OUTER); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_OUTER); } else if (new_bounds_type == "width") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_WIDTH); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_TO_WIDTH); } else if (new_bounds_type == "height") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_SCALE_TO_HEIGHT); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_TO_HEIGHT); } else if (new_bounds_type == "max") { - obs_sceneitem_set_bounds_type(OBS_BOUNDS_MAX_ONLY); + obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_MAX_ONLY); } else { // Is this the right course of action? From 7570fbf7a431ed2749c03850867871597adef1df Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 17 Oct 2017 19:07:40 -0400 Subject: [PATCH 24/28] strings to ENUM strings --- WSRequestHandler.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 2e482a76..db90ad49 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1435,32 +1435,32 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_t* bounds_data = obs_data_create(); obs_bounds_type bounds_type = obs_sceneitem_get_bounds_type(scene_item); if (bounds_type == OBS_BOUNDS_NONE) { - obs_data_set_string(bounds_data, "type", "none"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_NONE"); } else { switch(bounds_type) { // Is this implementation of bounds type good? Is passing an int better? case OBS_BOUNDS_STRETCH: { - obs_data_set_string(bounds_data, "type", "stretch"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_STRETCH"); break; } case OBS_BOUNDS_SCALE_INNER: { - obs_data_set_string(bounds_data, "type", "inner"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_SCALE_INNER"); break; } case OBS_BOUNDS_SCALE_OUTER: { - obs_data_set_string(bounds_data, "type", "outer"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_SCALE_OUTER"); break; } case OBS_BOUNDS_SCALE_TO_WIDTH: { - obs_data_set_string(bounds_data, "type", "width"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_SCALE_TO_WIDTH"); break; } case OBS_BOUNDS_SCALE_TO_HEIGHT: { - obs_data_set_string(bounds_data, "type", "height"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_SCALE_TO_HEIGHT"); break; } case OBS_BOUNDS_MAX_ONLY: { - obs_data_set_string(bounds_data, "type", "max"); + obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_MAX_ONLY"); break; } } @@ -1497,7 +1497,7 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { * @param {int} `crop.left` The new amount of pixels cropped off the left of the source before scaling. * @param {int} `crop.right` The new amount of pixels cropped off the right of the source before scaling. * @param {bool} `visible` The new visibility of the source. 'true' shows source, 'false' hides source. - * @param {String} `bounds.type` The new bounds type of the source: 'none' 'stretch' 'inner' 'outer' 'width' 'height' 'max' + * @param {String} `bounds.type` The new bounds type of the source. * @param {int} `bounds.alignment` The new alignment of the bounding box. (0-2, 4-6, 8-10) * @param {double} `bounds.x` The new width of the bounding box. * @param {double} `bounds.y' The new height of the bounding box. @@ -1600,25 +1600,25 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); if (obs_data_has_user_value(req_bounds, "type")) { const char* new_bounds_type = obs_data_get_string(req_bounds, "type"); - if (new_bounds_type == "none") { + if (new_bounds_type == "OBS_BOUNDS_NONE") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_NONE); } - else if (new_bounds_type == "stretch") { + else if (new_bounds_type == "OBS_BOUNDS_STRETCH") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_STRETCH); } - else if (new_bounds_type == "inner") { + else if (new_bounds_type == "OBS_BOUNDS_SCALE_INNER") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_INNER); } - else if (new_bounds_type == "outer") { + else if (new_bounds_type == "OBS_BOUNDS_SCALE_OUTER") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_OUTER); } - else if (new_bounds_type == "width") { + else if (new_bounds_type == "OBS_BOUNDS_SCALE_TO_WIDTH") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_TO_WIDTH); } - else if (new_bounds_type == "height") { + else if (new_bounds_type == "OBS_BOUNDS_SCALE_TO_HEIGHT") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_SCALE_TO_HEIGHT); } - else if (new_bounds_type == "max") { + else if (new_bounds_type == "OBS_BOUNDS_MAX_ONLY") { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_MAX_ONLY); } else { From b9ae28483c3ac0ba251d5d2bdfd6063fff4db617 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Mon, 23 Oct 2017 11:34:29 -0400 Subject: [PATCH 25/28] adding error messages --- WSRequestHandler.cpp | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index db90ad49..9d5b5575 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1400,7 +1400,6 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_t* data = obs_data_create(); - // is name even needed here? obs_data_set_string(data, "name", item_name); obs_data_t* pos_data = obs_data_create(); @@ -1413,7 +1412,6 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_set_double(data, "rotation", obs_sceneitem_get_rot(scene_item)); - obs_data_t* scale_data = obs_data_create(); vec2 scale; obs_sceneitem_get_scale(scene_item, &scale); @@ -1438,7 +1436,7 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_NONE"); } else { - switch(bounds_type) { // Is this implementation of bounds type good? Is passing an int better? + switch(bounds_type) { case OBS_BOUNDS_STRETCH: { obs_data_set_string(bounds_data, "type", "OBS_BOUNDS_STRETCH"); break; @@ -1472,10 +1470,6 @@ void WSRequestHandler::HandleGetSceneItemProperties(WSRequestHandler* req) { } obs_data_set_obj(data, "bounds", bounds_data); - // add source width? - // add source height? - // add locked? - obs_sceneitem_release(scene_item); req->SendOKResponse(data); obs_source_release(scene); @@ -1533,8 +1527,12 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { return; } + bool bad_request = false; + obs_data_t* error_message = obs_data_create(); + if (req->hasField("position")) { vec2 old_position; + obs_data_t* position_error = obs_data_create(); obs_sceneitem_get_pos(scene_item, &old_position); obs_data_t* req_position = obs_data_get_obj(req->data, "position"); vec2 new_position = old_position; @@ -1548,9 +1546,11 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { const uint32_t alignment = obs_data_get_int(req_position, "alignment"); if (Utils::IsValidAlignment(alignment)) { obs_sceneitem_set_alignment(scene_item, alignment); + } else { + bad_request = true; + obs_data_set_string(position_error, "alignment", "invalid"); + obs_data_set_obj(error_message, "position", position_error); } - // Send an error in the else statement? - // Append an error message to the response? } obs_sceneitem_set_pos(scene_item, &new_position); } @@ -1597,6 +1597,8 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { } if (req->hasField("bounds")) { + bool bad_bounds = false; + obs_data_t* bounds_error = obs_data_create(); obs_data_t* req_bounds = obs_data_get_obj(req->data, "bounds"); if (obs_data_has_user_value(req_bounds, "type")) { const char* new_bounds_type = obs_data_get_string(req_bounds, "type"); @@ -1622,8 +1624,8 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { obs_sceneitem_set_bounds_type(scene_item, OBS_BOUNDS_MAX_ONLY); } else { - // Is this the right course of action? - // Should we just append an error to the response for a bad bounds type? + bad_request = bad_bounds = true; + obs_data_set_string(bounds_error, "type", "invalid"); } } vec2 old_bounds; @@ -1640,14 +1642,22 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { const uint32_t bounds_alignment = obs_data_get_int(req_bounds, "alignment"); if (Utils::IsValidAlignment(bounds_alignment)) { obs_sceneitem_set_bounds_alignment(scene_item, bounds_alignment); + } else { + bad_request = bad_bounds = true; + obs_data_set_string(bounds_error, "alignment", "invalid"); } - // Send an error in the else statement? - // Append an error message to the response? + } + if (bad_bounds) { + obs_data_set_obj(error_message, "bounds", bounds_error); } } obs_sceneitem_release(scene_item); - req->SendOKResponse(); + if (bad_request) { + req->SendErrorResponse(error_message); + } else { + req->SendOKResponse(); + } obs_source_release(scene); } From 1d30f13fd8e5817a25b4595c04bece12fff74270 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Mon, 23 Oct 2017 12:04:43 -0400 Subject: [PATCH 26/28] adding error response object method --- WSRequestHandler.cpp | 11 +++++++++++ WSRequestHandler.h | 1 + 2 files changed, 12 insertions(+) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 9d5b5575..f07c0566 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -189,6 +189,17 @@ void WSRequestHandler::SendErrorResponse(const char* errorMessage) { SendResponse(response); } +void WSRequestHandler::SendErrorResponse(obs_data_t* additionalFields) { + obs_data_t* response = obs_data_create(); + obs_data_set_string(response, "status", "error"); + obs_data_set_string(response, "message-id", _messageId); + + if (additionalFields) + obs_data_set_obj(response, "error", additionalFields); + + SendResponse(response); +} + void WSRequestHandler::SendResponse(obs_data_t* response) { const char *json = obs_data_get_json(response); _client->sendTextMessage(json); diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 890d5317..796fe874 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -47,6 +47,7 @@ class WSRequestHandler : public QObject { void SendOKResponse(obs_data_t* additionalFields = NULL); void SendErrorResponse(const char* errorMessage); + void SendErrorResponse(obs_data_t* additionalFields = NULL); void SendResponse(obs_data_t* response); static void HandleGetVersion(WSRequestHandler* req); From a3ecb6e0e929713d45db148d72dd1eabaa0dd6cc Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 24 Oct 2017 02:16:39 -0400 Subject: [PATCH 27/28] adding missing scale setter in setter --- WSRequestHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index f07c0566..7857f545 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1581,6 +1581,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (obs_data_has_user_value(req_scale, "y")) { new_scale.y = obs_data_get_double(req_scale, "y"); } + obs_sceneitem_set_scale(scene_item, &new_scale); } if (req->hasField("crop")) { From e84e5388a5575cd3c51b8f49f504b432470ffcf3 Mon Sep 17 00:00:00 2001 From: Teddy Stoddard Date: Tue, 24 Oct 2017 11:54:21 -0400 Subject: [PATCH 28/28] fixing scale data get in setter --- WSRequestHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 7857f545..af37f3b5 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -1573,7 +1573,7 @@ void WSRequestHandler::HandleSetSceneItemProperties(WSRequestHandler* req) { if (req->hasField("scale")) { vec2 old_scale; obs_sceneitem_get_scale(scene_item, &old_scale); - obs_data_t* req_scale = obs_data_get_obj(req->data, "crop"); + obs_data_t* req_scale = obs_data_get_obj(req->data, "scale"); vec2 new_scale = old_scale; if (obs_data_has_user_value(req_scale, "x")) { new_scale.x = obs_data_get_double(req_scale, "x");