Add scene groups and rework save and load (#103)

This commit is contained in:
WarmUpTill
2021-01-23 17:39:35 +01:00
committed by GitHub
parent 1f4679433e
commit d989c2b570
38 changed files with 2182 additions and 636 deletions

View File

@@ -39,6 +39,7 @@ public:
void UpdateAutoStartScene(const QString &name);
void UpdateIdleDataTransition(const QString &name);
void UpdateIdleDataScene(const QString &name);
void SetEditSceneGroup(SceneGroup &sg);
void loadUI();
void setupGeneralTab();
@@ -54,13 +55,17 @@ public:
void setupFileTab();
void setupTimeTab();
void setupAudioTab();
void setupSceneGroupTab();
void setTabOrder();
static bool DisplayMessage(QString msg, bool question = false);
static void AskBackup(obs_data_t *obj);
static void populateSceneSelection(QComboBox *sel,
bool addPrevious = false,
bool addSceneGroup = false,
bool addSelect = true);
static void populateTransitionSelection(QComboBox *sel,
bool addSelect = true);
static void populateWindowSelection(QComboBox *sel,
@@ -81,6 +86,11 @@ public:
bool listMoveUp(QListWidget *list);
bool listMoveDown(QListWidget *list);
signals:
void SceneGroupAdded(const QString &name);
void SceneGroupRemoved(const QString &name);
void SceneGroupRenamed(const QString &oldName, const QString newName);
public slots:
void on_windowUp_clicked();
void on_windowDown_clicked();
@@ -189,6 +199,18 @@ public slots:
void on_audioDown_clicked();
void on_audioFallback_toggled(bool on);
void on_sceneGroupAdd_clicked();
void on_sceneGroupRemove_clicked();
void on_sceneGroupUp_clicked();
void on_sceneGroupDown_clicked();
void on_sceneGroupName_editingFinished();
void on_sceneGroups_currentRowChanged(int idx);
void on_sceneGroupSceneAdd_clicked();
void on_sceneGroupSceneRemove_clicked();
void on_sceneGroupSceneUp_clicked();
void on_sceneGroupSceneDown_clicked();
void on_priorityUp_clicked();
void on_priorityDown_clicked();
void on_threadPriority_currentTextChanged(const QString &text);

107
src/headers/scene-group.hpp Normal file
View File

@@ -0,0 +1,107 @@
#pragma once
#include <vector>
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QCheckBox>
#include <obs.hpp>
auto constexpr invalid_scene_group_name = "invalid-scene-group";
enum class AdvanceCondition {
Count,
Time,
Random,
};
struct SceneGroup {
OBSWeakSource getNextScene();
OBSWeakSource getNextSceneCount();
OBSWeakSource getNextSceneTime();
OBSWeakSource getNextSceneRandom();
void advanceIdx();
std::string name = invalid_scene_group_name;
AdvanceCondition type = AdvanceCondition::Count;
std::vector<OBSWeakSource> scenes = {};
int count = 1;
double time = 0;
bool repeat = false;
size_t currentIdx = 0;
int currentCount = -1;
std::chrono::high_resolution_clock::time_point lastAdvTime;
OBSWeakSource lastRandomScene = nullptr;
inline SceneGroup(){};
inline SceneGroup(std::string name_) : name(name_){};
inline SceneGroup(std::string name_, AdvanceCondition type_,
std::vector<OBSWeakSource> scenes_, int count_,
double time_, bool repeat_)
: name(name_),
type(type_),
scenes(scenes_),
count(count_),
time(time_),
repeat(repeat_)
{
}
};
enum class SwitchTargetType {
Scene,
SceneGroup,
};
class SceneGroupEditWidget : public QWidget {
Q_OBJECT
public:
SceneGroupEditWidget();
void SetEditSceneGroup(SceneGroup *sg);
void ShowCurrentTypeEdit();
private slots:
void TypeChanged(int type);
void CountChanged(int count);
void TimeChanged(double time);
void RepeatChanged(int state);
private:
QComboBox *type;
QWidget *timeEdit;
QWidget *countEdit;
QSpinBox *count;
QDoubleSpinBox *time;
QLabel *random;
QCheckBox *repeat;
SceneGroup *sceneGroup = nullptr;
};
// Based on OBS's NameDialog
class SGNameDialog : public QDialog {
Q_OBJECT
public:
SGNameDialog(QWidget *parent);
// Returns true if user clicks OK, false otherwise
// userTextInput returns string that user typed into dialog
static bool AskForName(QWidget *parent, const QString &title,
const QString &text, std::string &userTextInput,
const QString &placeHolder = QString(""),
int maxSize = 170);
private:
QLabel *label;
QLineEdit *userText;
};

View File

@@ -25,6 +25,8 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
const char *getType() { return "audio"; }
bool initialized();
bool valid();
void save(obs_data_t *obj);
void load(obs_data_t *obj);
static void setVolumeLevel(void *data,
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
@@ -32,10 +34,6 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
void resetVolmeter();
AudioSwitch(){};
AudioSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
OBSWeakSource audioSource_, int volumeThreshold_,
audioCondition condition_, double duration_,
bool usePreviousScene_);
AudioSwitch(const AudioSwitch &other);
AudioSwitch(AudioSwitch &&other);
~AudioSwitch();
@@ -46,6 +44,9 @@ struct AudioSwitch : virtual SceneSwitcherEntry {
struct AudioSwitchFallback : virtual SceneSwitcherEntry {
const char *getType() { return "audio_fallback"; }
void save(obs_data_t *obj);
void load(obs_data_t *obj);
bool enable = false;
double duration = 0;
unsigned int matchCount = 0;
@@ -55,7 +56,7 @@ class AudioSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
AudioSwitchWidget(AudioSwitch *s);
AudioSwitchWidget(QWidget *parent, AudioSwitch *s);
void UpdateVolmeterSource();
AudioSwitch *getSwitchData();
void setSwitchData(AudioSwitch *s);
@@ -83,7 +84,7 @@ class AudioSwitchFallbackWidget : public SwitchWidget {
Q_OBJECT
public:
AudioSwitchFallbackWidget(AudioSwitchFallback *s);
AudioSwitchFallbackWidget(QWidget *parent, AudioSwitchFallback *s);
private slots:
void DurationChanged(double dur);

View File

@@ -11,22 +11,15 @@ struct ExecutableSwitch : SceneSwitcherEntry {
bool inFocus = false;
const char *getType() { return "exec"; }
inline ExecutableSwitch(){};
inline ExecutableSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
const QString &exe_, bool inFocus_)
: SceneSwitcherEntry(scene_, transition_),
exe(exe_),
inFocus(inFocus_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class ExecutableSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
ExecutableSwitchWidget(ExecutableSwitch *s);
ExecutableSwitchWidget(QWidget *parent, ExecutableSwitch *s);
ExecutableSwitch *getSwitchData();
void setSwitchData(ExecutableSwitch *s);

View File

@@ -23,29 +23,15 @@ struct FileSwitch : SceneSwitcherEntry {
size_t lastHash = 0;
const char *getType() { return "file"; }
inline FileSwitch(){};
inline FileSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
const char *file_, const char *text_, bool remote_,
bool useRegex_, bool useTime_,
bool onlyMatchIfChanged_)
: SceneSwitcherEntry(scene_, transition_),
file(file_),
text(text_),
remote(remote_),
useRegex(useRegex_),
useTime(useTime_),
onlyMatchIfChanged(onlyMatchIfChanged_),
lastMod()
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class FileSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
FileSwitchWidget(FileSwitch *s);
FileSwitchWidget(QWidget *parent, FileSwitch *s);
FileSwitch *getSwitchData();
void setSwitchData(FileSwitch *s);

View File

@@ -3,6 +3,8 @@
#include <QComboBox>
struct SceneSwitcherEntry {
SwitchTargetType targetType = SwitchTargetType::Scene;
SceneGroup *group = nullptr;
OBSWeakSource scene = nullptr;
OBSWeakSource transition = nullptr;
bool usePreviousScene = false;
@@ -10,7 +12,18 @@ struct SceneSwitcherEntry {
virtual const char *getType() = 0;
virtual bool initialized();
virtual bool valid();
virtual void logMatchScene();
virtual void logMatchSceneGroup();
virtual void logMatch();
virtual OBSWeakSource getScene();
virtual void save(obs_data_t *obj,
const char *targetTypeSaveName = "targetType",
const char *targetSaveName = "target",
const char *transitionSaveName = "transition");
virtual void load(obs_data_t *obj,
const char *targetTypeLoadName = "targetType",
const char *targetLoadName = "target",
const char *transitionLoadName = "transition");
inline SceneSwitcherEntry() {}
@@ -23,6 +36,26 @@ struct SceneSwitcherEntry {
{
}
inline SceneSwitcherEntry(SceneGroup *group_, OBSWeakSource transition_,
bool usePreviousScene_ = false)
: group(group_),
transition(transition_),
usePreviousScene(usePreviousScene_)
{
}
inline SceneSwitcherEntry(SwitchTargetType targetType_,
SceneGroup *group_, OBSWeakSource scene_,
OBSWeakSource transition_,
bool usePreviousScene_ = false)
: targetType(targetType_),
group(group_),
scene(scene_),
transition(transition_),
usePreviousScene(usePreviousScene_)
{
}
virtual ~SceneSwitcherEntry() {}
};
@@ -30,7 +63,8 @@ class SwitchWidget : public QWidget {
Q_OBJECT
public:
SwitchWidget(SceneSwitcherEntry *s, bool usePreviousScene = true);
SwitchWidget(QWidget *parent, SceneSwitcherEntry *s,
bool usePreviousScene = true, bool addSceneGroup = false);
virtual SceneSwitcherEntry *getSwitchData();
virtual void setSwitchData(SceneSwitcherEntry *s);
@@ -39,6 +73,9 @@ public:
private slots:
void SceneChanged(const QString &text);
void TransitionChanged(const QString &text);
void SceneGroupAdd(const QString &name);
void SceneGroupRemove(const QString &name);
void SceneGroupRename(const QString &oldName, const QString &newName);
protected:
bool loading = true;

View File

@@ -12,4 +12,6 @@ struct IdleData : SceneSwitcherEntry {
bool alreadySwitched = false;
const char *getType() { return "idle"; }
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};

View File

@@ -34,6 +34,8 @@ struct MediaSwitch : SceneSwitcherEntry {
const char *getType() { return "media"; }
bool initialized();
bool valid();
void save(obs_data_t *obj);
void load(obs_data_t *obj);
void clearSignalHandler();
void resetSignalHandler();
@@ -41,10 +43,7 @@ struct MediaSwitch : SceneSwitcherEntry {
static void MediaEnded(void *data, calldata_t *);
inline MediaSwitch(){};
inline MediaSwitch(OBSWeakSource scene_, OBSWeakSource source_,
OBSWeakSource transition_, obs_media_state state_,
time_restriction restriction_, uint64_t time_,
bool usePreviousScene_);
MediaSwitch(const MediaSwitch &other);
MediaSwitch(MediaSwitch &&other);
~MediaSwitch();
@@ -57,7 +56,7 @@ class MediaSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
MediaSwitchWidget(MediaSwitch *s);
MediaSwitchWidget(QWidget *parent, MediaSwitch *s);
MediaSwitch *getSwitchData();
void setSwitchData(MediaSwitch *s);

View File

@@ -44,7 +44,7 @@ class PauseEntryWidget : public SwitchWidget {
Q_OBJECT
public:
PauseEntryWidget(PauseEntry *s);
PauseEntryWidget(QWidget *parent, PauseEntry *s);
PauseEntry *getSwitchData();
void setSwitchData(PauseEntry *s);

View File

@@ -6,20 +6,15 @@ struct RandomSwitch : SceneSwitcherEntry {
double delay = 0.0;
const char *getType() { return "random"; }
inline RandomSwitch() {}
inline RandomSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
double delay_)
: SceneSwitcherEntry(scene_, transition_), delay(delay_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class RandomSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
RandomSwitchWidget(RandomSwitch *s);
RandomSwitchWidget(QWidget *parent, RandomSwitch *s);
RandomSwitch *getSwitchData();
void setSwitchData(RandomSwitch *s);

View File

@@ -10,25 +10,15 @@ struct ScreenRegionSwitch : SceneSwitcherEntry {
int minX = 0, minY = 0, maxX = 0, maxY = 0;
const char *getType() { return "region"; }
inline ScreenRegionSwitch(){};
inline ScreenRegionSwitch(OBSWeakSource scene_,
OBSWeakSource transition_, int minX_,
int minY_, int maxX_, int maxY_)
: SceneSwitcherEntry(scene_, transition_),
minX(minX_),
minY(minY_),
maxX(maxX_),
maxY(maxY_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class ScreenRegionWidget : public SwitchWidget {
Q_OBJECT
public:
ScreenRegionWidget(ScreenRegionSwitch *s);
ScreenRegionWidget(QWidget *parent, ScreenRegionSwitch *s);
ScreenRegionSwitch *getSwitchData();
void setSwitchData(ScreenRegionSwitch *s);

View File

@@ -22,27 +22,15 @@ struct SceneSequenceSwitch : SceneSwitcherEntry {
bool initialized();
bool valid();
void logSleep(int dur);
inline SceneSequenceSwitch(){};
inline SceneSequenceSwitch(OBSWeakSource startScene_,
OBSWeakSource scene_,
OBSWeakSource transition_, double delay_,
int delayMultiplier_, bool interruptible_,
bool usePreviousScene_)
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
startScene(startScene_),
delay(delay_),
delayMultiplier(delayMultiplier_),
interruptible(interruptible_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class SequenceWidget : public SwitchWidget {
Q_OBJECT
public:
SequenceWidget(SceneSequenceSwitch *s);
SequenceWidget(QWidget *parent, SceneSequenceSwitch *s);
SceneSequenceSwitch *getSwitchData();
void setSwitchData(SceneSequenceSwitch *s);

View File

@@ -24,23 +24,15 @@ struct TimeSwitch : SceneSwitcherEntry {
QTime time = QTime(0, 0);
const char *getType() { return "time"; }
inline TimeSwitch(){};
inline TimeSwitch(OBSWeakSource scene_, OBSWeakSource transition_,
timeTrigger trigger_, QTime time_,
bool usePreviousScene_)
: SceneSwitcherEntry(scene_, transition_, usePreviousScene_),
trigger(trigger_),
time(time_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class TimeSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
TimeSwitchWidget(TimeSwitch *s);
TimeSwitchWidget(QWidget *parent, TimeSwitch *s);
TimeSwitch *getSwitchData();
void setSwitchData(TimeSwitch *s);

View File

@@ -33,7 +33,7 @@ class TransitionSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
TransitionSwitchWidget(SceneTransition *s);
TransitionSwitchWidget(QWidget *parent, SceneTransition *s);
SceneTransition *getSwitchData();
void setSwitchData(SceneTransition *s);
@@ -53,7 +53,7 @@ class DefTransitionSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
DefTransitionSwitchWidget(DefaultSceneTransition *s);
DefTransitionSwitchWidget(QWidget *parent, DefaultSceneTransition *s);
DefaultSceneTransition *getSwitchData();
void setSwitchData(DefaultSceneTransition *s);

View File

@@ -12,25 +12,15 @@ struct WindowSwitch : SceneSwitcherEntry {
bool focus = true;
const char *getType() { return "window"; }
inline WindowSwitch() {}
inline WindowSwitch(OBSWeakSource scene_, const char *window_,
OBSWeakSource transition_, bool fullscreen_,
bool maximized_, bool focus_)
: SceneSwitcherEntry(scene_, transition_),
window(window_),
fullscreen(fullscreen_),
maximized(maximized_),
focus(focus_)
{
}
void save(obs_data_t *obj);
void load(obs_data_t *obj);
};
class WindowSwitchWidget : public SwitchWidget {
Q_OBJECT
public:
WindowSwitchWidget(WindowSwitch *s);
WindowSwitchWidget(QWidget *parent, WindowSwitch *s);
WindowSwitch *getSwitchData();
void setSwitchData(WindowSwitch *s);

View File

@@ -7,6 +7,7 @@
#include <QThread>
#include <curl/curl.h>
#include "scene-group.hpp"
#include "switch-audio.hpp"
#include "switch-executable.hpp"
#include "switch-file.hpp"
@@ -114,6 +115,8 @@ struct SwitcherData {
std::deque<AudioSwitch> audioSwitches;
AudioSwitchFallback audioFallback;
std::deque<SceneGroup> sceneGroups;
std::vector<int> functionNamesByPriority = std::vector<int>{
default_priority_0, default_priority_1, default_priority_2,
default_priority_3, default_priority_4, default_priority_5,
@@ -210,6 +213,7 @@ struct SwitcherData {
void saveMediaSwitches(obs_data_t *obj);
void saveTimeSwitches(obs_data_t *obj);
void saveAudioSwitches(obs_data_t *obj);
void saveSceneGroups(obs_data_t *obj);
void saveGeneralSettings(obs_data_t *obj);
void saveHotkeys(obs_data_t *obj);
void saveVersion(obs_data_t *obj, std::string currentVersion);
@@ -227,6 +231,7 @@ struct SwitcherData {
void loadMediaSwitches(obs_data_t *obj);
void loadTimeSwitches(obs_data_t *obj);
void loadAudioSwitches(obs_data_t *obj);
void loadSceneGroups(obs_data_t *obj);
void loadGeneralSettings(obs_data_t *obj);
void loadHotkeys(obs_data_t *obj);

View File

@@ -9,6 +9,13 @@
#include <obs-module.h>
#include <obs-frontend-api.h>
static inline bool SceneGroupValid(SceneGroup *group)
{
if (group)
return group->name != invalid_scene_group_name;
return false;
}
static inline bool WeakSourceValid(obs_weak_source_t *ws)
{
obs_source_t *source = obs_weak_source_get_source(ws);
@@ -30,6 +37,25 @@ static inline std::string GetWeakSourceName(obs_weak_source_t *weak_source)
return name;
}
static inline SceneGroup *GetSceneGroupByName(const char *name)
{
if (!switcher)
return nullptr;
for (SceneGroup &sg : switcher->sceneGroups) {
if (sg.name == name) {
return &sg;
}
}
return nullptr;
}
static inline SceneGroup *GetSceneGroupByQString(const QString &name)
{
return GetSceneGroupByName(name.toUtf8().constData());
}
static inline OBSWeakSource GetWeakSourceByName(const char *name)
{
OBSWeakSource weak;