mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add canvas support to scene selection
This commit is contained in:
parent
8aa6a7df2c
commit
078d62fa18
|
|
@ -170,6 +170,8 @@ target_sources(
|
|||
lib/utils/auto-update-tooltip-label.hpp
|
||||
lib/utils/backup.cpp
|
||||
lib/utils/backup.hpp
|
||||
lib/utils/canvas-helpers.cpp
|
||||
lib/utils/canvas-helpers.hpp
|
||||
lib/utils/condition-logic.cpp
|
||||
lib/utils/condition-logic.hpp
|
||||
lib/utils/curl-helper.cpp
|
||||
|
|
|
|||
|
|
@ -2290,6 +2290,7 @@ AdvSceneSwitcher.tempVar.cursor.x="Cursor position (X)"
|
|||
AdvSceneSwitcher.tempVar.cursor.y="Cursor position (Y)"
|
||||
|
||||
AdvSceneSwitcher.selectScene="--select scene--"
|
||||
AdvSceneSwitcher.selectCanvas="--select canvas--"
|
||||
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
|
||||
AdvSceneSwitcher.selectCurrentScene="Current Scene"
|
||||
AdvSceneSwitcher.selectPreviewScene="Preview Scene"
|
||||
|
|
|
|||
296
lib/utils/canvas-helpers.cpp
Normal file
296
lib/utils/canvas-helpers.cpp
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
#include "canvas-helpers.hpp"
|
||||
#include "obs-module-helper.hpp"
|
||||
#include "scene-group.hpp"
|
||||
#include "scene-switch-helpers.hpp"
|
||||
#include "selection-helpers.hpp"
|
||||
#include "source-helpers.hpp"
|
||||
#include "ui-helpers.hpp"
|
||||
#include "utility.hpp"
|
||||
#include "variable.hpp"
|
||||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
#include <QLayout>
|
||||
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
Q_DECLARE_METATYPE(advss::OBSWeakCanvas);
|
||||
#else
|
||||
Q_DECLARE_METATYPE(OBSWeakCanvas);
|
||||
#endif
|
||||
|
||||
namespace advss {
|
||||
|
||||
void CanvasSelection::Populate()
|
||||
{
|
||||
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
static const auto enumCanvases = [](void *listPtr,
|
||||
obs_canvas_t *canvas) -> bool {
|
||||
auto list = static_cast<FilterComboBox *>(listPtr);
|
||||
OBSWeakCanvas weakCanvas = obs_canvas_get_weak_canvas(canvas);
|
||||
obs_weak_canvas_release(weakCanvas);
|
||||
QVariant variant;
|
||||
variant.setValue(weakCanvas);
|
||||
list->addItem(obs_canvas_get_name(canvas), variant);
|
||||
return true;
|
||||
};
|
||||
obs_enum_canvases(enumCanvases, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
CanvasSelection::CanvasSelection(QWidget *parent)
|
||||
: FilterComboBox(parent,
|
||||
obs_module_text("AdvSceneSwitcher.selectScene"))
|
||||
{
|
||||
setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
Populate();
|
||||
|
||||
connect(this, &FilterComboBox::currentIndexChanged, this,
|
||||
[this]() { emit CanvasChanged(GetCanvas()); });
|
||||
}
|
||||
|
||||
void CanvasSelection::SetCanvas(const OBSWeakCanvas &canvas)
|
||||
{
|
||||
QVariant variant;
|
||||
variant.setValue(canvas);
|
||||
setCurrentIndex(findData(variant));
|
||||
}
|
||||
|
||||
OBSWeakCanvas CanvasSelection::GetCanvas()
|
||||
{
|
||||
return itemData(currentIndex()).value<OBSWeakCanvas>();
|
||||
}
|
||||
|
||||
int GetCanvasCount()
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
return 1;
|
||||
#else
|
||||
static const auto enumCanvases = [](void *countPtr,
|
||||
obs_canvas_t *canvas) -> bool {
|
||||
auto count = static_cast<int *>(countPtr);
|
||||
(*count)++;
|
||||
return true;
|
||||
};
|
||||
int count = 0;
|
||||
obs_enum_canvases(enumCanvases, &count);
|
||||
return count;
|
||||
#endif
|
||||
}
|
||||
|
||||
OBSWeakCanvas GetWeakCanvasByName(const char *name)
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
return OBSWeakCanvas();
|
||||
#else
|
||||
struct Data {
|
||||
OBSWeakCanvas canvas;
|
||||
const std::string name;
|
||||
};
|
||||
|
||||
static const auto enumCanvases = [](void *dataPtr,
|
||||
obs_canvas_t *canvas) -> bool {
|
||||
auto data = static_cast<Data *>(dataPtr);
|
||||
if (data->name != obs_canvas_get_name(canvas)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
data->canvas = obs_canvas_get_weak_canvas(canvas);
|
||||
obs_weak_canvas_release(data->canvas);
|
||||
return false;
|
||||
};
|
||||
Data data{nullptr, name};
|
||||
obs_enum_canvases(enumCanvases, &data);
|
||||
return data.canvas;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetWeakCanvasName(const OBSWeakCanvas &weakCanvas)
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
return "Main";
|
||||
#else
|
||||
OBSCanvasAutoRelease canvas = obs_weak_canvas_get_canvas(weakCanvas);
|
||||
return canvas ? obs_canvas_get_name(canvas) : "";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsMainCanvas(obs_weak_canvas_t *weakCanvas)
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
return true;
|
||||
#else
|
||||
if (!weakCanvas) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OBSCanvasAutoRelease canvas = obs_weak_canvas_get_canvas(weakCanvas);
|
||||
OBSCanvasAutoRelease main = obs_get_main_canvas();
|
||||
return canvas == main;
|
||||
#endif
|
||||
}
|
||||
|
||||
OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &weakCanvas)
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
OBSCanvasAutoRelease canvas;
|
||||
#else
|
||||
if (!weakCanvas) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OBSCanvasAutoRelease canvas = obs_weak_canvas_get_canvas(weakCanvas);
|
||||
if (!canvas) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const auto enumCanvasScenes = [](void *scenePtr,
|
||||
obs_source_t *source) -> bool {
|
||||
auto scene = static_cast<OBSWeakSource *>(scenePtr);
|
||||
if (!obs_source_active(source)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*scene = obs_source_get_weak_source(source);
|
||||
obs_weak_source_release(*scene);
|
||||
return false;
|
||||
};
|
||||
|
||||
OBSWeakSource scene;
|
||||
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx)
|
||||
{
|
||||
if (idx < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
OBSCanvas canvas;
|
||||
#else
|
||||
if (!weakCanvas) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OBSCanvas canvas = OBSGetStrongRef(weakCanvas);
|
||||
if (!canvas) {
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Data {
|
||||
const int idx;
|
||||
int currentIdx;
|
||||
OBSSource scene;
|
||||
};
|
||||
|
||||
static const auto enumCanvasScenes = [](void *dataPtr,
|
||||
obs_source_t *source) -> bool {
|
||||
auto data = static_cast<Data *>(dataPtr);
|
||||
if (data->idx != data->currentIdx) {
|
||||
data->currentIdx++;
|
||||
return true;
|
||||
}
|
||||
|
||||
data->scene = source;
|
||||
return false;
|
||||
};
|
||||
|
||||
Data data{idx, 0, nullptr};
|
||||
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &data);
|
||||
|
||||
return OBSGetWeakRef(data.scene);
|
||||
}
|
||||
|
||||
int GetIndexOfScene(const OBSWeakCanvas &weakCanvas, const OBSWeakSource &scene)
|
||||
{
|
||||
if (!scene) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
OBSCanvas canvas;
|
||||
#else
|
||||
if (!weakCanvas) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OBSCanvas canvas = OBSGetStrongRef(weakCanvas);
|
||||
if (!canvas) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Data {
|
||||
int idx;
|
||||
OBSSource scene;
|
||||
};
|
||||
|
||||
static const auto enumCanvasScenes = [](void *dataPtr,
|
||||
obs_source_t *source) -> bool {
|
||||
auto data = static_cast<Data *>(dataPtr);
|
||||
if (source == data->scene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->idx++;
|
||||
return true;
|
||||
};
|
||||
|
||||
Data data{0, OBSGetStrongRef(scene)};
|
||||
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &data);
|
||||
|
||||
return data.idx;
|
||||
}
|
||||
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
|
||||
obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void obs_canvas_release(obs_canvas_t *) {}
|
||||
|
||||
void obs_weak_canvas_addref(obs_weak_canvas_t *) {}
|
||||
|
||||
void obs_weak_canvas_release(obs_weak_canvas_t *) {}
|
||||
|
||||
OBSCanvas OBSGetStrongRef(obs_weak_object_t *weak)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
obs_weak_canvas_t *obs_canvas_get_weak_canvas(obs_canvas_t *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
obs_canvas_t *obs_weak_canvas_get_canvas(obs_weak_canvas_t *)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void obs_canvas_enum_scenes(obs_canvas_t *,
|
||||
bool (*enum_proc)(void *, obs_source_t *),
|
||||
void *param)
|
||||
{
|
||||
obs_enum_scenes(enum_proc, param);
|
||||
}
|
||||
|
||||
OBSCanvas OBSGetStrongRef(obs_weak_canvas_t *)
|
||||
{
|
||||
return OBSCanvas();
|
||||
}
|
||||
|
||||
obs_canvas_t *obs_get_main_canvas()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace advss
|
||||
61
lib/utils/canvas-helpers.hpp
Normal file
61
lib/utils/canvas-helpers.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
|
||||
namespace advss {
|
||||
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
class EXPORT obs_canvas_t {};
|
||||
class EXPORT obs_weak_canvas_t {};
|
||||
|
||||
EXPORT obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *);
|
||||
EXPORT void obs_canvas_release(obs_canvas_t *);
|
||||
EXPORT void obs_weak_canvas_addref(obs_weak_canvas_t *);
|
||||
EXPORT void obs_weak_canvas_release(obs_weak_canvas_t *);
|
||||
|
||||
using OBSCanvas =
|
||||
OBSSafeRef<obs_canvas_t *, obs_canvas_get_ref, obs_canvas_release>;
|
||||
using OBSWeakCanvas = OBSRef<obs_weak_canvas_t *, obs_weak_canvas_addref,
|
||||
obs_weak_canvas_release>;
|
||||
using OBSCanvasAutoRelease =
|
||||
OBSRefAutoRelease<obs_canvas_t *, obs_canvas_release>;
|
||||
using OBSWeakCanvasAutoRelease =
|
||||
OBSRefAutoRelease<obs_weak_canvas_t *, obs_weak_canvas_release>;
|
||||
|
||||
EXPORT obs_weak_canvas_t *obs_canvas_get_weak_canvas(obs_canvas_t *);
|
||||
EXPORT obs_canvas_t *obs_weak_canvas_get_canvas(obs_weak_canvas_t *);
|
||||
EXPORT void obs_canvas_enum_scenes(obs_canvas_t *,
|
||||
bool (*enum_proc)(void *, obs_source_t *),
|
||||
void *param);
|
||||
EXPORT OBSCanvas OBSGetStrongRef(obs_weak_canvas_t *);
|
||||
EXPORT OBSWeakCanvas OBSGetWeakRef(obs_canvas_t *);
|
||||
EXPORT obs_canvas_t *obs_get_main_canvas();
|
||||
|
||||
#endif
|
||||
|
||||
EXPORT int GetCanvasCount();
|
||||
EXPORT OBSWeakCanvas GetWeakCanvasByName(const char *name);
|
||||
EXPORT std::string GetWeakCanvasName(const OBSWeakCanvas &canvas);
|
||||
EXPORT bool IsMainCanvas(obs_weak_canvas_t *canvas);
|
||||
EXPORT OBSWeakSource GetActiveCanvasScene(const OBSWeakCanvas &canvas);
|
||||
EXPORT OBSWeakSource GetSceneAtIndex(const OBSWeakCanvas &weakCanvas, int idx);
|
||||
EXPORT int GetIndexOfScene(const OBSWeakCanvas &weakCanvas,
|
||||
const OBSWeakSource &scene);
|
||||
|
||||
class CanvasSelection : public FilterComboBox {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EXPORT CanvasSelection(QWidget *parent);
|
||||
EXPORT void SetCanvas(const OBSWeakCanvas &);
|
||||
EXPORT OBSWeakCanvas GetCanvas();
|
||||
|
||||
signals:
|
||||
void CanvasChanged(const OBSWeakCanvas &);
|
||||
|
||||
private:
|
||||
void Populate();
|
||||
};
|
||||
|
||||
} // namespace advss
|
||||
|
|
@ -10,15 +10,18 @@
|
|||
|
||||
#include <obs-frontend-api.h>
|
||||
|
||||
#include <QLayout>
|
||||
|
||||
namespace advss {
|
||||
|
||||
constexpr std::string_view typeSaveName = "type";
|
||||
constexpr std::string_view nameSaveName = "name";
|
||||
constexpr std::string_view selectionSaveName = "sceneSelection";
|
||||
constexpr std::string_view canvasSaveName = "canvasSelection";
|
||||
|
||||
void SceneSelection::Save(obs_data_t *obj) const
|
||||
{
|
||||
auto data = obs_data_create();
|
||||
OBSDataAutoRelease data = obs_data_create();
|
||||
obs_data_set_int(data, typeSaveName.data(), static_cast<int>(_type));
|
||||
switch (_type) {
|
||||
case Type::SCENE:
|
||||
|
|
@ -41,8 +44,31 @@ void SceneSelection::Save(obs_data_t *obj) const
|
|||
default:
|
||||
break;
|
||||
}
|
||||
obs_data_set_string(data, canvasSaveName.data(),
|
||||
GetWeakCanvasName(_canvas).c_str());
|
||||
obs_data_set_obj(obj, selectionSaveName.data(), data);
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
static OBSWeakSource getWeakSceneSourceByName(const OBSWeakCanvas &weakCanvas,
|
||||
const char *name)
|
||||
{
|
||||
#if LIBOBS_API_VER < MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
return GetWeakSourceByName(name);
|
||||
#else
|
||||
if (!weakCanvas) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OBSCanvasAutoRelease canvas = obs_weak_canvas_get_canvas(weakCanvas);
|
||||
if (!canvas) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OBSSourceAutoRelease source =
|
||||
obs_canvas_get_source_by_name(canvas, name);
|
||||
OBSWeakSource scene = OBSGetWeakRef(source);
|
||||
return scene;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SceneSelection::Load(obs_data_t *obj, const char *name,
|
||||
|
|
@ -51,10 +77,15 @@ void SceneSelection::Load(obs_data_t *obj, const char *name,
|
|||
// TODO: Remove in future version
|
||||
if (!obs_data_has_user_value(obj, selectionSaveName.data())) {
|
||||
_type = static_cast<Type>(obs_data_get_int(obj, typeName));
|
||||
|
||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
||||
_canvas = obs_canvas_get_weak_canvas(mainCanvas);
|
||||
obs_weak_canvas_release(_canvas);
|
||||
|
||||
auto targetName = obs_data_get_string(obj, name);
|
||||
switch (_type) {
|
||||
case Type::SCENE:
|
||||
_scene = GetWeakSourceByName(targetName);
|
||||
_scene = getWeakSceneSourceByName(_canvas, targetName);
|
||||
break;
|
||||
case Type::GROUP:
|
||||
_group = GetSceneGroupByName(targetName);
|
||||
|
|
@ -69,12 +100,23 @@ void SceneSelection::Load(obs_data_t *obj, const char *name,
|
|||
return;
|
||||
}
|
||||
|
||||
auto data = obs_data_get_obj(obj, selectionSaveName.data());
|
||||
OBSDataAutoRelease data =
|
||||
obs_data_get_obj(obj, selectionSaveName.data());
|
||||
|
||||
if (obs_data_has_user_value(data, canvasSaveName.data())) {
|
||||
_canvas = GetWeakCanvasByName(
|
||||
obs_data_get_string(data, canvasSaveName.data()));
|
||||
} else {
|
||||
OBSCanvasAutoRelease mainCanvas = obs_get_main_canvas();
|
||||
_canvas = obs_canvas_get_weak_canvas(mainCanvas);
|
||||
obs_weak_canvas_release(_canvas);
|
||||
}
|
||||
|
||||
_type = static_cast<Type>(obs_data_get_int(data, typeSaveName.data()));
|
||||
auto targetName = obs_data_get_string(data, nameSaveName.data());
|
||||
switch (_type) {
|
||||
case Type::SCENE:
|
||||
_scene = GetWeakSourceByName(targetName);
|
||||
_scene = getWeakSceneSourceByName(_canvas, targetName);
|
||||
break;
|
||||
case Type::GROUP:
|
||||
_group = GetSceneGroupByName(targetName);
|
||||
|
|
@ -91,15 +133,18 @@ void SceneSelection::Load(obs_data_t *obj, const char *name,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
obs_data_release(data);
|
||||
}
|
||||
|
||||
static bool IsScene(const OBSWeakSource &source)
|
||||
static bool isScene(const OBSWeakSource &source)
|
||||
{
|
||||
auto s = obs_weak_source_get_source(source);
|
||||
bool ret = !!obs_scene_from_source(s);
|
||||
obs_source_release(s);
|
||||
return ret;
|
||||
OBSSourceAutoRelease s = obs_weak_source_get_source(source);
|
||||
return !!obs_scene_from_source(s);
|
||||
}
|
||||
|
||||
void SceneSelection::SetScene(const OBSWeakSource &scene)
|
||||
{
|
||||
_type = Type::SCENE;
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
OBSWeakSource SceneSelection::GetScene(bool advance) const
|
||||
|
|
@ -116,23 +161,30 @@ OBSWeakSource SceneSelection::GetScene(bool advance) const
|
|||
}
|
||||
return _group->getCurrentScene();
|
||||
case Type::PREVIOUS:
|
||||
if (!IsMainCanvas(_canvas)) {
|
||||
return nullptr;
|
||||
}
|
||||
return GetPreviousScene();
|
||||
case Type::CURRENT:
|
||||
return GetCurrentScene();
|
||||
if (IsMainCanvas(_canvas)) {
|
||||
return GetCurrentScene();
|
||||
} else {
|
||||
return GetActiveCanvasScene(_canvas);
|
||||
}
|
||||
case Type::PREVIEW: {
|
||||
auto s = obs_frontend_get_current_preview_scene();
|
||||
auto scene = obs_source_get_weak_source(s);
|
||||
obs_weak_source_release(scene);
|
||||
obs_source_release(s);
|
||||
return scene;
|
||||
OBSSourceAutoRelease s =
|
||||
obs_frontend_get_current_preview_scene();
|
||||
OBSWeakSourceAutoRelease scene = obs_source_get_weak_source(s);
|
||||
return scene.Get();
|
||||
}
|
||||
case Type::VARIABLE: {
|
||||
auto var = _variable.lock();
|
||||
if (!var) {
|
||||
return nullptr;
|
||||
}
|
||||
auto scene = GetWeakSourceByName(var->Value().c_str());
|
||||
if (IsScene(scene)) {
|
||||
auto scene =
|
||||
getWeakSceneSourceByName(_canvas, var->Value().c_str());
|
||||
if (isScene(scene)) {
|
||||
return scene;
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -190,8 +242,23 @@ void SceneSelection::ResolveVariables()
|
|||
SceneSelection SceneSelectionWidget::CurrentSelection()
|
||||
{
|
||||
SceneSelection s;
|
||||
const int idx = currentIndex();
|
||||
const auto name = currentText();
|
||||
|
||||
static auto mainCanvas = obs_get_main_canvas();
|
||||
static auto mainCanvasWeak = obs_canvas_get_weak_canvas(mainCanvas);
|
||||
[[maybe_unused]] static const bool _ = []() {
|
||||
// Let's just hope we don't have to deal with selecting scenes
|
||||
// when the OBS main canvas gets deleted and release the
|
||||
// references here already to avoid reporting leaks on shutdown
|
||||
obs_canvas_release(mainCanvas);
|
||||
obs_weak_canvas_release(mainCanvasWeak);
|
||||
return true;
|
||||
}();
|
||||
|
||||
s._canvas = _forceMainCanvas ? OBSWeakCanvas(mainCanvasWeak)
|
||||
: _canvas->GetCanvas();
|
||||
|
||||
const int idx = _scenes->currentIndex();
|
||||
const auto name = _scenes->currentText();
|
||||
if (idx == -1 || name.isEmpty()) {
|
||||
return s;
|
||||
}
|
||||
|
|
@ -214,7 +281,8 @@ SceneSelection SceneSelectionWidget::CurrentSelection()
|
|||
s._group = GetSceneGroupByQString(name);
|
||||
} else if (idx < _scenesEndIdx) {
|
||||
s._type = SceneSelection::Type::SCENE;
|
||||
s._scene = GetWeakSourceByQString(name);
|
||||
s._scene = getWeakSceneSourceByName(s._canvas,
|
||||
name.toStdString().c_str());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
@ -234,20 +302,6 @@ static QStringList getOrderList(bool current, bool previous, bool preview)
|
|||
return list;
|
||||
}
|
||||
|
||||
static QStringList getScenesList()
|
||||
{
|
||||
QStringList list;
|
||||
char **scenes = obs_frontend_get_scene_names();
|
||||
char **temp = scenes;
|
||||
while (*temp) {
|
||||
const char *name = *temp;
|
||||
list << name;
|
||||
temp++;
|
||||
}
|
||||
bfree(scenes);
|
||||
return list;
|
||||
}
|
||||
|
||||
static QStringList getSceneGroupsList()
|
||||
{
|
||||
QStringList list;
|
||||
|
|
@ -258,72 +312,108 @@ static QStringList getSceneGroupsList()
|
|||
return list;
|
||||
}
|
||||
|
||||
static QStringList getCanvasScenesList(obs_weak_canvas_t *weakCanvas)
|
||||
{
|
||||
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(31, 1, 0)
|
||||
if (!weakCanvas) {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
OBSCanvasAutoRelease canvas = obs_weak_canvas_get_canvas(weakCanvas);
|
||||
static const auto enumCanvasScenes = [](void *listPtr,
|
||||
obs_source_t *source) -> bool {
|
||||
auto list = static_cast<QStringList *>(listPtr);
|
||||
*list << obs_source_get_name(source);
|
||||
return true;
|
||||
};
|
||||
|
||||
QStringList list;
|
||||
obs_canvas_enum_scenes(canvas, enumCanvasScenes, &list);
|
||||
return list;
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::Reset()
|
||||
{
|
||||
auto previousSel = _currentSelection;
|
||||
PopulateSelection();
|
||||
PopulateSceneSelection(_currentSelection._canvas);
|
||||
SetScene(previousSel);
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::PopulateSelection()
|
||||
void SceneSelectionWidget::PopulateSceneSelection(obs_weak_canvas_t *canvas)
|
||||
{
|
||||
clear();
|
||||
if (_current || _previous) {
|
||||
const QStringList order =
|
||||
getOrderList(_current, _previous, _preview);
|
||||
AddSelectionGroup(this, order);
|
||||
_scenes->clear();
|
||||
if ((_current || _previous)) {
|
||||
const bool isMain = IsMainCanvas(canvas);
|
||||
const QStringList order = getOrderList(
|
||||
_current, _previous && isMain, _preview && isMain);
|
||||
AddSelectionGroup(_scenes, order);
|
||||
}
|
||||
_placeholderEndIdx = count();
|
||||
_placeholderEndIdx = _scenes->count();
|
||||
|
||||
if (_variables) {
|
||||
const QStringList variables = GetVariablesNameList();
|
||||
AddSelectionGroup(this, variables);
|
||||
AddSelectionGroup(_scenes, variables);
|
||||
}
|
||||
_variablesEndIdx = count();
|
||||
_variablesEndIdx = _scenes->count();
|
||||
|
||||
if (_sceneGroups) {
|
||||
const QStringList sceneGroups = getSceneGroupsList();
|
||||
AddSelectionGroup(this, sceneGroups);
|
||||
AddSelectionGroup(_scenes, sceneGroups);
|
||||
}
|
||||
_groupsEndIdx = count();
|
||||
_groupsEndIdx = _scenes->count();
|
||||
|
||||
const QStringList scenes = getScenesList();
|
||||
AddSelectionGroup(this, scenes);
|
||||
_scenesEndIdx = count();
|
||||
const QStringList scenes = getCanvasScenesList(canvas);
|
||||
AddSelectionGroup(_scenes, scenes);
|
||||
_scenesEndIdx = _scenes->count();
|
||||
|
||||
// Remove last separator
|
||||
removeItem(count() - 1);
|
||||
setCurrentIndex(-1);
|
||||
_scenes->removeItem(_scenes->count() - 1);
|
||||
_scenes->setCurrentIndex(-1);
|
||||
|
||||
_isPopulated = true;
|
||||
|
||||
Resize();
|
||||
}
|
||||
|
||||
SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
|
||||
bool sceneGroups, bool previous,
|
||||
bool current, bool preview)
|
||||
: FilterComboBox(parent,
|
||||
obs_module_text("AdvSceneSwitcher.selectScene")),
|
||||
: QWidget(parent),
|
||||
_scenes(new FilterComboBox(
|
||||
this, obs_module_text("AdvSceneSwitcher.selectScene"))),
|
||||
_canvas(new CanvasSelection(this)),
|
||||
_current(current),
|
||||
_previous(previous),
|
||||
_preview(preview),
|
||||
_variables(variables),
|
||||
_sceneGroups(sceneGroups)
|
||||
{
|
||||
setDuplicatesEnabled(true);
|
||||
PopulateSelection();
|
||||
_scenes->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
_scenes->setDuplicatesEnabled(true);
|
||||
|
||||
QWidget::connect(this, SIGNAL(currentIndexChanged(int)), this,
|
||||
QWidget::connect(_scenes, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(SelectionChanged(int)));
|
||||
QWidget::connect(_canvas, SIGNAL(CanvasChanged(const OBSWeakCanvas &)),
|
||||
this, SLOT(CanvasChangedSlot(const OBSWeakCanvas &)));
|
||||
QWidget::connect(_canvas, SIGNAL(CanvasChanged(const OBSWeakCanvas &)),
|
||||
this, SIGNAL(CanvasChanged(const OBSWeakCanvas &)));
|
||||
|
||||
// Scene groups
|
||||
QWidget::connect(GetSettingsWindow(),
|
||||
SIGNAL(SceneGroupAdded(const QString &)), this,
|
||||
SLOT(ItemAdd(const QString &)));
|
||||
QWidget::connect(GetSettingsWindow(),
|
||||
SIGNAL(SceneGroupRemoved(const QString &)), this,
|
||||
SLOT(ItemRemove(const QString &)));
|
||||
QWidget::connect(
|
||||
GetSettingsWindow(),
|
||||
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
|
||||
this, SLOT(ItemRename(const QString &, const QString &)));
|
||||
auto settingsWindow = GetSettingsWindow();
|
||||
if (settingsWindow) {
|
||||
QWidget::connect(settingsWindow,
|
||||
SIGNAL(SceneGroupAdded(const QString &)), this,
|
||||
SLOT(ItemAdd(const QString &)));
|
||||
QWidget::connect(settingsWindow,
|
||||
SIGNAL(SceneGroupRemoved(const QString &)),
|
||||
this, SLOT(ItemRemove(const QString &)));
|
||||
QWidget::connect(
|
||||
settingsWindow,
|
||||
SIGNAL(SceneGroupRenamed(const QString &,
|
||||
const QString &)),
|
||||
this,
|
||||
SLOT(ItemRename(const QString &, const QString &)));
|
||||
}
|
||||
|
||||
// Variables
|
||||
QWidget::connect(VariableSignalManager::Instance(),
|
||||
|
|
@ -335,19 +425,37 @@ SceneSelectionWidget::SceneSelectionWidget(QWidget *parent, bool variables,
|
|||
QWidget::connect(VariableSignalManager::Instance(),
|
||||
SIGNAL(Rename(const QString &, const QString &)), this,
|
||||
SLOT(ItemRename(const QString &, const QString &)));
|
||||
|
||||
auto layout = new QHBoxLayout();
|
||||
layout->addWidget(_canvas);
|
||||
layout->addWidget(_scenes);
|
||||
setLayout(layout);
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
if (GetCanvasCount() <= 1) {
|
||||
_canvas->hide();
|
||||
}
|
||||
|
||||
Resize();
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
||||
{
|
||||
int idx = -1;
|
||||
|
||||
_canvas->SetCanvas(s._canvas);
|
||||
if (!_isPopulated) {
|
||||
PopulateSceneSelection(s._canvas);
|
||||
}
|
||||
|
||||
switch (s.GetType()) {
|
||||
case SceneSelection::Type::SCENE: {
|
||||
if (_scenesEndIdx == -1) {
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
idx = FindIdxInRagne(this, _groupsEndIdx, _scenesEndIdx,
|
||||
idx = FindIdxInRagne(_scenes, _groupsEndIdx, _scenesEndIdx,
|
||||
s.ToString());
|
||||
break;
|
||||
}
|
||||
|
|
@ -356,7 +464,7 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
|||
idx = -1;
|
||||
break;
|
||||
}
|
||||
idx = FindIdxInRagne(this, _variablesEndIdx, _groupsEndIdx,
|
||||
idx = FindIdxInRagne(_scenes, _variablesEndIdx, _groupsEndIdx,
|
||||
s.ToString());
|
||||
break;
|
||||
}
|
||||
|
|
@ -367,7 +475,7 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
|||
}
|
||||
|
||||
idx = FindIdxInRagne(
|
||||
this, _selectIdx, _placeholderEndIdx,
|
||||
_scenes, _selectIdx, _placeholderEndIdx,
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.selectPreviousScene"));
|
||||
break;
|
||||
|
|
@ -379,7 +487,7 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
|||
}
|
||||
|
||||
idx = FindIdxInRagne(
|
||||
this, _selectIdx, _placeholderEndIdx,
|
||||
_scenes, _selectIdx, _placeholderEndIdx,
|
||||
obs_module_text("AdvSceneSwitcher.selectCurrentScene"));
|
||||
break;
|
||||
}
|
||||
|
|
@ -390,7 +498,7 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
|||
}
|
||||
|
||||
idx = FindIdxInRagne(
|
||||
this, _selectIdx, _placeholderEndIdx,
|
||||
_scenes, _selectIdx, _placeholderEndIdx,
|
||||
obs_module_text("AdvSceneSwitcher.selectPreviewScene"));
|
||||
break;
|
||||
}
|
||||
|
|
@ -399,22 +507,31 @@ void SceneSelectionWidget::SetScene(const SceneSelection &s)
|
|||
idx = -1;
|
||||
break;
|
||||
}
|
||||
idx = FindIdxInRagne(this, _placeholderEndIdx, _variablesEndIdx,
|
||||
s.ToString());
|
||||
idx = FindIdxInRagne(_scenes, _placeholderEndIdx,
|
||||
_variablesEndIdx, s.ToString());
|
||||
break;
|
||||
default:
|
||||
idx = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setCurrentIndex(idx);
|
||||
_scenes->setCurrentIndex(idx);
|
||||
_currentSelection = s;
|
||||
|
||||
Resize();
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::LockToMainCanvas()
|
||||
{
|
||||
_forceMainCanvas = true;
|
||||
_canvas->hide();
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
FilterComboBox::showEvent(event);
|
||||
const QSignalBlocker b(this);
|
||||
QWidget::showEvent(event);
|
||||
const QSignalBlocker b1(_scenes);
|
||||
const QSignalBlocker b2(_canvas);
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
|
@ -442,9 +559,16 @@ void SceneSelectionWidget::SelectionChanged(int)
|
|||
emit SceneChanged(_currentSelection);
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::CanvasChangedSlot(const OBSWeakCanvas &)
|
||||
{
|
||||
_currentSelection = CurrentSelection();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::ItemAdd(const QString &)
|
||||
{
|
||||
const QSignalBlocker b(this);
|
||||
const QSignalBlocker b1(_scenes);
|
||||
const QSignalBlocker b2(_canvas);
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +580,7 @@ bool SceneSelectionWidget::NameUsed(const QString &name)
|
|||
return true;
|
||||
}
|
||||
return _currentSelection._type == SceneSelection::Type::VARIABLE &&
|
||||
currentText() == name;
|
||||
_scenes->currentText() == name;
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::ItemRemove(const QString &name)
|
||||
|
|
@ -470,8 +594,19 @@ void SceneSelectionWidget::ItemRemove(const QString &name)
|
|||
|
||||
void SceneSelectionWidget::ItemRename(const QString &, const QString &)
|
||||
{
|
||||
const QSignalBlocker b(this);
|
||||
const QSignalBlocker b1(_scenes);
|
||||
const QSignalBlocker b2(_canvas);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SceneSelectionWidget::Resize()
|
||||
{
|
||||
_scenes->adjustSize();
|
||||
_scenes->updateGeometry();
|
||||
_canvas->adjustSize();
|
||||
_canvas->updateGeometry();
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
} // namespace advss
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
#include "filter-combo-box.hpp"
|
||||
|
||||
#include <obs.hpp>
|
||||
#include "canvas-helpers.hpp"
|
||||
|
||||
namespace advss {
|
||||
|
||||
|
|
@ -24,19 +22,22 @@ public:
|
|||
};
|
||||
|
||||
EXPORT Type GetType() const { return _type; }
|
||||
EXPORT void SetScene(const OBSWeakSource &scene);
|
||||
EXPORT OBSWeakSource GetScene(bool advance = true) const;
|
||||
EXPORT OBSWeakCanvas GetCanvas() const { return _canvas; };
|
||||
EXPORT std::string ToString(bool resolve = false) const;
|
||||
EXPORT void ResolveVariables();
|
||||
|
||||
private:
|
||||
OBSWeakSource _scene;
|
||||
OBSWeakCanvas _canvas;
|
||||
SceneGroup *_group = nullptr;
|
||||
std::weak_ptr<Variable> _variable;
|
||||
Type _type = Type::SCENE;
|
||||
friend class SceneSelectionWidget;
|
||||
};
|
||||
|
||||
class SceneSelectionWidget : public FilterComboBox {
|
||||
class SceneSelectionWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
|
@ -45,15 +46,18 @@ public:
|
|||
bool previous = false, bool current = false,
|
||||
bool preview = false);
|
||||
EXPORT void SetScene(const SceneSelection &);
|
||||
void LockToMainCanvas();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
signals:
|
||||
void SceneChanged(const SceneSelection &);
|
||||
void CanvasChanged(const OBSWeakCanvas &);
|
||||
|
||||
private slots:
|
||||
EXPORT void SelectionChanged(int);
|
||||
EXPORT void CanvasChangedSlot(const OBSWeakCanvas &);
|
||||
EXPORT void ItemAdd(const QString &name);
|
||||
EXPORT void ItemRemove(const QString &name);
|
||||
EXPORT void ItemRename(const QString &oldName, const QString &newName);
|
||||
|
|
@ -61,11 +65,15 @@ private slots:
|
|||
private:
|
||||
void Reset();
|
||||
SceneSelection CurrentSelection();
|
||||
void PopulateSelection();
|
||||
void PopulateSceneSelection(obs_weak_canvas_t *canvas);
|
||||
bool IsCurrentSceneSelected(const QString &name);
|
||||
bool IsPreviousSceneSelected(const QString &name);
|
||||
bool IsPreviewSceneSelected(const QString &name);
|
||||
bool NameUsed(const QString &name);
|
||||
void Resize();
|
||||
|
||||
FilterComboBox *_scenes;
|
||||
CanvasSelection *_canvas;
|
||||
|
||||
bool _current;
|
||||
bool _previous;
|
||||
|
|
@ -73,7 +81,10 @@ private:
|
|||
bool _variables;
|
||||
bool _sceneGroups;
|
||||
|
||||
bool _forceMainCanvas = false;
|
||||
|
||||
SceneSelection _currentSelection;
|
||||
bool _isPopulated = false;
|
||||
|
||||
// Order of entries
|
||||
// 1. "select entry" entry
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user