Move functions not required in advanced-scene-switcher.hpp

Create header for platform specific functions.
Move some UI helper functions to utility.hpp.
This commit is contained in:
WarmUpTill 2021-05-24 14:28:12 +02:00 committed by WarmUpTill
parent a93cec2bb9
commit 5496c256c0
33 changed files with 700 additions and 676 deletions

View File

@ -62,7 +62,6 @@ set(advanced-scene-switcher_HEADERS
${advanced-scene-switcher_HEADERS}
src/headers/advanced-scene-switcher.hpp
src/headers/switcher-data-structs.hpp
src/headers/utility.hpp
src/headers/scene-group.hpp
src/headers/scene-trigger.hpp
src/headers/switch-audio.hpp
@ -113,6 +112,8 @@ set(advanced-scene-switcher_HEADERS
src/headers/name-dialog.hpp
src/headers/duration-control.hpp
src/headers/section.hpp
src/headers/platform-funcs.hpp
src/headers/utility.hpp
src/headers/volume-control.hpp
src/headers/version.h
)
@ -176,6 +177,7 @@ set(advanced-scene-switcher_SOURCES
src/name-dialog.cpp
src/duration-control.cpp
src/section.cpp
src/utility.cpp
src/volume-control.cpp
src/version.cpp
)

View File

@ -1,13 +1,8 @@
#include <QMainWindow>
#include <QAction>
#include <QtGui/qstandarditemmodel.h>
#include <QPropertyAnimation>
#include <QGraphicsColorizeEffect>
#include <QMessageBox>
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <util/util.hpp>
#include "headers/advanced-scene-switcher.hpp"
#include "headers/curl-helper.hpp"
@ -72,329 +67,6 @@ void AdvSceneSwitcher::loadUI()
loading = false;
}
/******************************************************************************
* UI helpers
******************************************************************************/
void AdvSceneSwitcher::addSelectionEntry(QComboBox *sel,
const char *description,
bool selectable, const char *tooltip)
{
sel->addItem(description);
if (strcmp(tooltip, "") != 0) {
sel->setItemData(0, tooltip, Qt::ToolTipRole);
}
QStandardItemModel *model =
qobject_cast<QStandardItemModel *>(sel->model());
QModelIndex firstIndex =
model->index(0, sel->modelColumn(), sel->rootModelIndex());
QStandardItem *firstItem = model->itemFromIndex(firstIndex);
if (!selectable) {
firstItem->setSelectable(false);
firstItem->setEnabled(false);
}
}
void AdvSceneSwitcher::populateSceneSelection(QComboBox *sel, bool addPrevious,
bool addSceneGroup,
bool addSelect,
std::string selectText,
bool selectable)
{
if (addSelect) {
if (selectText.empty()) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectScene"),
selectable,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
} else {
addSelectionEntry(sel, selectText.c_str(), selectable);
}
}
BPtr<char *> scenes = obs_frontend_get_scene_names();
char **temp = scenes;
while (*temp) {
const char *name = *temp;
sel->addItem(name);
temp++;
}
if (addPrevious) {
sel->addItem(obs_module_text(
"AdvSceneSwitcher.selectPreviousScene"));
}
if (addSceneGroup) {
for (auto &sg : switcher->sceneGroups) {
sel->addItem(QString::fromStdString(sg.name));
}
}
}
void AdvSceneSwitcher::populateTransitionSelection(QComboBox *sel,
bool addCurrent,
bool addSelect,
bool selectable)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectTransition"),
selectable);
}
if (addCurrent) {
sel->addItem(
obs_module_text("AdvSceneSwitcher.currentTransition"));
}
obs_frontend_source_list *transitions = new obs_frontend_source_list();
obs_frontend_get_transitions(transitions);
for (size_t i = 0; i < transitions->sources.num; i++) {
const char *name =
obs_source_get_name(transitions->sources.array[i]);
sel->addItem(name);
}
obs_frontend_source_list_free(transitions);
}
void AdvSceneSwitcher::populateWindowSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel, obs_module_text("AdvSceneSwitcher.selectWindow"));
}
std::vector<std::string> windows;
GetWindowList(windows);
sort(windows.begin(), windows.end());
for (std::string &window : windows) {
sel->addItem(window.c_str());
}
#ifdef WIN32
sel->setItemData(0, obs_module_text("AdvSceneSwitcher.selectWindowTip"),
Qt::ToolTipRole);
#endif
}
void AdvSceneSwitcher::populateAudioSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectAudioSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_AUDIO) != 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> audioSources;
obs_enum_sources(sourceEnum, &audioSources);
sort(audioSources.begin(), audioSources.end());
for (std::string &source : audioSources) {
sel->addItem(source.c_str());
}
}
void AdvSceneSwitcher::populateVideoSelection(QComboBox *sel, bool addScenes,
bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectVideoSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
uint32_t flags = obs_source_get_output_flags(source);
std::string test = obs_source_get_name(source);
if ((flags & (OBS_SOURCE_VIDEO | OBS_SOURCE_ASYNC)) != 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> videoSources;
obs_enum_sources(sourceEnum, &videoSources);
sort(videoSources.begin(), videoSources.end());
for (std::string &source : videoSources) {
sel->addItem(source.c_str());
}
if (addScenes) {
populateSceneSelection(sel, false, false, false);
}
}
void AdvSceneSwitcher::populateMediaSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectMediaSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
std::string sourceId = obs_source_get_id(source);
if (sourceId.compare("ffmpeg_source") == 0 ||
sourceId.compare("vlc_source") == 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> mediaSources;
obs_enum_sources(sourceEnum, &mediaSources);
sort(mediaSources.begin(), mediaSources.end());
for (std::string &source : mediaSources) {
sel->addItem(source.c_str());
}
}
void AdvSceneSwitcher::populateProcessSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel, obs_module_text("AdvSceneSwitcher.selectProcess"));
}
QStringList processes;
GetProcessList(processes);
processes.sort();
for (QString &process : processes)
sel->addItem(process);
}
void AdvSceneSwitcher::listAddClicked(QListWidget *list,
SwitchWidget *newWidget,
QPushButton *addButton,
QMetaObject::Connection *addHighlight)
{
if (!list || !newWidget) {
blog(LOG_WARNING,
"listAddClicked called without valid list or widget");
return;
}
if (addButton && addHighlight) {
addButton->disconnect(*addHighlight);
}
QListWidgetItem *item;
item = new QListWidgetItem(list);
list->addItem(item);
item->setSizeHint(newWidget->minimumSizeHint());
list->setItemWidget(item, newWidget);
list->scrollToItem(item);
}
bool AdvSceneSwitcher::listMoveUp(QListWidget *list)
{
int index = list->currentRow();
if (index == -1 || index == 0) {
return false;
}
QWidget *row = list->itemWidget(list->currentItem());
QListWidgetItem *itemN = list->currentItem()->clone();
list->insertItem(index - 1, itemN);
list->setItemWidget(itemN, row);
list->takeItem(index + 1);
list->setCurrentRow(index - 1);
return true;
}
bool AdvSceneSwitcher::listMoveDown(QListWidget *list)
{
int index = list->currentRow();
if (index == -1 || index == list->count() - 1) {
return false;
}
QWidget *row = list->itemWidget(list->currentItem());
QListWidgetItem *itemN = list->currentItem()->clone();
list->insertItem(index + 2, itemN);
list->setItemWidget(itemN, row);
list->takeItem(index);
list->setCurrentRow(index + 1);
return true;
}
QMetaObject::Connection AdvSceneSwitcher::PulseWidget(QWidget *widget,
QColor endColor,
QColor startColor,
QString specifier)
{
if (switcher->disableHints) {
return QMetaObject::Connection();
}
widget->setStyleSheet(specifier + "{ \
border-style: outset; \
border-width: 2px; \
border-radius: 10px; \
border-color: rgb(0,0,0,0) \
}");
QGraphicsColorizeEffect *eEffect = new QGraphicsColorizeEffect(widget);
widget->setGraphicsEffect(eEffect);
QPropertyAnimation *paAnimation =
new QPropertyAnimation(eEffect, "color");
paAnimation->setStartValue(startColor);
paAnimation->setEndValue(endColor);
paAnimation->setDuration(1000);
// Play backwards to return to original state on timer end
paAnimation->setDirection(QAbstractAnimation::Backward);
auto con = QWidget::connect(
paAnimation, &QPropertyAnimation::finished, [paAnimation]() {
QTimer::singleShot(1000, [paAnimation] {
paAnimation->start();
});
});
paAnimation->start();
return con;
}
/******************************************************************************
* Saving and loading
******************************************************************************/

