diff --git a/src/WSRequestHandler.cpp b/src/WSRequestHandler.cpp index fbdccc97..321fa5a6 100644 --- a/src/WSRequestHandler.cpp +++ b/src/WSRequestHandler.cpp @@ -48,6 +48,7 @@ QHash WSRequestHandler::messageMap { { "ResetSceneItem", WSRequestHandler::HandleResetSceneItem }, { "DeleteSceneItem", WSRequestHandler::HandleDeleteSceneItem }, { "DuplicateSceneItem", WSRequestHandler::HandleDuplicateSceneItem }, + { "ReorderSceneItems", WSRequestHandler::HandleReorderSceneItems }, { "GetStreamingStatus", WSRequestHandler::HandleGetStreamingStatus }, { "StartStopStreaming", WSRequestHandler::HandleStartStopStreaming }, diff --git a/src/WSRequestHandler.h b/src/WSRequestHandler.h index ad3b779e..cb259827 100644 --- a/src/WSRequestHandler.h +++ b/src/WSRequestHandler.h @@ -75,6 +75,7 @@ class WSRequestHandler : public QObject { static void HandleResetSceneItem(WSRequestHandler* req); static void HandleDuplicateSceneItem(WSRequestHandler* req); static void HandleDeleteSceneItem(WSRequestHandler* req); + static void HandleReorderSceneItems(WSRequestHandler* req); static void HandleGetStreamingStatus(WSRequestHandler* req); static void HandleStartStopStreaming(WSRequestHandler* req); diff --git a/src/WSRequestHandler_SceneItems.cpp b/src/WSRequestHandler_SceneItems.cpp index f41fe50a..e1e279b6 100644 --- a/src/WSRequestHandler_SceneItems.cpp +++ b/src/WSRequestHandler_SceneItems.cpp @@ -686,4 +686,4 @@ void WSRequestHandler::HandleDuplicateSceneItem(WSRequestHandler* req) { obs_data_set_string(responseData, "scene", obs_source_get_name(toScene)); req->SendOKResponse(responseData); -} \ No newline at end of file +} diff --git a/src/WSRequestHandler_Scenes.cpp b/src/WSRequestHandler_Scenes.cpp index 822a822e..bebdb9c2 100644 --- a/src/WSRequestHandler_Scenes.cpp +++ b/src/WSRequestHandler_Scenes.cpp @@ -80,3 +80,69 @@ void WSRequestHandler::HandleGetSceneList(WSRequestHandler* req) { req->SendOKResponse(data); } + +/** +* Changes the order of scene items in the requested scene. +* +* @param {String (optional)} `scene` Name of the scene to reorder (defaults to current). +* @param {Scene|Array} `items` Ordered list of objects with name and/or id specified. Id preferred due to uniqueness per scene +* @param {int (optional)} `items[].id` Id of a specific scene item. Unique on a scene by scene basis. +* @param {String (optional)} `items[].name` Name of a scene item. Sufficiently unique if no scene items share sources within the scene. +* +* @api requests +* @name ReorderSceneItems +* @category scenes +* @since 4.5.0 +*/ +void WSRequestHandler::HandleReorderSceneItems(WSRequestHandler* req) { + QString sceneName = obs_data_get_string(req->data, "scene"); + OBSSourceAutoRelease scene = Utils::GetSceneFromNameOrCurrent(sceneName); + if (!scene) { + req->SendErrorResponse("requested scene doesn't exist"); + return; + } + + OBSDataArrayAutoRelease items = obs_data_get_array(req->data, "items"); + if (!items) { + req->SendErrorResponse("sceneItem order not specified"); + return; + } + + size_t count = obs_data_array_count(items); + + std::vector newOrder; + newOrder.reserve(count); + + for (size_t i = 0; i < count; ++i) { + OBSDataAutoRelease item = obs_data_array_item(items, i); + + OBSSceneItemAutoRelease sceneItem = Utils::GetSceneItemFromItem(scene, item); + obs_sceneitem_release(sceneItem); // ref dec + + if (!sceneItem) { + req->SendErrorResponse("Invalid sceneItem id or name specified"); + return; + } + + for (size_t j = 0; j <= i; ++j) { + if (sceneItem == newOrder[j]) { + req->SendErrorResponse("Duplicate sceneItem in specified order"); + return; + } + } + + newOrder.push_back(sceneItem); + } + + bool success = obs_scene_reorder_items(obs_scene_from_source(scene), newOrder.data(), count); + if (!success) { + req->SendErrorResponse("Invalid sceneItem order"); + return; + } + + for (auto const& item: newOrder) { + obs_sceneitem_release(item); + } + + req->SendOKResponse(); +}