mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-09-08 09:36:07 -05:00
UI rework (#44)
* rework general tab UI * rework audio tab UI * rework media tab UI * rework time tab UI * rework random tab UI * rework window tab UI * rework sreen region tab UI * rework sequence tab UI * rework transition tab UI * adjust log messages to new format * fix include path and warning * highlight widgets to guide users (can be disabled) * add helper frame for screen region tab * rename main SceneSwitcher widget to AdvSceneSwitcher to resolve naming conflicts with the frontend tools on certain platforms (e.g. Debian 10) * add media state 'any' * adjust media switch handling to support vlc source
This commit is contained in:
@@ -1,164 +1,157 @@
|
||||
#include "headers/advanced-scene-switcher.hpp"
|
||||
#include "headers/utility.hpp"
|
||||
|
||||
void SceneSwitcher::on_mediaSwitches_currentRowChanged(int idx)
|
||||
static QMetaObject::Connection addPulse;
|
||||
|
||||
void AdvSceneSwitcher::on_mediaAdd_clicked()
|
||||
{
|
||||
if (loading)
|
||||
return;
|
||||
if (idx == -1)
|
||||
return;
|
||||
|
||||
QListWidgetItem *item = ui->mediaSwitches->item(idx);
|
||||
|
||||
QString mediaSceneStr = item->data(Qt::UserRole).toString();
|
||||
ui->mediaAdd->disconnect(addPulse);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
for (auto &s : switcher->mediaSwitches) {
|
||||
if (mediaSceneStr.compare(s.mediaSwitchStr.c_str()) == 0) {
|
||||
QString sceneName = GetWeakSourceName(s.scene).c_str();
|
||||
QString sourceName =
|
||||
GetWeakSourceName(s.source).c_str();
|
||||
QString transitionName =
|
||||
GetWeakSourceName(s.transition).c_str();
|
||||
ui->mediaScenes->setCurrentText(sceneName);
|
||||
ui->mediaSources->setCurrentText(sourceName);
|
||||
ui->mediaTransitions->setCurrentText(transitionName);
|
||||
ui->mediaStates->setCurrentIndex(s.state);
|
||||
ui->mediaTimeRestrictions->setCurrentIndex(
|
||||
s.restriction);
|
||||
ui->mediaTime->setValue(s.time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switcher->mediaSwitches.emplace_back();
|
||||
|
||||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->mediaSwitches);
|
||||
ui->mediaSwitches->addItem(item);
|
||||
MediaSwitchWidget *sw =
|
||||
new MediaSwitchWidget(&switcher->mediaSwitches.back());
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->mediaSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_mediaAdd_clicked()
|
||||
{
|
||||
QString sourceName = ui->mediaSources->currentText();
|
||||
QString sceneName = ui->mediaScenes->currentText();
|
||||
QString transitionName = ui->mediaTransitions->currentText();
|
||||
obs_media_state state =
|
||||
(obs_media_state)ui->mediaStates->currentIndex();
|
||||
time_restriction restriction =
|
||||
(time_restriction)ui->mediaTimeRestrictions->currentIndex();
|
||||
uint64_t time = ui->mediaTime->value();
|
||||
|
||||
if (sceneName.isEmpty() || transitionName.isEmpty() ||
|
||||
sourceName.isEmpty())
|
||||
return;
|
||||
|
||||
OBSWeakSource source = GetWeakSourceByQString(sourceName);
|
||||
OBSWeakSource scene = GetWeakSourceByQString(sceneName);
|
||||
OBSWeakSource transition = GetWeakTransitionByQString(transitionName);
|
||||
|
||||
QString switchText = MakeMediaSwitchName(sourceName, sceneName,
|
||||
transitionName, state,
|
||||
restriction, time);
|
||||
QVariant v = QVariant::fromValue(switchText);
|
||||
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(switchText, ui->mediaSwitches);
|
||||
item->setData(Qt::UserRole, v);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switcher->mediaSwitches.emplace_back(
|
||||
scene, source, transition, state, restriction, time,
|
||||
(sceneName == QString(previous_scene_name)),
|
||||
switchText.toUtf8().constData());
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_mediaRemove_clicked()
|
||||
void AdvSceneSwitcher::on_mediaRemove_clicked()
|
||||
{
|
||||
QListWidgetItem *item = ui->mediaSwitches->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
std::string mediaStr =
|
||||
item->data(Qt::UserRole).toString().toUtf8().constData();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
int idx = ui->mediaSwitches->currentRow();
|
||||
auto &switches = switcher->mediaSwitches;
|
||||
|
||||
for (auto it = switches.begin(); it != switches.end(); ++it) {
|
||||
auto &s = *it;
|
||||
|
||||
if (s.mediaSwitchStr == mediaStr) {
|
||||
switches.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
switches.erase(switches.begin() + idx);
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_mediaUp_clicked()
|
||||
void AdvSceneSwitcher::on_mediaUp_clicked()
|
||||
{
|
||||
int index = ui->mediaSwitches->currentRow();
|
||||
if (index != -1 && index != 0) {
|
||||
ui->mediaSwitches->insertItem(
|
||||
index - 1, ui->mediaSwitches->takeItem(index));
|
||||
ui->mediaSwitches->setCurrentRow(index - 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->mediaSwitches.begin() + index,
|
||||
switcher->mediaSwitches.begin() + index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_mediaDown_clicked()
|
||||
{
|
||||
int index = ui->mediaSwitches->currentRow();
|
||||
if (index != -1 && index != ui->mediaSwitches->count() - 1) {
|
||||
ui->mediaSwitches->insertItem(
|
||||
index + 1, ui->mediaSwitches->takeItem(index));
|
||||
ui->mediaSwitches->setCurrentRow(index + 1);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
iter_swap(switcher->mediaSwitches.begin() + index,
|
||||
switcher->mediaSwitches.begin() + index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneSwitcher::on_mediaTimeRestrictions_currentIndexChanged(int idx)
|
||||
{
|
||||
if (idx == -1)
|
||||
if (!listMoveUp(ui->mediaSwitches))
|
||||
return;
|
||||
|
||||
if ((time_restriction)ui->mediaTimeRestrictions->currentIndex() ==
|
||||
TIME_RESTRICTION_NONE) {
|
||||
ui->mediaTime->setDisabled(true);
|
||||
} else {
|
||||
ui->mediaTime->setDisabled(false);
|
||||
}
|
||||
MediaSwitchWidget *s1 =
|
||||
(MediaSwitchWidget *)ui->mediaSwitches->itemWidget(
|
||||
ui->mediaSwitches->item(index));
|
||||
MediaSwitchWidget *s2 =
|
||||
(MediaSwitchWidget *)ui->mediaSwitches->itemWidget(
|
||||
ui->mediaSwitches->item(index - 1));
|
||||
MediaSwitchWidget::swapSwitchData(s1, s2);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
std::swap(switcher->mediaSwitches[index],
|
||||
switcher->mediaSwitches[index - 1]);
|
||||
}
|
||||
|
||||
void AdvSceneSwitcher::on_mediaDown_clicked()
|
||||
{
|
||||
int index = ui->mediaSwitches->currentRow();
|
||||
|
||||
if (!listMoveDown(ui->mediaSwitches))
|
||||
return;
|
||||
|
||||
MediaSwitchWidget *s1 =
|
||||
(MediaSwitchWidget *)ui->mediaSwitches->itemWidget(
|
||||
ui->mediaSwitches->item(index));
|
||||
MediaSwitchWidget *s2 =
|
||||
(MediaSwitchWidget *)ui->mediaSwitches->itemWidget(
|
||||
ui->mediaSwitches->item(index + 1));
|
||||
MediaSwitchWidget::swapSwitchData(s1, s2);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
|
||||
std::swap(switcher->mediaSwitches[index],
|
||||
switcher->mediaSwitches[index + 1]);
|
||||
}
|
||||
|
||||
void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
|
||||
OBSWeakSource &transition)
|
||||
{
|
||||
for (MediaSwitch &mediaSwitch : mediaSwitches) {
|
||||
if (!mediaSwitch.initialized())
|
||||
continue;
|
||||
|
||||
obs_source_t *source =
|
||||
obs_weak_source_get_source(mediaSwitch.source);
|
||||
auto duration = obs_source_media_get_duration(source);
|
||||
auto time = obs_source_media_get_time(source);
|
||||
obs_media_state state = obs_source_media_get_state(source);
|
||||
bool matched =
|
||||
state == mediaSwitch.state &&
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_NONE ||
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_LONGER &&
|
||||
time > mediaSwitch.time) ||
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_SHORTER &&
|
||||
time < mediaSwitch.time) ||
|
||||
(mediaSwitch.restriction ==
|
||||
TIME_RESTRICTION_REMAINING_SHORTER &&
|
||||
duration > time &&
|
||||
duration - time < mediaSwitch.time) ||
|
||||
(mediaSwitch.restriction ==
|
||||
TIME_RESTRICTION_REMAINING_LONGER &&
|
||||
duration > time &&
|
||||
duration - time > mediaSwitch.time));
|
||||
if (matched && !mediaSwitch.matched) {
|
||||
obs_source_release(source);
|
||||
|
||||
bool matchedStopped = mediaSwitch.state ==
|
||||
OBS_MEDIA_STATE_STOPPED &&
|
||||
mediaSwitch.stopped;
|
||||
|
||||
// The signal for the state ended is intentionally not used here
|
||||
// so matchedEnded can be used to specify the end of a VLC playlist
|
||||
// by two consequtive matches of OBS_MEDIA_STATE_ENDED
|
||||
//
|
||||
// This was done to reduce the likelyhood of interpreting a single
|
||||
// OBS_MEDIA_STATE_ENDED caught by obs_source_media_get_state()
|
||||
// as the end of the playlist of the VLC source, while actually being
|
||||
// in the middle of switching to the next item of the playlist
|
||||
//
|
||||
// If there is a separate obs_media_sate in the future for the
|
||||
// "end of playlist reached" signal the line below can be used
|
||||
// and an additional check for this new singal can be introduced
|
||||
//
|
||||
// bool matchedEnded = mediaSwitch.state == OBS_MEDIA_STATE_ENDED &&
|
||||
// mediaSwitch.ended;
|
||||
|
||||
bool matchedEnded = false;
|
||||
|
||||
if (state == OBS_MEDIA_STATE_ENDED) {
|
||||
matchedEnded = mediaSwitch.previousStateEnded;
|
||||
mediaSwitch.previousStateEnded = true;
|
||||
} else {
|
||||
mediaSwitch.previousStateEnded = false;
|
||||
}
|
||||
|
||||
// reset for next check
|
||||
mediaSwitch.stopped = false;
|
||||
mediaSwitch.ended = false;
|
||||
|
||||
bool matchedState = ((state == mediaSwitch.state) ||
|
||||
mediaSwitch.anyState) ||
|
||||
matchedStopped || matchedEnded;
|
||||
|
||||
bool matchedTimeNone =
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_NONE);
|
||||
bool matchedTimeLonger =
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_LONGER) &&
|
||||
(time > mediaSwitch.time);
|
||||
bool matchedTimeShorter =
|
||||
(mediaSwitch.restriction == TIME_RESTRICTION_SHORTER) &&
|
||||
(time < mediaSwitch.time);
|
||||
bool matchedTimeRemainLonger =
|
||||
(mediaSwitch.restriction ==
|
||||
TIME_RESTRICTION_REMAINING_LONGER) &&
|
||||
(duration > time && duration - time > mediaSwitch.time);
|
||||
bool matchedTimeRemainShorter =
|
||||
(mediaSwitch.restriction ==
|
||||
TIME_RESTRICTION_REMAINING_SHORTER) &&
|
||||
(duration > time && duration - time < mediaSwitch.time);
|
||||
|
||||
bool matchedTime = matchedTimeNone || matchedTimeLonger ||
|
||||
matchedTimeShorter ||
|
||||
matchedTimeRemainLonger ||
|
||||
matchedTimeRemainShorter;
|
||||
|
||||
bool matched = matchedState && matchedTime;
|
||||
|
||||
if (matched) {
|
||||
match = true;
|
||||
scene = (mediaSwitch.usePreviousScene)
|
||||
? previousScene
|
||||
@@ -167,9 +160,8 @@ void SwitcherData::checkMediaSwitch(bool &match, OBSWeakSource &scene,
|
||||
|
||||
if (verbose)
|
||||
mediaSwitch.logMatch();
|
||||
break;
|
||||
}
|
||||
mediaSwitch.matched = matched;
|
||||
obs_source_release(source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,113 +225,311 @@ void SwitcherData::loadMediaSwitches(obs_data_t *obj)
|
||||
"restriction");
|
||||
uint64_t time = obs_data_get_int(array_obj, "time");
|
||||
|
||||
std::string mediaStr = MakeMediaSwitchName(source, scene,
|
||||
transition, state,
|
||||
restriction, time)
|
||||
.toUtf8()
|
||||
.constData();
|
||||
|
||||
switcher->mediaSwitches.emplace_back(
|
||||
GetWeakSourceByName(scene), GetWeakSourceByName(source),
|
||||
GetWeakTransitionByName(transition), state, restriction,
|
||||
time, (strcmp(scene, previous_scene_name) == 0),
|
||||
mediaStr);
|
||||
time, (strcmp(scene, previous_scene_name) == 0));
|
||||
|
||||
obs_data_release(array_obj);
|
||||
}
|
||||
obs_data_array_release(mediaArray);
|
||||
}
|
||||
|
||||
void SceneSwitcher::setupMediaTab()
|
||||
void AdvSceneSwitcher::setupMediaTab()
|
||||
{
|
||||
populateSceneSelection(ui->mediaScenes, true);
|
||||
populateTransitionSelection(ui->mediaTransitions);
|
||||
|
||||
auto sourceEnum = [](void *data, obs_source_t *source) -> bool /* -- */
|
||||
{
|
||||
QComboBox *combo = reinterpret_cast<QComboBox *>(data);
|
||||
std::string sourceId = obs_source_get_id(source);
|
||||
if (sourceId.compare("ffmpeg_source") == 0 ||
|
||||
sourceId.compare("vlc_source") == 0) {
|
||||
const char *name = obs_source_get_name(source);
|
||||
combo->addItem(name);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
obs_enum_sources(sourceEnum, ui->mediaSources);
|
||||
|
||||
ui->mediaStates->addItem("None");
|
||||
ui->mediaStates->addItem("Playing");
|
||||
ui->mediaStates->addItem("Opening");
|
||||
ui->mediaStates->addItem("Buffering");
|
||||
ui->mediaStates->addItem("Paused");
|
||||
ui->mediaStates->addItem("Stopped");
|
||||
ui->mediaStates->addItem("Ended");
|
||||
ui->mediaStates->addItem("Error");
|
||||
|
||||
ui->mediaTimeRestrictions->addItem("None");
|
||||
ui->mediaTimeRestrictions->addItem("Time shorter");
|
||||
ui->mediaTimeRestrictions->addItem("Time longer");
|
||||
ui->mediaTimeRestrictions->addItem("Time remaining shorter");
|
||||
ui->mediaTimeRestrictions->addItem("Time remaining longer");
|
||||
|
||||
for (auto &s : switcher->mediaSwitches) {
|
||||
std::string sourceName = GetWeakSourceName(s.source);
|
||||
std::string sceneName = (s.usePreviousScene)
|
||||
? previous_scene_name
|
||||
: GetWeakSourceName(s.scene);
|
||||
std::string transitionName = GetWeakSourceName(s.transition);
|
||||
QString listText = MakeMediaSwitchName(
|
||||
sourceName.c_str(), sceneName.c_str(),
|
||||
transitionName.c_str(), s.state, s.restriction, s.time);
|
||||
|
||||
QListWidgetItem *item =
|
||||
new QListWidgetItem(listText, ui->mediaSwitches);
|
||||
item->setData(Qt::UserRole, listText);
|
||||
QListWidgetItem *item;
|
||||
item = new QListWidgetItem(ui->mediaSwitches);
|
||||
ui->mediaSwitches->addItem(item);
|
||||
MediaSwitchWidget *sw = new MediaSwitchWidget(&s);
|
||||
item->setSizeHint(sw->minimumSizeHint());
|
||||
ui->mediaSwitches->setItemWidget(item, sw);
|
||||
}
|
||||
|
||||
if (switcher->mediaSwitches.size() == 0)
|
||||
addPulse = PulseWidget(ui->mediaAdd, QColor(Qt::green));
|
||||
}
|
||||
|
||||
static inline QString
|
||||
MakeMediaSwitchName(const QString &source, const QString &scene,
|
||||
const QString &transition, obs_media_state state,
|
||||
time_restriction restriction, uint64_t time)
|
||||
bool MediaSwitch::initialized()
|
||||
{
|
||||
QString switchName = QStringLiteral("Switch to ") + scene +
|
||||
QStringLiteral(" using ") + transition +
|
||||
QStringLiteral(" if ") + source +
|
||||
QStringLiteral(" state is ");
|
||||
if (state == OBS_MEDIA_STATE_NONE) {
|
||||
switchName += QStringLiteral("none");
|
||||
} else if (state == OBS_MEDIA_STATE_PLAYING) {
|
||||
switchName += QStringLiteral("playing");
|
||||
} else if (state == OBS_MEDIA_STATE_OPENING) {
|
||||
switchName += QStringLiteral("opening");
|
||||
} else if (state == OBS_MEDIA_STATE_BUFFERING) {
|
||||
switchName += QStringLiteral("buffering");
|
||||
} else if (state == OBS_MEDIA_STATE_PAUSED) {
|
||||
switchName += QStringLiteral("paused");
|
||||
} else if (state == OBS_MEDIA_STATE_STOPPED) {
|
||||
switchName += QStringLiteral("stopped");
|
||||
} else if (state == OBS_MEDIA_STATE_ENDED) {
|
||||
switchName += QStringLiteral("ended");
|
||||
} else if (state == OBS_MEDIA_STATE_ERROR) {
|
||||
switchName += QStringLiteral("error");
|
||||
}
|
||||
if (restriction == TIME_RESTRICTION_SHORTER) {
|
||||
switchName += QStringLiteral(" and time shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_LONGER) {
|
||||
switchName += QStringLiteral(" and time longer than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_SHORTER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining shorter than ");
|
||||
} else if (restriction == TIME_RESTRICTION_REMAINING_LONGER) {
|
||||
switchName +=
|
||||
QStringLiteral(" and time remaining longer than ");
|
||||
}
|
||||
if (restriction != TIME_RESTRICTION_NONE) {
|
||||
switchName += std::to_string(time).c_str();
|
||||
switchName += QStringLiteral(" ms");
|
||||
}
|
||||
return switchName;
|
||||
return SceneSwitcherEntry::initialized() && source;
|
||||
}
|
||||
|
||||
bool MediaSwitch::valid()
|
||||
{
|
||||
return !initialized() ||
|
||||
(SceneSwitcherEntry::valid() && WeakSourceValid(source));
|
||||
}
|
||||
|
||||
void MediaSwitch::clearSignalHandler()
|
||||
{
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_disconnect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_disconnect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
void MediaSwitch::resetSignalHandler()
|
||||
{
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_disconnect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_disconnect(sh, "media_ended", MediaEnded, this);
|
||||
signal_handler_connect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_connect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
void MediaSwitch::MediaStopped(void *data, calldata_t *)
|
||||
{
|
||||
MediaSwitch *media = static_cast<MediaSwitch *>(data);
|
||||
media->stopped = true;
|
||||
}
|
||||
|
||||
void MediaSwitch::MediaEnded(void *data, calldata_t *)
|
||||
{
|
||||
MediaSwitch *media = static_cast<MediaSwitch *>(data);
|
||||
media->ended = true;
|
||||
}
|
||||
|
||||
inline MediaSwitch::MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
|
||||
OBSWeakSource transition_,
|
||||
obs_media_state state_,
|
||||
time_restriction restriction_, uint64_t time_,
|
||||
bool usePreviousScene_)
|
||||
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
|
||||
source(source_),
|
||||
state(state_),
|
||||
restriction(restriction_),
|
||||
time(time_)
|
||||
{
|
||||
anyState = state > 7;
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_connect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_connect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
MediaSwitch::MediaSwitch(const MediaSwitch &other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
source(other.source),
|
||||
state(other.state),
|
||||
restriction(other.restriction),
|
||||
time(other.time)
|
||||
{
|
||||
anyState = state > 7;
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_connect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_connect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
MediaSwitch::MediaSwitch(MediaSwitch &&other)
|
||||
: SceneSwitcherEntry(other.scene, other.transition,
|
||||
other.usePreviousScene),
|
||||
source(other.source),
|
||||
state(other.state),
|
||||
anyState(other.anyState),
|
||||
restriction(other.restriction),
|
||||
time(other.time)
|
||||
{
|
||||
}
|
||||
|
||||
MediaSwitch::~MediaSwitch()
|
||||
{
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_disconnect(sh, "media_stopped", MediaStopped, this);
|
||||
signal_handler_disconnect(sh, "media_ended", MediaEnded, this);
|
||||
obs_source_release(mediasource);
|
||||
}
|
||||
|
||||
MediaSwitch &MediaSwitch::operator=(const MediaSwitch &other)
|
||||
{
|
||||
MediaSwitch t(other);
|
||||
swap(*this, t);
|
||||
return *this = MediaSwitch(other);
|
||||
}
|
||||
|
||||
MediaSwitch &MediaSwitch::operator=(MediaSwitch &&other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
swap(*this, other);
|
||||
|
||||
obs_source_t *mediasource = obs_weak_source_get_source(other.source);
|
||||
signal_handler_t *sh = obs_source_get_signal_handler(mediasource);
|
||||
signal_handler_disconnect(sh, "media_stopped", MediaStopped, &other);
|
||||
signal_handler_disconnect(sh, "media_ended", MediaEnded, &other);
|
||||
obs_source_release(mediasource);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(MediaSwitch &first, MediaSwitch &second)
|
||||
{
|
||||
std::swap(first.scene, second.scene);
|
||||
std::swap(first.transition, second.transition);
|
||||
std::swap(first.usePreviousScene, second.usePreviousScene);
|
||||
std::swap(first.source, second.source);
|
||||
std::swap(first.state, second.state);
|
||||
std::swap(first.restriction, second.restriction);
|
||||
std::swap(first.time, second.time);
|
||||
std::swap(first.anyState, second.anyState);
|
||||
first.resetSignalHandler();
|
||||
second.resetSignalHandler();
|
||||
}
|
||||
|
||||
void populateMediaStates(QComboBox *list)
|
||||
{
|
||||
list->addItem("None");
|
||||
list->addItem("Playing");
|
||||
list->addItem("Opening");
|
||||
list->addItem("Buffering");
|
||||
list->addItem("Paused");
|
||||
list->addItem("Stopped");
|
||||
list->addItem("Ended");
|
||||
list->addItem("Error");
|
||||
list->addItem("Any");
|
||||
}
|
||||
|
||||
void populateTimeRestrictions(QComboBox *list)
|
||||
{
|
||||
list->addItem("None");
|
||||
list->addItem("Time shorter");
|
||||
list->addItem("Time longer");
|
||||
list->addItem("Time remaining shorter");
|
||||
list->addItem("Time remaining longer");
|
||||
}
|
||||
|
||||
MediaSwitchWidget::MediaSwitchWidget(MediaSwitch *s) : SwitchWidget(s)
|
||||
{
|
||||
meidaSources = new QComboBox();
|
||||
states = new QComboBox();
|
||||
timeRestrictions = new QComboBox();
|
||||
time = new QSpinBox();
|
||||
|
||||
whenLabel = new QLabel("When");
|
||||
stateLabel = new QLabel("state is");
|
||||
andLabel = new QLabel("and");
|
||||
switchLabel = new QLabel("switch to");
|
||||
usingLabel = new QLabel("using");
|
||||
|
||||
time->setSuffix("ms");
|
||||
time->setMaximum(99999999);
|
||||
time->setMinimum(0);
|
||||
|
||||
QWidget::connect(meidaSources,
|
||||
SIGNAL(currentTextChanged(const QString &)), this,
|
||||
SLOT(SourceChanged(const QString &)));
|
||||
QWidget::connect(states, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(StateChanged(int)));
|
||||
QWidget::connect(timeRestrictions, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(TimeRestrictionChanged(int)));
|
||||
QWidget::connect(time, SIGNAL(valueChanged(int)), this,
|
||||
SLOT(TimeChanged(int)));
|
||||
|
||||
AdvSceneSwitcher::populateMediaSelection(meidaSources);
|
||||
populateMediaStates(states);
|
||||
populateTimeRestrictions(timeRestrictions);
|
||||
|
||||
if (s) {
|
||||
meidaSources->setCurrentText(
|
||||
GetWeakSourceName(s->source).c_str());
|
||||
states->setCurrentIndex(s->state);
|
||||
timeRestrictions->setCurrentIndex(s->restriction);
|
||||
time->setValue(s->time);
|
||||
if (s->restriction == TIME_RESTRICTION_NONE)
|
||||
time->setDisabled(true);
|
||||
}
|
||||
|
||||
setStyleSheet("* { background-color: transparent; }");
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
|
||||
mainLayout->addWidget(whenLabel);
|
||||
mainLayout->addWidget(meidaSources);
|
||||
mainLayout->addWidget(stateLabel);
|
||||
mainLayout->addWidget(states);
|
||||
mainLayout->addWidget(andLabel);
|
||||
mainLayout->addWidget(timeRestrictions);
|
||||
mainLayout->addWidget(time);
|
||||
mainLayout->addWidget(switchLabel);
|
||||
mainLayout->addWidget(scenes);
|
||||
mainLayout->addWidget(usingLabel);
|
||||
mainLayout->addWidget(transitions);
|
||||
mainLayout->addStretch();
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
switchData = s;
|
||||
|
||||
loading = false;
|
||||
}
|
||||
|
||||
MediaSwitch *MediaSwitchWidget::getSwitchData()
|
||||
{
|
||||
return switchData;
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::setSwitchData(MediaSwitch *s)
|
||||
{
|
||||
switchData = s;
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::swapSwitchData(MediaSwitchWidget *s1,
|
||||
MediaSwitchWidget *s2)
|
||||
{
|
||||
SwitchWidget::swapSwitchData(s1, s2);
|
||||
|
||||
MediaSwitch *t = s1->getSwitchData();
|
||||
s1->setSwitchData(s2->getSwitchData());
|
||||
s2->setSwitchData(t);
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::SourceChanged(const QString &text)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->clearSignalHandler();
|
||||
switchData->source = GetWeakSourceByQString(text);
|
||||
switchData->resetSignalHandler();
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::StateChanged(int index)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->state = (obs_media_state)index;
|
||||
switchData->anyState = switchData->state > 7;
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::TimeRestrictionChanged(int index)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
|
||||
if ((time_restriction)index == TIME_RESTRICTION_NONE)
|
||||
time->setDisabled(true);
|
||||
else
|
||||
time->setDisabled(false);
|
||||
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->restriction = (time_restriction)index;
|
||||
}
|
||||
|
||||
void MediaSwitchWidget::TimeChanged(int time)
|
||||
{
|
||||
if (loading || !switchData)
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(switcher->m);
|
||||
switchData->time = time;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user