frontend: Add support loading/saving additional canvases
This commit is contained in:
parent
afd7619c98
commit
368185019e
@ -15,6 +15,7 @@ target_sources(
|
||||
widgets/OBSBasic.cpp
|
||||
widgets/OBSBasic.hpp
|
||||
widgets/OBSBasic_Browser.cpp
|
||||
widgets/OBSBasic_Canvases.cpp
|
||||
widgets/OBSBasic_Clipboard.cpp
|
||||
widgets/OBSBasic_ContextToolbar.cpp
|
||||
widgets/OBSBasic_Docks.cpp
|
||||
|
@ -842,7 +842,7 @@ void OBSBasic::InitOBSCallbacks()
|
||||
{
|
||||
ProfileScope("OBSBasic::InitOBSCallbacks");
|
||||
|
||||
signalHandlers.reserve(signalHandlers.size() + 9);
|
||||
signalHandlers.reserve(signalHandlers.size() + 10);
|
||||
signalHandlers.emplace_back(obs_get_signal_handler(), "source_create", OBSBasic::SourceCreated, this);
|
||||
signalHandlers.emplace_back(obs_get_signal_handler(), "source_remove", OBSBasic::SourceRemoved, this);
|
||||
signalHandlers.emplace_back(obs_get_signal_handler(), "source_activate", OBSBasic::SourceActivated, this);
|
||||
@ -866,6 +866,7 @@ void OBSBasic::InitOBSCallbacks()
|
||||
Qt::QueuedConnection);
|
||||
},
|
||||
this);
|
||||
signalHandlers.emplace_back(obs_get_signal_handler(), "canvas_remove", OBSBasic::CanvasRemoved, this);
|
||||
}
|
||||
|
||||
#define STARTUP_SEPARATOR "==== Startup complete ==============================================="
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <OBSApp.hpp>
|
||||
#include <oauth/Auth.hpp>
|
||||
#include <utility/BasicOutputHandler.hpp>
|
||||
#include <utility/OBSCanvas.hpp>
|
||||
#include <utility/VCamConfig.hpp>
|
||||
#include <utility/platform.hpp>
|
||||
#include <utility/undo_stack.hpp>
|
||||
@ -1108,6 +1109,23 @@ public:
|
||||
std::optional<SceneCollection> GetSceneCollectionByName(const std::string &collectionName) const;
|
||||
std::optional<SceneCollection> GetSceneCollectionByFileName(const std::string &fileName) const;
|
||||
|
||||
/* -------------------------------------
|
||||
* MARK: - OBSBasic_Canvases
|
||||
* -------------------------------------
|
||||
*/
|
||||
private:
|
||||
std::vector<OBS::Canvas> canvases;
|
||||
|
||||
static void CanvasRemoved(void *data, calldata_t *params);
|
||||
|
||||
public:
|
||||
const std::vector<OBS::Canvas> &GetCanvases() const noexcept { return canvases; }
|
||||
|
||||
const OBS::Canvas &AddCanvas(const std::string &name, obs_video_info *ovi = nullptr, int flags = 0);
|
||||
|
||||
public slots:
|
||||
bool RemoveCanvas(obs_canvas_t *canvas);
|
||||
|
||||
/* -------------------------------------
|
||||
* MARK: - OBSBasic_SceneItems
|
||||
* -------------------------------------
|
||||
|
47
frontend/widgets/OBSBasic_Canvases.cpp
Normal file
47
frontend/widgets/OBSBasic_Canvases.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
Copyright (C) 2025 by Dennis Sädtler <saedtler@twitch.tv>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
#include "OBSBasic.hpp"
|
||||
|
||||
void OBSBasic::CanvasRemoved(void *data, calldata_t *params)
|
||||
{
|
||||
obs_canvas_t *canvas = static_cast<obs_canvas_t *>(calldata_ptr(params, "canvas"));
|
||||
QMetaObject::invokeMethod(static_cast<OBSBasic *>(data), "RemoveCanvas", Q_ARG(OBSCanvas, OBSCanvas(canvas)));
|
||||
}
|
||||
|
||||
const OBS::Canvas &OBSBasic::AddCanvas(const std::string &name, obs_video_info *ovi, int flags)
|
||||
{
|
||||
OBSCanvas canvas = obs_canvas_create(name.c_str(), ovi, flags);
|
||||
auto &it = canvases.emplace_back(canvas);
|
||||
OnEvent(OBS_FRONTEND_EVENT_CANVAS_ADDED);
|
||||
return it;
|
||||
}
|
||||
|
||||
bool OBSBasic::RemoveCanvas(obs_canvas_t *canvas)
|
||||
{
|
||||
if (!canvas)
|
||||
return false;
|
||||
|
||||
auto canvas_it = std::find(std::begin(canvases), std::end(canvases), canvas);
|
||||
if (canvas_it != std::end(canvases)) {
|
||||
canvases.erase(canvas_it);
|
||||
OnEvent(OBS_FRONTEND_EVENT_CANVAS_REMOVED);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -808,7 +808,8 @@ static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent, v
|
||||
|
||||
static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, obs_data_array_t *quickTransitionData,
|
||||
int transitionDuration, obs_data_array_t *transitions, OBSScene &scene,
|
||||
OBSSource &curProgramScene, obs_data_array_t *savedProjectorList)
|
||||
OBSSource &curProgramScene, obs_data_array_t *savedProjectorList,
|
||||
obs_data_array_t *savedCanvases)
|
||||
{
|
||||
obs_data_t *saveData = obs_data_create();
|
||||
|
||||
@ -865,6 +866,7 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, obs_data_array
|
||||
obs_data_set_array(saveData, "quick_transitions", quickTransitionData);
|
||||
obs_data_set_array(saveData, "transitions", transitions);
|
||||
obs_data_set_array(saveData, "saved_projectors", savedProjectorList);
|
||||
obs_data_set_array(saveData, "canvases", savedCanvases);
|
||||
obs_data_array_release(sourcesArray);
|
||||
obs_data_array_release(groupsArray);
|
||||
|
||||
@ -885,8 +887,10 @@ void OBSBasic::Save(SceneCollection &collection)
|
||||
OBSDataArrayAutoRelease transitions = SaveTransitions();
|
||||
OBSDataArrayAutoRelease quickTrData = SaveQuickTransitions();
|
||||
OBSDataArrayAutoRelease savedProjectorList = SaveProjectors();
|
||||
OBSDataArrayAutoRelease savedCanvases = OBS::Canvas::SaveCanvases(canvases);
|
||||
OBSDataAutoRelease saveData = GenerateSaveData(sceneOrder, quickTrData, ui->transitionDuration->value(),
|
||||
transitions, scene, curProgramScene, savedProjectorList);
|
||||
transitions, scene, curProgramScene, savedProjectorList,
|
||||
savedCanvases);
|
||||
|
||||
obs_data_set_bool(saveData, "preview_locked", ui->preview->Locked());
|
||||
obs_data_set_bool(saveData, "scaling_enabled", ui->preview->IsFixedScaling());
|
||||
@ -1171,6 +1175,7 @@ void OBSBasic::LoadData(obs_data_t *data, SceneCollection &collection)
|
||||
OBSDataArrayAutoRelease sources = obs_data_get_array(data, "sources");
|
||||
OBSDataArrayAutoRelease groups = obs_data_get_array(data, "groups");
|
||||
OBSDataArrayAutoRelease transitions = obs_data_get_array(data, "transitions");
|
||||
OBSDataArrayAutoRelease collection_canvases = obs_data_get_array(data, "canvases");
|
||||
const char *sceneName = obs_data_get_string(data, "current_scene");
|
||||
const char *programSceneName = obs_data_get_string(data, "current_program_scene");
|
||||
const char *transitionName = obs_data_get_string(data, "current_transition");
|
||||
@ -1207,6 +1212,9 @@ void OBSBasic::LoadData(obs_data_t *data, SceneCollection &collection)
|
||||
LoadAudioDevice(AUX_AUDIO_3, 5, data);
|
||||
LoadAudioDevice(AUX_AUDIO_4, 6, data);
|
||||
|
||||
if (collection_canvases)
|
||||
canvases = OBS::Canvas::LoadCanvases(collection_canvases);
|
||||
|
||||
if (!sources) {
|
||||
sources = std::move(groups);
|
||||
} else {
|
||||
@ -1525,6 +1533,12 @@ void OBSBasic::ClearSceneData()
|
||||
obs_enum_scenes(cb, nullptr);
|
||||
obs_enum_sources(cb, nullptr);
|
||||
|
||||
for (const auto &canvas : canvases) {
|
||||
obs_canvas_enum_scenes(canvas, cb, nullptr);
|
||||
}
|
||||
|
||||
canvases.clear();
|
||||
|
||||
OnEvent(OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP);
|
||||
|
||||
undo_s.clear();
|
||||
|
Loading…
x
Reference in New Issue
Block a user