View File

@ -156,8 +156,11 @@ void AdvSceneSwitcher::SetStopped()
obs_module_text("AdvSceneSwitcher.generalTab.status.start"));
ui->pluginRunningText->setText(
obs_module_text("AdvSceneSwitcher.status.inactive"));
inactivePluse = PulseWidget(ui->pluginRunningText, QColor(Qt::red),
QColor(0, 0, 0, 0), "QLabel ");
if (!switcher->disableHints) {
inactivePluse = PulseWidget(ui->pluginRunningText,
QColor(Qt::red), QColor(0, 0, 0, 0),
"QLabel ");
}
currentStatusActive = false;
}

View File

@ -5,6 +5,7 @@
#include "ui_advanced-scene-switcher.h"
#endif
#include "switcher-data-structs.hpp"
#include "platform-funcs.hpp"
#define blog(level, msg, ...) blog(level, "[adv-ss] " msg, ##__VA_ARGS__)
#define vblog(level, msg, ...) \
@ -68,44 +69,8 @@ public:
void setupMacroTab();
void setTabOrder();
void restoreWindowGeo();
static void AskBackup(obs_data_t *obj);
static void addSelectionEntry(QComboBox *sel, const char *description,
bool selectable = false,
const char *tooltip = "");
static void populateSceneSelection(QComboBox *sel,
bool addPrevious = false,
bool addSceneGroup = false,
bool addSelect = true,
std::string selectText = "",
bool selectable = false);
static void populateTransitionSelection(QComboBox *sel,
bool addCurrent = true,
bool addSelect = true,
bool selectable = false);
static void populateWindowSelection(QComboBox *sel,
bool addSelect = true);
static void populateAudioSelection(QComboBox *sel,
bool addSelect = true);
static void populateVideoSelection(QComboBox *sel,
bool addScenes = true,
bool addSelect = true);
static void populateMediaSelection(QComboBox *sel,
bool addSelect = true);
static void populateProcessSelection(QComboBox *sel,
bool addSelect = true);
QMetaObject::Connection PulseWidget(QWidget *widget, QColor endColor,
QColor = QColor(0, 0, 0, 0),
QString specifier = "QLabel ");
void listAddClicked(QListWidget *list, SwitchWidget *newWidget,
QPushButton *addButton = nullptr,
QMetaObject::Connection *addHighlight = nullptr);
bool listMoveUp(QListWidget *list);
bool listMoveDown(QListWidget *list);
signals:
void MacroAdded(const QString &name);
void MacroRemoved(const QString &name);
@ -280,31 +245,6 @@ public slots:
private:
};
/******************************************************************************
* Windowtitle helper
******************************************************************************/
void GetWindowList(std::vector<std::string> &windows);
void GetWindowList(QStringList &windows);
void GetCurrentWindowTitle(std::string &title);
bool isFullscreen(const std::string &title);
bool isMaximized(const std::string &title);
/******************************************************************************
* Screenregion helper
******************************************************************************/
std::pair<int, int> getCursorPos();
/******************************************************************************
* Idle detection helper
******************************************************************************/
int secondsSinceLastInput();
/******************************************************************************
* Executable helper
******************************************************************************/
void GetProcessList(QStringList &processes);
bool isInFocus(const QString &executable);
/******************************************************************************
* Sceneswitch helper
******************************************************************************/

View File

