From b7df1e859699b191b625c04b45e68701639c0edd Mon Sep 17 00:00:00 2001 From: Palakis Date: Wed, 19 Apr 2017 13:43:58 +0200 Subject: [PATCH] Add SetPreviewScene request type and PreviewSceneChanged event --- Utils.cpp | 46 ++++++++++++++++++++++++++++++++++++-------- Utils.h | 4 ++++ WSEvents.cpp | 21 ++++++++++++++++++++ WSEvents.h | 2 ++ WSRequestHandler.cpp | 19 ++++++++++++++++-- WSRequestHandler.h | 1 + 6 files changed, 83 insertions(+), 10 deletions(-) diff --git a/Utils.cpp b/Utils.cpp index aeb8e4a2..6294d2ce 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -18,13 +18,12 @@ with this program. If not, see #include "Utils.h" #include +#include #include -#include -#include -#include -#include #include "obs-websocket.h" +Q_DECLARE_METATYPE(OBSScene); + obs_data_array_t* string_list_to_array(char** strings, char* key) { if (!strings) @@ -247,6 +246,21 @@ QPushButton* Utils::GetPreviewModeButtonControl() return main->findChild("modeSwitch"); } +QListWidget* Utils::GetSceneListControl() +{ + QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window(); + return main->findChild("scenes"); +} + +obs_scene_t* Utils::SceneListItemToScene(QListWidgetItem* item) +{ + if (!item) + return nullptr; + + QVariant item_data = item->data(static_cast(Qt::UserRole)); + return item_data.value(); +} + QLayout* Utils::GetPreviewLayout() { QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window(); @@ -288,16 +302,32 @@ const char* Utils::GetPreviewSceneName() { if (IsPreviewModeActive()) { - QMainWindow* main = (QMainWindow*)obs_frontend_get_main_window(); - QListWidget* sceneList = main->findChild("scenes"); + QListWidget* sceneList = GetSceneListControl(); - QString name = sceneList->selectedItems().first()->text(); - return name.toUtf8().constData(); + QList selected = sceneList->selectedItems(); + blog(LOG_INFO, "GetPreviewSceneName: %d selected item(s)", selected.count()); + + // Qt::UserRole == QtUserRole::OBSRef + obs_source_t* source = obs_scene_get_source(Utils::SceneListItemToScene(selected.first())); + + return obs_source_get_name(source); } return nullptr; } +void Utils::SetPreviewScene(const char* name) +{ + if (IsPreviewModeActive()) + { + QListWidget* sceneList = GetSceneListControl(); + QList matchingItems = sceneList->findItems(name, Qt::MatchExactly); + + if (matchingItems.count() > 0) + sceneList->setCurrentItem(matchingItems.first()); + } +} + void Utils::TransitionToProgram() { if (!IsPreviewModeActive()) diff --git a/Utils.h b/Utils.h index d75aca48..ecb96359 100644 --- a/Utils.h +++ b/Utils.h @@ -22,6 +22,7 @@ with this program. If not, see #include #include #include +#include #include #include @@ -46,6 +47,8 @@ class Utils static QPushButton* GetPreviewModeButtonControl(); static QLayout* GetPreviewLayout(); + static QListWidget* GetSceneListControl(); + static obs_scene_t* SceneListItemToScene(QListWidgetItem* item); static bool IsPreviewModeActive(); static void EnablePreviewMode(); @@ -53,6 +56,7 @@ class Utils static void TogglePreviewMode(); static const char* GetPreviewSceneName(); + static void SetPreviewScene(const char* name); static void TransitionToProgram(); static const char* OBSVersionString(); diff --git a/WSEvents.cpp b/WSEvents.cpp index ec20852a..4ae179a1 100644 --- a/WSEvents.cpp +++ b/WSEvents.cpp @@ -68,6 +68,9 @@ WSEvents::WSEvents(WSServer *srv) connect(statusTimer, SIGNAL(timeout()), this, SLOT(StreamStatus())); statusTimer->start(2000); // equal to frontend's constant BITRATE_UPDATE_SECONDS + QListWidget* sceneList = Utils::GetSceneListControl(); + connect(sceneList, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(SelectedSceneChanged(QListWidgetItem*, QListWidgetItem*))); + transition_handler = nullptr; scene_handler = nullptr; @@ -568,4 +571,22 @@ void WSEvents::OnSceneItemVisibilityChanged(void *param, calldata_t *data) instance->broadcastUpdate("SceneItemVisibilityChanged", fields); obs_data_release(fields); +} + +void WSEvents::SelectedSceneChanged(QListWidgetItem *current, QListWidgetItem *prev) +{ + if (Utils::IsPreviewModeActive()) + { + obs_scene_t* scene = Utils::SceneListItemToScene(current); + if (!scene) return; + + obs_source_t* scene_source = obs_scene_get_source(scene); + + obs_data_t* data = obs_data_create(); + obs_data_set_string(data, "scene-name", obs_source_get_name(scene_source)); + + broadcastUpdate("PreviewSceneChanged", data); + + obs_data_release(data); + } } \ No newline at end of file diff --git a/WSEvents.h b/WSEvents.h index 2c678364..31c3bf23 100644 --- a/WSEvents.h +++ b/WSEvents.h @@ -21,6 +21,7 @@ with this program. If not, see #define WSEVENTS_H #include +#include #include "WSServer.h" class WSEvents : public QObject @@ -43,6 +44,7 @@ class WSEvents : public QObject private Q_SLOTS: void StreamStatus(); void TransitionDurationChanged(int ms); + void SelectedSceneChanged(QListWidgetItem *current, QListWidgetItem *prev); void deferredInitOperations(); private: diff --git a/WSRequestHandler.cpp b/WSRequestHandler.cpp index 2d3e75f8..994ab318 100644 --- a/WSRequestHandler.cpp +++ b/WSRequestHandler.cpp @@ -72,6 +72,7 @@ WSRequestHandler::WSRequestHandler(QWebSocket *client) : messageMap["ListProfiles"] = WSRequestHandler::HandleListProfiles; messageMap["GetStudioModeStatus"] = WSRequestHandler::HandleGetStudioModeStatus; + messageMap["SetPreviewScene"] = WSRequestHandler::HandleSetPreviewScene; messageMap["EnableStudioMode"] = WSRequestHandler::HandleEnableStudioMode; messageMap["DisableStudioMode"] = WSRequestHandler::HandleDisableStudioMode; messageMap["ToggleStudioMode"] = WSRequestHandler::HandleToggleStudioMode; @@ -759,8 +760,8 @@ void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler *owner) obs_data_set_bool(response, "studio-mode", previewActive); if (previewActive) { - //const char* currentPreviewScene = Utils::GetPreviewSceneName(); - //obs_data_set_string(response, "preview-scene", currentPreviewScene); + const char* currentPreviewScene = Utils::GetPreviewSceneName(); + obs_data_set_string(response, "preview-scene", currentPreviewScene); } owner->SendOKResponse(response); @@ -768,6 +769,20 @@ void WSRequestHandler::HandleGetStudioModeStatus(WSRequestHandler *owner) obs_data_release(response); } +void WSRequestHandler::HandleSetPreviewScene(WSRequestHandler *owner) +{ + const char* scene_name = obs_data_get_string(owner->_requestData, "scene-name"); + if (!scene_name) + { + owner->SendErrorResponse("invalid request parameters"); + return; + } + + Utils::SetPreviewScene(scene_name); + + owner->SendOKResponse(); +} + void WSRequestHandler::HandleEnableStudioMode(WSRequestHandler *owner) { Utils::EnablePreviewMode(); diff --git a/WSRequestHandler.h b/WSRequestHandler.h index 06f434b5..6b595266 100644 --- a/WSRequestHandler.h +++ b/WSRequestHandler.h @@ -89,6 +89,7 @@ class WSRequestHandler : public QObject static void HandleGetTransitionDuration(WSRequestHandler *owner); static void HandleGetStudioModeStatus(WSRequestHandler *owner); + static void HandleSetPreviewScene(WSRequestHandler *owner); static void HandleEnableStudioMode(WSRequestHandler *owner); static void HandleDisableStudioMode(WSRequestHandler *owner); static void HandleToggleStudioMode(WSRequestHandler *owner);