@ -0,0 +1,11 @@
#pragma once
void GetWindowList(std::vector<std::string> &windows);
void GetWindowList(QStringList &windows);
void GetCurrentWindowTitle(std::string &title);
bool isFullscreen(const std::string &title);
bool isMaximized(const std::string &title);
std::pair<int, int> getCursorPos();
int secondsSinceLastInput();
void GetProcessList(QStringList &processes);
bool isInFocus(const QString &executable);

View File

@ -1,139 +1,26 @@
#pragma once
#include <QString>
#include <QTextStream>
#include <QLayout>
#include <QLabel>
#include <QMessageBox>
#include <unordered_map>
#include <QComboBox>
#include <QMetaObject>
#include <QListWidget>
#include <QPushButton>
#include <QColor>
#include <obs.hpp>
#include <obs-module.h>
#include <obs-frontend-api.h>
#include <deque>
#include <unordered_map>
#include "scene-group.hpp"
static inline bool WeakSourceValid(obs_weak_source_t *ws)
{
obs_source_t *source = obs_weak_source_get_source(ws);
if (source) {
obs_source_release(source);
}
return !!source;
}
static inline std::string GetWeakSourceName(obs_weak_source_t *weak_source)
{
std::string name;
obs_source_t *source = obs_weak_source_get_source(weak_source);
if (source) {
name = obs_source_get_name(source);
obs_source_release(source);
}
return name;
}
static inline OBSWeakSource GetWeakSourceByName(const char *name)
{
OBSWeakSource weak;
obs_source_t *source = obs_get_source_by_name(name);
if (source) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
obs_source_release(source);
}
return weak;
}
static inline OBSWeakSource GetWeakSourceByQString(const QString &name)
{
return GetWeakSourceByName(name.toUtf8().constData());
}
static inline OBSWeakSource GetWeakTransitionByName(const char *transitionName)
{
OBSWeakSource weak;
obs_source_t *source = nullptr;
if (strcmp(transitionName, "Default") == 0) {
source = obs_frontend_get_current_transition();
weak = obs_source_get_weak_source(source);
obs_source_release(source);
obs_weak_source_release(weak);
return weak;
}
obs_frontend_source_list *transitions = new obs_frontend_source_list();
obs_frontend_get_transitions(transitions);
bool match = false;
for (size_t i = 0; i < transitions->sources.num; i++) {
const char *name =
obs_source_get_name(transitions->sources.array[i]);
if (strcmp(transitionName, name) == 0) {
match = true;
source = transitions->sources.array[i];
break;
}
}
if (match) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
}
obs_frontend_source_list_free(transitions);
return weak;
}
static inline OBSWeakSource GetWeakTransitionByQString(const QString &name)
{
return GetWeakTransitionByName(name.toUtf8().constData());
}
static inline OBSWeakSource GetWeakFilterByName(OBSWeakSource source,
const char *name)
{
OBSWeakSource weak;
auto s = obs_weak_source_get_source(source);
if (s) {
auto filterSource = obs_source_get_filter_by_name(s, name);
weak = obs_source_get_weak_source(filterSource);
obs_weak_source_release(weak);
obs_source_release(filterSource);
obs_source_release(s);
}
return weak;
}
static inline OBSWeakSource GetWeakFilterByQString(OBSWeakSource source,
const QString &name)
{
return GetWeakFilterByName(source, name.toUtf8().constData());
}
static inline std::string
getNextDelim(const std::string &text,
std::unordered_map<std::string, QWidget *> placeholders)
{
size_t pos = std::string::npos;
std::string res = "";
for (const auto &ph : placeholders) {
size_t newPos = text.find(ph.first);
if (newPos <= pos) {
pos = newPos;
res = ph.first;
}
}
if (pos == std::string::npos) {
return "";
}
return res;
}
bool WeakSourceValid(obs_weak_source_t *ws);
std::string GetWeakSourceName(obs_weak_source_t *weak_source);
OBSWeakSource GetWeakSourceByName(const char *name);
OBSWeakSource GetWeakSourceByQString(const QString &name);
OBSWeakSource GetWeakTransitionByName(const char *transitionName);
OBSWeakSource GetWeakTransitionByQString(const QString &name);
OBSWeakSource GetWeakFilterByName(OBSWeakSource source, const char *name);
OBSWeakSource GetWeakFilterByQString(OBSWeakSource source, const QString &name);
bool compareIgnoringLineEnding(QString &s1, QString &s2);
/**
* Populate layout with labels and widgets based on provided text
@ -143,95 +30,32 @@ getNextDelim(const std::string &text,
* @param placeholders Map containing a mapping of placeholder strings to widgets.
* @param addStretch Add addStretch() to layout.
*/
static inline void
placeWidgets(std::string text, QBoxLayout *layout,
std::unordered_map<std::string, QWidget *> placeholders,
bool addStretch = true)
{
std::vector<std::pair<std::string, QWidget *>> labelsWidgetsPairs;
std::string delim = getNextDelim(text, placeholders);
while (delim != "") {
size_t pos = text.find(delim);
if (pos != std::string::npos) {
labelsWidgetsPairs.emplace_back(text.substr(0, pos),
placeholders[delim]);
text.erase(0, pos + delim.length());
}
delim = getNextDelim(text, placeholders);
}
if (text != "") {
labelsWidgetsPairs.emplace_back(text, nullptr);
}
for (auto &lw : labelsWidgetsPairs) {
if (lw.first != "") {
layout->addWidget(new QLabel(lw.first.c_str()));
}
if (lw.second) {
layout->addWidget(lw.second);
}
}
if (addStretch) {
layout->addStretch();
}
}
static inline void clearLayout(QLayout *layout)
{
QLayoutItem *item;
while ((item = layout->takeAt(0))) {
if (item->layout()) {
clearLayout(item->layout());
delete item->layout();
}
if (item->widget()) {
delete item->widget();
}
delete item;
}
}
static inline bool compareIgnoringLineEnding(QString &s1, QString &s2)
{
// Let QT deal with different types of lineendings
QTextStream s1stream(&s1);
QTextStream s2stream(&s2);
while (!s1stream.atEnd() || !s2stream.atEnd()) {
QString s1s = s1stream.readLine();
QString s2s = s2stream.readLine();
if (s1s != s2s) {
return false;
}
}
if (!s1stream.atEnd() && !s2stream.atEnd()) {
return false;
}
return true;
}
static inline bool DisplayMessage(const QString &msg, bool question = false)
{
if (question) {
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
nullptr, "Advanced Scene Switcher", msg,
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
return true;
} else {
return false;
}
} else {
QMessageBox Msgbox;
Msgbox.setWindowTitle("Advanced Scene Switcher");
Msgbox.setText(msg);
Msgbox.exec();
}
return false;
}
void placeWidgets(std::string text, QBoxLayout *layout,
std::unordered_map<std::string, QWidget *> placeholders,
bool addStretch = true);
void clearLayout(QLayout *layout);
QMetaObject::Connection PulseWidget(QWidget *widget, QColor endColor,
QColor = QColor(0, 0, 0, 0),
QString specifier = "QLabel ");
void listAddClicked(QListWidget *list, QWidget *newWidget,
QPushButton *addButton = nullptr,
QMetaObject::Connection *addHighlight = nullptr);
bool listMoveUp(QListWidget *list);
bool listMoveDown(QListWidget *list);
bool DisplayMessage(const QString &msg, bool question = false);
void addSelectionEntry(QComboBox *sel, const char *description,
bool selectable = false, const char *tooltip = "");
void populateTransitionSelection(QComboBox *sel, bool addCurrent = true,
bool addSelect = true,
bool selectable = false);
void populateWindowSelection(QComboBox *sel, bool addSelect = true);
void populateAudioSelection(QComboBox *sel, bool addSelect = true);
void populateVideoSelection(QComboBox *sel, bool addSelect = true);
void populateMediaSelection(QComboBox *sel, bool addSelect = true);
void populateProcessSelection(QComboBox *sel, bool addSelect = true);
void populateSourceSelection(QComboBox *list, bool addSelect = true);
void populateSceneSelection(QComboBox *sel, bool addPrevious = false,
bool addSceneGroup = false,
std::deque<SceneGroup> *sceneGroups = nullptr,
bool addSelect = true, std::string selectText = "",
bool selectable = false);

View File

@ -94,7 +94,7 @@ MacroActionAudioEdit::MacroActionAudioEdit(
_volumePercent->setSuffix("%");
populateActionSelection(_actions);
AdvSceneSwitcher::populateAudioSelection(_audioSources);
populateAudioSelection(_audioSources);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));

View File

@ -99,7 +99,7 @@ MacroActionMediaEdit::MacroActionMediaEdit(
_actions = new QComboBox();
populateActionSelection(_actions);
AdvSceneSwitcher::populateMediaSelection(_mediaSources);
populateMediaSelection(_mediaSources);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));

View File

@ -124,7 +124,7 @@ MacroActionSceneVisibilityEdit::MacroActionSceneVisibilityEdit(
_actions = new QComboBox();
populateActionSelection(_actions);
AdvSceneSwitcher::populateSceneSelection(_scenes);
populateSceneSelection(_scenes);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));

View File

@ -67,22 +67,6 @@ static inline void populateActionSelection(QComboBox *list)
}
}
static inline void populateSources(QComboBox *list)
{
auto enumSourcesWithSources = [](void *param, obs_source_t *source) {
if (!source) {
return true;
}
QComboBox *list = reinterpret_cast<QComboBox *>(param);
list->addItem(obs_source_get_name(source));
return true;
};
list->clear();
list->addItem(obs_module_text("AdvSceneSwitcher.selectSource"));
obs_enum_sources(enumSourcesWithSources, list);
}
MacroActionSourceEdit::MacroActionSourceEdit(
QWidget *parent, std::shared_ptr<MacroActionSource> entryData)
: QWidget(parent)
@ -91,7 +75,7 @@ MacroActionSourceEdit::MacroActionSourceEdit(
_actions = new QComboBox();
populateActionSelection(_actions);
populateSources(_sources);
populateSourceSelection(_sources);
QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this,
SLOT(ActionChanged(int)));

View File

@ -139,7 +139,7 @@ MacroConditionAudioEdit::MacroConditionAudioEdit(
SIGNAL(currentTextChanged(const QString &)), this,
SLOT(SourceChanged(const QString &)));
AdvSceneSwitcher::populateAudioSelection(_audioSources);
populateAudioSelection(_audioSources);
populateConditionSelection(_condition);
QHBoxLayout *switchLayout = new QHBoxLayout;

View File

@ -256,7 +256,7 @@ MacroConditionMediaEdit::MacroConditionMediaEdit(
QWidget::connect(_time, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(TimeUnitChanged(DurationUnit)));
AdvSceneSwitcher::populateMediaSelection(_mediaSources);
populateMediaSelection(_mediaSources);
populateMediaStates(_states);
populateMediaTimeRestrictions(_timeRestrictions);

View File

@ -61,7 +61,7 @@ MacroConditionProcessEdit::MacroConditionProcessEdit(
QWidget::connect(_focused, SIGNAL(stateChanged(int)), this,
SLOT(FocusChanged(int)));
AdvSceneSwitcher::populateProcessSelection(_processSelection);
populateProcessSelection(_processSelection);
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{processes}}", _processSelection},

View File

@ -79,7 +79,7 @@ MacroConditionSceneEdit::MacroConditionSceneEdit(
QWidget::connect(_duration, SIGNAL(UnitChanged(DurationUnit)), this,
SLOT(DurationUnitChanged(DurationUnit)));
AdvSceneSwitcher::populateSceneSelection(_sceneSelection);
populateSceneSelection(_sceneSelection);
populateTypeSelection(_sceneType);
QHBoxLayout *mainLayout = new QHBoxLayout;

View File

@ -160,7 +160,7 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
QWidget::connect(_browseButton, SIGNAL(clicked()), this,
SLOT(BrowseButtonClicked()));
AdvSceneSwitcher::populateVideoSelection(_videoSelection, false);
populateVideoSelection(_videoSelection);
populateConditionSelection(_condition);
QHBoxLayout *mainLayout = new QHBoxLayout;

View File

@ -115,7 +115,7 @@ MacroConditionWindowEdit::MacroConditionWindowEdit(
QWidget::connect(_focused, SIGNAL(stateChanged(int)), this,
SLOT(FocusChanged(int)));
AdvSceneSwitcher::populateWindowSelection(_windowSelection);
populateWindowSelection(_windowSelection);
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{windows}}", _windowSelection},

View File

@ -263,7 +263,9 @@ void AdvSceneSwitcher::setupMacroTab()
}
if (switcher->macros.size() == 0) {
addPulse = PulseWidget(ui->macroAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->macroAdd, QColor(Qt::green));
}
ui->macroHelp->setVisible(true);
} else {
ui->macroHelp->setVisible(false);

View File

@ -499,7 +499,10 @@ void AdvSceneSwitcher::setupSceneGroupTab()
}
if (switcher->sceneGroups.size() == 0) {
addPulse = PulseWidget(ui->sceneGroupAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->sceneGroupAdd,
QColor(Qt::green));
}
ui->sceneGroupHelp->setVisible(true);
} else {
ui->sceneGroupHelp->setVisible(false);

View File

@ -347,7 +347,10 @@ void AdvSceneSwitcher::setupTriggerTab()
}
if (switcher->sceneTriggers.size() == 0) {
addPulse = PulseWidget(ui->triggerAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse =
PulseWidget(ui->triggerAdd, QColor(Qt::green));
}
ui->triggerHelp->setVisible(true);
} else {
ui->triggerHelp->setVisible(false);
@ -381,7 +384,7 @@ void SceneTrigger::load(obs_data_t *obj)
static inline void populateTriggers(QComboBox *list)
{
AdvSceneSwitcher::addSelectionEntry(
addSelectionEntry(
list,
obs_module_text(
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerType.none"));
@ -396,7 +399,7 @@ static inline void populateTriggers(QComboBox *list)
inline void populateActions(QComboBox *list)
{
AdvSceneSwitcher::addSelectionEntry(
addSelectionEntry(
list,
obs_module_text(
"AdvSceneSwitcher.sceneTriggerTab.sceneTriggerAction.none"));
@ -451,7 +454,7 @@ SceneTriggerWidget::SceneTriggerWidget(QWidget *parent, SceneTrigger *s)
populateTriggers(triggers);
populateActions(actions);
AdvSceneSwitcher::populateAudioSelection(audioSources);
populateAudioSelection(audioSources);
if (s) {
triggers->setCurrentIndex(static_cast<int>(s->triggerType));

View File

@ -224,7 +224,9 @@ void AdvSceneSwitcher::setupAudioTab()
}
if (switcher->audioSwitches.size() == 0) {
addPulse = PulseWidget(ui->audioAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->audioAdd, QColor(Qt::green));
}
ui->audioHelp->setVisible(true);
} else {
ui->audioHelp->setVisible(false);
@ -447,7 +449,7 @@ AudioSwitchWidget::AudioSwitchWidget(QWidget *parent, AudioSwitch *s)
QWidget::connect(ignoreInactiveSource, SIGNAL(stateChanged(int)), this,
SLOT(IgnoreInactiveChanged(int)));
AdvSceneSwitcher::populateAudioSelection(audioSources);
populateAudioSelection(audioSources);
populateConditionSelection(condition);
if (s) {

View File

@ -187,7 +187,10 @@ void AdvSceneSwitcher::setupExecutableTab()
}
if (switcher->executableSwitches.size() == 0) {
addPulse = PulseWidget(ui->executableAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->executableAdd,
QColor(Qt::green));
}
ui->exeHelp->setVisible(true);
} else {
ui->exeHelp->setVisible(false);
@ -223,7 +226,7 @@ ExecutableSwitchWidget::ExecutableSwitchWidget(QWidget *parent,
QWidget::connect(requiresFocus, SIGNAL(stateChanged(int)), this,
SLOT(FocusChanged(int)));
AdvSceneSwitcher::populateProcessSelection(processes);
populateProcessSelection(processes);
processes->setEditable(true);
processes->setMaxVisibleItems(20);

View File

@ -415,7 +415,9 @@ void AdvSceneSwitcher::setupFileTab()
}
if (switcher->fileSwitches.size() == 0) {
addPulse = PulseWidget(ui->fileAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->fileAdd, QColor(Qt::green));
}
ui->fileHelp->setVisible(true);
} else {
ui->fileHelp->setVisible(false);

View File

@ -228,10 +228,9 @@ SwitchWidget::SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
SIGNAL(SceneGroupRenamed(const QString &, const QString &)),
this, SLOT(SceneGroupRename(const QString &, const QString &)));
AdvSceneSwitcher::populateSceneSelection(scenes, usePreviousScene,
addSceneGroup);
AdvSceneSwitcher::populateTransitionSelection(transitions,
addCurrentTransition);
populateSceneSelection(scenes, usePreviousScene, addSceneGroup,
&switcher->sceneGroups);
populateTransitionSelection(transitions, addCurrentTransition);
switchData = s;
showSwitchData();

View File

@ -244,7 +244,9 @@ void AdvSceneSwitcher::setupMediaTab()
}
if (switcher->mediaSwitches.size() == 0) {
addPulse = PulseWidget(ui->mediaAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->mediaAdd, QColor(Qt::green));
}
ui->mediaHelp->setVisible(true);
} else {
ui->mediaHelp->setVisible(false);
@ -458,7 +460,7 @@ MediaSwitchWidget::MediaSwitchWidget(QWidget *parent, MediaSwitch *s)
QWidget::connect(time, SIGNAL(valueChanged(int)), this,
SLOT(TimeChanged(int)));
AdvSceneSwitcher::populateMediaSelection(mediaSources);
populateMediaSelection(mediaSources);
populateMediaStates(states);
populateTimeRestrictions(timeRestrictions);

View File

@ -264,7 +264,9 @@ void AdvSceneSwitcher::setupPauseTab()
}
if (switcher->pauseEntries.size() == 0) {
addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->pauseAdd, QColor(Qt::green));
}
ui->pauseHelp->setVisible(true);
} else {
ui->pauseHelp->setVisible(false);
@ -315,7 +317,7 @@ PauseEntryWidget::PauseEntryWidget(QWidget *parent, PauseEntry *s)
populatePauseTypes(pauseTypes);
populatePauseTargets(pauseTargets);
AdvSceneSwitcher::populateWindowSelection(windows);
populateWindowSelection(windows);
windows->setEditable(true);
windows->setMaxVisibleItems(20);

View File

@ -125,15 +125,20 @@ void AdvSceneSwitcher::setupRandomTab()
}
if (switcher->randomSwitches.size() == 0) {
addPulse = PulseWidget(ui->randomAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse =
PulseWidget(ui->randomAdd, QColor(Qt::green));
}
ui->randomHelp->setVisible(true);
} else {
ui->randomHelp->setVisible(false);
}
if (switcher->switchIfNotMatching != RANDOM_SWITCH) {
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
QColor(0, 0, 0, 0), "QLabel ");
if (!switcher->disableHints) {
PulseWidget(ui->randomDisabledWarning, QColor(Qt::red),
QColor(0, 0, 0, 0), "QLabel ");
}
} else {
ui->randomDisabledWarning->setVisible(false);
}

View File

@ -245,7 +245,10 @@ void AdvSceneSwitcher::setupRegionTab()
}
if (switcher->screenRegionSwitches.size() == 0) {
addPulse = PulseWidget(ui->screenRegionAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->screenRegionAdd,
QColor(Qt::green));
}
ui->regionHelp->setVisible(true);
} else {
ui->regionHelp->setVisible(false);
@ -320,8 +323,8 @@ ScreenRegionWidget::ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s)
QWidget::connect(maxY, SIGNAL(valueChanged(int)), this,
SLOT(MaxYChanged(int)));
AdvSceneSwitcher::populateSceneSelection(
excludeScenes, false, false, true,
populateSceneSelection(
excludeScenes, false, false, nullptr, true,
obs_module_text(
"AdvSceneSwitcher.screenRegionTab.excludeScenes.None"),
true);

View File

@ -289,7 +289,10 @@ void AdvSceneSwitcher::setupSequenceTab()
}
if (switcher->sceneSequenceSwitches.size() == 0) {
addPulse = PulseWidget(ui->sceneSequenceAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->sceneSequenceAdd,
QColor(Qt::green));
}
ui->sequenceHelp->setVisible(true);
} else {
ui->sequenceHelp->setVisible(false);
@ -586,7 +589,7 @@ SequenceWidget::SequenceWidget(QWidget *parent, SceneSequenceSwitch *s,
QWidget::connect(reduce, SIGNAL(clicked()), this,
SLOT(ReduceClicked()));
AdvSceneSwitcher::populateSceneSelection(startScenes, false);
populateSceneSelection(startScenes);
interruptible->setToolTip(obs_module_text(
"AdvSceneSwitcher.sceneSequenceTab.interruptibleHint"));

View File

@ -191,7 +191,9 @@ void AdvSceneSwitcher::setupTimeTab()
}
if (switcher->timeSwitches.size() == 0) {
addPulse = PulseWidget(ui->timeAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->timeAdd, QColor(Qt::green));
}
ui->timeHelp->setVisible(true);
} else {
ui->timeHelp->setVisible(false);

View File

@ -495,7 +495,7 @@ TransitionSwitchWidget::TransitionSwitchWidget(QWidget *parent,
QWidget::connect(duration, SIGNAL(valueChanged(double)), this,
SLOT(DurationChanged(double)));
AdvSceneSwitcher::populateSceneSelection(scenes2, false);
populateSceneSelection(scenes2);
if (s) {
scenes2->setCurrentText(GetWeakSourceName(s->scene2).c_str());

View File

@ -194,7 +194,9 @@ void AdvSceneSwitcher::setupVideoTab()
}
if (switcher->videoSwitches.size() == 0) {
addPulse = PulseWidget(ui->videoAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse = PulseWidget(ui->videoAdd, QColor(Qt::green));
}
ui->videoHelp->setVisible(true);
} else {
ui->videoHelp->setVisible(false);
@ -399,10 +401,7 @@ VideoSwitchWidget::VideoSwitchWidget(QWidget *parent, VideoSwitch *s)
QWidget::connect(ignoreInactiveSource, SIGNAL(stateChanged(int)), this,
SLOT(IgnoreInactiveChanged(int)));
// TODO:
// Figure out why scene do not work for "match exactly".
// Until then do not allow selecting scenes
AdvSceneSwitcher::populateVideoSelection(videoSources, false);
populateVideoSelection(videoSources);
populateConditionSelection(condition);
if (s) {

View File

@ -348,7 +348,10 @@ void AdvSceneSwitcher::setupTitleTab()
}
if (switcher->windowSwitches.size() == 0) {
addPulse = PulseWidget(ui->windowAdd, QColor(Qt::green));
if (!switcher->disableHints) {
addPulse =
PulseWidget(ui->windowAdd, QColor(Qt::green));
}
ui->windowHelp->setVisible(true);
} else {
ui->windowHelp->setVisible(false);
@ -418,7 +421,7 @@ WindowSwitchWidget::WindowSwitchWidget(QWidget *parent, WindowSwitch *s)
QWidget::connect(focused, SIGNAL(stateChanged(int)), this,
SLOT(FocusChanged(int)));
AdvSceneSwitcher::populateWindowSelection(windows);
populateWindowSelection(windows);
windows->setEditable(true);
windows->setMaxVisibleItems(20);

555
src/utility.cpp Normal file
View File

@ -0,0 +1,555 @@
#pragma once
#include "headers/utility.hpp"
#include "headers/platform-funcs.hpp"
#include <QTextStream>
#include <QLabel>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QtGui/qstandarditemmodel.h>
#include <QPropertyAnimation>
#include <QGraphicsColorizeEffect>
#include <QTimer>
#include <QMessageBox>
#include <unordered_map>
#include <obs-module.h>
#include <util/util.hpp>
bool WeakSourceValid(obs_weak_source_t *ws)
{
obs_source_t *source = obs_weak_source_get_source(ws);
if (source) {
obs_source_release(source);
}
return !!source;
}
std::string GetWeakSourceName(obs_weak_source_t *weak_source)
{
std::string name;
obs_source_t *source = obs_weak_source_get_source(weak_source);
if (source) {
name = obs_source_get_name(source);
obs_source_release(source);
}
return name;
}
OBSWeakSource GetWeakSourceByName(const char *name)
{
OBSWeakSource weak;
obs_source_t *source = obs_get_source_by_name(name);
if (source) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
obs_source_release(source);
}
return weak;
}
OBSWeakSource GetWeakSourceByQString(const QString &name)
{
return GetWeakSourceByName(name.toUtf8().constData());
}
OBSWeakSource GetWeakTransitionByName(const char *transitionName)
{
OBSWeakSource weak;
obs_source_t *source = nullptr;
if (strcmp(transitionName, "Default") == 0) {
source = obs_frontend_get_current_transition();
weak = obs_source_get_weak_source(source);
obs_source_release(source);
obs_weak_source_release(weak);
return weak;
}
obs_frontend_source_list *transitions = new obs_frontend_source_list();
obs_frontend_get_transitions(transitions);
bool match = false;
for (size_t i = 0; i < transitions->sources.num; i++) {
const char *name =
obs_source_get_name(transitions->sources.array[i]);
if (strcmp(transitionName, name) == 0) {
match = true;
source = transitions->sources.array[i];
break;
}
}
if (match) {
weak = obs_source_get_weak_source(source);
obs_weak_source_release(weak);
}
obs_frontend_source_list_free(transitions);
return weak;
}
OBSWeakSource GetWeakTransitionByQString(const QString &name)
{
return GetWeakTransitionByName(name.toUtf8().constData());
}
OBSWeakSource GetWeakFilterByName(OBSWeakSource source, const char *name)
{
OBSWeakSource weak;
auto s = obs_weak_source_get_source(source);
if (s) {
auto filterSource = obs_source_get_filter_by_name(s, name);
weak = obs_source_get_weak_source(filterSource);
obs_weak_source_release(weak);
obs_source_release(filterSource);
obs_source_release(s);
}
return weak;
}
OBSWeakSource GetWeakFilterByQString(OBSWeakSource source, const QString &name)
{
return GetWeakFilterByName(source, name.toUtf8().constData());
}
std::string
getNextDelim(const std::string &text,
std::unordered_map<std::string, QWidget *> placeholders)
{
size_t pos = std::string::npos;
std::string res = "";
for (const auto &ph : placeholders) {
size_t newPos = text.find(ph.first);
if (newPos <= pos) {
pos = newPos;
res = ph.first;
}
}
if (pos == std::string::npos) {
return "";
}
return res;
}
void placeWidgets(std::string text, QBoxLayout *layout,
std::unordered_map<std::string, QWidget *> placeholders,
bool addStretch)
{
std::vector<std::pair<std::string, QWidget *>> labelsWidgetsPairs;
std::string delim = getNextDelim(text, placeholders);
while (delim != "") {
size_t pos = text.find(delim);
if (pos != std::string::npos) {
labelsWidgetsPairs.emplace_back(text.substr(0, pos),
placeholders[delim]);
text.erase(0, pos + delim.length());
}
delim = getNextDelim(text, placeholders);
}
if (text != "") {
labelsWidgetsPairs.emplace_back(text, nullptr);
}
for (auto &lw : labelsWidgetsPairs) {
if (lw.first != "") {
layout->addWidget(new QLabel(lw.first.c_str()));
}
if (lw.second) {
layout->addWidget(lw.second);
}
}
if (addStretch) {
layout->addStretch();
}
}
void clearLayout(QLayout *layout)
{
QLayoutItem *item;
while ((item = layout->takeAt(0))) {
if (item->layout()) {
clearLayout(item->layout());
delete item->layout();
}
if (item->widget()) {
delete item->widget();
}
delete item;
}
}
bool compareIgnoringLineEnding(QString &s1, QString &s2)
{
// Let QT deal with different types of lineendings
QTextStream s1stream(&s1);
QTextStream s2stream(&s2);
while (!s1stream.atEnd() || !s2stream.atEnd()) {
QString s1s = s1stream.readLine();
QString s2s = s2stream.readLine();
if (s1s != s2s) {
return false;
}
}
if (!s1stream.atEnd() && !s2stream.atEnd()) {
return false;
}
return true;
}
bool DisplayMessage(const QString &msg, bool question)
{
if (question) {
QMessageBox::StandardButton reply;
reply = QMessageBox::question(
nullptr, "Advanced Scene Switcher", msg,
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
return true;
} else {
return false;
}
} else {
QMessageBox Msgbox;
Msgbox.setWindowTitle("Advanced Scene Switcher");
Msgbox.setText(msg);
Msgbox.exec();
}
return false;
}
void addSelectionEntry(QComboBox *sel, const char *description, bool selectable,
const char *tooltip)
{
sel->addItem(description);
if (strcmp(tooltip, "") != 0) {
sel->setItemData(0, tooltip, Qt::ToolTipRole);
}
QStandardItemModel *model =
qobject_cast<QStandardItemModel *>(sel->model());
QModelIndex firstIndex =
model->index(0, sel->modelColumn(), sel->rootModelIndex());
QStandardItem *firstItem = model->itemFromIndex(firstIndex);
if (!selectable) {
firstItem->setSelectable(false);
firstItem->setEnabled(false);
}
}
void populateSourceSelection(QComboBox *list, bool addSelect)
{
auto enumSourcesWithSources = [](void *param, obs_source_t *source) {
if (!source) {
return true;
}
QComboBox *list = reinterpret_cast<QComboBox *>(param);
list->addItem(obs_source_get_name(source));
return true;
};
list->clear();
if (addSelect) {
addSelectionEntry(
list, obs_module_text("AdvSceneSwitcher.selectSource"),
false);
}
obs_enum_sources(enumSourcesWithSources, list);
}
void populateTransitionSelection(QComboBox *sel, bool addCurrent,
bool addSelect, bool selectable)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectTransition"),
selectable);
}
if (addCurrent) {
sel->addItem(
obs_module_text("AdvSceneSwitcher.currentTransition"));
}
obs_frontend_source_list *transitions = new obs_frontend_source_list();
obs_frontend_get_transitions(transitions);
for (size_t i = 0; i < transitions->sources.num; i++) {
const char *name =
obs_source_get_name(transitions->sources.array[i]);
sel->addItem(name);
}
obs_frontend_source_list_free(transitions);
}
void populateWindowSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel, obs_module_text("AdvSceneSwitcher.selectWindow"));
}
std::vector<std::string> windows;
GetWindowList(windows);
sort(windows.begin(), windows.end());
for (std::string &window : windows) {
sel->addItem(window.c_str());
}
#ifdef WIN32
sel->setItemData(0, obs_module_text("AdvSceneSwitcher.selectWindowTip"),
Qt::ToolTipRole);
#endif
}
void populateAudioSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectAudioSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_AUDIO) != 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> audioSources;
obs_enum_sources(sourceEnum, &audioSources);
sort(audioSources.begin(), audioSources.end());
for (std::string &source : audioSources) {
sel->addItem(source.c_str());
}
}
void populateVideoSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectVideoSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
uint32_t flags = obs_source_get_output_flags(source);
std::string test = obs_source_get_name(source);
if ((flags & (OBS_SOURCE_VIDEO | OBS_SOURCE_ASYNC)) != 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> videoSources;
obs_enum_sources(sourceEnum, &videoSources);
sort(videoSources.begin(), videoSources.end());
for (std::string &source : videoSources) {
sel->addItem(source.c_str());
}
}
void populateMediaSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectMediaSource"),
false,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
}
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
{
std::vector<std::string> *list =
reinterpret_cast<std::vector<std::string> *>(data);
std::string sourceId = obs_source_get_id(source);
if (sourceId.compare("ffmpeg_source") == 0 ||
sourceId.compare("vlc_source") == 0) {
list->push_back(obs_source_get_name(source));
}
return true;
};
std::vector<std::string> mediaSources;
obs_enum_sources(sourceEnum, &mediaSources);
sort(mediaSources.begin(), mediaSources.end());
for (std::string &source : mediaSources) {
sel->addItem(source.c_str());
}
}
void populateProcessSelection(QComboBox *sel, bool addSelect)
{
if (addSelect) {
addSelectionEntry(
sel, obs_module_text("AdvSceneSwitcher.selectProcess"));
}
QStringList processes;
GetProcessList(processes);
processes.sort();
for (QString &process : processes)
sel->addItem(process);
}
void populateSceneSelection(QComboBox *sel, bool addPrevious,
bool addSceneGroup,
std::deque<SceneGroup> *sceneGroups, bool addSelect,
std::string selectText, bool selectable)
{
if (addSelect) {
if (selectText.empty()) {
addSelectionEntry(
sel,
obs_module_text("AdvSceneSwitcher.selectScene"),
selectable,
obs_module_text(
"AdvSceneSwitcher.invaildEntriesWillNotBeSaved"));
} else {
addSelectionEntry(sel, selectText.c_str(), selectable);
}
}
BPtr<char *> scenes = obs_frontend_get_scene_names();
char **temp = scenes;
while (*temp) {
const char *name = *temp;
sel->addItem(name);
temp++;
}
if (addPrevious) {
sel->addItem(obs_module_text(
"AdvSceneSwitcher.selectPreviousScene"));
}
if (addSceneGroup && sceneGroups) {
for (auto &sg : *sceneGroups) {
sel->addItem(QString::fromStdString(sg.name));
}
}
}
QMetaObject::Connection PulseWidget(QWidget *widget, QColor endColor,
QColor startColor, QString specifier)
{
widget->setStyleSheet(specifier + "{ \
border-style: outset; \
border-width: 2px; \
border-radius: 10px; \
border-color: rgb(0,0,0,0) \
}");
QGraphicsColorizeEffect *eEffect = new QGraphicsColorizeEffect(widget);
widget->setGraphicsEffect(eEffect);
QPropertyAnimation *paAnimation =
new QPropertyAnimation(eEffect, "color");
paAnimation->setStartValue(startColor);
paAnimation->setEndValue(endColor);
paAnimation->setDuration(1000);
// Play backwards to return to original state on timer end
paAnimation->setDirection(QAbstractAnimation::Backward);
auto con = QWidget::connect(
paAnimation, &QPropertyAnimation::finished, [paAnimation]() {
QTimer::singleShot(1000, [paAnimation] {
paAnimation->start();
});
});
paAnimation->start();
return con;
}
void listAddClicked(QListWidget *list, QWidget *newWidget,
QPushButton *addButton,
QMetaObject::Connection *addHighlight)
{
if (!list || !newWidget) {
blog(LOG_WARNING,
"listAddClicked called without valid list or widget");
return;
}
if (addButton && addHighlight) {
addButton->disconnect(*addHighlight);
}
QListWidgetItem *item;
item = new QListWidgetItem(list);
list->addItem(item);
item->setSizeHint(newWidget->minimumSizeHint());
list->setItemWidget(item, newWidget);
list->scrollToItem(item);
}
bool listMoveUp(QListWidget *list)
{
int index = list->currentRow();
if (index == -1 || index == 0) {
return false;
}
QWidget *row = list->itemWidget(list->currentItem());
QListWidgetItem *itemN = list->currentItem()->clone();
list->insertItem(index - 1, itemN);
list->setItemWidget(itemN, row);
list->takeItem(index + 1);
list->setCurrentRow(index - 1);
return true;
}
bool listMoveDown(QListWidget *list)
{
int index = list->currentRow();
if (index == -1 || index == list->count() - 1) {
return false;
}
QWidget *row = list->itemWidget(list->currentItem());
QListWidgetItem *itemN = list->currentItem()->clone();
list->insertItem(index + 2, itemN);
list->setItemWidget(itemN, row);
list->takeItem(index);
list->setCurrentRow(index + 1);
return true;
}